Skip to content
Snippets Groups Projects
Commit 11635abe authored by Robert Martin-Legene's avatar Robert Martin-Legene
Browse files

Import from sanctioned servers

parent ade0a55a
No related branches found
No related tags found
No related merge requests found
FROM debian FROM debian
RUN useradd --create-home --shell /bin/bash bfa && mkdir /home/bfa/collector RUN useradd --create-home --shell /bin/bash bfa && install --owner=bfa --directory /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 libclass-accessor-perl RUN apt-get install -y libjson-perl libdbd-pg-perl libwww-perl libclass-accessor-perl less
WORKDIR /home/bfa WORKDIR /home/bfa
COPY collector.pl sql.pm /home/bfa/collector/
RUN chown -R bfa /home/bfa
USER bfa USER bfa
CMD /home/bfa/collector/collector.pl COPY sql.pm collectorcommon.pm collector.pl txfetcher.pl /home/bfa/collector/
#CMD sleep 14d CMD sleep 14d
ENV BFANODE http://public.47525974938.bfa.martin-legene.dk:8545/
...@@ -9,8 +9,6 @@ use Data::Dumper; ...@@ -9,8 +9,6 @@ use Data::Dumper;
use Math::BigInt; use Math::BigInt;
use LWP; use LWP;
use JSON; use JSON;
use Net::DNS;
use Net::DNS::Resolver;
use lib '/home/bfa/collector'; use lib '/home/bfa/collector';
use lib 'collector'; use lib 'collector';
use lib '.'; use lib '.';
...@@ -20,29 +18,32 @@ use sql; ...@@ -20,29 +18,32 @@ use sql;
my $netversion = Math::BigInt->new( "0xb10c4d39a" ); my $netversion = Math::BigInt->new( "0xb10c4d39a" );
# 200941592 # 200941592
my $chainid = Math::BigInt->new( "0xbfa2018" ); my $chainid = Math::BigInt->new( "0xbfa2018" );
my $idcounter = 0; my $maxinarow = 5000;
my $stop_request = 0;
my $ua;
my @blockqueue;
my %sealers; my %sealers;
my $stop_request;
my $sql; my $sql;
sub stop
{
$stop_request = 1;
$SIG{$_[0]} = 'DEFAULT';
print STDERR "\rStop request received ($_[0]).\n";
}
sub info(@) sub info(@)
{ {
return if not -t STDOUT; #return if not -t STDOUT;
# if 1 param only # if 1 param only
unshift @_, '%s' unshift @_, '%s' if $#_ == 0;
if $#_ == 0;
my $format = shift; my $format = shift;
$format = "%s: " . $format; local $_ = sprintf $format, @_;
my $txt = sprintf $format, astime(time), @_; print;
$txt .= "\n" if $txt !~ /\n$/; print "\n" if not /\n$/;
print $txt;
} }
sub astime sub astime
{ {
my @t = localtime( $_[0] ); my @t = localtime( $_[0] );
$t[5] += 1900; $t[5] += 1900;
$t[4] += 1; $t[4] += 1;
return sprintf '%04d%02d%02d-%02d%02d%02d', @t[5,4,3,2,1,0]; return sprintf '%04d%02d%02d-%02d%02d%02d', @t[5,4,3,2,1,0];
...@@ -56,15 +57,11 @@ sub shorthash($) ...@@ -56,15 +57,11 @@ sub shorthash($)
return $_; return $_;
} }
sub stop my $ua;
{ my $idcounter = 0;
$stop_request = 1;
print STDERR "\rStop request received ($_[0]).\n";
}
sub rpcreq sub rpcreq
{ {
my ( $opname, @params )= @_; my ( $opname, @params ) = @_;
$ua = LWP::UserAgent->new( keep_alive => 10 ) $ua = LWP::UserAgent->new( keep_alive => 10 )
if not defined $ua; if not defined $ua;
# $ua->ssl_opts( 'verify_hostname' => 0 ); # $ua->ssl_opts( 'verify_hostname' => 0 );
...@@ -73,11 +70,11 @@ sub rpcreq ...@@ -73,11 +70,11 @@ sub rpcreq
method => $opname, method => $opname,
id => $idcounter++, id => $idcounter++,
); );
my @args = map { my @args = map {
my $v = $args{$_}; my $v = $args{$_};
$v = qq/"${v}"/ if $v !~ /^\d+$/; $v = qq/"${v}"/ if $v !~ /^\d+$/;
sprintf qq/"%s":%s/, $_, $v; sprintf qq/"%s":%s/, $_, $v;
} keys %args; } keys %args;
if ( scalar @params ) if ( scalar @params )
{ {
my $p = '"params":['; my $p = '"params":[';
...@@ -93,50 +90,69 @@ sub rpcreq ...@@ -93,50 +90,69 @@ sub rpcreq
$p .= ']'; $p .= ']';
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 ' . 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 ' . 'server to connect to (e.g. http://10.20.30.40/), but it it ' .
'not set. Stopped' 'not set. Stopped'
unless defined $ENV{'BFANODE'}; unless defined $ENV{'BFANODE'};
my $res = $ua->post( my $res = $ua->post(
$ENV{BFANODE}, $ENV{BFANODE},
'Content-Type' => 'application/json', 'Content-Type' => 'application/json',
'Content' => $args, 'Content' => $args,
); );
die $res->status_line die $res->status_line
unless $res->is_success; unless $res->is_success;
my $json = decode_json($res->content); my $json = decode_json($res->content);
return $json->{'result'}; return $json->{'result'};
} }
sub getblock sub versioncheck
{ {
my $block = lc shift; my $n;
my $rpccmd; my $ok = 1;
if ( $block =~ /^0x[\da-f]{64}$/ ) $n = Math::BigInt->new( rpcreq( "net_version" ) );
if ( $n->bcmp( $netversion ) != 0 )
{ {
$rpccmd = 'eth_getBlockByHash'; warn "Network says it has net.version "
. $n->bstr
. " ("
. $n->as_hex
. "). Expected $netversion ("
. $netversion->as_hex
. ").\n";
$ok = 0;
} }
else $n = Math::BigInt->new( rpcreq( "eth_chainId" ) );
if ( $n->bcmp( $chainid ) != 0 )
{ {
$rpccmd = 'eth_getBlockByNumber'; warn sprintf("Network says it has eth.chainId %s (%s). Expected %s (%s).\n", $n->bstr, $n->as_hex, $chainid->bstr, $chainid->as_hex);
if ( $block =~ /^\d+$/ ) $ok = 0;
{
$block = Math::BigInt->new( $block )->as_hex;
}
} }
my $json = rpcreq( $rpccmd, $block, 'false' ); exit 1 if not $ok;
}
sub getblock
{
my $block = lc shift;
return ( undef, undef ) if $block =~ /^0x0{64}$/;
my $rpccmd = $block =~ /^0x[\da-f]{64}$/
? 'eth_getBlockByHash'
: 'eth_getBlockByNumber';
$block = Math::BigInt->new( $block )->as_hex
if $block =~ /^\d+$/;
my $json = rpcreq( $rpccmd, $block, 'true' );
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 we did not.\n" . Dumper( $rpccmd, $block ) . "Stopped "
if not defined $json; if not defined $json;
return if $sql->selectBlockByHash( $json->{'hash'} ); # Skip it if we already have it.
return ( undef, undef ) if $sql->selectBlockByHash( $json->{'hash'} );
foreach my $key (qw( foreach my $key (qw(
timestamp gasUsed gasLimit difficulty number totalDifficulty size timestamp gasUsed gasLimit difficulty number totalDifficulty size
)) { )) {
$json->{$key} = Math::BigInt->new( $json->{$key} )->bstr $json->{$key} = Math::BigInt->new( $json->{$key} )->bstr
if exists $json->{$key}; if exists $json->{$key};
} }
info "B %s %s %s %s %s %s/%s", info "B %s %s %s %s %s %s/%s",
shorthash $json->{'hash'}, shorthash $json->{'hash'},
astime($json->{'timestamp'}), astime($json->{'timestamp'}),
$json->{'number'}, $json->{'number'},
...@@ -154,207 +170,268 @@ sub getblock ...@@ -154,207 +170,268 @@ sub getblock
$json->{'gasLimit'}, $json->{'gasLimit'},
$json->{'size'} $json->{'size'}
); );
if ( scalar @{$json->{'transactions'}} ) my $txcount = 0;
foreach ( @{ $json->{'transactions'} } )
{ {
foreach my $txhash ( @{ $json->{'transactions'} } ) getTransByHash( $_ );
{ $txcount++;
getTransByHash( $txhash );
}
} }
# Put the parent block in front in @blockqueue my $nextblock = lc $json->{'parentHash'}
unshift @blockqueue, lc $json->{'parentHash'}
if $json->{'number'} != 0; if $json->{'number'} != 0;
return ( $nextblock, $txcount );
} }
sub getTransByHash sub getTransByHash
{ {
my $hash = shift; my $hash = shift;
# Don't get it via RPC if we already have it in the database # Don't get it via RPC if we already have it in the database
return my $json;
if $sql->selectTransactionByHash( $hash ); if ( ref $hash eq '' )
my $json = rpcreq( {
'eth_getTransactionByHash', # Don't fetch it, if we already have it in the database.
$hash return if $sql->selectTransactionByHash( $hash );
); $json = rpcreq( 'eth_getTransactionByHash', $hash );
die "Invalid object received when asking for $hash:\n".Dumper($json) if not exists $json->{'blockNumber'}; }
my $max = 0; elsif ( ref $hash eq 'HASH' )
my $rcpt = undef; {
do { $json = $hash;
$rcpt = rpcreq( }
'eth_getTransactionReceipt', else
$hash {
); die "Don't know how to fetch transactions of type "
if ( not $rcpt ) . ref($hash)
{ . ". Stopped";
sleep 1; }
warn "Couldn't get the transaction receipt for $hash\n"; die "Invalid object received when asking for $hash:\n"
} . Dumper('hash'=>$hash,'json'=>$json)
} while not $rcpt and $max++ < 10; if not exists $json->{'blockNumber'};
die "Couldn't get the transaction receipt for $hash:\n" if not $rcpt;
foreach my $key (qw( hash blockHash nonce gas gasPrice value from to input )) foreach my $key (qw( hash blockHash nonce gas gasPrice value from to input ))
{ {
die "JSON missing key $key:".Dumper($json) unless exists $json->{$key}; die "JSON missing key $key:".Dumper($json) unless exists $json->{$key};
} }
$json->{'status'} = $rcpt->{'status'}; foreach my $key (qw( nonce value gas gasPrice ))
$json->{'gasUsed'} = $rcpt->{'gasUsed'};
$json->{'contractAddress'}
= $rcpt->{'contractAddress'};
foreach my $key (qw( nonce value gas gasPrice gasUsed status))
{ {
$json->{$key} = Math::BigInt->new( $json->{$key} )->bstr; $json->{$key} = Math::BigInt->new( $json->{$key} )->bstr;
} }
info "T %s %s %s %s -> %s", info "T %s %s %s %s -> %s",
shorthash $json->{'hash'}, shorthash $json->{'hash'},
$json->{'nonce'}, $json->{'nonce'},
$json->{'value'}, $json->{'value'},
shorthash $json->{'from'}, shorthash $json->{'from'},
shorthash ($json->{'to'}||'<NULL>'); shorthash $json->{'to'}||'<NULL>';
my $input = $json->{'input'}; my $input = $json->{'input'};
my $inputlen = 0; my $inputlen = $input =~ /^0x/
if ( $input =~ /^0x/ ) ? (length($input)-2) / 2
{ : 0;
$inputlen = (length($input)-2) / 2; my $to = defined $json->{'to'}
} ? lc $json->{'to'}
my @args = ( : undef;
$sql->insertTransaction(
lc $json->{'hash'}, lc $json->{'hash'},
lc $json->{'blockHash'}, lc $json->{'blockHash'},
$json->{'nonce'}, $json->{'nonce'},
$json->{'gas'}, $json->{'gas'},
$json->{'gasPrice'}, $json->{'gasPrice'},
$json->{'value'}, $json->{'value'},
lc $json->{'from'}, lc $json->{'from'},
defined $json->{'to'} ? lc $json->{'to'} : undef, $to,
$json->{'status'},
$json->{'gasUsed'},
$input, $input,
$inputlen $inputlen,
'explicit'
); );
if ( $json->{'contractAddress'} ) getTransactionReceipt( $json->{'hash'} );
{
$sql->insertTransactionWithContractAddress( @args, lc $json->{'contractAddress'} );
}
else
{
$sql->insertTransaction( @args );
}
}
sub versioncheck
{
my $n;
my $ok = 1;
$n = Math::BigInt->new( rpcreq( "net_version" ) );
if ( $n->bcmp( $netversion ) != 0 )
{
warn "Network says it has net.version "
. $n->bstr
. " ("
. $n->as_hex
. "). Expected $netversion ("
. $netversion->as_hex
. ").\n";
$ok = 0;
}
$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);
$ok = 0;
}
exit 1 if not $ok;
return $ok;
} }
sub getsnap sub getsnap
{ {
my $blockhash = $_[0]; my $blockhash = $_[0];
my $json = rpcreq( my $json = rpcreq( 'clique_getSnapshotAtHash', $blockhash );
'clique_getSnapshotAtHash',
$blockhash
);
# Sanity check 1 - does the lookup return the block? # Sanity check 1 - does the lookup return the block?
return if not defined $json; die "Did not get a response from the node, when asking about \"$blockhash\". Stopped"
if not defined $json;
# 'recents' has a list of blocknumbers and the signer for that block number
my $recents = $json->{'recents'}; my $recents = $json->{'recents'};
# Blockhash of the requested block - we must use this for the insert # Blockhash of the requested block - we must use this for the insert, and
# is the highest blocknumbered block in the snapshot.
$blockhash = $json->{'hash'}; $blockhash = $json->{'hash'};
my $blocknumber = Math::BigInt->new( $json->{'number'} ); my $blocknumber = Math::BigInt->new( $json->{'number'} );
my $updatecounter = 0;
my @infonumbers; my @infonumbers;
while ( not $blocknumber->is_zero ) while ( not $blocknumber->is_zero )
{ {
my $sealerhash = $recents->{$blocknumber->bstr}; # Now we fetch the address of the sealer in the recents list,
# index by the block number
my $sealerhash = $recents->{$blocknumber->bstr};
last if not defined $sealerhash; last if not defined $sealerhash;
push @infonumbers, $blocknumber->bstr; my $ref = $sql->selectBlockByHash( $blockhash );
my $ref = $sql->selectBlockByHash( $blockhash );
# Stop if we get to blocks which we still haven't stored in the db # Stop if we get to blocks which we still haven't stored in the db
if ( not defined $ref ) if ( not defined $ref )
{ {
$blockhash = undef; $blockhash = undef;
last; last;
} }
# Stop if we got to a block with sealers. # Stop if we got to a block with sealers.
if ( exists $ref->{'sealerAccountId'} and defined $ref->{'sealerAccountId'} ) if ( exists $ref->{'sealerAccountId'} and defined $ref->{'sealerAccountId'} )
{ {
$blockhash = undef; $blockhash = undef;
last; last;
} }
push @infonumbers, $blocknumber->bstr;
$updatecounter++;
$sql->updateWhoSealed( $sealerhash, $blockhash ); $sql->updateWhoSealed( $sealerhash, $blockhash );
my $parentblockid = $ref->{'parentBlockhashId'}; my $parentblockid = $ref->{'parentBlockhashId'};
# For next block... # For next block...
$blockhash = $sql->selectBlockhashById( $parentblockid ); $blockhash = $sql->selectBlockhashById( $parentblockid );
$blocknumber->bsub(1); $blocknumber->bsub(1);
} }
info "S Snapshot at block # @infonumbers." info "S Snapshot at block # @infonumbers."
if @infonumbers; if @infonumbers;
return ($blockhash, $blocknumber); return ($blockhash, $blocknumber, $updatecounter);
} }
# Find strands of blocks in the database which have their sealer set to NULL # Find strands of blocks in the database which have their sealer set to NULL
sub allsnaps sub allsnaps
{ {
my $blockhash = $sql->selectMaxUnknownSigned; my $startblock = shift;
while ( defined $blockhash ) my $counter = 0;
my $extra = 0;
my $blockhash = (defined $startblock and $startblock =~ /^0x[\da-f]{64}$/)
? $startblock
: $sql->selectMaxUnknownSigned;
while ( defined $blockhash and not $stop_request and $counter < 10000 )
{ {
my $blocknumber; my $blocknumber;
( $blockhash, $blocknumber )= getsnap( $blockhash ); ( $blockhash, $blocknumber,
last if $blocknumber->is_zero; $extra ) = getsnap( $blockhash );
last if not defined $blockhash;
$counter += $extra;
last if $blocknumber->is_zero;
} }
return $counter;
}
sub getTransactionReceipt
{
my $hash = lc shift;
my $json = rpcreq( 'eth_getTransactionReceipt', $hash );
return if not defined $json;
return if not exists $json->{'transactionHash'};
return if not exists $json->{'status'};
return if not exists $json->{'gasUsed'};
my $status = Math::BigInt->new( $json->{'status'} )->bstr;
my $gasUsed = Math::BigInt->new( $json->{'gasUsed'} )->bstr;
my $contractAddress = $json->{'contractAddress'};
$sql->updateRcptInfo( $hash, $status, $gasUsed, $contractAddress );
} }
sub main sub main
{ {
$| = 1;
versioncheck(); versioncheck();
# Give Postgres time to start up. # Give postgres time to start up
sleep( 3 ); # if we are run from a tty, expect that postgres is already running
sleep 3 if not -t STDIN;
$sql = sql->new(); $sql = sql->new();
my $lastorphancheck= 0;
$SIG{'HUP'} = \&stop; $SIG{'HUP'} = \&stop;
$SIG{'INT'} = \&stop; $SIG{'INT'} = \&stop;
$SIG{'TERM'} = \&stop; $SIG{'TERM'} = \&stop;
$SIG{'TSTP'} = \&stop; my $lastmaintanance = 0;
while ( not $stop_request ) while ( not $stop_request )
{ {
my $now = time(); my @blockqueue;
if ( $lastorphancheck <= $now+600 ) my $deletecounter = 0;
my $snapcounter = 0;
my $extrarcptcounter = 0;
my $now = time();
if ( $lastmaintanance+300 <= $now )
{ {
$lastorphancheck = $now; # This block contains some rather expensive queries
# for things which are not urgent to get fixed,
# So we only run them every few minutes.
$lastmaintanance = $now;
# We don't only check for orphans.. first we see if
# we can create some by deleting duplicate blockheights.
# If any duplicates are found, we will be deleting the
# uncle and the canonical block. The canonical will
# the be listed as parent to an orphans and recreated.
my @blocks = $sql->selectduplicateblocknumbers;
if ( @blocks )
{
info( "D Deleting duplicate blocks @blocks." );
# Delete the receipts for these blocks, so we can
# remove the blocks.
$sql->deletetransactionsinblocknumbers( @blocks );
# Now we can remove the duplicate blocks.
$sql->deleteblocknumbers( @blocks );
$deletecounter += scalar @blocks;
}
#
# Orphans happen if some blocks have been deleted # Orphans happen if some blocks have been deleted
# or if the initial synchronization hasn't finished. # or if the initial synchronization hasn't finished.
# This check should be done when orphans can be # This check should be done when orphans can be
# suspected, but when is that? Maybe every 10 minutes. # suspected, but when is that? Maybe every 10 minutes.
push @blockqueue, $sql->listOrphans(); push @blockqueue, $sql->listOrphans();
# Look for transactions which hasn't had their receipts
# processed (not common that this should happen).
my @rcptqueue = $sql->selecttxwhichmissreceipts( $maxinarow );
while ( @rcptqueue and not $stop_request )
{
print "R Extra receipts: "
if $extrarcptcounter == 0;
$extrarcptcounter++;
print "r";
getTransactionReceipt( shift @rcptqueue );
}
print "\n" if $extrarcptcounter > 0;
# Find out who signed all blocks
my $n = 1;
while ( not $stop_request and $n > 0 )
{
$n = allsnaps();
$snapcounter += $n;
}
} }
do my $didsomething = 0;
{ do {
unshift @blockqueue, 'latest'; unshift @blockqueue, 'latest';
my $maxinarow = 100; my $blockcounter = 0;
getblock( shift @blockqueue ) my $newtx = 0;;
while @blockqueue and --$maxinarow and not $stop_request; while ( @blockqueue and $blockcounter <= 2500 and not $stop_request )
# Find out who signed all blocks {
allsnaps() if not $stop_request; my $block = shift @blockqueue;
info "Committing."; my ( $nextblock, $n )
$sql->commit; = getblock( $block );
} while @blockqueue and not $stop_request; # getblock returns two undefs if the block wasn't processed
sleep 5 if not @blockqueue and not $stop_request; next if not defined $n;
$blockcounter++;
$newtx += $n;
$snapcounter += allsnaps( $block );
# Put the parent block in front in @blockqueue
unshift @blockqueue, $nextblock
if defined $nextblock;
}
$didsomething = $blockcounter + $snapcounter + $extrarcptcounter;
if ( $didsomething > 0 )
{
info
"C Committing %d Delete%s, %d Block%s, %d Transaction%s, %d Snapshot%s, %d extra Receipt%s.",
$deletecounter, $deletecounter==1?'':'s',
$blockcounter, $blockcounter==1?'':'s',
$newtx, $newtx==1?'':'s',
$snapcounter, $snapcounter==1?'':'s',
$extrarcptcounter, $extrarcptcounter==1?'':'s';
$sql->commit;
}
$extrarcptcounter = 0;
$snapcounter = 0;
$deletecounter = 0;
} while $didsomething > 0 and not $stop_request;
my $sleep = 3;
while ( not $stop_request and $sleep-- > 0 )
{
printf " %d \r", $sleep if -t STDIN;
sleep 1;
}
} }
} }
......
...@@ -16,7 +16,7 @@ sub new ...@@ -16,7 +16,7 @@ sub new
my $self = bless {}, ref $class || $class; my $self = bless {}, ref $class || $class;
$self->dbh( DBI->connect( $self->dbh( DBI->connect(
'dbi:Pg:dbname=postgres;host=postgres','postgres',$ENV{'POSTGRES_PASSWORD'}, 'dbi:Pg:dbname=postgres;host=postgres','postgres',$ENV{'POSTGRES_PASSWORD'},
{AutoCommit=>0,RaiseError=>1} { AutoCommit=>0, RaiseError=>1 }
)); ));
return $self; return $self;
} }
...@@ -93,28 +93,24 @@ sub maxBlockNumber ...@@ -93,28 +93,24 @@ sub maxBlockNumber
return $ref->[0]; return $ref->[0];
} }
__PACKAGE__->mk_accessors( 'sth_insertTransactionWithContractAddress' ); __PACKAGE__->mk_accessors( 'sth_updateRcptInfo' );
sub insertTransactionWithContractAddress sub updateRcptInfo
{ {
my $self = shift; my $self = shift;
if ( not defined $self->sth_insertTransactionWithContractAddress ) if ( not defined $self->sth_updateRcptInfo )
{ {
$self->sth_insertTransactionWithContractAddress( $self->sth_updateRcptInfo(
$self->dbh->prepare(q( $self->dbh->prepare(q(
INSERT INTO transaction UPDATE transaction
( hash, "blockId", nonce, gas, SET status=?, "gasUsed"=?, "contractaddressAccountId"=?
"gasPrice", value, "fromAccountId","toAccountId", WHERE hash=?
status, "gasUsed", input, inputlen,
"contractaddressAccountId", "type" )
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)
)) ))
); );
} }
$_[1] = $self->selectBlockhashByHash( $_[1] ); $_[3] = $self->selectAccountIdByAddress( $_[3] ) if defined $_[3];
$_[6] = $self->selectAccountIdByAddress( $_[6] ); # hash is in the front but goes in the back in SQL
$_[7] = $self->selectAccountIdByAddress( $_[7] ) if defined $_[7]; push @_, shift;
$_[12] = $self->selectAccountIdByAddress( $_[12] ) if defined $_[12]; $self->sth_updateRcptInfo->execute( @_ );
$self->sth_insertTransactionWithContractAddress->execute( @_, 'explicit' );
} }
__PACKAGE__->mk_accessors( 'sth_insertTransaction' ); __PACKAGE__->mk_accessors( 'sth_insertTransaction' );
...@@ -128,16 +124,15 @@ sub insertTransaction ...@@ -128,16 +124,15 @@ sub insertTransaction
INSERT INTO transaction INSERT INTO transaction
( hash, "blockId", nonce, gas, ( hash, "blockId", nonce, gas,
"gasPrice", value, "fromAccountId","toAccountId", "gasPrice", value, "fromAccountId","toAccountId",
status, "gasUsed", input, inputlen, input, inputlen, "type" )
"type" ) VALUES (?,?,?,?,?,?,?,?,?,?,?)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)
)) ))
); );
} }
$_[1] = $self->selectBlockhashByHash( $_[1] ); $_[1] = $self->selectBlockhashByHash( $_[1] );
$_[6] = $self->selectAccountIdByAddress( $_[6] ); $_[6] = $self->selectAccountIdByAddress( $_[6] );
$_[7] = $self->selectAccountIdByAddress( $_[7] ) if defined $_[7]; $_[7] = $self->selectAccountIdByAddress( $_[7] ) if defined $_[7];
$self->sth_insertTransaction->execute( @_, 'explicit' ); $self->sth_insertTransaction->execute( @_ );
} }
my @cacheBlockhash; my @cacheBlockhash;
...@@ -405,7 +400,7 @@ sub selectTransactionByHash ...@@ -405,7 +400,7 @@ sub selectTransactionByHash
{ {
$self->sth_selectTransactionByHash( $self->sth_selectTransactionByHash(
$self->dbh->prepare(q( $self->dbh->prepare(q(
SELECT 1 SELECT "blockId", "fromAccountId", nonce
FROM transaction FROM transaction
WHERE hash=? WHERE hash=?
)) ))
...@@ -466,4 +461,99 @@ sub selectMaxUnknownSigned ...@@ -466,4 +461,99 @@ sub selectMaxUnknownSigned
return $blockhash; return $blockhash;
} }
__PACKAGE__->mk_accessors( 'sth_selecttxwhichmissreceipts' );
sub selecttxwhichmissreceipts
{
my ( $self, $maxinarow ) = @_;
if ( not defined $self->sth_selecttxwhichmissreceipts )
{
$self->sth_selecttxwhichmissreceipts(
$self->dbh->prepare(q(
SELECT hash, "type"
FROM transaction
WHERE "gasUsed" IS NULL
ORDER BY "toAccountId" desc,
nonce
))
);
}
my @txhashes;
$self->sth_selecttxwhichmissreceipts->execute();
while ( my $ref = $self->sth_selecttxwhichmissreceipts->fetchrow_arrayref and $maxinarow-- != 0 )
{
next if $ref->[1] eq 'external';
push @txhashes, $ref->[0];
}
$self->sth_selecttxwhichmissreceipts->finish();
return @txhashes;
}
__PACKAGE__->mk_accessors( 'sth_selectduplicateblocknumbers' );
sub selectduplicateblocknumbers
{
my ( $self ) = shift;
if ( not defined $self->sth_selectduplicateblocknumbers )
{
$self->sth_selectduplicateblocknumbers(
$self->dbh->prepare(q(
SELECT number
FROM block
WHERE number < (
SELECT MAX(number)
FROM block)-30
GROUP BY number
HAVING COUNT(number) > 1
))
);
}
my @blocknumbers;
$self->sth_selectduplicateblocknumbers->execute();
while ( my $ref = $self->sth_selectduplicateblocknumbers->fetchrow_arrayref )
{
push @blocknumbers, $ref->[0];
}
$self->sth_selectduplicateblocknumbers->finish();
return @blocknumbers;
}
__PACKAGE__->mk_accessors( 'sth_deletetransactionsinblocknumbers' );
sub deletetransactionsinblocknumbers
{
my ( $self ) = shift;
if ( not defined $self->sth_deletetransactionsinblocknumbers )
{
$self->sth_deletetransactionsinblocknumbers(
$self->dbh->prepare(q(
DELETE FROM transaction
WHERE "blockId" IN (
SELECT id
FROM block
WHERE number = ?
)
))
);
}
$self->sth_deletetransactionsinblocknumbers->execute($_)
foreach @_;
$self->sth_deletetransactionsinblocknumbers->finish();
}
__PACKAGE__->mk_accessors( 'sth_deleteblocknumber' );
sub deleteblocknumbers
{
my ( $self ) = shift;
if ( not defined $self->sth_deleteblocknumber )
{
$self->sth_deleteblocknumber(
$self->dbh->prepare(q(
DELETE FROM block
WHERE number = ?
))
);
}
$self->sth_deleteblocknumber->execute($_)
foreach @_;
$self->sth_deleteblocknumber->finish();
}
1; 1;
## POSTGRES SUPERUSER user name is postgres ## POSTGRES SUPERUSER user name is postgres
## POSTGRES SUPERUSER password is onlythelonely ## POSTGRES SUPERUSER password is onlythelonely
## POSTGRES USER leer 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
...@@ -20,10 +19,13 @@ services: ...@@ -20,10 +19,13 @@ services:
collector: collector:
build: collector build: collector
#command: "collector/colletor.pl"
restart: always restart: always
depends_on:
- postgres
environment: environment:
POSTGRES_PASSWORD: theswampthing POSTGRES_PASSWORD: theswampthing
BFANODE: http://200.108.146.200:8545/ BFANODE: http://public.47525974938.bfa.martin-legene.dk:8545/
volumes: volumes:
- ./collector:/home/bfa/collector - ./collector:/home/bfa/collector
......
...@@ -101,10 +101,8 @@ CREATE TABLE "public"."transaction" ( ...@@ -101,10 +101,8 @@ CREATE TABLE "public"."transaction" (
"toAccountId" bigint, "toAccountId" bigint,
"contractaddressAccountId" "contractaddressAccountId"
bigint, bigint,
"status" smallint "status" smallint,
NOT NULL, "gasUsed" numeric(79),
"gasUsed" numeric(79)
NOT NULL,
"inputlen" integer "inputlen" integer
NOT NULL, NOT NULL,
"input" text "input" text
...@@ -126,6 +124,9 @@ CREATE TABLE "public"."transaction" ( ...@@ -126,6 +124,9 @@ CREATE TABLE "public"."transaction" (
REFERENCES block(id) REFERENCES block(id)
NOT DEFERRABLE NOT DEFERRABLE
) WITH (oids = false); ) WITH (oids = false);
CREATE INDEX "transaction_hash"
ON "public"."transaction"
USING btree ("hash");
CREATE INDEX "transaction_contractaddressAccountId" CREATE INDEX "transaction_contractaddressAccountId"
ON "public"."transaction" ON "public"."transaction"
USING btree ("contractaddressAccountId"); USING btree ("contractaddressAccountId");
...@@ -138,6 +139,9 @@ CREATE INDEX "transaction_toAccountId" ...@@ -138,6 +139,9 @@ CREATE INDEX "transaction_toAccountId"
CREATE INDEX "transaction_blockId" CREATE INDEX "transaction_blockId"
ON "public"."transaction" ON "public"."transaction"
USING btree ("blockId"); USING btree ("blockId");
CREATE INDEX "transaction_gasUsed"
ON "public"."transaction"
USING btree ("gasUsed");
CREATE VIEW b CREATE VIEW b
AS AS
...@@ -167,9 +171,9 @@ CREATE VIEW t ...@@ -167,9 +171,9 @@ CREATE VIEW t
gas, gas,
"gasPrice" "gas price", "gasPrice" "gas price",
value, value,
a1.address "from", coalesce(a1.shortname, a1.name, a1.address) "from",
a2.address "to", coalesce(a2.shortname, a2.name, a2.address) "to",
a3.address "contractaddress", coalesce(a3.shortname, a3.name, a3.address) "contractaddress",
status, status,
transaction."gasUsed" "gas used", transaction."gasUsed" "gas used",
inputlen inputlen
...@@ -184,33 +188,46 @@ CREATE VIEW t ...@@ -184,33 +188,46 @@ CREATE VIEW t
AND a2.id = "toAccountId"; AND a2.id = "toAccountId";
INSERT INTO "account" ("id", "address", "shortname", "name") VALUES INSERT INTO "account" ("id", "address", "shortname", "name") VALUES
(1, '0x377ab0cd00744dbb07b369cd5c0872dcd362c8f0', 'UNER', 'Universidad Nacional de Entre Rios'), (1, '0x377ab0cd00744dbb07b369cd5c0872dcd362c8f0', 'UNER', 'Universidad Nacional de Entre Rios'),
(2, '0x2feb6a8876bd9e2116b47834b977506a08ea77bd', 'PNA', 'Prefectura Nacional Argentina'), (2, '0x2feb6a8876bd9e2116b47834b977506a08ea77bd', 'PNA', 'Prefectura Nacional Argentina'),
(3, '0x354779914a94ad428d2b53ae96cce3010bb0ce1e', 'RedLink', 'RedLink SA'), (3, '0x354779914a94ad428d2b53ae96cce3010bb0ce1e', 'RedLink', 'RedLink SA'),
(4, '0x998c2651db6f76ca568c0071667d265bcc1b1e98', NULL, 'ASI'), (4, '0x998c2651db6f76ca568c0071667d265bcc1b1e98', NULL, 'ASI'),
(5, '0xd1f17aa41354d58940c300ffd79a200944dda2df', NULL, 'Marandu'), (5, '0xd1f17aa41354d58940c300ffd79a200944dda2df', NULL, 'Marandu'),
(6, '0x39170a1ce03729d141dfaf8077c08b72c9cfdd0c', 'IXPBB', 'IXP Bahia Blanca'), (6, '0x39170a1ce03729d141dfaf8077c08b72c9cfdd0c', 'IXPBB', 'IXP Bahia Blanca'),
(7, '0x02665f10cb7b93b4491ac9594d188ef2973c310a', 'CABASE-MZA', 'CABASE Mendoza'), (7, '0x02665f10cb7b93b4491ac9594d188ef2973c310a', 'CABASE-MZA', 'CABASE Mendoza'),
(8, '0x19fe7b9b3a1bebde77c5374c8e13c623e3d1b5b2', 'ARIU', 'Asociación Redes de Interconexión Universitaria'), (8, '0x19fe7b9b3a1bebde77c5374c8e13c623e3d1b5b2', 'ARIU', 'Asociación Redes de Interconexión Universitaria'),
(9, '0xe70fbc9d6be2fe509e4de7317637d8ee83d4f13c', 'CABASE-PMY', 'CABASE Puerto Madryn'), (9, '0xe70fbc9d6be2fe509e4de7317637d8ee83d4f13c', 'CABASE-PMY', 'CABASE Puerto Madryn'),
(10, '0xe191ac3108cb2c5d70d0e978876c048d4ba41b03', 'ANSV', 'Agencia Nacional de Seguridad Vial'), (10, '0xe191ac3108cb2c5d70d0e978876c048d4ba41b03', 'ANSV', 'Agencia Nacional de Seguridad Vial'),
(11, '0xf36475eb25ba0c825455f150b26e24ab9449a443', 'SRT', 'Superintendencia de Riesgos del Trabajo'), (11, '0xf36475eb25ba0c825455f150b26e24ab9449a443', 'SRT', 'Superintendencia de Riesgos del Trabajo'),
(12, '0xd1420aa9dd092f50f68913e9e53b378a68e76ed7', 'SMGP/OPTIC', 'Secretaría de Modernización de la Gestión Pública / Oficina Provincial de Tecnologías de la Información y la Comunicación - Gobierno de la Provincia del Neuquén'), (12, '0xd1420aa9dd092f50f68913e9e53b378a68e76ed7', 'SMGP/OPTIC', 'Secretaría de Modernización de la Gestión Pública / Oficina Provincial de Tecnologías de la Información y la Comunicación - Gobierno de la Provincia del Neuquén'),
(13, '0x2388d2cdb2cd6e7722b4af39c3bb406dd31f560e', 'UNR', 'Universidad Nacional de Rosario'), (13, '0x2388d2cdb2cd6e7722b4af39c3bb406dd31f560e', 'UNR', 'Universidad Nacional de Rosario'),
(14, '0x342e1d075d820ed3f9d9a05967ec4055ab23fa1e', 'CABASE', 'CABASE CABA'), (14, '0x342e1d075d820ed3f9d9a05967ec4055ab23fa1e', 'CABASE', 'CABASE CABA'),
(15, '0xb3d1209aefbe00c78b2247656e2ddfa9e3897526', 'Colescriba', 'Colegio de Escribanos de la Provincia de Buenos Aires'), (15, '0xb3d1209aefbe00c78b2247656e2ddfa9e3897526', 'Colescriba', 'Colegio de Escribanos de la Provincia de Buenos Aires'),
(16, '0xa14152753515674ae47453bea5e155a20c4ebabc', 'UP', 'Universidad de Palermo'), (16, '0xa14152753515674ae47453bea5e155a20c4ebabc', 'UP', 'Universidad de Palermo'),
(17, '0x97a47d718eab9d660b10de08ef42bd7fd915b783', 'UNLP', 'Universidad Nacional de La Plata'), (17, '0x97a47d718eab9d660b10de08ef42bd7fd915b783', 'UNLP', 'Universidad Nacional de La Plata'),
(18, '0x850b30dc584b39275a7ddcaf74a5c0e211523a30', 'UM', 'Ultima Milla'), (18, '0x850b30dc584b39275a7ddcaf74a5c0e211523a30', 'UM', 'Ultima Milla'),
(19, '0x609043ebde4a06bd28a1de238848e8f82cca9c23', 'UNSJ', 'Universidad Nacional de San Juan'), (19, '0x609043ebde4a06bd28a1de238848e8f82cca9c23', 'UNSJ', 'Universidad Nacional de San Juan'),
(20, '0xb43b53af0db2c3fac788195f4b4dcf2b3d72aa44', NULL, 'IPlan'), (20, '0xb43b53af0db2c3fac788195f4b4dcf2b3d72aa44', NULL, 'IPlan'),
(21, '0x46991ada2a2544468eb3673524641bf293f23ccc', 'UNC', 'Universidad Nacional de Cordoba'), (21, '0x46991ada2a2544468eb3673524641bf293f23ccc', 'UNC', 'Universidad Nacional de Cordoba'),
(22, '0x401d7a8432caa1025d5f093276cc6ec957b87c00', 'ONTI', 'Oficina Nacional de Tecnologias de Informacion'), (22, '0x401d7a8432caa1025d5f093276cc6ec957b87c00', 'ONTI', 'Oficina Nacional de Tecnologias de Informacion'),
(23, '0x91c055c6478bd0ad6d19bcb58f5e7ca7b04e67f1', 'DGSI', 'Dirección General de Sistemas Informáticos'), (23, '0x91c055c6478bd0ad6d19bcb58f5e7ca7b04e67f1', 'DGSI', 'Dirección General de Sistemas Informáticos'),
(24, '0x52f8a89484947cd29903b6f52ec6beda69965e38', 'CABASE-PSS', 'CABASE Posadas'), (24, '0x52f8a89484947cd29903b6f52ec6beda69965e38', 'CABASE-PSS', 'CABASE Posadas'),
(25, '0x9b3ac6719b02ec7bb4820ae178d31c0bbda3a4e0', 'Everis', 'Everis'), (25, '0x9b3ac6719b02ec7bb4820ae178d31c0bbda3a4e0', 'Everis', 'Everis'),
(26, '0x99d6c9fca2a61d4ecdeb403515eb8508dc560c6b', NULL, NULL), (26, '0x99d6c9fca2a61d4ecdeb403515eb8508dc560c6b', NULL, 'Ultima Milla 0x99 anterior'),
(27, '0xc0310a7b3b25f49b11b901a667208a3eda8d7ceb', '', 'SyT'), (27, '0xc0310a7b3b25f49b11b901a667208a3eda8d7ceb', NULL, 'SyT'),
(28, '0xabeff859aa6b0fb206d840dbf19de970065d4437', NULL, 'Belatrix'); (28, '0xabeff859aa6b0fb206d840dbf19de970065d4437', NULL, 'Belatrix');
(401, '0xbfa02a9639318f5ed1291e2cee387aa9f9d68f98', NULL, 'BFA vault 01'),
(402, '0xbfa1c42c7381a4ad32e13ce3263b639a0e0488f2', NULL, 'BFA vault 02'),
(403, '0xbfa2c97c3f59cc929e8feb1aee2aca0b38235d18', NULL, 'BFA vault 03'),
(404, '0xbfa3eb31f6526a5b29ae2302508bb6b1400d1fd1', NULL, 'BFA vault 04'),
(405, '0xbfa846ddd1fb18af693f24d316c12d8e88f4b79f', NULL, 'BFA vault 05'),
(406, '0xbfa8b1acfb51da0975274c6ebd46704c6c670a07', NULL, 'BFA vault 06'),
(407, '0xbfab583022c5c18fec70965d63985b86f96c5657', NULL, 'BFA vault 07'),
(408, '0xbfae9512c1cf4d9ce549333725c02ee8b3e5f049', NULL, 'BFA vault 08'),
(500, '0xd15dd6dbbe722b451156a013c01b29d91e23c3d6', 'dist1-mgr', 'admin de destileria1'),
(501, '0xecb6aff6e38dc58c4d9aae2f7927a282bcb77ac2', 'SC dist1', 'SC destileria1'),
(502, '0xbf1ce9cca7dedea3fdb22d169b49643664602ee1', 'DGSI-dist2', 'Destileria de DGSI'),
(503, '0xc3cf96af51d3c41dfbe428de75a8e5597d4d7a7b', 'SC-dist2', 'SC destileria de DGSI'),
-- 2020-07-13 05:48:47.242334+00 -- 2020-07-13 05:48:47.242334+00
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment