From 051cfd203187d5ea9c0f7cdcffe238b98acf2cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Martin-Leg=C3=A8ne?= <robert@nic.ar> Date: Mon, 1 Oct 2018 04:14:24 -0300 Subject: [PATCH] Fixed walker.pl + introduced libbfa.pm --- bin/libbfa.pm | 108 ++++++++++++++++++++++++++++++++++++++ bin/walker.pl | 142 +++++++++++++++++++++++++------------------------- 2 files changed, 179 insertions(+), 71 deletions(-) create mode 100644 bin/libbfa.pm diff --git a/bin/libbfa.pm b/bin/libbfa.pm new file mode 100644 index 0000000..56dc58a --- /dev/null +++ b/bin/libbfa.pm @@ -0,0 +1,108 @@ +# 20180927 Robert Martin-Legene <robert@nic.ar> + +package libbfa; +use Math::BigInt; +use IO::File; +use LWP; +use JSON; +use Carp; +$Carp::Verbose = 1; + +sub _cat +{ + my $filename = shift; + my $fh = IO::File->new($filename); + return if not defined $fh; + local $_ = join( '', $fh->getlines ); + $fh->close; + return if not defined $_; + s|^\s+||; + s|\s+$||; + return if $_ eq ''; + return $_; +} + +sub _filecontents_or_default +{ + my ($self, $filename, $default) = @_; + local $_ = $self->_cat( $filename ); + return $default if not defined $_; + return $_; +} + +sub new +{ + my ( $class ) = @_; + my $self = bless {}, ref $class || $class; + # BFAHOME + die '$BFAHOME not set. Did you source bfa/bin/env ?\n' + if not exists $ENV{'BFAHOME'}; + $self->{'home'} = $ENV{'BFAHOME'}; + # BFANETWORKID + $self->{'networkid'} = $ENV{'BFANETWORKID'} = + exists $ENV{'BFANETWORKID'} + ? $ENV{'BFANETWORKID'} + : 47525974938; + # BFANETWORKDIR + $self->{'networkdir'} = $ENV{'BFANETWORKDIR'} = + exists $ENV{'BFANETWORKDIR'} + ? $ENV{'BFANETWORKDIR'} + : $self->{'home'}.'/network'; + # BFANODEDIR + $self->{'nodedir'} = $ENV{'BFANODEDIR'} = + exists $ENV{'BFANODEDIR'} + ? $ENV{'BFANODEDIR'} + : $self->{'networkdir'}.'/node'; + # ACCOUNT + if ( not exists $ENV{'BFAACCOUNT'} ) { + my $dir = $self->{'nodedir'}; + my @files = sort <${dir}/*--*>; + # found none? + if (scalar(@files) > 0 ) + { + my $file = $files[0]; + $file =~ s/^.*--//; + $self->{'account'} = $ENV{'BFAACCOUNT'} = + '0x' . $file; + } + } + # + $self->{'netport'} = $self->_filecontents_or_default( $self->{'nodedir'}.'/netport', 30303 ); + $self->{'rpcport'} = $self->_filecontents_or_default( $self->{'nodedir'}.'/netport', 8545 ); + $self->{'ua'} = LWP::UserAgent->new; + return $self; +} + +sub contract +{ + my $self = shift; + my $contract = {}; + my $contname = shift; + my $contdir = join('/', [ $self->{'networkdir'}, 'contracts', $contname ] ); + my $contaddr = readlink $contdir; + return if not defined $contaddr; + $contaddr =~ s|^.*/||; + $contract->{'address'} = #contaddr; + my $abistr = $self->_cat( $contdir . '/abi' ); + die "Can not find abi file, stopped" if not defined $abistr; + eval { my $contract->{'abi'} = decode_json( $abistr ) }; + die "Can not decode json, stopped" if not defined $contract->{'abi'}; + return $contract; +} + +sub rpcreq +{ + my ( $self, $opname, @params ) = @_; + my $req = HTTP::Request->new( POST => "http://127.0.0.1:".$self->{'rpcport'} ); + $req->content_type('application/json'); + my $extra = scalar @params + ? sprintf(qq(,\"params\":[%s]), join(',', @params)) + : ''; + $req->content( qq({"jsonrpc":"2.0","method":"${opname}"${extra},"id":1})); + my $res = $self->{'ua'}->request($req); + die $res->status_line + unless $res->is_success; + return $res->content; +} + +1; diff --git a/bin/walker.pl b/bin/walker.pl index 038369f..7705e9d 100755 --- a/bin/walker.pl +++ b/bin/walker.pl @@ -6,13 +6,16 @@ use IO::File; use Math::BigInt; use Carp; $Carp::Verbose = 1; - -die "\$BFAHOME not set. Did you source bfa/bin/env ?\n" - unless exists $ENV{BFAHOME}; -chdir "$ENV{BFAHOME}" or die $!; +BEGIN { + die "\$BFAHOME not set. Did you source bfa/bin/env ?\n" + unless exists $ENV{BFAHOME}; +} +use libbfa; +use Data::Dumper; +my $libbfa; package tools; -my $rpcport; +use Data::Dumper; my $ua = LWP::UserAgent->new; our $CSI = "\x1b["; our $clearEOS = "${CSI}J"; @@ -22,8 +25,10 @@ our $normal = "${CSI}m"; sub new { - my $class = shift; - return bless {@_}, ref $class || $class; + my ($class, $libbfa) = @_; + my $self = bless {}, ref $class || $class; + $self->{'libbfa'} = $libbfa; + return $self; } sub wait @@ -68,11 +73,7 @@ sub hex2string($) sub rpcreq { my ( $opname, @params ) = @_; - if ( not defined $rpcport ) - { - $rpcport = tools::cat "$ENV{BFAHOME}/network5445/node1/rpcport" or die; - } - my $req = HTTP::Request->new( POST => "http://127.0.0.1:$rpcport" ); + my $req = HTTP::Request->new( POST => 'http://127.0.0.1:' . $libbfa->{'rpcport'} ); $req->content_type('application/json'); my $extra = scalar @params ? sprintf(qq(,\"params\":[%s]), join(',', @params)) @@ -86,11 +87,13 @@ sub rpcreq package balance; use JSON; +use Data::Dumper; sub new { - my ($class, $acct, $at) = @_; + my ($class, $libbfa, $acct, $at) = @_; my $self = bless {}, ref $class || $class; + $self->{'libbfa'} = $libbfa; $self->get( $acct, $at ) if defined $acct; return $self; } @@ -118,10 +121,11 @@ sub at sub get { my ($self, $acct, $at) = @_; + my $libbfa = $self->{'libbfa'}; $self->acct($acct) if defined $acct; $self->at($at) if defined $at; my @params = ( sprintf(qq("%s","%s"),$self->acct,$self->at) ); - my $content = tools::rpcreq( 'eth_getBalance', @params ); + my $content = $libbfa->rpcreq( 'eth_getBalance', @params ); my $json; eval { $json = decode_json( $content ) }; my $error = error->new( $content ); @@ -139,6 +143,7 @@ sub get package error; use JSON; +use Data::Dumper; sub new { @@ -173,15 +178,24 @@ sub message package block; use LWP; use JSON; +use Data::Dumper; sub new { - my ( $class, $json_raw ) = @_; + my ( $class, $libbfa ) = @_; + my $self = bless {}, ref $class || $class; + $self->{'libbfa'} = $libbfa; + return $self; +} + +sub parse +{ + my ( $self, $json_raw ) = @_; + $self->{'libbfa'} = $libbfa; return unless defined $json_raw; return if $json_raw eq ''; - my $self = bless {}, ref $class || $class; - $self->{'json_raw'} = $json_raw; - eval { $self->{'json'} = decode_json( $json_raw ) }; + $self->{'json_raw'} = $json_raw; + eval { $self->{'json'} = decode_json( $json_raw ) }; return if $@; $self->error( error->new($json_raw) ); return $self; @@ -292,59 +306,38 @@ sub clear return $t; } -sub signature +sub get { - my ($self) = @_; - my $t = $self->extradata; - return unless defined $t; - return substr($t, -130); - my $res = $self->result; - die unless defined $res; -use Data::Dumper; -die Dumper($res). - clear($res->{'parentHash'}). - clear($res->{'sha3Uncles'}). - clear($res->{'miner'}). - clear($res->{'stateRoot'}). - clear($res->{'transactionsRoot'}). - clear($res->{'receiptsRoot'}). - clear($res->{'logsBloom'}). - clear($res->{'difficulty'}). - clear($res->{'number'}). - clear($res->{'gasLimit'}). - clear($res->{'gasUsed'}). - clear($res->{'timestamp'}). - substr( clear($res->{'extraData'}), 0, -130 ). ('0' x 130). - clear($res->{'mixHash'}). - clear($self->{'nonce'}); -} - -sub get($;$) -{ - my ($number) = @_; - $number = sprintf('0x%x', $number) if $number ne 'earliest'; - my $cachefile = "cache/block.$number"; - my $block; - if ( -r $cachefile ) + my ($self, $number) = @_; + my $cachefile; + if ( $number =~ /^[0-9]+$/ ) + { + $number = sprintf('0x%x', $number); + $cachefile = "cache/block.$number"; + } + my $libbfa = $self->{'libbfa'}; + my $block = block->new( $libbfa ); + if ( defined $cachefile and -r $cachefile ) { - $block = block->new( tools::cat $cachefile ); + $block = $block->parse( tools::cat $cachefile ); return $block if defined $block and not $block->error; # We delete the cache file if we couldn't use the data in it. unlink $cachefile; # and then we continue to fetch it } - my $content = tools::rpcreq( 'eth_getBlockByNumber', qq("$number"), "false"); - $block = block->new( $content ); + my $content = tools::rpcreq( 'eth_getBlockByNumber', qq("$number"), "false"); + $block = $block->parse( $content ); return if not defined $block; return if not exists $block->{'json'}; - die $block->error->message - if $block->error; + die $block->error->message if $block->error; return if not $block->result; - my $fh = IO::File->new( $cachefile, 'w' ) - or die $!; - $fh->print( $block->{'json_raw'} ); - $fh->close; + if ( defined $cachefile ) + { + my $fh = IO::File->new( $cachefile, 'w' ) or die $!; + $fh->print( $block->{'json_raw'} ); + $fh->close; + } return $block; } @@ -379,12 +372,12 @@ sub sprint $txt.= sprintf "Confirming signer at epoch: 0x%s with an ETH balance of %s\n", $sealer, - balance->new->get($sealer, $self->number); + balance->new->get($libbfa, $sealer, $self->number); $lines++; } } $txt .= sprintf - '%s block:%s gaslimit:%s td:%d Vanity: %s', + '%s block:%s gaslimit:%s td:%d Vanity:%s', tools::gmt($self->timestamp), $self->number, $self->gasLimit, @@ -401,33 +394,40 @@ sub sprint } package main; +use Data::Dumper; $| = 1; +chdir "$ENV{BFAHOME}" or die $!; mkdir 'cache'; -my $number = shift || tools::cat 'walker.block.last' || 'earliest'; +my $number = shift || 'latest'; my $tools = tools->new; -my @blks; my $parent; +$libbfa = libbfa->new(); while ( 1 ) { - my $block = block::get($number); + my $block = block->new->get( $number ); if ( not defined $block ) { $tools->wait(); next; } - $parent = block::get($block->number-1) if not defined $parent and $block->number > 1; - if ( defined $parent and $parent->hash ne $block->parentHash ) +#print Dumper(['block'=>$block]); + $number = $block->number; + if (not defined $parent and + $block->number > 1) + { + $parent = $block->get( $block->number-1 ); + } + if ( defined $parent and + $parent->hash ne $block->parentHash ) { printf "\r${tools::red}%s${tools::normal}\n", scalar($parent->sprint); ($parent, $block, $number) = (undef, $parent, $number-1); $block->delete_cache; next; } - shift @blks while scalar @blks > 32; - push @blks, $block; $block->print; - $number = $block->number + 1; - $parent = $block; + $number = $block->number + 1; + $parent = $block; } -- GitLab