chainsyncer/chainsyncer/driver.py

105 lines
2.8 KiB
Python
Raw Normal View History

2021-02-03 19:40:03 +01:00
# standard imports
import uuid
import logging
2021-02-03 21:10:08 +01:00
import time
2021-02-03 19:40:03 +01:00
2021-02-17 12:44:35 +01:00
# external imports
from chainlib.eth.block import (
block_by_number,
Block,
)
# local imports
from chainsyncer.filter import SyncFilter
2021-02-03 19:40:03 +01:00
logg = logging.getLogger()
2021-02-11 12:46:36 +01:00
def noop_progress(s, block_number, tx_index):
logg.debug('({},{}) {}'.format(block_number, tx_index, s))
2021-02-03 19:40:03 +01:00
class Syncer:
2021-02-03 21:10:08 +01:00
running_global = True
yield_delay=0.005
2021-02-03 21:10:08 +01:00
def __init__(self, backend, progress_callback=noop_progress):
2021-02-03 20:55:39 +01:00
self.cursor = None
self.running = True
self.backend = backend
2021-02-17 12:44:35 +01:00
self.filter = SyncFilter()
self.progress_callback = progress_callback
2021-02-03 20:55:39 +01:00
def chain(self):
"""Returns the string representation of the chain spec for the chain the syncer is running on.
:returns: Chain spec string
:rtype: str
"""
return self.bc_cache.chain()
2021-02-03 19:40:03 +01:00
2021-02-11 09:02:17 +01:00
def add_filter(self, f):
2021-02-17 12:44:35 +01:00
self.filter.add(f)
2021-02-11 09:02:17 +01:00
2021-02-03 19:40:03 +01:00
2021-02-17 12:44:35 +01:00
class BlockSyncer(Syncer):
2021-02-03 19:40:03 +01:00
2021-02-17 12:44:35 +01:00
def __init__(self, backend, progress_callback=noop_progress):
super(BlockSyncer, self).__init__(backend, progress_callback)
2021-02-03 19:40:03 +01:00
2021-02-17 12:44:35 +01:00
def loop(self, interval, conn):
2021-02-12 09:12:03 +01:00
g = self.backend.get()
last_tx = g[1]
last_block = g[0]
self.progress_callback('loop started', last_block, last_tx)
2021-02-03 20:55:39 +01:00
while self.running and Syncer.running_global:
while True:
2021-02-17 12:44:35 +01:00
try:
block = self.get(conn)
except Exception:
break
2021-02-12 09:12:03 +01:00
last_block = block.number
2021-02-17 12:44:35 +01:00
self.process(conn, block)
2021-02-11 12:46:36 +01:00
start_tx = 0
2021-02-12 09:12:03 +01:00
self.progress_callback('processed block {}'.format(self.backend.get()), last_block, last_tx)
time.sleep(self.yield_delay)
2021-02-17 12:44:35 +01:00
self.progress_callback('loop ended', last_block + 1, last_tx)
2021-02-03 21:10:08 +01:00
time.sleep(interval)
2021-02-03 20:55:39 +01:00
2021-02-03 19:40:03 +01:00
2021-02-17 12:44:35 +01:00
class HeadSyncer(BlockSyncer):
2021-02-03 19:40:03 +01:00
2021-02-17 12:44:35 +01:00
def __init__(self, backend, progress_callback=noop_progress):
super(HeadSyncer, self).__init__(backend, progress_callback)
2021-02-03 19:40:03 +01:00
2021-02-17 12:44:35 +01:00
def process(self, conn, block):
2021-02-11 12:46:36 +01:00
logg.debug('process block {}'.format(block))
2021-02-03 23:03:39 +01:00
i = 0
tx = None
while True:
try:
tx = block.tx(i)
2021-02-11 12:46:36 +01:00
self.progress_callback('processing {}'.format(repr(tx)), block.number, i)
self.backend.set(block.number, i)
2021-02-17 12:44:35 +01:00
self.filter.apply(conn, block, tx)
2021-02-03 23:03:39 +01:00
except IndexError as e:
self.backend.set(block.number + 1, 0)
2021-02-03 23:03:39 +01:00
break
i += 1
2021-02-17 12:44:35 +01:00
def get(self, conn):
2021-02-03 20:55:39 +01:00
(block_number, tx_number) = self.backend.get()
2021-02-03 19:40:03 +01:00
block_hash = []
2021-02-17 12:44:35 +01:00
o = block_by_number(block_number)
r = conn.do(o)
b = Block(r)
logg.debug('get {}'.format(b))
2021-02-03 19:40:03 +01:00
2021-02-17 12:44:35 +01:00
return b