eth-gas-sum

Sync a running total of gas usage across EVM blocks
git clone git://holbrook.no/ethd-gas-sum.git
Log | Files | Refs

commit 7b94b17fd3835f5b516dfb46821f9050866fb8b0
Author: nolash <dev@holbrook.no>
Date:   Mon, 25 Oct 2021 22:19:47 +0200

Initial commit

Diffstat:
Aeth_gas_sum/runnable/sum.py | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arequirements.txt | 2++
2 files changed, 120 insertions(+), 0 deletions(-)

diff --git a/eth_gas_sum/runnable/sum.py b/eth_gas_sum/runnable/sum.py @@ -0,0 +1,118 @@ +# 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() diff --git a/requirements.txt b/requirements.txt @@ -0,0 +1,2 @@ +chainsyncer==0.0.7a3 +chainlib-eth==0.0.10a15