commit e16cc956e0d9c39a4a7242f4234d974aac02fec2
parent 9012b9884a6ca3166235f64cd965bb44d21524d0
Author: lash <dev@holbrook.no>
Date: Thu, 12 May 2022 08:20:06 +0000
Rehabilitate 'count' tool
Diffstat:
7 files changed, 243 insertions(+), 22 deletions(-)
diff --git a/chainlib/eth/block.py b/chainlib/eth/block.py
@@ -1,4 +1,7 @@
-import sys
+# standard imports
+import logging
+import datetime
+
# external imports
from chainlib.jsonrpc import JSONRPCRequest
from chainlib.block import Block as BaseBlock
@@ -12,6 +15,8 @@ from hexathon import (
from chainlib.eth.tx import Tx
from .src import Src
+logg = logging.getLogger(__name__)
+
def block_latest(id_generator=None):
"""Implements chainlib.interface.ChainInterface method
@@ -87,21 +92,29 @@ class Block(BaseBlock, Src):
tx_generator = Tx
- def __init__(self, src):
- super(Block, self).__init__(src)
- import sys
- self.set_hash(src['hash'])
+ def __init__(self, src=None):
+ super(Block, self).__init__(src=src)
+
+ self.set_hash(self.src['hash'])
try:
- self.number = int(strip_0x(src['number']), 16)
+ self.number = int(strip_0x(self.src['number']), 16)
except TypeError:
- self.number = int(src['number'])
- self.txs = src['transactions']
- self.block_src = src
+ self.number = int(self.src['number'])
+ self.txs = self.src['transactions']
+ self.block_src = self.src
try:
- self.timestamp = int(strip_0x(src['timestamp']), 16)
+ self.timestamp = int(strip_0x(self.src['timestamp']), 16)
except TypeError:
- self.timestamp = int(src['timestamp'])
- self.author = src['author']
+ self.timestamp = int(self.src['timestamp'])
+
+ try:
+ self.author = self.src['author']
+ except KeyError:
+ self.author = self.src['miner']
+
+ self.fee_limit = self.src['gas_limit']
+ self.fee_cost = self.src['gas_used']
+ self.parent_hash = self.src['parent_hash']
def tx_index_by_hash(self, tx_hash):
@@ -121,3 +134,29 @@ class Block(BaseBlock, Src):
if idx == -1:
raise AttributeError('tx {} not found in block {}'.format(tx_hash, self.hash))
return idx
+
+
+ def to_human(self):
+ s = """hash: {}
+number: {}
+parent: {}
+timestamp: {}
+time: {}
+author: {}
+gas_limit: {}
+gas_used: {}
+txs: {}
+""".format(
+ self.hash,
+ self.number,
+ self.parent_hash,
+ self.timestamp,
+ datetime.datetime.fromtimestamp(self.timestamp),
+ self.author,
+ self.fee_limit,
+ self.fee_cost,
+ len(self.txs),
+ )
+
+ return s
+
diff --git a/chainlib/eth/runnable/balance.py b/chainlib/eth/runnable/balance.py
@@ -40,7 +40,7 @@ logg = logging.getLogger()
script_dir = os.path.dirname(os.path.realpath(__file__))
-argparser = chainlib.eth.cli.ArgumentParser() #arg_flags)
+argparser = chainlib.eth.cli.ArgumentParser()
arg_flags = ArgFlag()
arg = Arg(arg_flags)
flags = arg_flags.STD_READ
diff --git a/chainlib/eth/runnable/block.py b/chainlib/eth/runnable/block.py
@@ -0,0 +1,138 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# standard imports
+import sys
+import os
+import json
+import argparse
+import logging
+import enum
+import select
+
+# external imports
+from potaahto.symbols import snake_and_camel
+from hexathon import (
+ add_0x,
+ strip_0x,
+ )
+import sha3
+from chainlib.jsonrpc import (
+ JSONRPCRequest,
+ jsonrpc_result,
+ IntSequenceGenerator,
+ )
+from chainlib.chain import ChainSpec
+from chainlib.status import Status
+
+# local imports
+from chainlib.eth.connection import EthHTTPConnection
+from chainlib.eth.tx import (
+ Tx,
+ pack,
+ )
+from chainlib.eth.address import (
+ to_checksum_address,
+ is_checksum_address,
+ )
+from chainlib.eth.block import (
+ Block,
+ block_by_hash,
+ block_by_number,
+ )
+from chainlib.eth.runnable.util import decode_for_puny_humans
+from chainlib.eth.jsonrpc import to_blockheight_param
+import chainlib.eth.cli
+from chainlib.eth.cli.arg import (
+ Arg,
+ ArgFlag,
+ process_args,
+ )
+from chainlib.eth.cli.config import (
+ Config,
+ process_config,
+ )
+from chainlib.eth.cli.log import process_log
+
+logg = logging.getLogger()
+
+script_dir = os.path.dirname(os.path.realpath(__file__))
+config_dir = os.path.join(script_dir, '..', 'data', 'config')
+
+argparser = chainlib.eth.cli.ArgumentParser()
+arg_flags = ArgFlag()
+arg = Arg(arg_flags)
+flags = arg_flags.STD_BASE_READ
+flags = arg_flags.less(flags, arg_flags.CHAIN_SPEC)
+argparser = process_args(argparser, arg, flags)
+argparser.add_argument('block', nargs='?', type=str, help='Block hash or number to retrieve')
+args = argparser.parse_args()
+
+logg = process_log(args, logg)
+
+config = Config()
+config = process_config(config, arg, args, flags)
+logg.debug('config loaded:\n{}'.format(config))
+
+rpc = chainlib.eth.cli.Rpc()
+conn = rpc.connect_by_config(config)
+
+chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC'))
+
+item = add_0x(args.block)
+
+
+def get_block(conn, block_identifier, id_generator):
+ maybe_hex = None
+ r = None
+ try:
+ maybe_hex = strip_0x(block_identifier)
+ except ValueError:
+ r = get_block_number(conn, block_identifier, id_generator)
+
+ if len(maybe_hex) != 64:
+ r = get_block_number(conn, block_identifier, id_generator)
+
+ if maybe_hex != block_identifier:
+ r = get_block_hash(conn, block_identifier, id_generator)
+ else:
+ r = get_block_number(conn, block_identifier, id_generator)
+
+ return block_process(r)
+
+
+def get_block_number(conn, block_number, id_generator):
+ block_number = int(block_number)
+ o = block_by_number(block_number, include_tx=False)
+ block_src = conn.do(o)
+ if block_src == None:
+ logg.error('Block number {} not found'.format(block_number))
+ sys.exit(1)
+ return block_src
+
+def get_block_hash(conn, block_hash, id_generator):
+ block_hash = add_0x(block_hash)
+ o = block_by_hash(block_hash, include_tx=False)
+ block_src = conn.do(o)
+ if block_src == None:
+ logg.error('Block hash {} not found'.format(block_hash))
+ sys.exit(1)
+ return block_src
+
+
+def block_process(block_src):
+ return Block(block_src)
+
+
+def main():
+ block_identifier = item
+ r = get_block(conn, block_identifier, rpc.id_generator)
+ if not config.true('_RAW'):
+ r = r.to_human()
+ else:
+ r = repr(r)
+ if r != None:
+ print(r)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/chainlib/eth/runnable/count.py b/chainlib/eth/runnable/count.py
@@ -10,6 +10,16 @@ import select
# local imports
import chainlib.eth.cli
+from chainlib.eth.cli.arg import (
+ Arg,
+ ArgFlag,
+ process_args,
+ )
+from chainlib.eth.cli.config import (
+ Config,
+ process_config,
+ )
+from chainlib.eth.cli.log import process_log
from chainlib.eth.address import AddressChecksum
from chainlib.eth.connection import EthHTTPConnection
from chainlib.eth.tx import count
@@ -25,11 +35,21 @@ logg = logging.getLogger()
script_dir = os.path.dirname(os.path.realpath(__file__))
config_dir = os.path.join(script_dir, '..', 'data', 'config')
-arg_flags = chainlib.eth.cli.argflag_std_base_read | chainlib.eth.cli.Flag.WALLET
-argparser = chainlib.eth.cli.ArgumentParser(arg_flags)
-argparser.add_positional('address', type=str, help='Ethereum address of recipient')
+argparser = chainlib.eth.cli.ArgumentParser()
+arg_flags = ArgFlag()
+arg = Arg(arg_flags)
+flags = arg_flags.STD_BASE_READ | arg_flags.WALLET | arg_flags.UNSAFE
+argparser = process_args(argparser, arg, flags)
+
+argparser.add_argument('address', type=str, help='Ethereum address of recipient')
args = argparser.parse_args()
-config = chainlib.eth.cli.Config.from_args(args, arg_flags, default_config_dir=config_dir)
+
+logg = process_log(args, logg)
+logg.debug('flags {} {} {}'.format(flags, arg_flags.SEQ, flags & arg_flags.SEQ))
+
+config = Config()
+config = process_config(config, arg, args, flags)
+logg.debug('config loaded:\n{}'.format(config))
holder_address = args.address
wallet = chainlib.eth.cli.Wallet()
diff --git a/chainlib/eth/runnable/get.py b/chainlib/eth/runnable/get.py
@@ -41,6 +41,16 @@ from chainlib.eth.block import (
from chainlib.eth.runnable.util import decode_for_puny_humans
from chainlib.eth.jsonrpc import to_blockheight_param
import chainlib.eth.cli
+from chainlib.eth.cli.arg import (
+ Arg,
+ ArgFlag,
+ process_args,
+ )
+from chainlib.eth.cli.config import (
+ Config,
+ process_config,
+ )
+from chainlib.eth.cli.log import process_log
logging.basicConfig(level=logging.WARNING, format='%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(message)s')
logg = logging.getLogger()
@@ -48,12 +58,20 @@ logg = logging.getLogger()
script_dir = os.path.dirname(os.path.realpath(__file__))
config_dir = os.path.join(script_dir, '..', 'data', 'config')
-arg_flags = chainlib.eth.cli.argflag_std_base_read
-arg_flags = chainlib.eth.cli.argflag_reset(arg_flags, chainlib.eth.cli.Flag.CHAIN_SPEC)
-argparser = chainlib.eth.cli.ArgumentParser(arg_flags)
-argparser.add_positional('item', type=str, help='Address or transaction to retrieve data for')
+argparser = chainlib.eth.cli.ArgumentParser()
+arg_flags = ArgFlag()
+arg = Arg(arg_flags)
+flags = arg_flags.STD_BASE_READ
+flags = arg_flags.less(flags, arg_flags.CHAIN_SPEC)
+argparser = process_args(argparser, arg, flags)
+argparser.add_argument('item', type=str, help='Address or transaction to retrieve data for')
args = argparser.parse_args()
-config = chainlib.eth.cli.Config.from_args(args, arg_flags, default_config_dir=config_dir)
+
+logg = process_log(args, logg)
+
+config = Config()
+config = process_config(config, arg, args, flags)
+logg.debug('config loaded:\n{}'.format(config))
rpc = chainlib.eth.cli.Rpc()
conn = rpc.connect_by_config(config)
diff --git a/chainlib/eth/src.py b/chainlib/eth/src.py
@@ -1,5 +1,6 @@
# standard imports
import logging
+import json
# external imports
from potaahto.symbols import snake_and_camel
@@ -46,3 +47,7 @@ class Src(BaseSrc):
v = uniform(v, compact_value=False, allow_empty=True)
return v
+
+
+ def __repr__(self):
+ return json.dumps(self.src)
diff --git a/setup.cfg b/setup.cfg
@@ -48,3 +48,4 @@ console_scripts =
eth-info = chainlib.eth.runnable.info:main
eth-nonce = chainlib.eth.runnable.count:main
eth-wait = chainlib.eth.runnable.wait:main
+ eth-block = chainlib.eth.runnable.block:main