block.py (4562B)
1 # SPDX-License-Identifier: GPL-3.0-or-later 2 3 # standard imports 4 import sys 5 import os 6 import json 7 import argparse 8 import logging 9 import enum 10 import select 11 12 # external imports 13 from potaahto.symbols import snake_and_camel 14 from hexathon import ( 15 add_0x, 16 strip_0x, 17 ) 18 import sha3 19 from chainlib.jsonrpc import ( 20 JSONRPCRequest, 21 jsonrpc_result, 22 IntSequenceGenerator, 23 ) 24 from chainlib.chain import ChainSpec 25 from chainlib.status import Status 26 from chainlib.settings import ChainSettings 27 28 # local imports 29 from chainlib.eth.connection import EthHTTPConnection 30 from chainlib.eth.tx import ( 31 Tx, 32 pack, 33 ) 34 from chainlib.eth.address import ( 35 to_checksum_address, 36 is_checksum_address, 37 ) 38 from chainlib.eth.block import ( 39 Block, 40 block_by_hash, 41 block_by_number, 42 block_latest, 43 ) 44 from chainlib.eth.jsonrpc import to_blockheight_param 45 import chainlib.eth.cli 46 from chainlib.eth.cli.arg import ( 47 Arg, 48 ArgFlag, 49 process_args, 50 ) 51 from chainlib.eth.cli.config import ( 52 Config, 53 process_config, 54 ) 55 from chainlib.eth.cli.log import process_log 56 from chainlib.eth.settings import process_settings 57 58 logg = logging.getLogger() 59 60 script_dir = os.path.dirname(os.path.realpath(__file__)) 61 config_dir = os.path.join(script_dir, '..', 'data', 'config') 62 63 def process_config_local(config, arg, args, flags): 64 if len(args.block) > 0: 65 config.add(args.block[0], '_BLOCK', False) 66 return config 67 68 69 def process_settings_local(settings, config): 70 block_identifier = config.get('_POSARG') 71 if block_identifier == None: 72 return process_settings(settings, config) 73 74 maybe_hex = None 75 is_number = False 76 try: 77 maybe_hex = strip_0x(block_identifier) 78 except ValueError: 79 is_number = True 80 81 if maybe_hex != None: 82 if len(maybe_hex) != 64: 83 is_number = True 84 else: 85 is_number = True 86 87 r = None 88 if not is_number: 89 config.add(block_identifier, '_HASH', False) 90 else: 91 settings.set('_BLOCK', int(block_identifier)) 92 93 return process_settings(settings, config) 94 95 96 argparser = chainlib.eth.cli.ArgumentParser() 97 arg_flags = ArgFlag() 98 arg = Arg(arg_flags) 99 flags = arg_flags.STD_BASE_READ 100 flags = arg_flags.less(flags, arg_flags.CHAIN_SPEC) 101 argparser = process_args(argparser, arg, flags) 102 argparser.add_argument('block', type=str, help='Block hash or number to retrieve') 103 args = argparser.parse_args() 104 105 logg = process_log(args, logg) 106 107 config = Config() 108 config = process_config(config, arg, args, flags, positional_name='block') 109 config = process_config_local(config, arg, args, flags) 110 logg.debug('config loaded:\n{}'.format(config)) 111 112 settings = ChainSettings() 113 settings = process_settings_local(settings, config) 114 logg.debug('settings loaded:\n{}'.format(settings)) 115 116 117 def get_block(settings): 118 hsh = None 119 try: 120 hsh = settings.get('HASH')[0] 121 except TypeError: 122 pass 123 r = None 124 if hsh == None: 125 r = get_block_number( 126 settings.get('CONN'), 127 settings.get('_BLOCK'), 128 settings.get('RPC_ID_GENERATOR'), 129 ) 130 else: 131 r = get_block_hash( 132 settings.get('CONN'), 133 hsh, 134 settings.get('RPC_ID_GENERATOR'), 135 ) 136 137 return block_process(r) 138 139 140 def get_block_number_latest(conn, id_generator): 141 o = block_latest(id_generator) 142 r = conn.do(o) 143 return int(r, 16) 144 145 146 def get_block_number(conn, block_number, id_generator): 147 o = None 148 if block_number == None: 149 block_number = get_block_number_latest(conn, id_generator) 150 o = block_by_number(block_number, include_tx=False) 151 block_src = conn.do(o) 152 if block_src == None: 153 logg.error('Block number {} not found'.format(block_number)) 154 sys.exit(1) 155 return block_src 156 157 158 def get_block_hash(conn, block_hash, id_generator): 159 block_hash = add_0x(block_hash) 160 o = block_by_hash(block_hash, include_tx=False) 161 block_src = conn.do(o) 162 if block_src == None: 163 logg.error('Block hash {} not found'.format(block_hash)) 164 sys.exit(1) 165 return block_src 166 167 168 def block_process(block_src): 169 return Block(block_src, dialect_filter=settings.get('RPC_DIALECT_FILTER')) 170 171 172 def main(): 173 r = get_block(settings) 174 175 if not config.true('_RAW'): 176 r = r.to_human() 177 else: 178 r = repr(r) 179 if r != None: 180 print(r) 181 182 183 if __name__ == '__main__': 184 main()