diff --git a/bigchaindb/core.py b/bigchaindb/core.py index 661ac740..e33c91e4 100644 --- a/bigchaindb/core.py +++ b/bigchaindb/core.py @@ -217,26 +217,27 @@ class Bigchain(object): else: return None - def get_tx_by_payload_hash(self, payload_hash): + def get_tx_by_payload_uuid(self, payload_uuid): """Retrieves transactions related to a digital asset. When creating a transaction one of the optional arguments is the `payload`. The payload is a generic dict that contains information about the digital asset. - To make it easy to query the bigchain for that digital asset we create a sha3-256 hash of the - serialized payload and store it with the transaction. This makes it easy for developers to keep track - of their digital assets in bigchain. + To make it easy to query the bigchain for that digital asset we create a UUID for the payload and + store it with the transaction. This makes it easy for developers to keep track of their digital + assets in bigchain. Args: - payload_hash (str): sha3-256 hash of the serialized payload. + payload_uuid (str): the UUID for this particular payload. Returns: A list of transactions containing that payload. If no transaction exists with that payload it returns an empty list `[]` """ - cursor = r.table('bigchain') \ - .get_all(payload_hash, index='payload_hash') \ + .get_all(payload_uuid, index='payload_uuid') \ + .concat_map(lambda block: block['block']['transactions']) \ + .filter(lambda transaction: transaction['transaction']['data']['uuid'] == payload_uuid) \ .run(self.conn) transactions = list(cursor) diff --git a/bigchaindb/db/utils.py b/bigchaindb/db/utils.py index 13a48a4a..882c982c 100644 --- a/bigchaindb/db/utils.py +++ b/bigchaindb/db/utils.py @@ -52,7 +52,7 @@ def init(): r.db(dbname).table('backlog')\ .index_create('assignee__transaction_timestamp', [r.row['assignee'], r.row['transaction']['timestamp']])\ .run(conn) - # secondary index for payload hash + # secondary index for payload data by UUID r.db(dbname).table('bigchain')\ .index_create('payload_uuid', r.row['block']['transactions']['transaction']['data']['uuid'], multi=True)\ .run(conn) diff --git a/tests/db/conftest.py b/tests/db/conftest.py index c1a0876c..432303cc 100644 --- a/tests/db/conftest.py +++ b/tests/db/conftest.py @@ -45,6 +45,12 @@ def setup_database(request, node_config): r.db(db_name).table('bigchain').index_create('block_number', r.row['block']['block_number']).run() # to order transactions by timestamp r.db(db_name).table('backlog').index_create('transaction_timestamp', r.row['transaction']['timestamp']).run() + # to query by payload uuid + r.db(db_name).table('bigchain').index_create( + 'payload_uuid', + r.row['block']['transactions']['transaction']['data']['uuid'], + multi=True, + ).run() # compound index to read transactions from the backlog per assignee r.db(db_name).table('backlog')\ .index_create('assignee__transaction_timestamp', [r.row['assignee'], r.row['transaction']['timestamp']])\ diff --git a/tests/db/test_bigchain_api.py b/tests/db/test_bigchain_api.py index bf2d0bba..5d7a29e3 100644 --- a/tests/db/test_bigchain_api.py +++ b/tests/db/test_bigchain_api.py @@ -56,6 +56,22 @@ class TestBigchainApi(object): assert len(tx['transaction']['data']['uuid']) == 36 assert tx['transaction']['data']['payload'] == payload + def test_get_transactions_for_payload(self, b, user_vk): + payload = {'msg': 'Hello BigchainDB!'} + tx = b.create_transaction(b.me, user_vk, None, 'CREATE', payload=payload) + payload_uuid = tx['transaction']['data']['uuid'] + + block = b.create_block([tx]) + b.write_block(block, durability='hard') + + matches = b.get_tx_by_payload_uuid(payload_uuid) + assert len(matches) == 1 + assert matches[0]['id'] == tx['id'] + + def test_get_transactions_for_payload_mismatch(self, b, user_vk): + matches = b.get_tx_by_payload_uuid('missing') + assert not matches + @pytest.mark.usefixtures('inputs') def test_create_transaction_transfer(self, b, user_vk, user_sk): input_tx = b.get_owned_ids(user_vk).pop()