2021-04-08 19:53:36 +02:00
# standard imports
import sys
import os
import logging
import argparse
2022-04-07 15:29:44 +02:00
import uuid
2021-04-08 19:53:36 +02:00
# external imports
import confini
2022-04-07 15:29:44 +02:00
from chainsyncer . store . fs import SyncFsStore
from chainsyncer . driver . chain_interface import ChainInterfaceDriver
2021-04-08 19:53:36 +02:00
from chainsyncer . filter import SyncFilter
from chainsyncer . error import NoBlockForYou
from chainlib . chain import ChainSpec
from chainlib . eth . connection import EthHTTPConnection
2022-03-08 10:56:15 +01:00
from chainlib . interface import ChainInterface
from chainlib . eth . block import (
block_by_number ,
Block ,
block_latest ,
)
from chainlib . eth . tx import (
receipt ,
Tx ,
)
2021-04-08 19:53:36 +02:00
2021-04-08 21:48:00 +02:00
# local imports
2021-04-08 22:15:57 +02:00
from eth_stat_syncer . store import (
GasAggregator ,
RunStore ,
)
2021-04-08 21:48:00 +02:00
2021-04-08 19:53:36 +02:00
logging . basicConfig ( level = logging . WARNING )
logg = logging . getLogger ( )
2022-04-07 15:29:44 +02:00
script_dir = os . path . realpath ( os . path . dirname ( __file__ ) )
exec_dir = os . path . realpath ( os . getcwd ( ) )
default_config_dir = os . environ . get ( ' confini_dir ' , os . path . join ( exec_dir , ' config ' ) )
2021-04-08 19:53:36 +02:00
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 ' )
2022-04-07 15:29:44 +02:00
argparser . add_argument ( ' --moving ' , action = ' append ' , default = [ ] , type = int , help = ' add moving average ' )
argparser . add_argument ( ' --offset ' , type = int , default = 0 , help = ' Start sync on this block ' )
2021-04-08 19:53:36 +02:00
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 ' )
2022-04-07 15:54:45 +02:00
argparser . add_argument ( ' --cache-dir ' , dest = ' cache_dir ' , type = str , help = ' Directory to store gas cache ' )
2022-04-07 15:29:44 +02:00
argparser . add_argument ( ' --state-dir ' , dest = ' state_dir ' , default = exec_dir , type = str , help = ' Directory to store sync state ' )
argparser . add_argument ( ' --session-id ' , dest = ' session_id ' , type = str , help = ' Use state from specified session id ' )
2021-04-08 19:53:36 +02:00
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 ' )
2022-04-07 15:29:44 +02:00
config . add ( args . offset , ' _SYNC_OFFSET ' , True )
config . add ( os . path . realpath ( args . state_dir ) , ' _STATE_DIR ' , True )
config . add ( args . cache_dir , ' _CACHE_DIR ' , True )
config . add ( args . session_id , ' _SESSION_ID ' , True )
config . add ( args . moving , ' _MOVING ' , True )
2021-04-08 19:53:36 +02:00
logg . debug ( ' loaded config: {} \n ' . format ( config ) )
chain_spec = ChainSpec . from_chain_str ( config . get ( ' CHAIN_SPEC ' ) )
conn = EthHTTPConnection ( args . p )
2022-04-07 15:29:44 +02:00
if config . get ( ' _SESSION_ID ' ) == None :
config . add ( str ( uuid . uuid4 ( ) ) , ' _SESSION_ID ' , True )
2021-04-08 19:53:36 +02:00
class GasPriceFilter ( SyncFilter ) :
2021-04-08 21:48:00 +02:00
def __init__ ( self , chain_spec , gas_aggregator ) :
2021-04-08 19:53:36 +02:00
self . chain_spec = chain_spec
2021-04-08 21:48:00 +02:00
self . gas_aggregator = gas_aggregator
2021-04-08 19:53:36 +02:00
2022-04-07 15:29:44 +02:00
def filter ( self , conn , block , tx , db_session = None ) :
2021-04-08 21:48:00 +02:00
self . gas_aggregator . put ( tx . gas_price )
2022-04-07 15:29:44 +02:00
return False
2021-04-08 19:53:36 +02:00
2022-03-08 10:56:15 +01:00
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
2021-04-08 19:53:36 +02:00
def main ( ) :
2022-04-07 15:54:45 +02:00
gas_store = RunStore ( basedir = config . get ( ' _CACHE_DIR ' ) )
2022-04-07 15:29:44 +02:00
cap = 360
try :
v = max ( config . get ( ' _MOVING ' ) )
if v > cap :
cap = v
except ValueError :
pass
gas_aggregator = GasAggregator ( gas_store , cap , moving = config . get ( ' _MOVING ' ) )
2021-04-08 21:48:00 +02:00
gas_filter = GasPriceFilter ( chain_spec , gas_aggregator )
2021-04-08 19:53:36 +02:00
2022-04-07 15:29:44 +02:00
start_block = 0
if config . get ( ' _SYNC_OFFSET ' ) != None :
start_block = config . get ( ' _SYNC_OFFSET ' )
else :
o = block_latest ( )
r = conn . do ( o )
n = int ( r , 16 )
start_block = n
logg . info ( ' block height at start {} ' . format ( start_block ) )
2021-04-08 19:53:36 +02:00
2022-03-08 10:56:15 +01:00
chain_interface = EthChainInterface ( )
2022-04-07 15:29:44 +02:00
sync_store = SyncFsStore ( config . get ( ' _STATE_DIR ' ) , session_id = config . get ( ' _SESSION_ID ' ) )
sync_store . register ( gas_filter )
drv = ChainInterfaceDriver ( sync_store , chain_interface , offset = start_block , target = - 1 , block_callback = gas_aggregator . block_callback )
r = drv . run ( conn )
2021-04-08 19:53:36 +02:00
if __name__ == ' __main__ ' :
main ( )