WIP docstrings

This commit is contained in:
nolash 2021-08-27 10:52:05 +02:00
parent 88098e356b
commit 1dd403b4a2
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
7 changed files with 128 additions and 17 deletions

View File

@ -38,15 +38,50 @@ logg = logging.getLogger(__name__)
class SQLBackend:
"""SQL flavor of the chainqueue backend implementation.
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))
:param conn_spec: Backend-dependent connection specification string. See chainqueue.db.models.base.SessionBase.connect
:type conn_spec: str
:param error_parser: Error parser to use for RPC calls within the backend component
:type error_parser: Object implementing chainlib.error.DefaultErrorParser
:param pool_size: Connection pool size for pool-capable sql engines. See chainqueue.db.models.base.SessionBase.connect
:type pool_size: int
:param debug: Activate SQL engine level debug. See chainqueue.db.models.base.SessionBase.connect
:type debug: bool
:todo: define a backend abstract interface class
"""
#def __init__(self, conn_spec, error_parser=None, *args, **kwargs):
def __init__(self, conn_spec, error_parser=None, pool_size=0, debug=False, *args, **kwargs):
#SessionBase.connect(conn_spec, pool_size=kwargs.get('poolsize', 0), debug=kwargs.get('debug', False))
SessionBase.connect(conn_spec, pool_size=pool_size, debug=debug)
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):
"""Create a new transaction record in backend.
The nonce field is provided as a convenience to avoid needless resources spent on decoding the transaction data to retrieve it. However, this means that no check will be performed to verify that nonce matches the nonce encoded in the transaction, and thus it is the caller's responsibility to ensure that it is correct.
:param chain_spec: Chain spec to add record for
:type chain_spec: chainlib.chain.ChainSpec
:param nonce: Transaction nonce
:type nonce: int
:param holder_address: Address of transaction sender
:type holder_address: str
:param tx_hash: Transaction hash
:type tx_hash: str
:param signed_tx: Signed transaction data
:type signed_tx: str
:param obsolete_predecessors: If set, will mark older transactions with same nonce from holder_address as obsolete
:type obsolete_predecessors: bool
:param session: Sqlalchemy database session
:type session: sqlalchemy.orm.Session
:rtype: int
:returns: 0 if successfully added
"""
try:
queue_create(chain_spec, nonce, holder_address, tx_hash, signed_tx, obsolete_predecessors=True, session=session)
except IntegrityError as e:
@ -57,16 +92,61 @@ class SQLBackend:
def cache(self, tx, session=None):
"""Create a new cache record for existing outgoing transaction in backend.
:param tx: Transaction dict representation
:type tx: dict
:param session: Sqlalchemy database session
:type session: sqlalchemy.orm.Session
:rtype: int
:returns: 0 if successful
"""
(tx, txc_id) = cache_tx_dict(tx, session=session)
logg.debug('cached {} db insert id {}'.format(tx, txc_id))
return 0
def get_tx(self, chain_spec, tx_hash, session=None):
def get_otx(self, chain_spec, tx_hash, session=None):
"""Retrieve a single otx summary dictionary by transaction hash.
Alias of chainqueue.sql.query.get_tx
:param chain_spec: Chain spec context to look up transaction with
:type chain_spec: chainlib.chain.ChainSpec
:param tx_hash: Transaction hash
:type tx_hash: str
:param session: Sqlalchemy database session
:type session: sqlalchemy.orm.Session
:rtype: dict
:returns: otx record summary
"""
return backend_get_tx(chain_spec, tx_hash, session=session)
def get(self, chain_spec, decoder, session=None, requeue=False, *args, **kwargs):
"""Gets transaction lists based on given criteria.
Calls chainqueue.sql.query.get_upcoming_tx. If requeue is True, the QUEUED status bit will be set on all matched transactions.
:param chain_spec: Chain spec context to look up transactions for
:type chain_spec: chainlib.chain.ChainSpec
:param decoder: Decoder instance to parse values from serialized transaction data in record
:type decoder: Function taking serialized tx as parameter
:param session: Sqlalchemy database session
:type session: sqlalchemy.orm.Session
:param status: Only match transaction that have the given bits set
:type status: int
:param not_status: Only match transactions that have none of the given bits set
:type not_status: int
:param recipient: Only match transactions that has the given address as recipient
:type recipient: str
:param before: Only match tranaactions that were last checked before the given time
:type before: datetime.datetime
:param limit: Return at most given number of transaction. If 0, will return all matched transactions.
:type limit: int
:rtype: dict
:returns: key value pairs of transaction hash and signed transaction data for all matching transactions
"""
txs = get_upcoming_tx(chain_spec, status=kwargs.get('status'), decoder=decoder, not_status=kwargs.get('not_status', 0), recipient=kwargs.get('recipient'), before=kwargs.get('before'), limit=kwargs.get('limit', 0))
if requeue:
for tx_hash in txs.keys():
@ -75,6 +155,21 @@ class SQLBackend:
def dispatch(self, chain_spec, rpc, tx_hash, payload, session=None):
"""Send a single queued transaction.
:param chain_spec: Chain spec context for network send
:type chain_spec: chainlib.chain.ChainSpec
:param rpc: RPC connection to use for send
:type rpc: chainlib.connection.RPCConnection
:param tx_hash: Transaction hash of transaction to send
:type tx_hash: str
:param payload: Prepared RPC query to send
:type payload: any
:param session: Sqlalchemy database session
:type session: sqlalchemy.orm.Session
:rtype: int
:returns: 0 if no error
"""
set_reserved(chain_spec, tx_hash, session=session)
fail = False
r = 1
@ -102,8 +197,12 @@ class SQLBackend:
def create_session(self, session=None):
"""Alias for chainqueue.db.models.base.SessionBase.bind_session
"""
return SessionBase.bind_session(session=session)
def release_session(self, session):
"""Alias for chainqueue.db.models.base.SessionBase.release_session
"""
return SessionBase.release_session(session=session)

View File

@ -1,3 +1,5 @@
# TODO: this module could require better naming to discern what type of data the different methods return. Currently it's a mix of otx summary, otx objects, tx cache objects, tx representation dicts and hash/signedtx kv pairs
# standard imports
import logging
import time
@ -127,6 +129,7 @@ def get_nonce_tx_cache(chain_spec, nonce, sender, decoder=None, session=None):
:type decoder: TODO - define transaction decoder
:param session: Backend state integrity session
:type session: varies
:raises CacheIntegrityError: Cached data does not match intepreted data.
:returns: Transactions
:rtype: dict, with transaction hash as key, signed raw transaction as value
"""
@ -160,17 +163,15 @@ def get_paused_tx_cache(chain_spec, status=None, sender=None, session=None, deco
:type chain_spec: chainlib.chain.ChainSpec
:param status: If set, will return transactions with this local queue status only
:type status: cic_eth.db.enum.StatusEnum
:param recipient: Recipient address to return transactions for
:type recipient: str, 0x-hex
:param chain_id: Numeric chain id to use to parse signed transaction data
:type chain_id: number
:param decoder: Transaction decoder
:type decoder: TODO - define transaction decoder
:param sender: Sender address to return transactions for
:type sender: str
:param session: Backend state integrity session
:type session: varies
:param decoder: Transaction decoder
:type decoder: Function accepting signed transaction data as input
:raises ValueError: Status is finalized, sent or never attempted sent
:returns: Transactions
:rtype: dict, with transaction hash as key, signed raw transaction as value
:returns: Key value pairs with transaction hash and signed raw transaction
:rtype: dict
"""
session = SessionBase.bind_session(session)
q = session.query(Otx)
@ -465,13 +466,13 @@ def get_account_tx(chain_spec, address, as_sender=True, as_recipient=True, count
return txs
def count_tx(chain_spec, address=None, status=None, status_target=None, session=None):
"""
def count_tx(chain_spec, sender=None, status=None, status_target=None, session=None):
"""Count transaction records matching the given criteria.
:param chain_spec: Chain spec for transaction network
:type chain_spec: chainlib.chain.ChainSpec
:param address: Address to count transactions for
:type address: str
:param sender: Sender address to count transactions for
:type sender: str
:param status: Status to count transactions for
:type status: chainqueue.enum.StatusEnum
:param status_target: If set, will match status argument exactly against the given value

View File

@ -379,7 +379,7 @@ def obsolete_by_cache(chain_spec, tx_hash, final, session=None):
:param tx_hash: Transaction hash of record to modify, in hex
:type tx_hash: str
:param final: Transaction hash superseding record, in hex
:type tx_hash: str
:type final: str
:param session: Backend state integrity session
:type session: varies
:raises TxStateChangeError: Transaction is not obsoletable

View File

@ -38,6 +38,7 @@ def create(chain_spec, nonce, holder_address, tx_hash, signed_tx, obsolete_prede
:type obsolete_predecessors: bool
:param session: Backend state integrity session
:type session: varies
:raises TxStateChangeError: Transaction obsoletion failed
:returns: transaction hash, in hex
:rtype: str
"""

View File

@ -21,6 +21,11 @@ db_config = {
class ChainQueueDb:
"""SQLITE database setup for unit tests
:param debug: Activate sql level debug (outputs sql statements)
:type debug: bool
"""
base = SessionBase
@ -48,8 +53,12 @@ class ChainQueueDb:
def bind_session(self, session=None):
"""Create session using underlying session base
"""
return self.base.bind_session(session)
def release_session(self, session=None):
"""Release session using underlying session base
"""
return self.base.release_session(session)

View File

@ -1,6 +1,6 @@
[metadata]
name = chainqueue
version = 0.0.4a6
version = 0.0.4a7
description = Generic blockchain transaction queue control
author = Louis Holbrook
author_email = dev@holbrook.no

View File

@ -39,6 +39,7 @@ class TestBasic(TestBase):
tx = add_0x(os.urandom(128).hex())
nonce = 42
otx = Otx(nonce, tx_hash, tx)
otx.block = 1024
self.session.add(otx)
alice = add_0x(os.urandom(20).hex())