2021-04-02 11:51:00 +02:00
|
|
|
# standard imports
|
|
|
|
import logging
|
|
|
|
|
|
|
|
# local imports
|
|
|
|
from chainqueue.db.models.otx import Otx
|
|
|
|
from chainqueue.db.models.tx import TxCache
|
|
|
|
from chainqueue.db.models.base import SessionBase
|
|
|
|
from chainqueue.db.enum import (
|
|
|
|
StatusBits,
|
|
|
|
)
|
|
|
|
from chainqueue.error import TxStateChangeError
|
|
|
|
|
|
|
|
logg = logging.getLogger().getChild(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
def create(nonce, holder_address, tx_hash, signed_tx, chain_spec, obsolete_predecessors=True, session=None):
|
|
|
|
"""Create a new transaction queue record.
|
|
|
|
|
|
|
|
:param nonce: Transaction nonce
|
|
|
|
:type nonce: int
|
|
|
|
:param holder_address: Sender address
|
|
|
|
:type holder_address: str, 0x-hex
|
|
|
|
:param tx_hash: Transaction hash
|
|
|
|
:type tx_hash: str, 0x-hex
|
|
|
|
:param signed_tx: Signed raw transaction
|
|
|
|
:type signed_tx: str, 0x-hex
|
|
|
|
:param chain_spec: Chain spec to create transaction for
|
|
|
|
:type chain_spec: ChainSpec
|
|
|
|
:returns: transaction hash
|
|
|
|
:rtype: str, 0x-hash
|
|
|
|
"""
|
|
|
|
session = SessionBase.bind_session(session)
|
|
|
|
|
|
|
|
o = Otx.add(
|
|
|
|
nonce=nonce,
|
|
|
|
tx_hash=tx_hash,
|
|
|
|
signed_tx=signed_tx,
|
|
|
|
session=session,
|
|
|
|
)
|
|
|
|
session.flush()
|
|
|
|
|
2021-04-02 14:02:22 +02:00
|
|
|
# TODO: No magic, please, should be separate step
|
2021-04-02 11:51:00 +02:00
|
|
|
if obsolete_predecessors:
|
|
|
|
q = session.query(Otx)
|
|
|
|
q = q.join(TxCache)
|
|
|
|
q = q.filter(Otx.nonce==nonce)
|
|
|
|
q = q.filter(TxCache.sender==holder_address)
|
|
|
|
q = q.filter(Otx.tx_hash!=tx_hash)
|
|
|
|
q = q.filter(Otx.status.op('&')(StatusBits.FINAL)==0)
|
|
|
|
|
|
|
|
for otx in q.all():
|
|
|
|
logg.info('otx {} obsoleted by {}'.format(otx.tx_hash, tx_hash))
|
|
|
|
try:
|
|
|
|
otx.cancel(confirmed=False, session=session)
|
|
|
|
except TxStateChangeError as e:
|
|
|
|
logg.exception('obsolete fail: {}'.format(e))
|
|
|
|
session.close()
|
|
|
|
raise(e)
|
|
|
|
except Exception as e:
|
|
|
|
logg.exception('obsolete UNEXPECTED fail: {}'.format(e))
|
|
|
|
session.close()
|
|
|
|
raise(e)
|
|
|
|
|
|
|
|
session.commit()
|
|
|
|
SessionBase.release_session(session)
|
|
|
|
logg.debug('queue created nonce {} from {} hash {}'.format(nonce, holder_address, tx_hash))
|
|
|
|
return tx_hash
|