chaind/chaind/filter.py

96 lines
3.1 KiB
Python
Raw Normal View History

2022-04-10 18:21:52 +02:00
# standard imports
import logging
2022-04-29 08:26:43 +02:00
import time
2022-04-10 18:21:52 +02:00
2022-03-14 22:17:31 +01:00
# external imports
from chainlib.status import Status as TxStatus
2022-04-10 18:21:52 +02:00
from chainsyncer.filter import SyncFilter
from chainqueue.error import NotLocalTxError
from chaind.adapters.fs import ChaindFsAdapter
2022-05-02 11:59:13 +02:00
from shep.error import StateLockedKey
2022-03-14 22:17:31 +01:00
2022-04-29 08:26:43 +02:00
# local imports
from .error import (
QueueLockError,
2022-05-02 11:59:13 +02:00
BackendError,
)
2022-05-02 11:59:13 +02:00
from chaind.lock import StoreLock
2022-04-29 08:26:43 +02:00
2022-04-10 18:21:52 +02:00
logg = logging.getLogger(__name__)
2022-03-14 22:17:31 +01:00
2022-04-10 18:21:52 +02:00
class StateFilter(SyncFilter):
2022-03-14 22:17:31 +01:00
def __init__(self, chain_spec, adapter_path, tx_adapter, throttler=None):
self.chain_spec = chain_spec
self.adapter_path = adapter_path
self.tx_adapter = tx_adapter
2022-03-14 22:17:31 +01:00
self.throttler = throttler
def filter(self, conn, block, tx, session=None):
cache_tx = None
2022-05-02 11:59:13 +02:00
store_lock = StoreLock()
queue_adapter = None
while True:
try:
queue_adapter = ChaindFsAdapter(
self.chain_spec,
self.adapter_path,
self.tx_adapter,
None,
)
2022-05-02 11:59:13 +02:00
except BackendError as e:
logg.error('adapter instantiation failed: {}, one more try'.format(e))
2022-05-02 11:59:13 +02:00
store_lock.again()
continue
2022-05-02 11:59:13 +02:00
store_lock.reset()
try:
cache_tx = queue_adapter.get(tx.hash)
2022-05-02 11:59:13 +02:00
break
except NotLocalTxError:
logg.debug('skipping not local transaction {}'.format(tx.hash))
return False
2022-05-02 11:59:13 +02:00
except BackendError as e:
logg.error('adapter instantiation failed: {}, one more try'.format(e))
2022-05-02 11:59:13 +02:00
queue_adapter = None
store_lock.again()
continue
if cache_tx == None:
raise NotLocalTxError(tx.hash)
2022-05-02 11:59:13 +02:00
store_lock = StoreLock()
queue_lock = StoreLock(error=QueueLockError)
2022-04-29 08:26:43 +02:00
while True:
try:
if tx.status == TxStatus.SUCCESS:
queue_adapter.succeed(block, tx)
2022-04-29 08:26:43 +02:00
else:
queue_adapter.fail(block, tx)
2022-05-01 09:55:51 +02:00
break
2022-04-29 08:26:43 +02:00
except QueueLockError as e:
logg.debug('queue item {} is blocked, will retry: {}'.format(tx.hash, e))
2022-05-02 11:59:13 +02:00
queue_lock.again()
except FileNotFoundError as e:
logg.debug('queue item {} not found, possible race condition, will retry: {}'.format(tx.hash, e))
2022-05-02 11:59:13 +02:00
store_lock.again()
continue
except NotLocalTxError as e:
logg.debug('queue item {} not found, possible race condition, will retry: {}'.format(tx.hash, e))
2022-05-02 11:59:13 +02:00
store_lock.again()
continue
except StateLockedKey as e:
logg.debug('queue item {} not found, possible race condition, will retry: {}'.format(tx.hash, e))
store_lock.again()
continue
logg.info('filter registered {} for {} in {}'.format(tx.status.name, tx.hash, block))
2022-04-29 08:26:43 +02:00
2022-03-14 22:17:31 +01:00
if self.throttler != None:
self.throttler.dec(tx.hash)
2022-04-10 18:21:52 +02:00
return False