list.py (3877B)
1 # standard imports 2 import sys 3 import argparse 4 import confini 5 import logging 6 import os 7 import importlib 8 9 # external imports 10 from chainlib.chain import ChainSpec 11 from chainlib.eth.connection import EthHTTPConnection 12 from chainlib.eth.block import ( 13 block_by_hash, 14 Block, 15 ) 16 from chainlib.eth.tx import ( 17 receipt, 18 Tx, 19 ) 20 from eth_cache.store.file import FileStore 21 from eth_cache.rpc import CacheRPC 22 23 # local imports 24 from eth_monitor.index import AddressIndex 25 from eth_monitor.filters.out import OutFilter 26 from eth_monitor.rules import AddressRules 27 28 29 logging.basicConfig(level=logging.WARNING) 30 logg = logging.getLogger() 31 32 default_eth_provider = os.environ.get('RPC_PROVIDER', 'http://localhost:8545') 33 34 script_dir = os.path.realpath(os.path.dirname(__file__)) 35 exec_dir = os.path.realpath(os.getcwd()) 36 #default_config_dir = os.environ.get('CONFINI_DIR', os.path.join(exec_dir, 'config')) 37 base_config_dir = os.path.join(script_dir, '..', 'data', 'config') 38 39 40 argparser = argparse.ArgumentParser('list transactions') 41 argparser.add_argument('-p', '--provider', dest='p', default=default_eth_provider, type=str, help='Web3 provider url (http only)') 42 argparser.add_argument('-c', type=str, help='config file') 43 argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='Chain specification string') 44 argparser.add_argument('--seq', action='store_true', help='Use sequential rpc ids') 45 argparser.add_argument('-a', '--address', dest='a', default=[], action='append', type=str, help='Add address to includes list') 46 argparser.add_argument('--filter', type=str, action='append', help='Add python module filter path') 47 argparser.add_argument('-v', action='store_true', help='Be verbose') 48 argparser.add_argument('-vv', action='store_true', help='Be more verbose') 49 argparser.add_argument('--fresh', action='store_true', help='Do not read block and tx data from cache, even if available') 50 argparser.add_argument('--renderer', type=str, action='append', default=[], help='Python modules to dynamically load for rendering of transaction output') 51 argparser.add_argument('cache_dir', type=str, help='Directory to read cache data from') 52 args = argparser.parse_args(sys.argv[1:]) 53 54 55 if args.vv: 56 logg.setLevel(logging.DEBUG) 57 elif args.v: 58 logg.setLevel(logging.INFO) 59 60 config_dir = args.c 61 config = confini.Config(base_config_dir, os.environ.get('CONFINI_ENV_PREFIX'), override_dirs=args.c) 62 config.process() 63 args_override = { 64 'CHAIN_SPEC': getattr(args, 'i'), 65 } 66 config.dict_override(args_override, 'cli') 67 config.add(getattr(args, 'cache_dir'), '_CACHE_DIR') 68 logg.debug('loaded config:\{}'.format(config)) 69 70 chain_spec = ChainSpec.from_chain_str(args.i) 71 72 rpc_id_generator = None 73 if args.seq: 74 rpc_id_generator = IntSequenceGenerator() 75 76 auth = None 77 if os.environ.get('RPC_AUTHENTICATION') == 'basic': 78 from chainlib.auth import BasicAuth 79 auth = BasicAuth(os.environ['RPC_USERNAME'], os.environ['RPC_PASSWORD']) 80 rpc = EthHTTPConnection(args.p) 81 82 83 def main(): 84 store = FileStore(chain_spec, config.get('_CACHE_DIR')) 85 use_rpc = rpc 86 if not args.fresh: 87 use_rpc = CacheRPC(rpc, store) 88 89 renderers_mods = [] 90 for renderer in args.renderer: 91 m = importlib.import_module(renderer) 92 renderers_mods.append(m) 93 94 idx = AddressIndex(rpc, store) 95 96 for address in args.a: 97 idx.load_address_tx(address) 98 99 OutFilter.init(store) 100 out_filter = OutFilter(chain_spec, renderers=renderers_mods) 101 102 for tx_src in idx.get_address(address): 103 o = block_by_hash(tx_src['block_hash']) 104 block_src = use_rpc.do(o) 105 106 o = receipt(tx_src['hash']) 107 rcpt = use_rpc.do(o) 108 109 block = Block(block_src) 110 tx = Tx(tx_src, block=block, rcpt=rcpt) 111 out_filter.filter(use_rpc, block, tx, db_session=None) 112 113 114 if __name__ == '__main__': 115 main()