diff --git a/chainqueue/db/models/otx.py b/chainqueue/db/models/otx.py index deeea0c..63cb102 100644 --- a/chainqueue/db/models/otx.py +++ b/chainqueue/db/models/otx.py @@ -189,10 +189,8 @@ class Otx(SessionBase): SessionBase.release_session(session) raise TxStateChangeError('REJECTED on tx that has not been RESERVED ({})'.format(status)) - - self.__set_status(StatusBits.NODE_ERROR | StatusBits.FINAL, session) - + self.__reset_status(StatusBits.QUEUED | StatusBits.RESERVED, session) if self.tracing: self.__state_log(session=session) @@ -221,7 +219,7 @@ class Otx(SessionBase): self.__set_status(StatusBits.OBSOLETE, session) if manual: self.manual(session=session) - self.__reset_status(StatusBits.QUEUED | StatusBits.IN_NETWORK, session) + self.__reset_status(StatusBits.QUEUED | StatusBits.IN_NETWORK | StatusBits.RESERVED, session) if self.tracing: self.__state_log(session=session) diff --git a/chainqueue/sql/backend.py b/chainqueue/sql/backend.py index 16a09a5..bbb2a97 100644 --- a/chainqueue/sql/backend.py +++ b/chainqueue/sql/backend.py @@ -6,7 +6,11 @@ import urllib.error from sqlalchemy.exc import ( IntegrityError, ) -from chainlib.error import JSONRPCException +from chainlib.error import ( + RPCException, + RPCNonceException, + DefaultErrorParser, + ) from hexathon import ( add_0x, strip_0x, @@ -26,6 +30,7 @@ from chainqueue.sql.state import ( set_reserved, set_sent, set_fubar, + set_rejected, ) from chainqueue.sql.tx import cache_tx_dict @@ -34,8 +39,11 @@ logg = logging.getLogger(__name__) class SQLBackend: - def __init__(self, conn_spec, *args, **kwargs): + def __init__(self, conn_spec, error_parser=None, *args, **kwargs): SessionBase.connect(conn_spec, pool_size=kwargs.get('poolsize', 0), debug=kwargs.get('debug', False)) + if error_parser == None: + error_parser = DefaultErrorParser() + self.error_parser = error_parser def create(self, chain_spec, nonce, holder_address, tx_hash, signed_tx, obsolete_predecessors=True, session=None): @@ -71,7 +79,7 @@ class SQLBackend: fail = False r = 1 try: - rpc.do(payload) + rpc.do(payload, error_parser=self.error_parser) r = 0 except ConnectionError as e: logg.error('dispatch {} connection error {}'.format(tx_hash, e)) @@ -79,7 +87,11 @@ class SQLBackend: except urllib.error.URLError as e: logg.error('dispatch {} urllib error {}'.format(tx_hash, e)) fail = True - except JSONRPCException as e: + except RPCNonceException as e: + logg.error('nonce error {} default {}'.format(tx_hash, e)) + set_rejected(chain_spec, tx_hash, session=session) + return 1 + except RPCException as e: logg.exception('error! {}'.format(e)) set_fubar(chain_spec, tx_hash, session=session) raise e diff --git a/requirements.txt b/requirements.txt index 2ffa881..93e2d9c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,4 @@ alembic==1.4.2 SQLAlchemy==1.3.20 confini>=0.4.1a1,<0.5.0 pyxdg~=0.27 -chainlib~=0.0.9a2 +chainlib~=0.0.9a3 diff --git a/setup.cfg b/setup.cfg index e48b94b..c912ff2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = chainqueue -version = 0.0.4a4 +version = 0.0.4a5 description = Generic blockchain transaction queue control author = Louis Holbrook author_email = dev@holbrook.no