2022-03-18 00:48:23 +01:00
|
|
|
# standard imports
|
|
|
|
import unittest
|
|
|
|
import tempfile
|
|
|
|
import shutil
|
|
|
|
import logging
|
|
|
|
import stat
|
|
|
|
import os
|
|
|
|
|
|
|
|
# local imports
|
|
|
|
from chainsyncer.store.fs import SyncFsStore
|
|
|
|
from chainsyncer.session import SyncSession
|
|
|
|
from chainsyncer.error import (
|
|
|
|
LockError,
|
|
|
|
FilterDone,
|
|
|
|
IncompleteFilterError,
|
|
|
|
)
|
|
|
|
from chainsyncer.unittest import (
|
|
|
|
MockFilter,
|
|
|
|
MockConn,
|
|
|
|
MockTx,
|
|
|
|
MockBlock,
|
2022-04-30 09:35:08 +02:00
|
|
|
MockFilterError,
|
|
|
|
state_event_handler,
|
|
|
|
filter_state_event_handler,
|
2022-03-18 00:48:23 +01:00
|
|
|
)
|
|
|
|
|
2022-04-30 09:35:08 +02:00
|
|
|
|
|
|
|
logging.basicConfig(level=logging.STATETRACE)
|
2022-03-18 00:48:23 +01:00
|
|
|
logg = logging.getLogger()
|
|
|
|
|
|
|
|
|
2022-04-30 09:35:08 +02:00
|
|
|
|
2022-03-18 00:48:23 +01:00
|
|
|
class TestFilter(unittest.TestCase):
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
self.path = tempfile.mkdtemp()
|
2022-04-30 09:35:08 +02:00
|
|
|
self.store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
2022-03-18 00:48:23 +01:00
|
|
|
self.session = SyncSession(self.store)
|
|
|
|
self.conn = MockConn()
|
|
|
|
|
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
shutil.rmtree(self.path)
|
|
|
|
|
|
|
|
|
|
|
|
def test_filter_basic(self):
|
|
|
|
fltr_one = MockFilter('foo')
|
2022-03-18 01:02:18 +01:00
|
|
|
self.store.register(fltr_one)
|
2022-03-18 00:48:23 +01:00
|
|
|
fltr_two = MockFilter('bar')
|
2022-03-18 01:02:18 +01:00
|
|
|
self.store.register(fltr_two)
|
2022-03-18 00:48:23 +01:00
|
|
|
|
2022-03-18 20:12:07 +01:00
|
|
|
self.session.start()
|
|
|
|
|
2022-03-18 00:48:23 +01:00
|
|
|
tx_hash = os.urandom(32).hex()
|
|
|
|
tx = MockTx(42, tx_hash)
|
|
|
|
block = MockBlock(13, [tx_hash])
|
|
|
|
self.session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
self.assertEqual(len(fltr_one.contents), 1)
|
|
|
|
self.assertEqual(len(fltr_two.contents), 1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_filter_interrupt(self):
|
|
|
|
fltr_one = MockFilter('foo', brk=True)
|
2022-03-18 01:02:18 +01:00
|
|
|
self.store.register(fltr_one)
|
2022-03-18 00:48:23 +01:00
|
|
|
fltr_two = MockFilter('bar')
|
2022-03-18 01:02:18 +01:00
|
|
|
self.store.register(fltr_two)
|
2022-03-18 00:48:23 +01:00
|
|
|
|
2022-03-18 20:12:07 +01:00
|
|
|
self.session.start()
|
|
|
|
|
2022-03-18 00:48:23 +01:00
|
|
|
tx_hash = os.urandom(32).hex()
|
|
|
|
tx = MockTx(42, tx_hash)
|
|
|
|
block = MockBlock(13, [tx_hash])
|
|
|
|
self.session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
self.assertEqual(len(fltr_one.contents), 1)
|
|
|
|
self.assertEqual(len(fltr_two.contents), 0)
|
|
|
|
|
|
|
|
|
2022-04-30 09:35:08 +02:00
|
|
|
def test_filter_resume_single_revert(self):
|
|
|
|
fltr_one = MockFilter('foo', brk_hard=True)
|
|
|
|
self.store.register(fltr_one)
|
|
|
|
|
|
|
|
self.session.start()
|
|
|
|
|
|
|
|
item = self.store.get('0')
|
|
|
|
item.next()
|
|
|
|
|
|
|
|
tx_hash = os.urandom(32).hex()
|
|
|
|
tx = MockTx(42, tx_hash)
|
|
|
|
block = MockBlock(13, [tx_hash])
|
|
|
|
|
|
|
|
with self.assertRaises(MockFilterError):
|
|
|
|
self.session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
# Unlock the state, reverting to previous filter
|
|
|
|
store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
|
|
|
self.conn = MockConn()
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
store.register(fltr_one)
|
|
|
|
store.connect()
|
|
|
|
store.start(ignore_lock=True)
|
|
|
|
store.unlock_filter(revert=True)
|
|
|
|
|
|
|
|
store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
|
|
|
session = SyncSession(store)
|
|
|
|
self.conn = MockConn()
|
|
|
|
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
store.register(fltr_one)
|
|
|
|
|
|
|
|
session.start()
|
|
|
|
|
|
|
|
session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_filter_resume_single_continue(self):
|
|
|
|
fltr_one = MockFilter('foo', brk_hard=True)
|
|
|
|
self.store.register(fltr_one)
|
|
|
|
|
|
|
|
self.session.start()
|
|
|
|
|
|
|
|
item = self.store.get('0')
|
|
|
|
item.next()
|
|
|
|
|
|
|
|
tx_hash = os.urandom(32).hex()
|
|
|
|
tx = MockTx(42, tx_hash)
|
|
|
|
block = MockBlock(13, [tx_hash])
|
|
|
|
|
|
|
|
with self.assertRaises(MockFilterError):
|
|
|
|
self.session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
# Unlock the state, reverting to previous filter
|
|
|
|
store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
|
|
|
self.conn = MockConn()
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
store.register(fltr_one)
|
|
|
|
store.connect()
|
|
|
|
store.start(ignore_lock=True)
|
|
|
|
store.unlock_filter(revert=False)
|
|
|
|
|
|
|
|
store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
|
|
|
session = SyncSession(store)
|
|
|
|
self.conn = MockConn()
|
|
|
|
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
store.register(fltr_one)
|
|
|
|
store.connect()
|
|
|
|
|
|
|
|
session.start()
|
|
|
|
|
|
|
|
session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
|
2022-04-30 09:49:10 +02:00
|
|
|
|
|
|
|
def test_filter_resume_multi_revert_last(self):
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
self.store.register(fltr_one)
|
|
|
|
|
|
|
|
fltr_two = MockFilter('bar', brk_hard=True)
|
|
|
|
self.store.register(fltr_two)
|
|
|
|
|
|
|
|
self.session.start()
|
|
|
|
|
|
|
|
item = self.store.get('0')
|
|
|
|
item.next()
|
|
|
|
|
|
|
|
tx_hash = os.urandom(32).hex()
|
|
|
|
tx = MockTx(42, tx_hash)
|
|
|
|
block = MockBlock(13, [tx_hash])
|
|
|
|
|
|
|
|
with self.assertRaises(MockFilterError):
|
|
|
|
self.session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
# Unlock the state, reverting to previous filter
|
|
|
|
store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
|
|
|
self.conn = MockConn()
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
store.register(fltr_one)
|
|
|
|
fltr_bar = MockFilter('bar')
|
|
|
|
store.register(fltr_bar)
|
|
|
|
store.connect()
|
|
|
|
store.start(ignore_lock=True)
|
|
|
|
store.unlock_filter(revert=True)
|
|
|
|
|
|
|
|
store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
|
|
|
session = SyncSession(store)
|
|
|
|
self.conn = MockConn()
|
|
|
|
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
store.register(fltr_one)
|
|
|
|
fltr_two = MockFilter('bar')
|
|
|
|
store.register(fltr_two)
|
|
|
|
|
|
|
|
store.connect()
|
|
|
|
|
|
|
|
session.start()
|
|
|
|
|
|
|
|
session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
|
|
|
|
def test_filter_resume_multi_continue_last(self):
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
self.store.register(fltr_one)
|
|
|
|
|
|
|
|
fltr_two = MockFilter('bar', brk_hard=True)
|
|
|
|
self.store.register(fltr_two)
|
|
|
|
|
|
|
|
self.session.start()
|
|
|
|
|
|
|
|
item = self.store.get('0')
|
|
|
|
item.next()
|
|
|
|
|
|
|
|
tx_hash = os.urandom(32).hex()
|
|
|
|
tx = MockTx(42, tx_hash)
|
|
|
|
block = MockBlock(13, [tx_hash])
|
|
|
|
|
|
|
|
with self.assertRaises(MockFilterError):
|
|
|
|
self.session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
# Unlock the state, reverting to previous filter
|
|
|
|
store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
|
|
|
self.conn = MockConn()
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
store.register(fltr_one)
|
|
|
|
fltr_bar = MockFilter('bar')
|
|
|
|
store.register(fltr_bar)
|
|
|
|
store.connect()
|
|
|
|
store.start(ignore_lock=True)
|
|
|
|
store.unlock_filter(revert=False)
|
|
|
|
|
|
|
|
store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
|
|
|
session = SyncSession(store)
|
|
|
|
self.conn = MockConn()
|
|
|
|
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
store.register(fltr_one)
|
|
|
|
fltr_two = MockFilter('bar')
|
|
|
|
store.register(fltr_two)
|
|
|
|
|
|
|
|
session.start()
|
|
|
|
|
|
|
|
session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
|
|
|
|
def test_filter_resume_multi_revert_middle(self):
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
self.store.register(fltr_one)
|
|
|
|
|
|
|
|
fltr_two = MockFilter('bar', brk_hard=True)
|
|
|
|
self.store.register(fltr_two)
|
|
|
|
|
|
|
|
fltr_three = MockFilter('baz')
|
|
|
|
self.store.register(fltr_three)
|
|
|
|
|
|
|
|
self.session.start()
|
|
|
|
|
|
|
|
item = self.store.get('0')
|
|
|
|
item.next()
|
|
|
|
|
|
|
|
tx_hash = os.urandom(32).hex()
|
|
|
|
tx = MockTx(42, tx_hash)
|
|
|
|
block = MockBlock(13, [tx_hash])
|
|
|
|
|
|
|
|
with self.assertRaises(MockFilterError):
|
|
|
|
self.session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
# Unlock the state, reverting to previous filter
|
|
|
|
store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
|
|
|
self.conn = MockConn()
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
store.register(fltr_one)
|
|
|
|
fltr_two = MockFilter('bar')
|
|
|
|
store.register(fltr_two)
|
|
|
|
fltr_three = MockFilter('baz')
|
|
|
|
store.register(fltr_three)
|
|
|
|
|
|
|
|
store.connect()
|
|
|
|
store.start(ignore_lock=True)
|
|
|
|
store.unlock_filter(revert=True)
|
|
|
|
|
|
|
|
store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
|
|
|
session = SyncSession(store)
|
|
|
|
self.conn = MockConn()
|
|
|
|
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
store.register(fltr_one)
|
|
|
|
fltr_two = MockFilter('bar')
|
|
|
|
store.register(fltr_two)
|
|
|
|
fltr_three = MockFilter('baz')
|
|
|
|
store.register(fltr_three)
|
|
|
|
|
|
|
|
store.connect()
|
|
|
|
|
|
|
|
session.start()
|
|
|
|
|
|
|
|
session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
|
|
|
|
def test_filter_resume_multi_continue_middle(self):
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
self.store.register(fltr_one)
|
|
|
|
|
|
|
|
fltr_two = MockFilter('bar', brk_hard=True)
|
|
|
|
self.store.register(fltr_two)
|
|
|
|
|
|
|
|
fltr_three = MockFilter('baz')
|
|
|
|
self.store.register(fltr_three)
|
|
|
|
|
|
|
|
self.session.start()
|
|
|
|
|
|
|
|
item = self.store.get('0')
|
|
|
|
item.next()
|
|
|
|
|
|
|
|
tx_hash = os.urandom(32).hex()
|
|
|
|
tx = MockTx(42, tx_hash)
|
|
|
|
block = MockBlock(13, [tx_hash])
|
|
|
|
|
|
|
|
with self.assertRaises(MockFilterError):
|
|
|
|
self.session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
# Unlock the state, reverting to previous filter
|
|
|
|
store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
|
|
|
self.conn = MockConn()
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
store.register(fltr_one)
|
|
|
|
fltr_two = MockFilter('bar')
|
|
|
|
store.register(fltr_two)
|
|
|
|
fltr_three = MockFilter('baz')
|
|
|
|
store.register(fltr_three)
|
|
|
|
|
|
|
|
store.connect()
|
|
|
|
store.start(ignore_lock=True)
|
|
|
|
store.unlock_filter(revert=False)
|
|
|
|
|
|
|
|
store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler)
|
|
|
|
session = SyncSession(store)
|
|
|
|
self.conn = MockConn()
|
|
|
|
|
|
|
|
fltr_one = MockFilter('foo')
|
|
|
|
store.register(fltr_one)
|
|
|
|
fltr_two = MockFilter('bar')
|
|
|
|
store.register(fltr_two)
|
|
|
|
fltr_three = MockFilter('baz')
|
|
|
|
store.register(fltr_three)
|
|
|
|
|
|
|
|
session.start()
|
|
|
|
|
|
|
|
session.filter(self.conn, block, tx)
|
|
|
|
|
|
|
|
|
2022-03-18 00:48:23 +01:00
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest.main()
|
|
|
|
|