75 lines
2.5 KiB
Python
75 lines
2.5 KiB
Python
# 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
|
||
"""
|
||
def __init__(self, bc_cache, mx=500):
|
||
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, 0x-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
|