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

149 lines
5.0 KiB
Python
Raw Normal View History

2021-10-25 22:19:47 +02:00
# 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')
2021-10-26 08:29:58 +02:00
argparser.add_argument('--end', type=int, help='end block (not inclusive)')
2021-10-25 22:19:47 +02:00
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_argument('--sender', type=str, action='append', default=[], help='sender address sender to monitor')
argparser.add_argument('--recipient', type=str, action='append', default=[], help='recipient address sender to monitor')
argparser.add_argument('--address', type=str, action='append', default=[], help='sender or recipient address to monitor')
2021-10-25 22:19:47 +02:00
args = argparser.parse_args()
extra_args = {
'start': None,
'end': None,
'address': None,
'sender': None,
'recipient': None,
2021-10-25 22:19:47 +02:00
'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, senders, recipients):
self.senders = senders
self.recipients = recipients
2021-10-25 22:19:47 +02:00
self.tx_gas = {}
self.gas_sum = 0
2022-03-05 08:37:28 +01:00
self.match_label = None
if len(senders) == 0 and len(recipients) == 0:
self.match_label = 'match'
2021-10-25 22:19:47 +02:00
def filter(self, conn, block, tx, db_session):
sender = hex_uniform(strip_0x(tx.outputs[0]))
recipient = hex_uniform(strip_0x(tx.inputs[0]))
2022-03-05 08:37:28 +01:00
match_label = self.match_label
if match_label == None:
if sender in self.senders:
match_label = 'sender ' + sender
elif recipient in self.recipients:
match_label = 'recipient ' + receipient
self.gas_sum += tx.gas_used
self.tx_gas[tx.hash] = tx.gas_used
logg.info('{} tx {} ({}/{}) gas {} new sum {}'.format(match_label, tx.hash, tx.block.number, tx.index, tx.gas_used, self.gas_sum))
2021-10-25 22:19:47 +02:00
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:
2021-10-26 08:29:58 +02:00
backend = FileBackend.live(chain_spec, start, base_dir=config.get('_OUTPUT_DIR'))
2021-10-25 22:19:47 +02:00
syncer = HeadSyncer(backend, chain_interface)
senders = []
recipients = []
for address in config.get('_SENDER'):
clean_address = hex_uniform(strip_0x(address))
senders.append(clean_address)
logg.debug('monitoring sender {}'.format(clean_address))
for address in config.get('_RECIPIENT'):
clean_address = hex_uniform(strip_0x(address))
recipients.append(clean_address)
logg.debug('monitoring recipient {}'.format(clean_address))
for address in config.get('_ADDRESS'):
clean_address = hex_uniform(strip_0x(address))
if address not in senders:
senders.append(clean_address)
logg.debug('monitoring sender {}'.format(clean_address))
if address not in recipients:
recipients.append(clean_address)
logg.debug('monitoring recipient {}'.format(clean_address))
gas_filter = GasAddFilter(chain_spec, senders, recipients)
2021-10-25 22:19:47 +02:00
syncer.add_filter(gas_filter)
2021-10-26 08:29:58 +02:00
2021-10-25 22:19:47 +02:00
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()