eth-monitor/eth_monitor/runnable/import.py

148 lines
4.8 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# standard imports
import argparse
import logging
import sys
import os
import time
# external imports
from chainlib.encode import TxHexNormalizer
from chainlib.eth.connection import EthHTTPConnection
from chainlib.chain import ChainSpec
# local imports
from eth_monitor.filters.cache import Filter as CacheFilter
from eth_monitor.filters import RuledFilter
from eth_monitor.store.file import FileStore
from eth_monitor.rules import (
AddressRules,
RuleSimple,
)
logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger()
normalize_address = TxHexNormalizer().wallet_address
argparser = argparse.ArgumentParser('master eth events monitor')
argparser.add_argument('--api-key-file', dest='api_key_file', type=str, help='File to read API key from')
argparser.add_argument('--cache-dir', dest='cache_dir', type=str, help='Directory to store tx data')
argparser.add_argument('--store-tx-data', dest='store_tx_data', action='store_true', help='Include all transaction data objects by default')
argparser.add_argument('--store-block-data', dest='store_block_data', action='store_true', help='Include all block data objects by default')
argparser.add_argument('-i', '--chain-spec', dest='i', type=str, default='evm:ethereum:1', help='Chain specification string')
argparser.add_argument('-f', '--address-file', dest='address_file', default=[], type=str, action='append', help='Add addresses from file')
argparser.add_argument('-a', '--address', default=[], type=str, action='append', help='Add address')
argparser.add_argument('--delay', type=float, default=0.2, help='Seconds to wait between each retrieval from importer')
argparser.add_argument('-v', action='store_true', help='Be verbose')
argparser.add_argument('-vv', action='store_true', help='Be more verbose')
argparser.add_argument('-p', type=str, help='RPC provider')
args = argparser.parse_args(sys.argv[1:])
if args.vv:
logg.setLevel(logging.DEBUG)
elif args.v:
logg.setLevel(logging.INFO)
api_key = os.environ.get('API_KEY')
if args.api_key_file != None:
f = open(args.api_key_file, 'r')
api_key = f.read()
f.close()
rpc = EthHTTPConnection(args.p)
chain_spec = ChainSpec.from_chain_str(args.i)
def conn_socks_tor(host='127.0.0.1', port=9050):
import socks
import socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4, host, port, True)
socket.socket = socks.socksocket
def collect_addresses(addresses=[], address_files=[]):
address_collection = []
for a in addresses:
a = normalize_address(a)
if a in address_collection:
logg.debug('skipping duplicate address {}'.format(a))
address_collection.append(a)
logg.info('added address {}'.format(a))
for fp in address_files:
logg.debug('processing file ' + fp)
f = open(fp, 'r')
while True:
a = f.readline()
if a == '':
break
a = a.rstrip()
a = normalize_address(a)
if a in address_collection:
logg.debug('skipping duplicate address {}'.format(a))
address_collection.append(a)
logg.info('added address {}'.format(a))
f.close()
return address_collection
def setup_address_rules(addresses):
rules = AddressRules()
outputs = []
inputs = []
execs = []
for address in addresses:
outputs.append(address)
inputs.append(address)
execs.append(address)
rule = RuleSimple(outputs, inputs, execs, description='etherscan import')
rules.include(rule)
return rules
def setup_filter(chain_spec, cache_dir, include_tx_data, include_block_data, address_rules):
store = FileStore(chain_spec, cache_dir, address_rules=address_rules)
cache_dir = os.path.realpath(cache_dir)
if cache_dir == None:
import tempfile
cache_dir = tempfile.mkdtemp()
logg.info('using chain spec {} and dir {}'.format(chain_spec, cache_dir))
RuledFilter.init(store, include_tx_data=include_tx_data, include_block_data=include_block_data)
def main():
conn_socks_tor()
addresses = collect_addresses(args.address, args.address_file)
from eth_monitor.importers.etherscan import Importer as EtherscanImporter
address_rules = setup_address_rules(args.address)
setup_filter(
chain_spec,
args.cache_dir,
bool(args.store_tx_data),
bool(args.store_block_data),
address_rules,
)
cache_filter = CacheFilter(
rules_filter=address_rules,
)
filters = [
cache_filter,
]
importer = EtherscanImporter(rpc, api_key, filters=filters, block_callback=RuledFilter.block_callback)
for a in addresses:
importer.get(a)
time.sleep(args.delay)
if __name__ == '__main__':
main()