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
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
FROM
debian
RUN
useradd
--create-home
--shell
/bin/bash bfa
&&
mkdir
/home/bfa/collector
RUN
useradd
--create-home
--shell
/bin/bash bfa
&&
mkdir
/home/bfa/collector
RUN
apt-get update
&&
apt-get upgrade
-y
RUN
apt-get update
&&
apt-get upgrade
-y
RUN
apt-get
install
-y
libjson-perl libnet-dns-perl libdbd-pg-perl libwww-perl vim
RUN
apt-get
install
-y
libjson-perl libnet-dns-perl libdbd-pg-perl libwww-perl vim
COPY
collector.pl /home/bfa/collector
COPY
collector.pl /home/bfa/collector
RUN
chown
-R
bfa /home/bfa
RUN
chown
-R
bfa /home/bfa
USER
bfa
USER
bfa
#CMD /home/bfa/collector/collector.sh
ENV
BFANODE public.47525974938.bfa.martin-legene.dk.
CMD
sleep 14d
#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;
...
@@ -11,8 +11,8 @@ use LWP;
use
JSON
;
use
JSON
;
use
Net::
DNS
;
use
Net::
DNS
;
use
Net::DNS::
Resolver
;
use
Net::DNS::
Resolver
;
use
DBI
;
use
lib
'
.
'
;
use
"
sql
"
use
sql
;
# 47525974938;
# 47525974938;
my
$netversion
=
Math::
BigInt
->
new
(
"
0xb10c4d39a
"
);
my
$netversion
=
Math::
BigInt
->
new
(
"
0xb10c4d39a
"
);
...
@@ -20,12 +20,9 @@ my $netversion = Math::BigInt->new( "0xb10c4d39a" );
...
@@ -20,12 +20,9 @@ my $netversion = Math::BigInt->new( "0xb10c4d39a" );
my
$chainid
=
Math::
BigInt
->
new
(
"
0xbfa2018
"
);
my
$chainid
=
Math::
BigInt
->
new
(
"
0xbfa2018
"
);
my
$idcounter
=
0
;
my
$idcounter
=
0
;
my
$ua
;
my
$ua
;
my
@endpoints
;
my
@blockqueue
;
my
@blockqueue
;
my
%sealers
;
my
%sealers
;
# Set maxruns to 1 if you want to just do a single run to keep
my
$sql
;
# your database up-to-date.
my
$maxruns
=
0
;
sub
info
(@)
sub
info
(@)
{
{
...
@@ -54,8 +51,9 @@ sub shorthash($)
...
@@ -54,8 +51,9 @@ sub shorthash($)
sub
rpcreq
sub
rpcreq
{
{
my
(
$endpoint
,
my
(
$opname
,
@params
)
=
@_
;
$opname
,
@params
)
=
@_
;
$ua
=
LWP::
UserAgent
->
new
(
keep_alive
=>
10
)
if
not
defined
$ua
;
# $ua->ssl_opts( 'verify_hostname' => 0 );
# $ua->ssl_opts( 'verify_hostname' => 0 );
my
%args
=
(
my
%args
=
(
jsonrpc
=>
'
2.0
',
jsonrpc
=>
'
2.0
',
...
@@ -83,8 +81,12 @@ sub rpcreq
...
@@ -83,8 +81,12 @@ sub rpcreq
push
@args
,
$p
;
push
@args
,
$p
;
}
}
my
$args
=
'
{
'
.
join
('
,
',
@args
)
.
'
}
';
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
(
my
$res
=
$ua
->
post
(
$
endpoint
,
$
ENV
{
BFANODE
}
,
'
Content-Type
'
=>
'
application/json
',
'
Content-Type
'
=>
'
application/json
',
'
Content
'
=>
$args
,
'
Content
'
=>
$args
,
);
);
...
@@ -94,88 +96,17 @@ sub rpcreq
...
@@ -94,88 +96,17 @@ sub rpcreq
return
$json
->
{'
result
'};
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
sub
getblock
{
{
my
$blockid
=
$_
[
0
];
my
$block
=
shift
;
my
$json
;
my
$rpccmd
=
$block
=~
/^(earliest|latest|pending)$/
$blockid
=
Math::
BigInt
->
new
(
$blockid
)
?
'
eth_getBlockByNumber
'
if
ref
(
$blockid
)
eq
''
:
'
eth_getBlockByHash
';
and
$blockid
=~
/^\d+$/
;
my
$json
=
rpcreq
(
$rpccmd
,
$block
,
'
false
'
);
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
'
);
}
die
"
We should have received some kind of JSON from our RPC call,
"
.
die
"
We should have received some kind of JSON from our RPC call,
"
.
"
but apparently not. Stopped
"
"
but apparently not. Stopped
"
if
not
defined
$json
;
if
not
defined
$json
;
$sth_selectBlockByHash
->
execute
(
$json
->
{'
hash
'}
);
return
if
$sql
->
selectBlockByHash
(
$json
->
{'
hash
'}
);
return
if
$sth_selectBlockByHash
->
fetch
;
foreach
my
$key
(
qw(
foreach
my
$key
(
qw(
timestamp gasUsed gasLimit difficulty number totalDifficulty size
timestamp gasUsed gasLimit difficulty number totalDifficulty size
)
)
{
)
)
{
...
@@ -190,7 +121,7 @@ sub getblock
...
@@ -190,7 +121,7 @@ sub getblock
$json
->
{'
size
'},
$json
->
{'
size
'},
$json
->
{'
gasUsed
'},
$json
->
{'
gasUsed
'},
$json
->
{'
gasLimit
'};
$json
->
{'
gasLimit
'};
$sth_insertBlock
->
execute
(
$
sql
->
sth_insertBlock
->
execute
(
lc
$json
->
{'
hash
'},
lc
$json
->
{'
hash
'},
lc
$json
->
{'
parentHash
'},
lc
$json
->
{'
parentHash
'},
$json
->
{'
number
'},
$json
->
{'
number
'},
...
@@ -213,11 +144,11 @@ sub getblock
...
@@ -213,11 +144,11 @@ sub getblock
sub
getTransByHash
sub
getTransByHash
{
{
my
$hash
=
$_
[
0
];
my
$hash
=
shift
;
$sth_selectTransactionByHash
->
execute
(
$hash
);
# Don't get it via RPC if we already have it in the database
return
if
$sth_selectTransactionByHash
->
fetch
;
return
if
$sql
->
selectTransactionByHash
(
$hash
);
my
$json
=
rpcreq
(
my
$json
=
rpcreq
(
$endpoints
[
0
],
'
eth_getTransactionByHash
',
'
eth_getTransactionByHash
',
$hash
$hash
);
);
...
@@ -225,7 +156,6 @@ sub getTransByHash
...
@@ -225,7 +156,6 @@ sub getTransByHash
my
$rcpt
=
undef
;
my
$rcpt
=
undef
;
do
{
do
{
$rcpt
=
rpcreq
(
$rcpt
=
rpcreq
(
$endpoints
[
0
],
'
eth_getTransactionReceipt
',
'
eth_getTransactionReceipt
',
$hash
$hash
);
);
...
@@ -234,7 +164,7 @@ sub getTransByHash
...
@@ -234,7 +164,7 @@ sub getTransByHash
sleep
1
;
sleep
1
;
warn
"
Couldn't get the transaction receipt for
$hash
\n
";
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
;
die
"
Couldn't get the transaction receipt for
$hash
\n
"
if
not
$rcpt
;
$json
->
{'
status
'}
=
$rcpt
->
{'
status
'};
$json
->
{'
status
'}
=
$rcpt
->
{'
status
'};
$json
->
{'
gasUsed
'}
=
$rcpt
->
{'
gasUsed
'};
$json
->
{'
gasUsed
'}
=
$rcpt
->
{'
gasUsed
'};
...
@@ -251,8 +181,11 @@ sub getTransByHash
...
@@ -251,8 +181,11 @@ sub getTransByHash
shorthash
$json
->
{'
from
'},
shorthash
$json
->
{'
from
'},
shorthash
$json
->
{'
to
'};
shorthash
$json
->
{'
to
'};
my
$input
=
$json
->
{'
input
'};
my
$input
=
$json
->
{'
input
'};
$input
=~
s/^0x//
;
my
$inputlen
=
0
;
my
$inputlen
=
length
(
$input
)
/
2
;
if
(
$input
=~
/^0x/
)
{
$inputlen
=
(
length
(
$input
)
-
2
)
/
2
;
}
my
@args
=
(
my
@args
=
(
lc
$json
->
{'
hash
'},
lc
$json
->
{'
hash
'},
lc
$json
->
{'
blockHash
'},
lc
$json
->
{'
blockHash
'},
...
@@ -262,31 +195,26 @@ sub getTransByHash
...
@@ -262,31 +195,26 @@ sub getTransByHash
$json
->
{'
value
'},
$json
->
{'
value
'},
lc
$json
->
{'
from
'},
lc
$json
->
{'
from
'},
lc
$json
->
{'
to
'},
lc
$json
->
{'
to
'},
$inputlen
,
$json
->
{'
gasUsed
'},
$json
->
{'
status
'},
$json
->
{'
status
'},
$json
->
{'
gasUsed
'},
$input
,
$inputlen
,
);
);
my
$function
=
$sth_insertTransaction
;
if
(
$json
->
{'
contractAddress
'}
)
if
(
$json
->
{'
contractAddress
'}
)
{
{
push
@args
,
$json
->
{'
contractAddress
'};
$sql
->
insertTransactionWithContractAddress
(
@args
,
lc
$json
->
{'
contractAddress
'}
);
$function
=
$sth_insertTransactionWithContractAddress
;
}
else
{
$sql
->
insertTransaction
(
@args
);
}
}
$function
->
execute
(
@args
);
}
sub
getTransRcptByHash
{
my
$hash
=
$_
[
0
];
}
}
sub
versioncheck
sub
versioncheck
{
{
my
$n
;
my
$n
;
my
$ok
=
1
;
my
$ok
=
1
;
$n
=
Math::
BigInt
->
new
(
$n
=
Math::
BigInt
->
new
(
rpcreq
(
"
net_version
"
)
);
rpcreq
(
$endpoints
[
0
],
"
net_version
"
)
);
if
(
$n
->
bcmp
(
$netversion
)
!=
0
)
if
(
$n
->
bcmp
(
$netversion
)
!=
0
)
{
{
warn
"
Network says it has net.version
"
warn
"
Network says it has net.version
"
...
@@ -298,9 +226,7 @@ sub versioncheck
...
@@ -298,9 +226,7 @@ sub versioncheck
.
"
).
\n
";
.
"
).
\n
";
$ok
=
0
;
$ok
=
0
;
}
}
$n
=
Math::
BigInt
->
new
(
$n
=
Math::
BigInt
->
new
(
rpcreq
(
"
eth_chainId
"
)
);
rpcreq
(
$endpoints
[
0
],
"
eth_chainId
"
)
);
if
(
$n
->
bcmp
(
$chainid
)
!=
0
)
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
);
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
...
@@ -310,76 +236,56 @@ sub versioncheck
return
$ok
;
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
sub
getsnap
{
{
my
$number
=
$_
[
0
];
my
$blockhash
=
$_
[
0
];
my
@blocks
;
$number
=
Math::
BigInt
->
new
(
$number
)
if
ref
(
$number
)
ne
'
Math::BigInt
';
my
$json
=
rpcreq
(
my
$json
=
rpcreq
(
$endpoints
[
0
],
'
clique_getSnapshotAtHash
',
'
clique_getSnapshot
',
$blockhash
$number
->
as_hex
);
);
# Sanity check 1 - does the lookup return the block?
return
if
not
defined
$json
;
return
if
not
defined
$json
;
my
$recents
=
$json
->
{'
recents
'};
my
$recents
=
$json
->
{'
recents
'};
return
if
not
defined
$recents
;
# Blockhash of the requested block - we must use this for the insert
my
$hash
=
$json
->
{'
hash
'};
$blockhash
=
$json
->
{'
hash
'};
my
$count
=
0
;
my
$blocknumber
=
Math::
BigInt
->
new
(
$json
->
{'
number
'}
);
while
(
exists
$recents
->
{
$number
->
bstr
}
)
my
@infonumbers
;
while
(
not
$blocknumber
->
is_zero
)
{
{
push
@blocks
,
$number
->
bstr
;
my
$sealerhash
=
$recents
->
{
$blocknumber
->
bstr
};
$sth_selectBlockByHash
->
execute
(
$hash
);
last
if
not
defined
$sealerhash
;
my
$row
=
$sth_selectBlockByHash
->
fetchrow_hashref
;
push
@infonumbers
,
$blocknumber
->
bstr
;
return
if
not
defined
$row
;
my
$ref
=
$sql
->
selectBlockByHash
(
$blockhash
);
my
$newnumber
=
Math::
BigInt
->
new
(
$row
->
{'
number
'}
);
# Stop if we get to blocks which we still haven't stored in the db
return
if
$newnumber
->
bcmp
(
$number
)
!=
0
;
return
(
undef
,
$blocknumber
)
if
not
defined
$ref
;
# Stop if we got to a block with sealers.
# Stop if we got to a block with sealers.
return
if
defined
$row
->
{'
sealer
'};
return
(
undef
,
$blocknumber
)
my
$sealerhash
=
$recents
->
{
$number
->
bstr
};
if
exists
$ref
->
{'
sealerAccountId
'}
and
defined
$ref
->
{'
sealerAccountId
'};
return
if
not
defined
$sealerhash
;
$sql
->
updateWhoSealed
(
$sealerhash
,
$blockhash
);
my
$internalid
=
sealer
(
$sealerhash
);
my
$parentblockid
=
$ref
->
{'
parentBlockhashId
'};
return
if
not
defined
$internalid
;
my
$rows_affected
=
$sth_updatewhosealed
->
execute
(
$internalid
,
$hash
);
# For next block...
# For next block...
$
hash
=
$
row
->
{'
parentHash
'}
;
$
blockhash
=
$
sql
->
selectBlockhashById
(
$parentblockid
)
;
$number
->
bsub
(
1
);
$
block
number
->
bsub
(
1
);
}
}
info
"
S Snapshot at block #
@
block
s
.
\n
";
info
"
S Snapshot at block #
@
infonumber
s
.
\n
";
return
$
number
;
return
(
$blockhash
,
$block
number
)
;
}
}
# Find strands of blocks in the database which have their sealer set to NULL
sub
allsnaps
sub
allsnaps
{
{
$sth_selectmaxunknownsigned
->
execute
();
my
$blockhash
=
$sql
->
selectMaxUnknownSigned
;
my
$unkn
=
$sth_selectmaxunknownsigned
->
fetchrow_hashref
;
my
$number
=
Math::
BigInt
->
new
(
$unkn
->
{'
number
'}
);
my
$committer
=
0
;
my
$committer
=
0
;
while
(
defined
$
number
and
not
$number
->
is_zero
)
while
(
defined
$
blockhash
)
{
{
$number
=
getsnap
(
$number
);
my
$blocknumber
;
$dbh
->
commit
(
$blockhash
,
$blocknumber
)
=
getsnap
(
$blockhash
);
$sql
->
commit
if
(
$committer
++
%
75
)
==
0
;
if
(
$committer
++
%
75
)
==
0
;
last
if
$blocknumber
->
is_zero
;
}
}
$dbh
->
commit
;
}
}
sub
main
sub
main
...
@@ -387,20 +293,15 @@ sub main
...
@@ -387,20 +293,15 @@ sub main
$|
=
1
;
$|
=
1
;
info
"
Connecting to database and setting up
"
info
"
Connecting to database and setting up
"
.
"
prepared statements.
\n
";
.
"
prepared statements.
\n
";
sql::
setup
;
$sql
=
sql
->
new
();
#
info
"
Looking for public RPC endpoints of
"
.
"
the BFA.
\n
";
$ua
=
LWP::
UserAgent
->
new
(
keep_alive
=>
10
);
endpoint_find
();
versioncheck
();
versioncheck
();
info
"
Looking for orphaned blocks in the
"
info
"
Looking for orphaned blocks in the
"
.
"
database.
\n
";
.
"
database.
\n
";
push
@blockqueue
,
sql
::
listOrphans
();
push
@blockqueue
,
sql
->
listOrphans
();
while
(
--
$maxruns
!=
0
)
while
(
1
)
{
{
unshift
@blockqueue
,
"
latest
"
;
unshift
@blockqueue
,
'
latest
'
;
while
(
@blockqueue
)
while
(
@blockqueue
)
{
{
my
$maxinarow
=
2500
;
my
$maxinarow
=
2500
;
...
@@ -408,7 +309,7 @@ sub main
...
@@ -408,7 +309,7 @@ sub main
while
@blockqueue
and
--
$maxinarow
;
while
@blockqueue
and
--
$maxinarow
;
# Find out who signed all blocks
# Find out who signed all blocks
allsnaps
();
allsnaps
();
$
dbh
->
commit
;
$
sql
->
commit
;
}
}
sleep
5
;
sleep
5
;
}
}
...
...
This diff is collapsed.
Click to expand it.
collector/sql.pm
+
304
−
87
View file @
4f137abf
...
@@ -4,105 +4,322 @@
...
@@ -4,105 +4,322 @@
package
sql
;
package
sql
;
use
DBI
;
use
DBI
;
use
base
qw( Class::Accessor )
;
my
@blockqueue
;
__PACKAGE__
->
mk_accessors
(
'
dbh
'
);
my
$dbh
;
sub
new
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
{
{
$dbh
=
DBI
->
connect
(
my
(
$class
)
=
@_
;
my
$self
=
bless
{},
ref
$class
||
$class
;
$self
->
dbh
(
DBI
->
connect
(
'
dbi:Pg:dbname=postgres;host=postgres
','
postgres
','
onlythelonely
',
'
dbi:Pg:dbname=postgres;host=postgres
','
postgres
','
onlythelonely
',
{
AutoCommit
=>
0
,
RaiseError
=>
1
}
{
AutoCommit
=>
0
,
RaiseError
=>
1
}
)
));
or
die
DBI::
errstr
;
return
$self
;
$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
;
}
}
sub
listOrphans
sub
commit
{
{
my
@results
;
my
(
$self
)
=
@_
;
my
$sth_selectOrphans
$self
->
dbh
->
commit
;
=
$dbh
->
prepare
(
q(
}
SELECT parentHash,number
sub
listOrphans
{
my
(
$self
)
=
@_
;
my
$sth
=
$self
->
dbh
->
prepare
(
q(
SELECT parentBlockhashId,id
FROM blocks
FROM blocks
WHERE parent
H
ash NOT IN (
WHERE parent
Blockh
ash
Id
NOT IN (
SELECT
hash
SELECT
id
FROM blocks
FROM blocks
)
)
)
)
or
die
$
DBI::
errstr
;
)
);
$sth_selectOrphans
->
execute
();
my
@results
;
while
(
my
$row
=
$sth_selectOrphans
->
fetch
)
$sth
->
execute
();
while
(
my
$row
=
$sth
->
fetchrow_arrayref
)
{
{
# Block 0 has it's parent listed as 0x0{64}
# Block 0 has it's parent listed as 0x0{64}
next
if
$row
->
[
0
]
=~
/^0x0{64}$/
;
next
if
$row
->
[
0
]
=~
/^0x0{64}$/
;
push
@results
,
$row
->
[
0
]
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
;
1
;
\ No newline at end of file
This diff is collapsed.
Click to expand it.
docker-compose.yml
+
1
−
2
View file @
4f137abf
...
@@ -2,8 +2,7 @@
...
@@ -2,8 +2,7 @@
## POSTGRES SUPERUSER user name is postgres
## POSTGRES SUPERUSER user name is postgres
## POSTGRES SUPERUSER password is onlythelonely
## POSTGRES SUPERUSER password is onlythelonely
## POSTGRES USER dgsi has password bfa
## POSTGRES USER leer has password bfa defined in postgres/90-add-db-user.sh
# defined in postgres/90-add-db-user.sh
version
:
'
3.4'
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