chainlib-eth

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

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()