diff --git a/apps/cic-cache/cic_cache/cache.py b/apps/cic-cache/cic_cache/cache.py index 06397b31..33d23f8b 100644 --- a/apps/cic-cache/cic_cache/cache.py +++ b/apps/cic-cache/cic_cache/cache.py @@ -36,7 +36,7 @@ class BloomCache(Cache): return n - def load_transactions(self, offset, limit, oldest=False): + def load_transactions(self, offset, limit, block_offset=None, block_limit=None, oldest=False): """Retrieves a list of transactions from cache and creates a bloom filter pointing to blocks and transactions. Block and transaction numbers are serialized as 32-bit big-endian numbers. The input to the second bloom filter is the concatenation of the serialized block number and transaction index. @@ -53,7 +53,7 @@ class BloomCache(Cache): :return: Lowest block, bloom filter for blocks, bloom filter for blocks|tx :rtype: tuple """ - rows = list_transactions_mined(self.session, offset, limit, block_offset=None, block_limit=None, oldest=oldest) + rows = list_transactions_mined(self.session, offset, limit, block_offset=block_offset, block_limit=block_limit, oldest=oldest) f_block = moolb.Bloom(BloomCache.__get_filter_size(limit), 3) f_blocktx = moolb.Bloom(BloomCache.__get_filter_size(limit), 3) @@ -62,7 +62,12 @@ class BloomCache(Cache): for r in rows: if highest_block == -1: highest_block = r[0] - lowest_block = r[0] + lowest_block = r[0] + else: + if oldest: + highest_block = r[0] + else: + lowest_block = r[0] block = r[0].to_bytes(4, byteorder='big') tx = r[1].to_bytes(4, byteorder='big') f_block.add(block) @@ -71,7 +76,7 @@ class BloomCache(Cache): return (lowest_block, highest_block, f_block.to_bytes(), f_blocktx.to_bytes(),) - def load_transactions_account(self, address, offset, limit, oldest=False): + def load_transactions_account(self, address, offset, limit, block_offset=None, block_limit=None, oldest=False): """Same as load_transactions(...), but only retrieves transactions where the specified account address is sender or recipient. :param address: Address to retrieve transactions for. @@ -83,7 +88,7 @@ class BloomCache(Cache): :return: Lowest block, bloom filter for blocks, bloom filter for blocks|tx :rtype: tuple """ - rows = list_transactions_account_mined(self.session, address, offset, limit, block_offset=None, block_limit=None, oldest=oldest) + rows = list_transactions_account_mined(self.session, address, offset, limit, block_offset=block_offset, block_limit=block_limit, oldest=oldest) f_block = moolb.Bloom(BloomCache.__get_filter_size(limit), 3) f_blocktx = moolb.Bloom(BloomCache.__get_filter_size(limit), 3) @@ -92,7 +97,12 @@ class BloomCache(Cache): for r in rows: if highest_block == -1: highest_block = r[0] - lowest_block = r[0] + lowest_block = r[0] + else: + if oldest: + highest_block = r[0] + else: + lowest_block = r[0] block = r[0].to_bytes(4, byteorder='big') tx = r[1].to_bytes(4, byteorder='big') f_block.add(block) diff --git a/apps/cic-cache/cic_cache/db/list.py b/apps/cic-cache/cic_cache/db/list.py index c83d4dc7..48916bee 100644 --- a/apps/cic-cache/cic_cache/db/list.py +++ b/apps/cic-cache/cic_cache/db/list.py @@ -32,9 +32,9 @@ def list_transactions_mined( if block_offset: if block_limit: - s = "SELECT block_number, tx_index FROM tx ORDER BY block_number {}, tx_index {} WHERE block_number >= {} and block_number <= {} LIMIT {} OFFSET {}".format(order_by, order_by, limit, offset, block_offset, block_limit) + s = "SELECT block_number, tx_index FROM tx WHERE block_number >= {} and block_number <= {} ORDER BY block_number {}, tx_index {} LIMIT {} OFFSET {}".format(block_offset, block_limit, order_by, order_by, limit, offset) else: - s = "SELECT block_number, tx_index FROM tx ORDER BY block_number {}, tx_index {} WHERE block_number >= {} LIMIT {} OFFSET {}".format(order_by, order_by, limit, offset, block_offset) + s = "SELECT block_number, tx_index FROM tx WHERE block_number >= {} ORDER BY block_number {}, tx_index {} LIMIT {} OFFSET {}".format(block_offset, order_by, order_by, limit, offset) else: s = "SELECT block_number, tx_index FROM tx ORDER BY block_number {}, tx_index {} LIMIT {} OFFSET {}".format(order_by, order_by, limit, offset) r = session.execute(s) diff --git a/apps/cic-cache/tests/test_cache.py b/apps/cic-cache/tests/test_cache.py index c4578a09..8b3146fc 100644 --- a/apps/cic-cache/tests/test_cache.py +++ b/apps/cic-cache/tests/test_cache.py @@ -8,6 +8,7 @@ import json import pytest # local imports +from cic_cache import db from cic_cache import BloomCache from cic_cache.cache import DataCache @@ -18,7 +19,6 @@ def test_cache( init_database, list_defaults, list_actors, - list_tokens, txs, ): @@ -37,9 +37,6 @@ def test_cache( def test_cache_data( init_database, - list_defaults, - list_actors, - list_tokens, txs, tag_txs, ): @@ -47,9 +44,109 @@ def test_cache_data( session = init_database c = DataCache(session) - b = c.load_transactions_with_data(0, 100, block_offset=410000, block_limit=420000, oldest=True) + #b = c.load_transactions_with_data(0, 100, block_offset=410000, block_limit=420000, oldest=True) + b = c.load_transactions_with_data(0, 3) #410000, 420000) #, 100, block_offset=410000, block_limit=420000, oldest=True) assert len(b[2]) == 2 - assert b[2][0]['tx_hash'] == txs[1] - assert b[2][1]['tx_type'] == 'unknown' - assert b[2][0]['tx_type'] == 'test.taag' + assert b[2][0]['tx_hash'] == txs[0] + assert b[2][0]['tx_type'] == 'unknown' + assert b[2][1]['tx_type'] == 'test.taag' + + +def test_cache_ranges( + init_database, + list_defaults, + list_actors, + list_tokens, + txs, + ): + + session = init_database + + tx_number = 666 + tx_hash_second = '0x' + os.urandom(32).hex() + tx_signed_second = '0x' + os.urandom(128).hex() + nonce = 3 + + dt = datetime.datetime.utcnow() + dt += datetime.timedelta(hours=1) + db.add_transaction( + session, + tx_hash_second, + list_defaults['block']+2, + tx_number, + list_actors['alice'], + list_actors['diane'], + list_tokens['bar'], + list_tokens['bar'], + 2048, + 4096, + False, + dt.timestamp(), + ) + + oldest = list_defaults['block'] - 1 + mid = list_defaults['block'] + newest = list_defaults['block'] + 2 + + c = BloomCache(session) + b = c.load_transactions(0, 100) + assert b[0] == oldest + assert b[1] == newest + + b = c.load_transactions(1, 2) + assert b[0] == oldest + assert b[1] == mid + + b = c.load_transactions(0, 2) + assert b[0] == mid + assert b[1] == newest + + b = c.load_transactions(0, 1) + assert b[0] == newest + assert b[1] == newest + + b = c.load_transactions(0, 100, oldest=True) + assert b[0] == oldest + assert b[1] == newest + + b = c.load_transactions(0, 100, block_offset=list_defaults['block']) + assert b[0] == mid + assert b[1] == newest + + b = c.load_transactions(0, 100, block_offset=list_defaults['block'] - 1, block_limit=list_defaults['block']) + assert b[0] == oldest + assert b[1] == mid + + # now check when supplying account + b = c.load_transactions_account(list_actors['alice'], 0, 100) + assert b[0] == oldest + assert b[1] == newest + + b = c.load_transactions_account(list_actors['bob'], 0, 100) + assert b[0] == mid + assert b[1] == mid + + b = c.load_transactions_account(list_actors['diane'], 0, 100) + assert b[0] == oldest + assert b[1] == newest + + # add block filter to the mix + b = c.load_transactions_account(list_actors['alice'], 0, 100, block_offset=list_defaults['block']) + assert b[0] == mid + assert b[1] == newest + + b = c.load_transactions_account(list_actors['alice'], 0, 100, block_offset=list_defaults['block']) + assert b[0] == mid + assert b[1] == newest + + b = c.load_transactions_account(list_actors['bob'], 0, 100, block_offset=list_defaults['block'] - 1, block_limit=list_defaults['block']) + assert b[0] == mid + assert b[1] == mid + + b = c.load_transactions_account(list_actors['diane'], 0, 100, block_offset=list_defaults['block'] - 1, block_limit=list_defaults['block']) + assert b[0] == oldest + assert b[1] == oldest + + +