Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
B
blockdb
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
blockchain
blockdb
Commits
4f137abf
Commit
4f137abf
authored
4 years ago
by
Robert Martin-Legene
Browse files
Options
Downloads
Patches
Plain Diff
Rewrote for better database layout
parent
d1780003
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
collector/Dockerfile
+10
-9
10 additions, 9 deletions
collector/Dockerfile
collector/collector.pl
+75
-174
75 additions, 174 deletions
collector/collector.pl
collector/sql.pm
+304
-87
304 additions, 87 deletions
collector/sql.pm
docker-compose.yml
+1
-2
1 addition, 2 deletions
docker-compose.yml
with
390 additions
and
272 deletions
collector/Dockerfile
+
10
−
9
View file @
4f137abf
FROM
debian
RUN
useradd
--create-home
--shell
/bin/bash bfa
&&
mkdir
/home/bfa/collector
RUN
apt-get update
&&
apt-get upgrade
-y
RUN
apt-get
install
-y
libjson-perl libnet-dns-perl libdbd-pg-perl libwww-perl vim
COPY
collector.pl /home/bfa/collector
RUN
chown
-R
bfa /home/bfa
USER
bfa
#CMD /home/bfa/collector/collector.sh
CMD
sleep 14d
FROM
debian
RUN
useradd
--create-home
--shell
/bin/bash bfa
&&
mkdir
/home/bfa/collector
RUN
apt-get update
&&
apt-get upgrade
-y
RUN
apt-get
install
-y
libjson-perl libnet-dns-perl libdbd-pg-perl libwww-perl vim
COPY
collector.pl /home/bfa/collector
RUN
chown
-R
bfa /home/bfa
USER
bfa
ENV
BFANODE public.47525974938.bfa.martin-legene.dk.
#CMD /home/bfa/collector/collector.sh
CMD
sleep 14d
\ No newline at end of file
This diff is collapsed.
Click to expand it.
collector/collector.pl
+
75
−
174
View file @
4f137abf
...
...
@@ -11,8 +11,8 @@ use LWP;
use
JSON
;
use
Net::
DNS
;
use
Net::DNS::
Resolver
;
use
DBI
;
use
"
sql
"
use
lib
'
.
'
;
use
sql
;
# 47525974938;
my
$netversion
=
Math::
BigInt
->
new
(
"
0xb10c4d39a
"
);
...
...
@@ -20,12 +20,9 @@ my $netversion = Math::BigInt->new( "0xb10c4d39a" );
my
$chainid
=
Math::
BigInt
->
new
(
"
0xbfa2018
"
);
my
$idcounter
=
0
;
my
$ua
;
my
@endpoints
;
my
@blockqueue
;
my
%sealers
;
# Set maxruns to 1 if you want to just do a single run to keep
# your database up-to-date.
my
$maxruns
=
0
;
my
$sql
;
sub
info
(@)
{
...
...
@@ -54,8 +51,9 @@ sub shorthash($)
sub
rpcreq
{
my
(
$endpoint
,
$opname
,
@params
)
=
@_
;
my
(
$opname
,
@params
)
=
@_
;
$ua
=
LWP::
UserAgent
->
new
(
keep_alive
=>
10
)
if
not
defined
$ua
;
# $ua->ssl_opts( 'verify_hostname' => 0 );
my
%args
=
(
jsonrpc
=>
'
2.0
',
...
...
@@ -83,8 +81,12 @@ sub rpcreq
push
@args
,
$p
;
}
my
$args
=
'
{
'
.
join
('
,
',
@args
)
.
'
}
';
die
'
The environment variable $BFANODE must contain a URL for a
'
.
'
server to connect to (e.g. https://10.20.30.40/), but it it
'
.
'
not set. Stopped
'
unless
defined
$ENV
{'
BFANODE
'};
my
$res
=
$ua
->
post
(
$
endpoint
,
$
ENV
{
BFANODE
}
,
'
Content-Type
'
=>
'
application/json
',
'
Content
'
=>
$args
,
);
...
...
@@ -94,88 +96,17 @@ sub rpcreq
return
$json
->
{'
result
'};
}
sub
endpoint_find
{
my
$networknumber
=
$netversion
->
bstr
;
my
$res
=
Net::DNS::
Resolver
->
new
();
my
$origin
=
'
bfa.martin-legene.dk
';
my
$fqdn
=
sprintf
'
_rpc._tcp.public.%s.%s.
',
$networknumber
,
$origin
;
my
$reply
=
$res
->
query
(
$fqdn
,
'
SRV
'
);
die
"
No SRV RR found for public endpoints. Stopped
"
if
not
$reply
;
my
@answer
;
@answer
=
rrsort
(
'
SRV
',
'
priority
',
$reply
->
answer
);
die
"
DNS SRV query returned no SRV records. Stopped
"
if
not
@answer
;
my
%protolookup
=
(
'
_rpc
'
=>
'
http
',
'
_rpcs
'
=>
'
https
',
);
@endpoints
=
();
foreach
my
$answer
(
@answer
)
{
my
$targetname
=
$answer
->
target
;
info
"
Publicly open endpoint found at %s.
\n
",
$targetname
;
my
$r_a
=
$res
->
query
(
$targetname
,
'
A
'
);
my
$r_aaaa
=
$res
->
query
(
$targetname
,
'
AAAA
'
);
my
@addresses
=
();
push
@addresses
,
rrsort
(
'
A
',
$r_a
->
answer
)
if
$r_a
;
push
@addresses
,
rrsort
(
'
AAAA
',
$r_aaaa
->
answer
)
if
$r_aaaa
;
warn
"
No address found for
$targetname
,
"
if
not
@addresses
;
my
$label1
=
(
split
(
/\./
,
$fqdn
,
2
))[
0
];
foreach
my
$address_rr
(
@addresses
)
{
next
if
not
exists
$protolookup
{
$label1
};
my
$proto
=
$protolookup
{
$label1
};
push
@endpoints
,
sprintf
(
'
%s://%s:%s
',
$proto
,
$address_rr
->
address
,
$answer
->
port
);
}
}
info
"
Preferring endpoint at %s
\n
",
$endpoints
[
0
];
}
sub
getblock
{
my
$blockid
=
$_
[
0
];
my
$json
;
$blockid
=
Math::
BigInt
->
new
(
$blockid
)
if
ref
(
$blockid
)
eq
''
and
$blockid
=~
/^\d+$/
;
if
(
ref
$blockid
eq
'
Math::BigInt
'
or
$blockid
=~
/^(earliest|latest|pending)$/
)
{
my
$specific
=
ref
$blockid
eq
'
Math::BigInt
'
?
$blockid
->
as_hex
:
$blockid
;
$json
=
rpcreq
(
$endpoints
[
0
],
'
eth_getBlockByNumber
',
$specific
,
'
false
'
);
}
else
{
$sth_selectBlockByHash
->
execute
(
$blockid
);
return
if
$sth_selectBlockByHash
->
fetch
;
$json
=
rpcreq
(
$endpoints
[
0
],
'
eth_getBlockByHash
',
$blockid
,
'
false
'
);
}
my
$block
=
shift
;
my
$rpccmd
=
$block
=~
/^(earliest|latest|pending)$/
?
'
eth_getBlockByNumber
'
:
'
eth_getBlockByHash
';
my
$json
=
rpcreq
(
$rpccmd
,
$block
,
'
false
'
);
die
"
We should have received some kind of JSON from our RPC call,
"
.
"
but apparently not. Stopped
"
if
not
defined
$json
;
$sth_selectBlockByHash
->
execute
(
$json
->
{'
hash
'}
);
return
if
$sth_selectBlockByHash
->
fetch
;
return
if
$sql
->
selectBlockByHash
(
$json
->
{'
hash
'}
);
foreach
my
$key
(
qw(
timestamp gasUsed gasLimit difficulty number totalDifficulty size
)
)
{
...
...
@@ -190,7 +121,7 @@ sub getblock
$json
->
{'
size
'},
$json
->
{'
gasUsed
'},
$json
->
{'
gasLimit
'};
$sth_insertBlock
->
execute
(
$
sql
->
sth_insertBlock
->
execute
(
lc
$json
->
{'
hash
'},
lc
$json
->
{'
parentHash
'},
$json
->
{'
number
'},
...
...
@@ -213,11 +144,11 @@ sub getblock
sub
getTransByHash
{
my
$hash
=
$_
[
0
];
$sth_selectTransactionByHash
->
execute
(
$hash
);
return
if
$sth_selectTransactionByHash
->
fetch
;
my
$hash
=
shift
;
# Don't get it via RPC if we already have it in the database
return
if
$sql
->
selectTransactionByHash
(
$hash
);
my
$json
=
rpcreq
(
$endpoints
[
0
],
'
eth_getTransactionByHash
',
$hash
);
...
...
@@ -225,7 +156,6 @@ sub getTransByHash
my
$rcpt
=
undef
;
do
{
$rcpt
=
rpcreq
(
$endpoints
[
0
],
'
eth_getTransactionReceipt
',
$hash
);
...
...
@@ -234,7 +164,7 @@ sub getTransByHash
sleep
1
;
warn
"
Couldn't get the transaction receipt for
$hash
\n
";
}
}
while
not
$rcpt
and
$max
++
<
6
0
;
}
while
not
$rcpt
and
$max
++
<
1
0
;
die
"
Couldn't get the transaction receipt for
$hash
\n
"
if
not
$rcpt
;
$json
->
{'
status
'}
=
$rcpt
->
{'
status
'};
$json
->
{'
gasUsed
'}
=
$rcpt
->
{'
gasUsed
'};
...
...
@@ -251,8 +181,11 @@ sub getTransByHash
shorthash
$json
->
{'
from
'},
shorthash
$json
->
{'
to
'};
my
$input
=
$json
->
{'
input
'};
$input
=~
s/^0x//
;
my
$inputlen
=
length
(
$input
)
/
2
;
my
$inputlen
=
0
;
if
(
$input
=~
/^0x/
)
{
$inputlen
=
(
length
(
$input
)
-
2
)
/
2
;
}
my
@args
=
(
lc
$json
->
{'
hash
'},
lc
$json
->
{'
blockHash
'},
...
...
@@ -262,31 +195,26 @@ sub getTransByHash
$json
->
{'
value
'},
lc
$json
->
{'
from
'},
lc
$json
->
{'
to
'},
$inputlen
,
$json
->
{'
gasUsed
'},
$json
->
{'
status
'},
$json
->
{'
gasUsed
'},
$input
,
$inputlen
,
);
my
$function
=
$sth_insertTransaction
;
if
(
$json
->
{'
contractAddress
'}
)
{
push
@args
,
$json
->
{'
contractAddress
'};
$function
=
$sth_insertTransactionWithContractAddress
;
$sql
->
insertTransactionWithContractAddress
(
@args
,
lc
$json
->
{'
contractAddress
'}
);
}
else
{
$sql
->
insertTransaction
(
@args
);
}
$function
->
execute
(
@args
);
}
sub
getTransRcptByHash
{
my
$hash
=
$_
[
0
];
}
sub
versioncheck
{
my
$n
;
my
$ok
=
1
;
$n
=
Math::
BigInt
->
new
(
rpcreq
(
$endpoints
[
0
],
"
net_version
"
)
);
$n
=
Math::
BigInt
->
new
(
rpcreq
(
"
net_version
"
)
);
if
(
$n
->
bcmp
(
$netversion
)
!=
0
)
{
warn
"
Network says it has net.version
"
...
...
@@ -298,9 +226,7 @@ sub versioncheck
.
"
).
\n
";
$ok
=
0
;
}
$n
=
Math::
BigInt
->
new
(
rpcreq
(
$endpoints
[
0
],
"
eth_chainId
"
)
);
$n
=
Math::
BigInt
->
new
(
rpcreq
(
"
eth_chainId
"
)
);
if
(
$n
->
bcmp
(
$chainid
)
!=
0
)
{
warn
sprintf
("
Network says it has eth.chainId %s (%s). Expected %s (%s).
\n
",
$n
->
bstr
,
$n
->
as_hex
,
$chainid
->
bstr
,
$chainid
->
as_hex
);
...
...
@@ -310,76 +236,56 @@ sub versioncheck
return
$ok
;
}
sub
sealer
{
my
$hash
=
$_
[
0
];
my
$row
;
die
unless
defined
$hash
;
return
$sealers
{
$hash
}
if
exists
$sealers
{
$hash
};
$sth_selectsealer
->
execute
(
$hash
);
return
$sealers
{
$hash
}
=
$row
->
[
0
]
if
$row
=
$sth_selectsealer
->
fetch
;
$sth_insertsealer
->
execute
(
$hash
);
$sth_selectsealer
->
execute
(
$hash
);
die
"
Apparently we failed to get find/create a new sealer. Stopped
"
if
not
$row
=
$sth_selectsealer
->
fetch
;
return
$sealers
{
$hash
}
=
$row
->
[
0
];
}
sub
getsnap
{
my
$number
=
$_
[
0
];
my
@blocks
;
$number
=
Math::
BigInt
->
new
(
$number
)
if
ref
(
$number
)
ne
'
Math::BigInt
';
my
$blockhash
=
$_
[
0
];
my
$json
=
rpcreq
(
$endpoints
[
0
],
'
clique_getSnapshot
',
$number
->
as_hex
'
clique_getSnapshotAtHash
',
$blockhash
);
# Sanity check 1 - does the lookup return the block?
return
if
not
defined
$json
;
my
$recents
=
$json
->
{'
recents
'};
return
if
not
defined
$recents
;
my
$hash
=
$json
->
{'
hash
'};
my
$count
=
0
;
while
(
exists
$recents
->
{
$number
->
bstr
}
)
# Blockhash of the requested block - we must use this for the insert
$blockhash
=
$json
->
{'
hash
'};
my
$blocknumber
=
Math::
BigInt
->
new
(
$json
->
{'
number
'}
);
my
@infonumbers
;
while
(
not
$blocknumber
->
is_zero
)
{
push
@blocks
,
$number
->
bstr
;
$sth_selectBlockByHash
->
execute
(
$hash
);
my
$row
=
$sth_selectBlockByHash
->
fetchrow_hashref
;
return
if
not
defined
$row
;
my
$newnumber
=
Math::
BigInt
->
new
(
$row
->
{'
number
'}
);
return
if
$newnumber
->
bcmp
(
$number
)
!=
0
;
my
$sealerhash
=
$recents
->
{
$blocknumber
->
bstr
};
last
if
not
defined
$sealerhash
;
push
@infonumbers
,
$blocknumber
->
bstr
;
my
$ref
=
$sql
->
selectBlockByHash
(
$blockhash
);
# Stop if we get to blocks which we still haven't stored in the db
return
(
undef
,
$blocknumber
)
if
not
defined
$ref
;
# Stop if we got to a block with sealers.
return
if
defined
$row
->
{'
sealer
'};
my
$sealerhash
=
$recents
->
{
$number
->
bstr
};
return
if
not
defined
$sealerhash
;
my
$internalid
=
sealer
(
$sealerhash
);
return
if
not
defined
$internalid
;
my
$rows_affected
=
$sth_updatewhosealed
->
execute
(
$internalid
,
$hash
);
return
(
undef
,
$blocknumber
)
if
exists
$ref
->
{'
sealerAccountId
'}
and
defined
$ref
->
{'
sealerAccountId
'};
$sql
->
updateWhoSealed
(
$sealerhash
,
$blockhash
);
my
$parentblockid
=
$ref
->
{'
parentBlockhashId
'};
# For next block...
$
hash
=
$
row
->
{'
parentHash
'}
;
$number
->
bsub
(
1
);
$
blockhash
=
$
sql
->
selectBlockhashById
(
$parentblockid
)
;
$
block
number
->
bsub
(
1
);
}
info
"
S Snapshot at block #
@
block
s
.
\n
";
return
$
number
;
info
"
S Snapshot at block #
@
infonumber
s
.
\n
";
return
(
$blockhash
,
$block
number
)
;
}
# Find strands of blocks in the database which have their sealer set to NULL
sub
allsnaps
{
$sth_selectmaxunknownsigned
->
execute
();
my
$unkn
=
$sth_selectmaxunknownsigned
->
fetchrow_hashref
;
my
$number
=
Math::
BigInt
->
new
(
$unkn
->
{'
number
'}
);
my
$blockhash
=
$sql
->
selectMaxUnknownSigned
;
my
$committer
=
0
;
while
(
defined
$
number
and
not
$number
->
is_zero
)
while
(
defined
$
blockhash
)
{
$number
=
getsnap
(
$number
);
$dbh
->
commit
my
$blocknumber
;
(
$blockhash
,
$blocknumber
)
=
getsnap
(
$blockhash
);
$sql
->
commit
if
(
$committer
++
%
75
)
==
0
;
last
if
$blocknumber
->
is_zero
;
}
$dbh
->
commit
;
}
sub
main
...
...
@@ -387,20 +293,15 @@ sub main
$|
=
1
;
info
"
Connecting to database and setting up
"
.
"
prepared statements.
\n
";
sql::
setup
;
#
info
"
Looking for public RPC endpoints of
"
.
"
the BFA.
\n
";
$ua
=
LWP::
UserAgent
->
new
(
keep_alive
=>
10
);
endpoint_find
();
$sql
=
sql
->
new
();
versioncheck
();
info
"
Looking for orphaned blocks in the
"
.
"
database.
\n
";
push
@blockqueue
,
sql
::
listOrphans
();
push
@blockqueue
,
sql
->
listOrphans
();
while
(
--
$maxruns
!=
0
)
while
(
1
)
{
unshift
@blockqueue
,
"
latest
"
;
unshift
@blockqueue
,
'
latest
'
;
while
(
@blockqueue
)
{
my
$maxinarow
=
2500
;
...
...
@@ -408,7 +309,7 @@ sub main
while
@blockqueue
and
--
$maxinarow
;
# Find out who signed all blocks
allsnaps
();
$
dbh
->
commit
;
$
sql
->
commit
;
}
sleep
5
;
}
...
...
This diff is collapsed.
Click to expand it.
collector/sql.pm
+
304
−
87
View file @
4f137abf
...
...
@@ -4,105 +4,322 @@
package
sql
;
use
DBI
;
use
base
qw( Class::Accessor )
;
my
@blockqueue
;
my
$dbh
;
my
$sth_insertBlock
;
my
$sth_selectBlockByHash
;
my
$sth_selectTransactionByHash
;
my
$sth_insertTransaction
;
my
$sth_insertTransactionWithContractAddress
;
my
$sth_insertsealer
;
my
$sth_selectsealer
;
my
$sth_updatewhosealed
;
my
$sth_selectmaxunknownsigned
;
sub
setup
__PACKAGE__
->
mk_accessors
(
'
dbh
'
);
sub
new
{
$dbh
=
DBI
->
connect
(
my
(
$class
)
=
@_
;
my
$self
=
bless
{},
ref
$class
||
$class
;
$self
->
dbh
(
DBI
->
connect
(
'
dbi:Pg:dbname=postgres;host=postgres
','
postgres
','
onlythelonely
',
{
AutoCommit
=>
0
,
RaiseError
=>
1
}
)
or
die
DBI::
errstr
;
$sth_insertBlock
=
$dbh
->
prepare
(
q(
INSERT INTO blocks
( hash, parentHash, number, timestamp,
difficulty, gasUsed, gasLimit, size )
VALUES (?,?,?,?,?,?,?,?)
)
)
or
die
$
DBI::
errstr
;
$sth_selectBlockByHash
=
$dbh
->
prepare
(
q(
SELECT parenthash,number,sealer
FROM blocks
WHERE hash=?
)
)
or
die
$
DBI::
errstr
;
$sth_selectTransactionByHash
=
$dbh
->
prepare
(
q(
SELECT "exists"
FROM transactions
WHERE hash=?
)
)
or
die
$
DBI::
errstr
;
$sth_insertTransactionWithContractAddress
=
$dbh
->
prepare
(
q(
INSERT INTO transactions
( hash, blockHash, nonce, gas,
gasPrice, value, _from, _to,
inputlen, gasUsed, status, contractAddress )
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)
)
)
or
die
$
DBI::
errstr
;
$sth_insertTransaction
=
$dbh
->
prepare
(
q(
INSERT INTO transactions
( hash, blockHash, nonce, gas,
gasPrice, value, _from, _to,
inputlen, gasUsed, status )
VALUES (?,?,?,?,?,?,?,?,?,?,?)
)
)
or
die
$
DBI::
errstr
;
$sth_selectsealer
=
$dbh
->
prepare
(
q(
SELECT internalid
FROM sealers
WHERE hash=?
)
)
or
die
$
DBI::
errstr
;
$sth_insertsealer
=
$dbh
->
prepare
(
q(
INSERT INTO sealers
( hash )
VALUES (?)
)
)
or
die
$
DBI::
errstr
;
$sth_updatewhosealed
=
$dbh
->
prepare
(
q(
UPDATE blocks
SET sealer=?
WHERE hash=?
AND sealer IS NULL
)
)
or
die
$
DBI::
errstr
;
$sth_selectmaxunknownsigned
=
$dbh
->
prepare
(
q(
SELECT number
FROM blocks
WHERE number = (
SELECT MAX(number)
FROM blocks
WHERE sealer IS NULL
)
)
)
or
die
$
DBI::
errstr
;
));
return
$self
;
}
sub
listOrphans
sub
commit
{
my
@results
;
my
$sth_selectOrphans
=
$dbh
->
prepare
(
q(
SELECT parentHash,number
my
(
$self
)
=
@_
;
$self
->
dbh
->
commit
;
}
sub
listOrphans
{
my
(
$self
)
=
@_
;
my
$sth
=
$self
->
dbh
->
prepare
(
q(
SELECT parentBlockhashId,id
FROM blocks
WHERE parent
H
ash NOT IN (
SELECT
hash
WHERE parent
Blockh
ash
Id
NOT IN (
SELECT
id
FROM blocks
)
)
)
or
die
$
DBI::
errstr
;
$sth_selectOrphans
->
execute
();
while
(
my
$row
=
$sth_selectOrphans
->
fetch
)
)
);
my
@results
;
$sth
->
execute
();
while
(
my
$row
=
$sth
->
fetchrow_arrayref
)
{
# Block 0 has it's parent listed as 0x0{64}
next
if
$row
->
[
0
]
=~
/^0x0{64}$/
;
push
@results
,
$row
->
[
0
]
next
if
$row
->
[
0
]
=~
/^0x0{64}$/
;
push
@results
,
$self
->
selectBlockhashById
(
$row
->
[
0
]
);
}
$sth
->
finish
;
return
@results
;
}
__PACKAGE__
->
mk_accessors
(
'
sth_insertTransactionWithContractAddress
'
);
sub
insertTransactionWithContractAddress
{
my
$self
=
shift
;
if
(
not
defined
$self
->
sth_insertTransactionWithContractAddress
)
{
$self
->
sth_insertTransactionWithContractAddress
(
$self
->
dbh
->
prepare
(
q(
INSERT INTO transactions
( hash, blockId, nonce, gas,
gasPrice, value, fromAccountId, toAccountId,
status, gasUsed, input, inputlen,
contractaddressAccountId )
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)
)
)
);
}
$_
[
1
]
=
$self
->
selectBlockhashByHash
(
$_
[
1
]
);
$self
->
sth_insertTransactionWithContractAddress
->
execute
(
@
_
);
}
__PACKAGE__
->
mk_accessors
(
'
sth_insertTransaction
'
);
sub
insertTransaction
{
my
$self
=
shift
;
$self
->
sth_insertTransaction
(
$self
->
dbh
->
prepare
(
q(
INSERT INTO transactions
( hash, blockId, nonce, gas,
gasPrice, value, fromAccountId, toAccountId,
status, gasUsed, input, inputlen )
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)
)
)
);
$_
[
1
]
=
$self
->
selectBlockhashByHash
(
$_
[
1
]
);
$self
->
sth_insertTransaction
->
execute
(
@
_
);
}
__PACKAGE__
->
mk_accessors
(
'
sth_selectBlockhashById
'
);
sub
selectBlockhashById
{
my
(
$self
,
$id
)
=
@_
;
if
(
not
defined
$self
->
sth_selectBlockhashById
)
{
$self
->
sth_selectBlockhashById
(
$self
->
dbh
->
prepare
(
q(
SELECT hash
FROM blockhash
WHERE id=?
)
)
);
}
$self
->
sth_selectBlockhashById
->
execute
(
$id
);
my
$ref
=
$self
->
sth_selectBlockhashById
->
fetchrow_arrayref
;
$self
->
sth_selectBlockhashById
->
finish
;
return
if
not
defined
$ref
;
return
$ref
->
[
0
];
}
__PACKAGE__
->
mk_accessors
(
'
sth_selectBlockhashByHash
'
);
sub
selectBlockhashByHash
{
my
(
$self
,
$hash
)
=
@_
;
if
(
not
defined
$self
->
sth_selectBlockhashByHash
)
{
$self
->
sth_selectBlockhashByHash
(
$self
->
dbh
->
prepare
(
q(
SELECT id
FROM blockhash
WHERE hash=?
)
)
);
}
my
$inserts
=
0
;
while
(
1
)
{
# Try to look up the hash
$self
->
sth_selectBlockhashByHash
->
execute
(
$hash
);
my
$ref
=
$self
->
sth_selectBlockhashByHash
->
fetchrow_arrayref
;
$self
->
sth_selectBlockhashByHash
->
finish
;
# If found, return it immediately
return
$ref
->
[
0
]
if
defined
$ref
;
# Do maximum 1 attempt to insert a hash
return
if
$inserts
>
0
;
# Insert a hash, because it is not already in the database.
$self
->
insertBlockhash
(
$hash
);
# Avoid loops.
$inserts
++
;
}
}
__PACKAGE__
->
mk_accessors
(
'
sth_insertBlockhash
'
);
sub
insertBlockhash
{
my
(
$self
,
$hash
)
=
@_
;
if
(
not
defined
$self
->
sth_insertBlockhash
)
{
$self
->
sth_insertBlockhash
(
$self
->
dbh
->
prepare
(
q(
INSERT INTO blockhash
( hash )
VALUES (?)
)
)
)
}
$self
->
sth_insertBlockhash
->
execute
(
$hash
);
}
__PACKAGE__
->
mk_accessors
(
'
sth_selectAccountIdByAddress
'
);
my
%account
;
sub
selectAccountIdByAddress
{
my
(
$self
,
$address
)
=
@_
;
if
(
not
defined
$self
->
sth_selectAccountIdByAddress
)
{
$self
->
sth_selectAccountIdByAddress
(
$self
->
dbh
->
prepare
(
q(
SELECT id
FROM account
WHERE address=?
)
)
);
}
while
(
not
exists
$account
{
$address
}
)
{
# Try to look up the hash
$self
->
sth_selectAccountIdByAddress
->
execute
(
$address
);
my
$ref
=
$self
->
sth_selectAccountIdByAddress
->
fetchrow_arrayref
;
$self
->
sth_selectAccountIdByAddress
->
finish
;
# If found, return it immediately
if
(
defined
$ref
)
{
$account
{
$address
}
=
$row
->
[
0
];
last
;
}
# Do maximum 1 attempt to insert a hash
# (this is actually a failure and should not happen)
return
if
$inserts
>
0
;
# Insert a hash, because it is not already in the database.
$self
->
insertAccount
(
$hash
);
# Avoid loops.
$inserts
++
;
}
return
$account
{
$address
};
}
__PACKAGE__
->
mk_accessors
(
'
sth_insertAccount
'
);
sub
insertAccount
{
my
(
$self
,
$address
)
=
@_
;
if
(
not
defined
$self
->
sth_insertAccount
)
{
$self
->
sth_insertAccount
(
$self
->
dbh
->
prepare
(
q(
INSERT INTO account
( address )
VALUES (?)
)
)
);
}
$self
->
sth_insertAccount
->
execute
(
$hash
);
}
__PACKAGE__
->
mk_accessors
(
'
sth_insertBlock
'
);
sub
insertBlock
{
my
(
$self
,
$hash
,
$parentHash
,
$number
,
$timestamp
,
$difficulty
,
$gasUsed
,
$gasLimit
,
$size
)
=
@_
;
if
(
not
defined
$self
->
sth_insertBlock
)
{
$self
->
sth_insertBlock
(
$self
->
dbh
->
prepare
(
q(
INSERT INTO blocks
( id, parentBlockhashId, number, timestamp,
difficulty, gasUsed, gasLimit, size )
VALUES (?,?,?,?,?,?,?,?)
)
)
);
}
my
$id
=
$self
->
selectBlockhashByHash
(
$hash
);
my
$parentid
=
$self
->
selectBlockhashByHash
(
$parentHash
);
$self
->
sth_insertBlock
->
execute
(
$id
,
$parentid
,
$number
,
$timestamp
,
$difficulty
,
$gasUsed
,
$gasLimit
,
$size
);
}
__PACKAGE__
->
mk_accessors
(
'
sth_selectBlockByHash
'
);
sub
selectBlockByHash
{
my
(
$self
,
$hash
)
=
@_
;
if
(
not
defined
$self
->
sth_selectBlockByHash
)
{
$self
->
sth_selectBlockByHash
(
$self
->
dbh
->
prepare
(
q(
SELECT parenthash,number,sealer
FROM blocks
WHERE hash=?
)
)
);
}
$sth
->
sth_selectBlockByHash
(
$hash
);
my
$row
=
$sth
->
selectBlockByHash
->
fetchrow_hashref
;
$sth
->
selectBlockByHash
->
finish
;
return
if
not
defined
$row
;
return
$row
;
}
__PACKAGE__
->
mk_accessors
(
'
sth_selectTransactionByHash
'
);
sub
selectTransactionByHash
{
my
(
$self
,
$hash
)
=
@_
;
if
(
not
defined
$self
->
sth_selectTransactionByHash
)
{
$self
->
sth_selectTransactionByHash
(
$self
->
dbh
->
prepare
(
q(
SELECT 1
FROM transactions
WHERE hash=?
)
)
);
}
$sth
->
sth_selectTransactionByHash
(
$hash
);
my
$row
=
$sth
->
selectTransactionByHash
->
fetchrow_hashref
;
$sth
->
selectTransactionByHash
->
finish
;
return
if
not
defined
$row
;
return
$row
;
}
__PACKAGE__
->
mk_accessors
(
'
sth_selectAccountIdByAddress
'
);
sub
updateWhoSealed
{
my
(
$self
,
$sealerhash
,
$blockhash
)
=
@_
;
if
(
not
defined
$self
->
sth_updatewhosealed
)
{
$self
->
sth_updatewhosealed
(
$self
->
dbh
->
prepare
(
q(
UPDATE blocks
SET sealerAccountId=?
WHERE id=?
AND sealerAccountId IS NULL
)
)
);
}
my
$blockid
=
$self
->
selectBlockhashByHash
(
$blockhash
);
my
$sealerid
=
$self
->
selectSealerByHash
(
$sealerhash
);
$self
->
sth_updatewhosealed
->
execute
(
$sealerid
,
$blockid
);
}
__PACKAGE__
->
mk_accessors
(
'
sth_selectmaxunknownsigned
'
);
sub
selectMaxUnknownSigned
{
my
(
$self
)
=
@_
;
if
(
not
defined
$self
->
sth_selectmaxunknownsigned
)
{
$self
->
sth_selectmaxunknownsigned
(
$self
->
dbh
->
prepare
(
q(
SELECT id
FROM blocks
WHERE number = (
SELECT MAX(number)
FROM blocks
WHERE sealer IS NULL
)
)
)
);
}
$self
->
sth_selectmaxunknownsigned
->
execute
();
my
$ref
=
$self
->
sth_selectmaxunknownsigned
->
fetchrow_hashref
;
$self
->
sth_selectmaxunknownsigned
->
finish
();
my
$blockid
=
$ref
->
{'
number
'};
my
$blockhash
=
$self
->
selectBlockhashById
(
$blockid
);
return
$blockhash
;
}
1
;
\ No newline at end of file
1
;
This diff is collapsed.
Click to expand it.
docker-compose.yml
+
1
−
2
View file @
4f137abf
...
...
@@ -2,8 +2,7 @@
## POSTGRES SUPERUSER user name is postgres
## POSTGRES SUPERUSER password is onlythelonely
## POSTGRES USER dgsi has password bfa
# defined in postgres/90-add-db-user.sh
## POSTGRES USER leer has password bfa defined in postgres/90-add-db-user.sh
version
:
'
3.4'
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment