ethd-gas-sum/eth_gas_sum/runnable/sum.py

119 lines
3.6 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 logging
# external imports
import chainlib.eth.cli
from chainlib.chain import ChainSpec
from chainsyncer.backend.file import FileBackend
from chainlib.interface import ChainInterface
from chainlib.eth.block import (
block_latest,
block_by_number,
Block,
)
from chainlib.eth.tx import (
receipt,
Tx,
)
from chainsyncer.driver.history import HistorySyncer
from chainsyncer.driver.head import HeadSyncer
from hexathon import (
strip_0x,
uniform as hex_uniform,
)
logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger()
arg_flags = chainlib.eth.cli.argflag_std_read
argparser = chainlib.eth.cli.ArgumentParser(arg_flags)
argparser.add_argument('--start', type=int, help='start at block')
argparser.add_argument('--end', type=int, default=0, help='end block (not inclusive)')
argparser.add_argument('--interval', type=int, default=5, help='syncer poll interval for new blocks')
argparser.add_argument('-d', type=str, required=True, help='output directory')
argparser.add_positional('address', type=str, append=True, help='address sender to monitor')
args = argparser.parse_args()
extra_args = {
'start': None,
'end': None,
'address': None,
'd': '_OUTPUT_DIR',
'interval': 'SYNCER_LOOP_INTERVAL',
}
# process config
config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args)
logg.debug('config loaded\n'+ str(config))
# set up rpc
rpc = chainlib.eth.cli.Rpc()
conn = rpc.connect_by_config(config)
chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC'))
class EthChainInterface(ChainInterface):
def __init__(self):
self._block_by_number = block_by_number
self._block_from_src = Block.from_src
self._tx_receipt = receipt
self._src_normalize = Tx.src_normalize
class GasAddFilter:
def __init__(self, chain_spec, addresses):
self.addresses = []
for address in addresses:
clean_address = hex_uniform(strip_0x(address))
self.addresses.append(clean_address)
logg.debug('added {} to gas sum filter'.format(clean_address))
self.tx_gas = {}
self.gas_sum = 0
def filter(self, conn, block, tx, db_session):
sender = hex_uniform(strip_0x(tx.outputs[0]))
if sender in self.addresses:
self.gas_sum += tx.gas_used
self.tx_gas[tx.hash] = tx.gas_used
logg.debug('sender {} tx {} gas {} new sum {}'.format(sender, tx.hash, tx.gas_used, self.gas_sum))
def sum(self):
return self.gas_sum
def main():
loop_interval = config.get('SYNCER_LOOP_INTERVAL')
start = config.get('_START')
if start == None:
o = block_latest()
r = conn.do(o)
block_current = int(r, 16)
start = block_current + 1
end = config.get('_END')
syncer = None
chain_interface = EthChainInterface()
if end != None:
backend = FileBackend.initial(chain_spec, end, start_block_height=start, base_dir=config.get('_OUTPUT_DIR'))
syncer = HistorySyncer(backend, chain_interface)
else:
FileBackend.live(chain_spec, start, base_dir=config.get('_OUTPUT_DIR'))
syncer = HeadSyncer(backend, chain_interface)
gas_filter = GasAddFilter(chain_spec, config.get('_ADDRESS'))
syncer.add_filter(gas_filter)
r = syncer.loop(config.get('SYNCER_LOOP_INTERVAL'), conn)
for k in gas_filter.tx_gas.keys():
print('tx {} gas {}'.format(k, gas_filter.tx_gas[k]))
print('total gas: ' + str(gas_filter.sum()))
if __name__ == '__main__':
main()