eth-monitor/eth_monitor/runnable/list.py

119 lines
3.9 KiB
Python

# standard imports
import sys
import argparse
import confini
import logging
import os
import importlib
# external imports
from chainlib.chain import ChainSpec
from chainlib.eth.connection import EthHTTPConnection
from chainlib.eth.block import (
block_by_hash,
Block,
)
from chainlib.eth.tx import (
receipt,
Tx,
)
# local imports
from eth_monitor.store.file import FileStore
from eth_monitor.index import AddressIndex
from eth_monitor.rpc import CacheRPC
from eth_monitor.filters.out import OutFilter
from eth_monitor.rules import AddressRules
logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger()
default_eth_provider = os.environ.get('RPC_PROVIDER')
if default_eth_provider == None:
default_eth_provider = os.environ.get('ETH_PROVIDER', 'http://localhost:8545')
script_dir = os.path.realpath(os.path.dirname(__file__))
exec_dir = os.path.realpath(os.getcwd())
#default_config_dir = os.environ.get('CONFINI_DIR', os.path.join(exec_dir, 'config'))
base_config_dir = os.path.join(script_dir, '..', 'data', 'config')
argparser = argparse.ArgumentParser('list transactions')
argparser.add_argument('-p', '--provider', dest='p', default=default_eth_provider, type=str, help='Web3 provider url (http only)')
argparser.add_argument('-c', type=str, help='config file')
argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='Chain specification string')
argparser.add_argument('--seq', action='store_true', help='Use sequential rpc ids')
argparser.add_argument('--output', default=[], action='append', type=str, help='Add output (sender) addresses to includes list')
argparser.add_argument('--filter', type=str, action='append', help='Add python module filter path')
argparser.add_argument('-v', action='store_true', help='Be verbose')
argparser.add_argument('-vv', action='store_true', help='Be more verbose')
argparser.add_argument('--fresh', action='store_true', help='Do not read block and tx data from cache, even if available')
argparser.add_argument('--renderer', type=str, action='append', default=[], help='Python modules to dynamically load for rendering of transaction output')
argparser.add_argument('cache_dir', type=str, help='Directory to read cache data from')
args = argparser.parse_args(sys.argv[1:])
if args.vv:
logg.setLevel(logging.DEBUG)
elif args.v:
logg.setLevel(logging.INFO)
config_dir = args.c
config = confini.Config(base_config_dir, os.environ.get('CONFINI_ENV_PREFIX'), override_dirs=args.c)
config.process()
args_override = {
'CHAIN_SPEC': getattr(args, 'i'),
}
config.dict_override(args_override, 'cli')
config.add(getattr(args, 'cache_dir'), '_CACHE_DIR')
logg.debug('loaded config:\{}'.format(config))
chain_spec = ChainSpec.from_chain_str(args.i)
rpc_id_generator = None
if args.seq:
rpc_id_generator = IntSequenceGenerator()
auth = None
if os.environ.get('RPC_AUTHENTICATION') == 'basic':
from chainlib.auth import BasicAuth
auth = BasicAuth(os.environ['RPC_USERNAME'], os.environ['RPC_PASSWORD'])
rpc = EthHTTPConnection(args.p)
def main():
store = FileStore(chain_spec, config.get('_CACHE_DIR'))
use_rpc = rpc
if not args.fresh:
use_rpc = CacheRPC(rpc, store)
renderers_mods = []
for renderer in args.renderer:
m = importlib.import_module(renderer)
renderers_mods.append(m)
idx = AddressIndex(rpc, store)
for address in args.output:
idx.load_address_tx(address)
OutFilter.init(store)
out_filter = OutFilter(chain_spec, renderers=renderers_mods)
for tx_src in idx.get_address(address):
o = block_by_hash(tx_src['block_hash'])
block_src = use_rpc.do(o)
o = receipt(tx_src['hash'])
rcpt = use_rpc.do(o)
block = Block(block_src)
tx = Tx(tx_src, block=block, rcpt=rcpt)
out_filter.filter(use_rpc, block, tx, db_session=None)
if __name__ == '__main__':
main()