chainlib-eth

Ethereum implementation of the chainlib interface
Log | Files | Refs | README | LICENSE

commit 6ee3ea4638aa9e03fa9009cee4d28a7b0ee8e5be
parent 31e75f60dee5a03ee7488f7829f7d4c42755c9c4
Author: nolash <dev@holbrook.no>
Date:   Mon, 25 Oct 2021 11:24:55 +0200

Handle null-value block hashes on receipts

Diffstat:
Mchainlib/eth/block.py | 14++++++++++++++
Mchainlib/eth/connection.py | 16+++++++++++-----
Mchainlib/eth/runnable/info.py | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Msetup.cfg | 2+-
4 files changed, 82 insertions(+), 28 deletions(-)

diff --git a/chainlib/eth/block.py b/chainlib/eth/block.py @@ -60,6 +60,20 @@ def transaction_count(block_hash, id_generator=None): return j.finalize(o) +def syncing(id_generator=None): + """Request the syncing state of the node + + :param id_generator: JSONRPC id generator + :type id_generator: JSONRPCIdGenerator + :rtype: dict + :returns: rpc query object + """ + j = JSONRPCRequest(id_generator) + o = j.template() + o['method'] = 'eth_syncing' + return j.finalize(o) + + class Block(BaseBlock): """Encapsulates an Ethereum block diff --git a/chainlib/eth/connection.py b/chainlib/eth/connection.py @@ -36,6 +36,7 @@ from chainlib.jsonrpc import ( from chainlib.eth.tx import ( unpack, ) +from potaahto.symbols import snake_and_camel logg = logging.getLogger(__name__) @@ -88,11 +89,16 @@ class EthHTTPConnection(JSONRPCHTTPConnection): e = jsonrpc_result(r, error_parser) if e != None: - logg.debug('({}) poll receipt completed {}'.format(str(self), r)) - logg.debug('e {}'.format(strip_0x(e['status']))) - if strip_0x(e['status']) == '00': - raise RevertEthException(tx_hash_hex) - return e + e = snake_and_camel(e) + # In openethereum we encounter receipts that have NONE block hashes and numbers. WTF... + if e['block_hash'] == None: + logg.warning('poll receipt attempt {} returned receipt but with a null block hash value!'.format(i)) + else: + logg.debug('({}) poll receipt completed {}'.format(str(self), r)) + logg.debug('e {}'.format(strip_0x(e['status']))) + if strip_0x(e['status']) == '00': + raise RevertEthException(tx_hash_hex) + return e if timeout > 0.0: delta = (datetime.datetime.utcnow() - t) + datetime.timedelta(seconds=delay) diff --git a/chainlib/eth/runnable/info.py b/chainlib/eth/runnable/info.py @@ -24,6 +24,7 @@ from chainlib.eth.chain import network_id from chainlib.eth.block import ( block_latest, block_by_number, + syncing, Block, ) from chainlib.eth.tx import count @@ -43,25 +44,35 @@ logg = logging.getLogger() script_dir = os.path.dirname(os.path.realpath(__file__)) config_dir = os.path.join(script_dir, '..', 'data', 'config') +results_translation = { + 'network_id': 'Network Id', + 'block': 'Block', + 'syncing': 'Syncing', + 'gas_limit': 'Gas Limit', + 'gas_price': 'Gas Price', + 'block_time': 'Block time', + } + + arg_flags = chainlib.eth.cli.argflag_std_read argparser = chainlib.eth.cli.ArgumentParser(arg_flags) -argparser.add_positional('address', type=str, help='Address to retrieve info for', required=False) argparser.add_argument('--long', action='store_true', help='Calculate averages through sampling of blocks and txs') +argparser.add_argument('--local', action='store_true', help='Include local info') +argparser.add_positional('entry', required=False, help='Output single item') args = argparser.parse_args() -config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args={'long': None}, default_config_dir=config_dir) +extra_args = { + 'local': None, + 'long': None, + 'entry': None, + } +config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args, default_config_dir=config_dir) -holder_address = None -try: - holder_address = add_0x(args.address) -except ValueError: - pass -wallet = chainlib.eth.cli.Wallet() -wallet.from_config(config) -if wallet.get_signer_address() == None and holder_address != None: - wallet.from_address(holder_address) +if config.get('_ENTRY') != None: + if config.get('_ENTRY') not in results_translation.keys(): + raise ValueError('Unknown entry {}'.format(config.get('_ENTRY'))) -rpc = chainlib.eth.cli.Rpc(wallet=wallet) +rpc = chainlib.eth.cli.Rpc() conn = rpc.connect_by_config(config) token_symbol = 'eth' @@ -72,12 +83,25 @@ human = not config.true('_RAW') longmode = config.true('_LONG') +def set_result(results, k, v, w=sys.stdout): + kt = results_translation[k] + if str(config.get('_ENTRY')) == k: + w.write('{}'.format(v)) + return True + logg.info('{}: {}\n'.format(kt, v)) + results[k] = v + return False + + def main(): + results = {} + o = network_id(id_generator=rpc.id_generator) r = conn.do(o) #if human: # n = format(n, ',') - sys.stdout.write('Network id: {}\n'.format(r)) + if set_result(results, 'network_id', r): + return o = block_latest(id_generator=rpc.id_generator) r = conn.do(o) @@ -85,7 +109,8 @@ def main(): first_block_number = n if human: n = format(n, ',') - sys.stdout.write('Block: {}\n'.format(n)) + if set_result(results, 'block', n): + return o = block_by_number(first_block_number, False, id_generator=rpc.id_generator) r = conn.do(o) @@ -111,22 +136,31 @@ def main(): if human: n = format(n, ',') - sys.stdout.write('Gaslimit: {}\n'.format(n)) - sys.stdout.write('Blocktime: {}\n'.format(aggr_time / BLOCK_SAMPLES)) + if set_result(results, 'gas_limit', n): + return + if set_result(results, 'block_time', aggr_time / BLOCK_SAMPLES): + return o = price(id_generator=rpc.id_generator) r = conn.do(o) n = int(r, 16) if human: n = format(n, ',') - sys.stdout.write('Gasprice: {}\n'.format(n)) + if set_result(results, 'gas_price', n): + return - if holder_address != None: - o = count(holder_address) + if config.get('_LOCAL'): + o = syncing() r = conn.do(o) - n = int(r, 16) - sys.stdout.write('Address: {}\n'.format(holder_address)) - sys.stdout.write('Nonce: {}\n'.format(n)) + if set_result(results, 'syncing', r): + return + + if config.get('_ENTRY') != None: + raise RuntimeError('entry {} ({}) not processed, please review the flag settings'.format(config.get('_ENTRY'), results_translation[config.get('_ENTRY')])) + + for k in results.keys(): + kt = results_translation[k] + sys.stdout.write('{}: {}\n'.format(kt, results[k])) if __name__ == '__main__': diff --git a/setup.cfg b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = chainlib-eth -version = 0.0.10a13 +version = 0.0.10a15 description = Ethereum implementation of the chainlib interface author = Louis Holbrook author_email = dev@holbrook.no