commit 1770c46cb41248c1411d6dde3efe80a285f0b960
parent 5e99a91d8b13bf9ddc9f73032f98c2fd860d2705
Author: williamluke <williamluke4@gmail.com>
Date: Tue, 8 Feb 2022 12:01:33 +0000
Merge pull request 'lash/backmerge' (#2) from lash/backmerge into master
Reviewed-on: https://git.grassecon.net/chaintool/chainqueue/pulls/2
Diffstat:
9 files changed, 342 insertions(+), 216 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -5,3 +5,4 @@ build/
dist/
*.html
*.egg-info/
+.venv
diff --git a/chainqueue/encode.py b/chainqueue/encode.py
@@ -1,2 +1,3 @@
# external imports
from chainlib.encode import TxHexNormalizer
+TxNormalizer = TxHexNormalizer
diff --git a/chainqueue/sql/query.py b/chainqueue/sql/query.py
@@ -462,6 +462,70 @@ def get_account_tx(chain_spec, address, as_sender=True, as_recipient=True, count
return txs
+def get_latest_txs(chain_spec, count=10, since=None, until=None, status=None, not_status=None, status_target=None, session=None):
+ """Returns the lastest local queue transactions
+
+ The since parameter effect depends on its type. Results are returned inclusive of the given parameter condition.
+
+ :param chain_spec: Chain spec for transaction network
+ :type chain_spec: chainlib.chain.ChainSpec
+ :param status: Only include transactions where the given status bits are set
+ :type status: chainqueue.enum.StatusEnum
+ :param not_status: Only include transactions where the given status bits are not set
+ :type not_status: chainqueue.enum.StatusEnum
+ :param status_target: Only include transaction where the status argument is exact match
+ :type status_target: chainqueue.enum.StatusEnum
+ :param session: Backend state integrity session
+ :type session: varies
+ :raises ValueError: If address is set to be neither sender nor recipient
+ :returns: Transactions
+ :rtype: dict, with transaction hash as key, signed raw transaction as value
+ """
+ txs = {}
+
+ session = SessionBase.bind_session(session)
+
+ try:
+ filter_offset = sql_range_filter(session, criteria=since)
+ filter_limit = sql_range_filter(session, criteria=until)
+ except NotLocalTxError as e:
+ logg.error('query build failed: {}'.format(e))
+ return {}
+
+ q = session.query(Otx)
+ q = q.join(TxCache)
+
+ if filter_offset != None:
+ if filter_offset[0] == 'id':
+ q = q.filter(Otx.id>=filter_offset[1])
+ elif filter_offset[0] == 'date':
+ q = q.filter(Otx.date_created>=filter_offset[1])
+
+ if filter_limit != None:
+ if filter_limit[0] == 'id':
+ q = q.filter(Otx.id<=filter_limit[1])
+ elif filter_limit[0] == 'date':
+ q = q.filter(Otx.date_created<=filter_limit[1])
+
+ if status != None:
+ if status_target == None:
+ status_target = status
+ q = q.filter(Otx.status.op('&')(status)==status_target)
+
+ if not_status != None:
+ q = q.filter(Otx.status.op('&')(not_status)==0)
+
+ q = q.order_by(Otx.nonce.asc(), Otx.date_created.asc()).limit(count)
+ results = q.all()
+ for r in results:
+ if txs.get(r.tx_hash) != None:
+ logg.debug('tx {} already recorded'.format(r.tx_hash))
+ continue
+ txs[r.tx_hash] = r.signed_tx
+
+ SessionBase.release_session(session)
+
+ return txs
def count_tx(chain_spec, sender=None, status=None, status_target=None, session=None):
"""Count transaction records matching the given criteria.
diff --git a/chainqueue/sql/tx.py b/chainqueue/sql/tx.py
@@ -17,7 +17,8 @@ from chainqueue.db.enum import (
)
from chainqueue.error import TxStateChangeError
-logg = logging.getLogger().getChild(__name__)
+#logg = logging.getLogger(__name__)
+logg = logging.getLogger()
def create(chain_spec, nonce, holder_address, tx_hash, signed_tx, obsolete_predecessors=True, session=None):
diff --git a/requirements.txt b/requirements.txt
@@ -1,8 +1,8 @@
pysha3==1.0.2
-hexathon~=0.0.1a8
-leveldir~=0.0.2
+hexathon~=0.1.0
+leveldir~=0.3.0
alembic==1.4.2
SQLAlchemy==1.3.20
-confini>=0.4.1a1,<0.5.0
+confini~=0.5.1
pyxdg~=0.27
-chainlib~=0.0.10a3
+chainlib~=0.0.12
diff --git a/setup.cfg b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = chainqueue
-version = 0.0.6a1
+version = 0.0.6a4
description = Generic blockchain transaction queue control
author = Louis Holbrook
author_email = dev@holbrook.no
diff --git a/test_requirements.txt b/test_requirements.txt
@@ -1 +0,0 @@
-chainlib==0.0.9a10
diff --git a/tests/chainqueue_base.py b/tests/chainqueue_base.py
@@ -66,16 +66,17 @@ class TestTxBase(TestOtxBase):
self.to_value = 13
backend = SQLBackend(self.db.dsn)
- tx = {
- 'hash': self.tx_hash,
- 'from': self.alice,
- 'to': self.bob,
- 'source_token': self.foo_token,
- 'destination_token': self.bar_token,
- 'from_value': self.from_value,
- 'to_value': self.to_value,
- }
- backend.cache(tx, session=self.session)
+ txc = TxCache(
+ self.tx_hash,
+ self.alice,
+ self.bob,
+ self.foo_token,
+ self.bar_token,
+ self.from_value,
+ self.to_value,
+ session=self.session,
+ )
+ self.session.add(txc)
self.session.commit()
otx = Otx.load(self.tx_hash)
diff --git a/tests/test_query.py b/tests/test_query.py
@@ -30,205 +30,205 @@ logg = logging.getLogger()
class TestTxQuery(TestTxBase):
-# def test_get_tx(self):
-# tx = get_tx(self.chain_spec, self.tx_hash)
-# expected_keys = [
-# 'otx_id',
-# 'status',
-# 'signed_tx',
-# 'nonce',
-# ]
-# for k in tx.keys():
-# expected_keys.remove(k)
-#
-# self.assertEqual(len(expected_keys), 0)
-#
-#
-# def test_nonce_tx(self):
-#
-# nonce_hashes = [self.tx_hash]
-# tx_hash = add_0x(os.urandom(32).hex())
-# signed_tx = add_0x(os.urandom(128).hex())
-# create(
-# self.chain_spec,
-# 42,
-# self.alice,
-# tx_hash,
-# signed_tx,
-# session=self.session,
-# )
-# txc = TxCache(
-# tx_hash,
-# self.alice,
-# self.bob,
-# self.foo_token,
-# self.bar_token,
-# self.from_value,
-# self.to_value,
-# session=self.session,
-# )
-# self.session.add(txc)
-# self.session.commit()
-#
-# nonce_hashes.append(tx_hash)
-#
-# tx_hash = add_0x(os.urandom(32).hex())
-# signed_tx = add_0x(os.urandom(128).hex())
-# create(
-# self.chain_spec,
-# 41,
-# self.alice,
-# tx_hash,
-# signed_tx,
-# session=self.session,
-# )
-# txc = TxCache(
-# tx_hash,
-# self.alice,
-# self.bob,
-# self.foo_token,
-# self.bar_token,
-# self.from_value,
-# self.to_value,
-# session=self.session,
-# )
-# self.session.add(txc)
-#
-# txs = get_nonce_tx_cache(self.chain_spec, 42, self.alice)
-# self.assertEqual(len(txs.keys()), 2)
-#
-# for h in nonce_hashes:
-# self.assertTrue(strip_0x(h) in txs)
-#
-#
-# def test_paused_tx_cache(self):
-# set_waitforgas(self.chain_spec, self.tx_hash)
-#
-# tx_hash = add_0x(os.urandom(32).hex())
-# signed_tx = add_0x(os.urandom(128).hex())
-# create(
-# self.chain_spec,
-# 43,
-# self.alice,
-# tx_hash,
-# signed_tx,
-# session=self.session,
-# )
-# txc = TxCache(
-# tx_hash,
-# self.alice,
-# self.bob,
-# self.foo_token,
-# self.bar_token,
-# self.from_value,
-# self.to_value,
-# session=self.session,
-# )
-# self.session.add(txc)
-# self.session.commit()
-#
-# txs = get_paused_tx_cache(self.chain_spec, status=StatusBits.GAS_ISSUES, sender=self.alice, session=self.session)
-# self.assertEqual(len(txs.keys()), 1)
-#
-# txs = get_paused_tx_cache(self.chain_spec, status=StatusBits.GAS_ISSUES, session=self.session)
-# self.assertEqual(len(txs.keys()), 1)
-#
-# tx_hash = add_0x(os.urandom(32).hex())
-# signed_tx = add_0x(os.urandom(128).hex())
-# create(
-# self.chain_spec,
-# 42,
-# self.bob,
-# tx_hash,
-# signed_tx,
-# session=self.session,
-# )
-# txc = TxCache(
-# tx_hash,
-# self.bob,
-# self.alice,
-# self.bar_token,
-# self.foo_token,
-# self.to_value,
-# self.from_value,
-# session=self.session,
-# )
-# self.session.add(txc)
-# self.session.commit()
-#
-# txs = get_paused_tx_cache(self.chain_spec, status=StatusBits.GAS_ISSUES, session=self.session)
-# self.assertEqual(len(txs.keys()), 1)
-#
-# set_waitforgas(self.chain_spec, tx_hash)
-# self.session.commit()
-#
-# txs = get_paused_tx_cache(self.chain_spec, status=StatusBits.GAS_ISSUES, session=self.session)
-# self.assertEqual(len(txs.keys()), 2)
-#
-# txs = get_paused_tx_cache(self.chain_spec, status=StatusBits.GAS_ISSUES, sender=self.bob, session=self.session)
-# self.assertEqual(len(txs.keys()), 1)
-#
-#
-# def test_count(self):
-# for i in range(3):
-# tx_hash = add_0x(os.urandom(32).hex())
-# signed_tx = add_0x(os.urandom(128).hex())
-# create(
-# self.chain_spec,
-# i,
-# self.alice,
-# tx_hash,
-# signed_tx,
-# session=self.session,
-# )
-# txc = TxCache(
-# tx_hash,
-# self.alice,
-# self.bob,
-# self.foo_token,
-# self.bar_token,
-# self.from_value,
-# self.to_value,
-# session=self.session,
-# )
-# self.session.add(txc)
-# set_ready(self.chain_spec, tx_hash, session=self.session)
-# set_reserved(self.chain_spec, tx_hash, session=self.session)
-# if i > 0:
-# set_sent(self.chain_spec, tx_hash, session=self.session)
-# if i == 2:
-# set_final(self.chain_spec, tx_hash, session=self.session)
-#
-# tx_hash = add_0x(os.urandom(32).hex())
-# signed_tx = add_0x(os.urandom(128).hex())
-# create(
-# self.chain_spec,
-# i,
-# self.bob,
-# tx_hash,
-# signed_tx,
-# session=self.session,
-# )
-# txc = TxCache(
-# tx_hash,
-# self.bob,
-# self.carol,
-# self.foo_token,
-# self.bar_token,
-# self.from_value,
-# self.to_value,
-# session=self.session,
-# )
-#
-# self.session.add(txc)
-# set_ready(self.chain_spec, tx_hash, session=self.session)
-# set_reserved(self.chain_spec, tx_hash, session=self.session)
-# set_sent(self.chain_spec, tx_hash, session=self.session)
-# self.session.commit()
-#
-# self.assertEqual(count_tx(self.chain_spec, status=StatusBits.IN_NETWORK | StatusBits.FINAL, status_target=StatusBits.IN_NETWORK), 2)
-# self.assertEqual(count_tx(self.chain_spec, address=self.alice, status=StatusBits.IN_NETWORK | StatusBits.FINAL, status_target=StatusBits.IN_NETWORK), 1)
-#
+ def test_get_tx(self):
+ tx = get_tx(self.chain_spec, self.tx_hash)
+ expected_keys = [
+ 'otx_id',
+ 'status',
+ 'signed_tx',
+ 'nonce',
+ ]
+ for k in tx.keys():
+ expected_keys.remove(k)
+
+ self.assertEqual(len(expected_keys), 0)
+
+
+ def test_nonce_tx(self):
+
+ nonce_hashes = [self.tx_hash]
+ tx_hash = add_0x(os.urandom(32).hex())
+ signed_tx = add_0x(os.urandom(128).hex())
+ create(
+ self.chain_spec,
+ 42,
+ self.alice,
+ tx_hash,
+ signed_tx,
+ session=self.session,
+ )
+ txc = TxCache(
+ tx_hash,
+ self.alice,
+ self.bob,
+ self.foo_token,
+ self.bar_token,
+ self.from_value,
+ self.to_value,
+ session=self.session,
+ )
+ self.session.add(txc)
+ self.session.commit()
+
+ nonce_hashes.append(tx_hash)
+
+ tx_hash = add_0x(os.urandom(32).hex())
+ signed_tx = add_0x(os.urandom(128).hex())
+ create(
+ self.chain_spec,
+ 41,
+ self.alice,
+ tx_hash,
+ signed_tx,
+ session=self.session,
+ )
+ txc = TxCache(
+ tx_hash,
+ self.alice,
+ self.bob,
+ self.foo_token,
+ self.bar_token,
+ self.from_value,
+ self.to_value,
+ session=self.session,
+ )
+ self.session.add(txc)
+
+ txs = get_nonce_tx_cache(self.chain_spec, 42, self.alice)
+ self.assertEqual(len(txs.keys()), 2)
+
+ for h in nonce_hashes:
+ self.assertTrue(strip_0x(h) in txs)
+
+
+ def test_paused_tx_cache(self):
+ set_waitforgas(self.chain_spec, self.tx_hash)
+
+ tx_hash = add_0x(os.urandom(32).hex())
+ signed_tx = add_0x(os.urandom(128).hex())
+ create(
+ self.chain_spec,
+ 43,
+ self.alice,
+ tx_hash,
+ signed_tx,
+ session=self.session,
+ )
+ txc = TxCache(
+ tx_hash,
+ self.alice,
+ self.bob,
+ self.foo_token,
+ self.bar_token,
+ self.from_value,
+ self.to_value,
+ session=self.session,
+ )
+ self.session.add(txc)
+ self.session.commit()
+
+ txs = get_paused_tx_cache(self.chain_spec, status=StatusBits.GAS_ISSUES, sender=self.alice, session=self.session)
+ self.assertEqual(len(txs.keys()), 1)
+
+ txs = get_paused_tx_cache(self.chain_spec, status=StatusBits.GAS_ISSUES, session=self.session)
+ self.assertEqual(len(txs.keys()), 1)
+
+ tx_hash = add_0x(os.urandom(32).hex())
+ signed_tx = add_0x(os.urandom(128).hex())
+ create(
+ self.chain_spec,
+ 42,
+ self.bob,
+ tx_hash,
+ signed_tx,
+ session=self.session,
+ )
+ txc = TxCache(
+ tx_hash,
+ self.bob,
+ self.alice,
+ self.bar_token,
+ self.foo_token,
+ self.to_value,
+ self.from_value,
+ session=self.session,
+ )
+ self.session.add(txc)
+ self.session.commit()
+
+ txs = get_paused_tx_cache(self.chain_spec, status=StatusBits.GAS_ISSUES, session=self.session)
+ self.assertEqual(len(txs.keys()), 1)
+
+ set_waitforgas(self.chain_spec, tx_hash)
+ self.session.commit()
+
+ txs = get_paused_tx_cache(self.chain_spec, status=StatusBits.GAS_ISSUES, session=self.session)
+ self.assertEqual(len(txs.keys()), 2)
+
+ txs = get_paused_tx_cache(self.chain_spec, status=StatusBits.GAS_ISSUES, sender=self.bob, session=self.session)
+ self.assertEqual(len(txs.keys()), 1)
+
+
+ def test_count(self):
+ for i in range(3):
+ tx_hash = add_0x(os.urandom(32).hex())
+ signed_tx = add_0x(os.urandom(128).hex())
+ create(
+ self.chain_spec,
+ i,
+ self.alice,
+ tx_hash,
+ signed_tx,
+ session=self.session,
+ )
+ txc = TxCache(
+ tx_hash,
+ self.alice,
+ self.bob,
+ self.foo_token,
+ self.bar_token,
+ self.from_value,
+ self.to_value,
+ session=self.session,
+ )
+ self.session.add(txc)
+ set_ready(self.chain_spec, tx_hash, session=self.session)
+ set_reserved(self.chain_spec, tx_hash, session=self.session)
+ if i > 0:
+ set_sent(self.chain_spec, tx_hash, session=self.session)
+ if i == 2:
+ set_final(self.chain_spec, tx_hash, session=self.session)
+
+ tx_hash = add_0x(os.urandom(32).hex())
+ signed_tx = add_0x(os.urandom(128).hex())
+ create(
+ self.chain_spec,
+ i,
+ self.bob,
+ tx_hash,
+ signed_tx,
+ session=self.session,
+ )
+ txc = TxCache(
+ tx_hash,
+ self.bob,
+ self.carol,
+ self.foo_token,
+ self.bar_token,
+ self.from_value,
+ self.to_value,
+ session=self.session,
+ )
+
+ self.session.add(txc)
+ set_ready(self.chain_spec, tx_hash, session=self.session)
+ set_reserved(self.chain_spec, tx_hash, session=self.session)
+ set_sent(self.chain_spec, tx_hash, session=self.session)
+ self.session.commit()
+
+ self.assertEqual(count_tx(self.chain_spec, status=StatusBits.IN_NETWORK | StatusBits.FINAL, status_target=StatusBits.IN_NETWORK), 2)
+ self.assertEqual(count_tx(self.chain_spec, sender=self.alice, status=StatusBits.IN_NETWORK | StatusBits.FINAL, status_target=StatusBits.IN_NETWORK), 1)
+
def test_account_tx(self):
@@ -345,6 +345,65 @@ class TestTxQuery(TestTxBase):
txs = get_account_tx(self.chain_spec, self.alice, as_sender=True, as_recipient=False, not_status=StatusBits.QUEUED, status=StatusBits.IN_NETWORK, session=self.session)
self.assertEqual(len(txs.keys()), 1)
+ def test_latest_txs(self):
+
+ nonce_hashes = [self.tx_hash]
+ tx_hash = add_0x(os.urandom(32).hex())
+ signed_tx = add_0x(os.urandom(128).hex())
+ create(
+ self.chain_spec,
+ 42,
+ self.alice,
+ tx_hash,
+ signed_tx,
+ session=self.session,
+ )
+ txc = TxCache(
+ tx_hash,
+ self.alice,
+ self.bob,
+ self.foo_token,
+ self.bar_token,
+ self.from_value,
+ self.to_value,
+ session=self.session,
+ )
+ self.session.add(txc)
+ self.session.commit()
+
+ nonce_hashes.append(tx_hash)
+
+ time_between = datetime.datetime.utcnow()
+
+ tx_hash = add_0x(os.urandom(32).hex())
+ signed_tx = add_0x(os.urandom(128).hex())
+ create(
+ self.chain_spec,
+ 41,
+ self.alice,
+ tx_hash,
+ signed_tx,
+ session=self.session,
+ )
+ txc = TxCache(
+ tx_hash,
+ self.alice,
+ self.bob,
+ self.foo_token,
+ self.bar_token,
+ self.from_value,
+ self.to_value,
+ session=self.session,
+ )
+ self.session.add(txc)
+
+ nonce_hashes.append(tx_hash)
+
+ txs = get_latest_txs(self.chain_spec, session=self.session)
+ self.assertEqual(len(txs.keys()), 3)
+
+ txs = get_latest_txs(self.chain_spec, count=1, session=self.session)
+ self.assertEqual(len(txs.keys()), 1)
if __name__ == '__main__':
unittest.main()