2021-02-01 18:12:51 +01:00
# standard imports
import logging
# third-party imports
from web3 . exceptions import BlockNotFound
from . error import LoopDone
# local imports
from . mined import MinedSyncer
from . base import Syncer
from cic_eth . db . models . base import SessionBase
logg = logging . getLogger ( )
class HistorySyncer ( MinedSyncer ) :
""" Implements the get method in Syncer for retrieving all blocks between last processed block before previous shutdown and block height at time of syncer start.
: param bc_cache : Retrieves block cache cursors for chain head and latest processed block .
: type bc_cache : Object implementing methods from cic_eth . sync . SyncerBackend
: param mx : Maximum number of blocks to return in one call
: type mx : int
"""
2021-02-12 21:03:38 +01:00
def __init__ ( self , bc_cache , mx = 500 ) :
2021-02-01 18:12:51 +01:00
super ( HistorySyncer , self ) . __init__ ( bc_cache )
self . max = mx
self . target = bc_cache . target ( )
logg . info ( ' History syncer target block number {} ' . format ( self . target ) )
session_offset = self . bc_cache . get ( )
self . block_offset = session_offset [ 0 ]
self . tx_offset = session_offset [ 1 ]
logg . info ( ' History syncer starting at {} : {} ' . format ( session_offset [ 0 ] , session_offset [ 1 ] ) )
self . filter = [ ]
""" Implements Syncer.get
BUG : Should also raise LoopDone when block array is empty after loop .
: param w3 : Web3 object
: type w3 : web3 . Web3
: raises LoopDone : If a block is not found .
: return : Return a batch of blocks to process
: rtype : list of str , 0 x - hex
"""
def get ( self , w3 ) :
sync_db = self . bc_cache
height = self . bc_cache . get ( )
logg . debug ( ' height {} ' . format ( height ) )
block_last = height [ 0 ]
tx_last = height [ 1 ]
if not self . running :
raise LoopDone ( ( block_last , tx_last ) )
b = [ ]
block_target = block_last + self . max
if block_target > self . target :
block_target = self . target
logg . debug ( ' target {} last {} max {} ' . format ( block_target , block_last , self . max ) )
for i in range ( block_last , block_target ) :
if i == self . target :
logg . info ( ' reached target {} , exiting ' . format ( i ) )
self . running = False
break
bhash = w3 . eth . getBlock ( i ) . hash
b . append ( bhash )
logg . debug ( ' appending block {} {} ' . format ( i , bhash . hex ( ) ) )
if block_last == block_target :
logg . info ( ' aleady reached target {} , exiting ' . format ( self . target ) )
self . running = False
return b