Merge pull request #411 from shauns/patch-1

Complete move from payload hashes to payload UUIDs
This commit is contained in:
Rodolphe Marques 2016-07-04 16:05:29 +02:00 committed by GitHub
commit f2812c6c46
4 changed files with 31 additions and 8 deletions

View File

@ -217,26 +217,27 @@ class Bigchain(object):
else: else:
return None 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. """Retrieves transactions related to a digital asset.
When creating a transaction one of the optional arguments is the `payload`. The payload is a generic 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. 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 To make it easy to query the bigchain for that digital asset we create a UUID for the payload and
serialized payload and store it with the transaction. This makes it easy for developers to keep track store it with the transaction. This makes it easy for developers to keep track of their digital
of their digital assets in bigchain. assets in bigchain.
Args: Args:
payload_hash (str): sha3-256 hash of the serialized payload. payload_uuid (str): the UUID for this particular payload.
Returns: Returns:
A list of transactions containing that payload. If no transaction exists with that payload it A list of transactions containing that payload. If no transaction exists with that payload it
returns an empty list `[]` returns an empty list `[]`
""" """
cursor = r.table('bigchain') \ 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) .run(self.conn)
transactions = list(cursor) transactions = list(cursor)

View File

@ -52,7 +52,7 @@ def init():
r.db(dbname).table('backlog')\ r.db(dbname).table('backlog')\
.index_create('assignee__transaction_timestamp', [r.row['assignee'], r.row['transaction']['timestamp']])\ .index_create('assignee__transaction_timestamp', [r.row['assignee'], r.row['transaction']['timestamp']])\
.run(conn) .run(conn)
# secondary index for payload hash # secondary index for payload data by UUID
r.db(dbname).table('bigchain')\ r.db(dbname).table('bigchain')\
.index_create('payload_uuid', r.row['block']['transactions']['transaction']['data']['uuid'], multi=True)\ .index_create('payload_uuid', r.row['block']['transactions']['transaction']['data']['uuid'], multi=True)\
.run(conn) .run(conn)

View File

@ -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() r.db(db_name).table('bigchain').index_create('block_number', r.row['block']['block_number']).run()
# to order transactions by timestamp # to order transactions by timestamp
r.db(db_name).table('backlog').index_create('transaction_timestamp', r.row['transaction']['timestamp']).run() 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 # compound index to read transactions from the backlog per assignee
r.db(db_name).table('backlog')\ r.db(db_name).table('backlog')\
.index_create('assignee__transaction_timestamp', [r.row['assignee'], r.row['transaction']['timestamp']])\ .index_create('assignee__transaction_timestamp', [r.row['assignee'], r.row['transaction']['timestamp']])\

View File

@ -56,6 +56,22 @@ class TestBigchainApi(object):
assert len(tx['transaction']['data']['uuid']) == 36 assert len(tx['transaction']['data']['uuid']) == 36
assert tx['transaction']['data']['payload'] == payload 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') @pytest.mark.usefixtures('inputs')
def test_create_transaction_transfer(self, b, user_vk, user_sk): def test_create_transaction_transfer(self, b, user_vk, user_sk):
input_tx = b.get_owned_ids(user_vk).pop() input_tx = b.get_owned_ids(user_vk).pop()