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:
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