chainsyncer

Blockchain syncer driver
Log | Files | Refs | LICENSE

commit 6f1ad9cb76a950071cb53aaef5ce9d61741a170e
parent 8b085083ef197bce5f950fa9f231e0bac64153de
Author: lash <dev@holbrook.no>
Date:   Sun, 13 Aug 2023 17:56:32 +0100

Apply dialect filters in chain interface driver

Diffstat:
MCHANGELOG | 3+++
Mchainsyncer/driver/chain_interface.py | 21+++++++++++++--------
Mchainsyncer/store/base.py | 2++
Mchainsyncer/unittest/base.py | 26+++++++++++++++++++-------
Mrequirements.txt | 2+-
Mrun_tests.sh | 1+
Msetup.cfg | 2+-
Mtests/test_session.py | 14++++++++++++++
8 files changed, 54 insertions(+), 17 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG @@ -1,3 +1,6 @@ +* 0.8.3 + - Apply dialect on receipts and block tx constructors + - Avoid filter state crash when no filters defined * 0.8.2 - Add filter prepare method (with context) to interface * 0.8.1 diff --git a/chainsyncer/driver/chain_interface.py b/chainsyncer/driver/chain_interface.py @@ -47,7 +47,7 @@ class ChainInterfaceDriver(SyncDriver): hsh = txs[j].hash o = self.chain_interface.tx_receipt(hsh) r = conn.do(o) - txs[j].apply_receipt(r) + txs[j].apply_receipt(r, dialect_filter=self.chain_interface.dialect_filter) logg.debug('get receipt {}/{}: {}'.format(j+1, c, hsh)) i += 1 return i @@ -70,7 +70,7 @@ class ChainInterfaceDriver(SyncDriver): for j in range(len(rcpts)): rcpt = rcpts_r[j] if rcpt != None: - txs[j].apply_receipt(self.chain_interface.src_normalize(rcpt)) + txs[j].apply_receipt(self.chain_interface.src_normalize(rcpt), dialect_filter=self.chain_interface.dialect_filter) i += 1 return i @@ -81,16 +81,20 @@ class ChainInterfaceDriver(SyncDriver): while True: # handle block objects regardless of whether the tx data is embedded or not try: - tx = block.tx(i) - except AttributeError: - tx_hash = block.txs[i] - o = self.chain_interface.tx_by_hash(tx_hash, block=block) + tx = block.tx(i, dialect_filter=self.chain_interface.dialect_filter) + except AttributeError as e: + try: + tx_hash = block.txs[i] + except IndexError: + break + o = self.chain_interface.tx_by_hash(tx_hash) r = conn.do(o) - except IndexError: + tx = self.chain_interface.tx_from_src(r, block=block) + except IndexError as e: break txs.append(tx) i += 1 - + j = len(txs) i = 0 while i < j: @@ -98,4 +102,5 @@ class ChainInterfaceDriver(SyncDriver): for tx in txs: self.process_single(conn, block, tx) + raise IndexError() diff --git a/chainsyncer/store/base.py b/chainsyncer/store/base.py @@ -68,6 +68,8 @@ class SyncItem: def reset(self, check_incomplete=True): + if self.filter_state.state(self.state_key) & self.filter_state.from_name('RESET') > 0: + return if check_incomplete: if self.count > 0: if self.filter_state.state(self.state_key) & self.filter_state.from_name('LOCK') > 0: diff --git a/chainsyncer/unittest/base.py b/chainsyncer/unittest/base.py @@ -6,6 +6,7 @@ import hashlib # external imports from hexathon import add_0x from shep.state import State +from chainlib.interface import ChainInterface # local imports #from chainsyncer.driver.history import HistorySyncer @@ -88,12 +89,12 @@ class MockTx: :param tx_hash: Transaction hash :type tx_hash: str """ - def __init__(self, index, tx_hash): + def __init__(self, index, tx_hash, dialect_filter=None): self.hash = tx_hash self.index = index - def apply_receipt(self, rcpt): + def apply_receipt(self, rcpt, dialect_filter=None): """Save receipt source in mock tx object. :param rcpt: Transaction receipt @@ -117,13 +118,13 @@ class MockBlock: self.hash = os.urandom(32).hex() - def tx(self, i): + def tx(self, i, dialect_filter=None): """Get block transaction at given index. :param i: Transaction index :type i: int """ - return MockTx(i, self.txs[i].hash) + return MockTx(i, self.txs[i].hash, dialect_filter=dialect_filter) class MockStore(State): @@ -220,10 +221,11 @@ class MockDriver(SyncDriver): i += 1 -class MockChainInterface: +class MockChainInterface(ChainInterface): - def __init__(self, batch_limit=1): - self.batch_limit = batch_limit + #def __init__(self, dialect_filter=None, batch_limit=1): + # self.dialect_filter = dialect_filter + # self.batch_limit = batch_limit def block_by_number(self, number): @@ -246,6 +248,12 @@ class MockChainInterface: return ('receipt', hsh,) + def tx_from_src(self, src, block=None): + b = os.urandom(32) + return MockTx(0, b.hex()) + + + class MockChainInterfaceConn(MockConn): def __init__(self, interface): @@ -275,6 +283,10 @@ class MockChainInterfaceConn(MockConn): return {} + def handle_tx_by_hash(self, hsh): + return None + + class MockItem: def __init__(self, target, offset, cursor, state_key): diff --git a/requirements.txt b/requirements.txt @@ -1,5 +1,5 @@ confini~=0.6.1 semver==2.13.0 hexathon~=0.1.7 -chainlib~=0.5.0 +chainlib~=0.5.2 shep~=0.3.0 diff --git a/run_tests.sh b/run_tests.sh @@ -4,6 +4,7 @@ set -e set -x path=${PYTHONPATH:-.} export PYTHONPATH=$path +>&2 echo using pythonpath $PYTHONPATH for f in `ls tests/*.py`; do python $f if [ $? -gt 0 ]; then diff --git a/setup.cfg b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = chainsyncer -version = 0.8.2 +version = 0.8.3 description = Generic blockchain syncer driver author = Louis Holbrook author_email = dev@holbrook.no diff --git a/tests/test_session.py b/tests/test_session.py @@ -151,5 +151,19 @@ class TestFilter(unittest.TestCase): self.assertEqual(len(fltr_one.contents), 6) + def test_resume_nofilter(self): + #drv = MockDriver(self.store, interrupt_block=7, target=10) + drv = MockDriver(self.store, target=2) + generator = MockBlockGenerator() + generator.generate([3, 1, 1], driver=drv) + with self.assertRaises(SyncDone): + drv.run(self.conn, interval=0.1) + + drv = MockDriver(self.store, target=4) + generator = MockBlockGenerator(offset=3) + generator.generate([3, 1, 1], driver=drv) + drv.run(self.conn, interval=0.1) + + if __name__ == '__main__': unittest.main()