Initial commit
This commit is contained in:
commit
5b47ab5661
2
config/chain.ini
Normal file
2
config/chain.ini
Normal file
@ -0,0 +1,2 @@
|
||||
[chain]
|
||||
spec =
|
2
config/rpc.ini
Normal file
2
config/rpc.ini
Normal file
@ -0,0 +1,2 @@
|
||||
[rpc]
|
||||
provider =
|
125
eth_stat_syncer/runnable/syncer.py
Normal file
125
eth_stat_syncer/runnable/syncer.py
Normal file
@ -0,0 +1,125 @@
|
||||
# standard imports
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
import argparse
|
||||
import datetime
|
||||
|
||||
# external imports
|
||||
import confini
|
||||
from chainsyncer.backend import MemBackend
|
||||
from chainsyncer.driver import (
|
||||
HeadSyncer,
|
||||
HistorySyncer,
|
||||
)
|
||||
from chainsyncer.filter import SyncFilter
|
||||
from chainsyncer.error import NoBlockForYou
|
||||
from chainlib.chain import ChainSpec
|
||||
from chainlib.eth.connection import EthHTTPConnection
|
||||
from chainlib.eth.block import block_latest
|
||||
|
||||
logging.basicConfig(level=logging.WARNING)
|
||||
logg = logging.getLogger()
|
||||
|
||||
default_config_dir = os.environ.get('CONFINI_DIR', './config')
|
||||
|
||||
argparser = argparse.ArgumentParser()
|
||||
argparser.add_argument('-p', '--provider', dest='p', type=str, help='rpc provider')
|
||||
argparser.add_argument('-c', '--config', dest='c', default=default_config_dir, type=str, help='rpc provider')
|
||||
argparser.add_argument('-i', '--chain-spec', dest='i', default='evm:ethereum:1', type=str, help='chain spec')
|
||||
argparser.add_argument('--start', type=int, help='number of blocks to sample at startup')
|
||||
argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration')
|
||||
argparser.add_argument('-v', action='store_true', help='be verbose')
|
||||
argparser.add_argument('-vv', action='store_true', help='be more verbose')
|
||||
args = argparser.parse_args()
|
||||
|
||||
if args.vv:
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
elif args.v:
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
config = confini.Config(args.c, args.env_prefix)
|
||||
config.process()
|
||||
# override args
|
||||
args_override = {
|
||||
'CHAIN_SPEC': getattr(args, 'i'),
|
||||
'RPC_PROVIDER': getattr(args, 'p'),
|
||||
}
|
||||
config.dict_override(args_override, 'cli flag')
|
||||
config.add(args.start, '_START', True)
|
||||
logg.debug('loaded config: {}\n'.format(config))
|
||||
|
||||
chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC'))
|
||||
|
||||
conn = EthHTTPConnection(args.p)
|
||||
|
||||
|
||||
class GasStore:
|
||||
|
||||
def __init__(self, store):
|
||||
self.store = store
|
||||
self.avg = 0
|
||||
self.count = 0
|
||||
self.timestamp = datetime.datetime.utcnow()
|
||||
|
||||
|
||||
def put(self, v):
|
||||
aggr = self.avg * self.count
|
||||
aggr += v
|
||||
self.count += 1
|
||||
self.avg = int(aggr / self.count)
|
||||
logg.info('added {} to aggregate {} new average {} from {} samples'.format(v, aggr, self.avg, self.count))
|
||||
return self.avg
|
||||
|
||||
|
||||
def get(self):
|
||||
return self.avg
|
||||
|
||||
|
||||
class GasPriceFilter(SyncFilter):
|
||||
|
||||
def __init__(self, chain_spec, gas_store):
|
||||
self.chain_spec = chain_spec
|
||||
self.gas_store = gas_store
|
||||
|
||||
|
||||
def filter(self, conn, block, tx, db_session):
|
||||
self.gas_store.put(tx.gas_price)
|
||||
|
||||
|
||||
def block_callback(block, tx):
|
||||
logg.info('synced {}'.format(block))
|
||||
|
||||
|
||||
def main():
|
||||
gas_store = GasStore(None)
|
||||
gas_filter = GasPriceFilter(chain_spec, gas_store)
|
||||
|
||||
o = block_latest()
|
||||
r = conn.do(o)
|
||||
n = int(r, 16)
|
||||
start_block = n
|
||||
logg.info('block height at start {}'.format(start_block))
|
||||
|
||||
if config.get('_START') != None:
|
||||
offset = start_block - config.get('_START')
|
||||
syncer_backend = MemBackend(chain_spec, None, target_block=start_block)
|
||||
syncer_backend.set(offset, 0)
|
||||
syncer = HistorySyncer(syncer_backend, block_callback=block_callback)
|
||||
syncer.add_filter(gas_filter)
|
||||
try:
|
||||
syncer.loop(0.0, conn)
|
||||
except NoBlockForYou:
|
||||
logg.info('history done at {}'.format(syncer.backend.get()))
|
||||
pass
|
||||
|
||||
syncer_backend = MemBackend(chain_spec, None)
|
||||
syncer_backend.set(start_block + 1, 0)
|
||||
syncer = HeadSyncer(syncer_backend, block_callback=block_callback)
|
||||
syncer.add_filter(gas_filter)
|
||||
syncer.loop(1.0, conn)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
chainsyncer==0.0.1a22
|
||||
chainlib==0.0.2a6
|
32
setup.cfg
Normal file
32
setup.cfg
Normal file
@ -0,0 +1,32 @@
|
||||
[metadata]
|
||||
name = eth-stat-syncer
|
||||
version = 0.0.1a1
|
||||
description = Cache live EVM blockchain stats
|
||||
author = Louis Holbrook
|
||||
author_email = dev@holbrook.no
|
||||
url = https://gitlab.com/nolash/giftable-erc-token
|
||||
keywords =
|
||||
ethereum
|
||||
classifiers =
|
||||
Programming Language :: Python :: 3
|
||||
Operating System :: OS Independent
|
||||
Development Status :: 3 - Alpha
|
||||
Environment :: No Input/Output (Daemon)
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
||||
Topic :: Internet
|
||||
#Topic :: Blockchain :: EVM
|
||||
license = GPL3
|
||||
licence_files =
|
||||
LICENSE
|
||||
|
||||
[options]
|
||||
include_package_data = True
|
||||
python_requires = >= 3.6
|
||||
packages =
|
||||
eth_stat_syncer
|
||||
eth_stat_syncer.runnable
|
||||
|
||||
[options.entry_points]
|
||||
console_scripts =
|
||||
eth-stat-syncerd = eth_stat_tracker.runnable.syncer:main
|
26
setup.py
Normal file
26
setup.py
Normal file
@ -0,0 +1,26 @@
|
||||
from setuptools import setup
|
||||
|
||||
requirements = []
|
||||
f = open('requirements.txt', 'r')
|
||||
while True:
|
||||
l = f.readline()
|
||||
if l == '':
|
||||
break
|
||||
requirements.append(l.rstrip())
|
||||
f.close()
|
||||
|
||||
test_requirements = []
|
||||
f = open('test_requirements.txt', 'r')
|
||||
while True:
|
||||
l = f.readline()
|
||||
if l == '':
|
||||
break
|
||||
test_requirements.append(l.rstrip())
|
||||
f.close()
|
||||
|
||||
|
||||
setup(
|
||||
include_package_data=True,
|
||||
install_requires=requirements,
|
||||
tests_require=test_requirements,
|
||||
)
|
Loading…
Reference in New Issue
Block a user