From 7e33f2bd52689b1f5d86bf7bf18dfadf50bd4d43 Mon Sep 17 00:00:00 2001 From: libscott Date: Tue, 20 Dec 2016 17:28:15 +0100 Subject: [PATCH] Tx ID as Asset ID (#926) * Allow AssetLinks to be used in place of Assets in the Transaction Model and enforce `Transaction.transfer()` to only take an AssetLink * Remove AssetLink's inheritance from Asset * Remove id from the Asset model * Fix get_txids_by_asset_id query for rethinkdb after removing asset's uuid Because `CREATE` transactions don't have an asset that contains an id anymore, one way to find all the transactions related to an asset is to query the database twice: once for the `CREATE` transaction and another for the `TRANSFER` transactions. * Add TODO notice for vote test utils to be fixtures * Update asset model documentation to reflect usage of transaction id * Fix outdated asset description in transaction schema --- bigchaindb/backend/query.py | 8 +- bigchaindb/backend/rethinkdb/query.py | 26 +++-- bigchaindb/backend/rethinkdb/schema.py | 2 +- bigchaindb/common/schema/transaction.yaml | 9 +- bigchaindb/common/transaction.py | 94 +++++++-------- bigchaindb/models.py | 2 +- .../generate_http_server_api_documentation.py | 2 +- docs/server/source/data-models/asset-model.md | 7 +- tests/assets/test_digital_assets.py | 50 ++++---- tests/assets/test_divisible_assets.py | 68 +++++------ tests/common/conftest.py | 17 +-- tests/common/test_asset.py | 15 +-- tests/common/test_transaction.py | 100 ++++++++-------- tests/conftest.py | 19 ++- tests/db/test_bigchain_api.py | 109 ++++++++++++------ tests/pipelines/test_block_creation.py | 25 ++-- tests/pipelines/test_stale_monitor.py | 6 +- tests/pipelines/test_vote.py | 8 +- tests/web/test_transactions.py | 8 +- 19 files changed, 316 insertions(+), 259 deletions(-) diff --git a/bigchaindb/backend/query.py b/bigchaindb/backend/query.py index 88f215c4..e71f6be3 100644 --- a/bigchaindb/backend/query.py +++ b/bigchaindb/backend/query.py @@ -111,12 +111,12 @@ def get_blocks_status_from_transaction(connection, transaction_id): def get_txids_by_asset_id(connection, asset_id): """Retrieves transactions ids related to a particular asset. - A digital asset in bigchaindb is identified by an uuid. This allows us - to query all the transactions related to a particular digital asset, - knowing the id. + A digital asset in bigchaindb is identified by its ``CREATE`` + transaction's ID. Knowing this ID allows us to query all the + transactions related to a particular digital asset. Args: - asset_id (str): the id for this particular metadata. + asset_id (str): the ID of the asset. Returns: A list of transactions ids related to the asset. If no transaction diff --git a/bigchaindb/backend/rethinkdb/query.py b/bigchaindb/backend/rethinkdb/query.py index 8fa6a512..b4a48eba 100644 --- a/bigchaindb/backend/rethinkdb/query.py +++ b/bigchaindb/backend/rethinkdb/query.py @@ -1,3 +1,4 @@ +from itertools import chain from time import time import rethinkdb as r @@ -75,23 +76,32 @@ def get_blocks_status_from_transaction(connection, transaction_id): def get_txids_by_asset_id(connection, asset_id): # here we only want to return the transaction ids since later on when # we are going to retrieve the transaction with status validation - return connection.run( + + # First find the asset's CREATE transaction + create_tx_cursor = connection.run( + _get_asset_create_tx_query(asset_id).get_field('id')) + + # Then find any TRANSFER transactions related to the asset + transfer_tx_cursor = connection.run( r.table('bigchain') .get_all(asset_id, index='asset_id') .concat_map(lambda block: block['block']['transactions']) .filter(lambda transaction: transaction['asset']['id'] == asset_id) .get_field('id')) + return chain(create_tx_cursor, transfer_tx_cursor) + @register_query(RethinkDBConnection) def get_asset_by_id(connection, asset_id): - return connection.run( - r.table('bigchain', read_mode=READ_MODE) - .get_all(asset_id, index='asset_id') - .concat_map(lambda block: block['block']['transactions']) - .filter(lambda transaction: transaction['asset']['id'] == asset_id) - .filter(lambda transaction: transaction['operation'] == 'CREATE') - .pluck('asset')) + return connection.run(_get_asset_create_tx_query(asset_id).pluck('asset')) + + +def _get_asset_create_tx_query(asset_id): + return r.table('bigchain', read_mode=READ_MODE) \ + .get_all(asset_id, index='transaction_id') \ + .concat_map(lambda block: block['block']['transactions']) \ + .filter(lambda transaction: transaction['id'] == asset_id) @register_query(RethinkDBConnection) diff --git a/bigchaindb/backend/rethinkdb/schema.py b/bigchaindb/backend/rethinkdb/schema.py index 66ed7b20..4a76a06b 100644 --- a/bigchaindb/backend/rethinkdb/schema.py +++ b/bigchaindb/backend/rethinkdb/schema.py @@ -60,7 +60,7 @@ def create_bigchain_secondary_index(connection, dbname): .table('bigchain') .index_create('transaction_id', r.row['block']['transactions']['id'], multi=True)) - # secondary index for asset uuid + # secondary index for asset links (in TRANSFER transactions) connection.run( r.db(dbname) .table('bigchain') diff --git a/bigchaindb/common/schema/transaction.yaml b/bigchaindb/common/schema/transaction.yaml index c13320c3..2af489f9 100644 --- a/bigchaindb/common/schema/transaction.yaml +++ b/bigchaindb/common/schema/transaction.yaml @@ -105,13 +105,14 @@ definitions: description: | Description of the asset being transacted. In the case of a ``TRANSFER`` transaction, this field contains only the ID of asset. In the case - of a ``CREATE`` transaction, this field may contain properties: + of a ``CREATE`` transaction, this field contains only the user-defined + payload. additionalProperties: false - required: - - id properties: id: - "$ref": "#/definitions/uuid4" + "$ref": "#/definitions/sha3_hexdigest" + description: | + ID of the transaction that created the asset. data: description: | User provided metadata associated with the asset. May also be ``null``. diff --git a/bigchaindb/common/transaction.py b/bigchaindb/common/transaction.py index b9d09d40..9b423902 100644 --- a/bigchaindb/common/transaction.py +++ b/bigchaindb/common/transaction.py @@ -1,6 +1,5 @@ from copy import deepcopy from functools import reduce -from uuid import uuid4 from cryptoconditions import (Fulfillment as CCFulfillment, ThresholdSha256Fulfillment, Ed25519Fulfillment) @@ -384,14 +383,11 @@ class Asset(object): Attributes: data (dict): A dictionary of data that can be added to an Asset. - data_id (str): A unique identifier of `data`'s content. """ - def __init__(self, data=None, data_id=None): + def __init__(self, data=None): """An Asset is not required to contain any extra data from outside.""" self.data = data - self.data_id = data_id if data_id is not None else self.to_hash() - self.validate_asset() def __eq__(self, other): @@ -409,7 +405,6 @@ class Asset(object): format. """ return { - 'id': self.data_id, 'data': self.data, } @@ -423,38 +418,37 @@ class Asset(object): Returns: :class:`~bigchaindb.common.transaction.Asset` """ - return cls(asset.get('data'), asset['id']) - - def to_hash(self): - """Generates a unqiue uuid for an Asset""" - return str(uuid4()) + return cls(asset.get('data')) @staticmethod def get_asset_id(transactions): - """Get the asset id from a list of transaction ids. + """Get the asset id from a list of :class:`~.Transactions`. This is useful when we want to check if the multiple inputs of a transaction are related to the same asset id. Args: transactions (:obj:`list` of :class:`~bigchaindb.common. - transaction.Transaction`): list of transaction usually inputs - that should have a matching asset_id + transaction.Transaction`): A list of Transactions. + Usually input Transactions that should have a matching + asset ID. Returns: - str: uuid of the asset. + str: ID of the asset. Raises: - AssetIdMismatch: If the inputs are related to different assets. + :exc:`AssetIdMismatch`: If the inputs are related to different + assets. """ if not isinstance(transactions, list): transactions = [transactions] - # create a set of asset_ids - asset_ids = {tx.asset.data_id for tx in transactions} + # create a set of the transactions' asset ids + asset_ids = {tx.id if tx.operation == Transaction.CREATE else tx.asset.id + for tx in transactions} - # check that all the transasctions have the same asset_id + # check that all the transasctions have the same asset id if len(asset_ids) > 1: raise AssetIdMismatch(('All inputs of all transactions passed' ' need to have the same asset id')) @@ -475,20 +469,20 @@ class Asset(object): raise AmountError('`amount` must be greater than 0') -class AssetLink(Asset): +class AssetLink(object): """An object for unidirectional linking to a Asset. """ - def __init__(self, data_id=None): + def __init__(self, asset_id=None): """Used to point to a specific Asset. Args: - data_id (str): A Asset to link to. + asset_id (str): The ID of an asset to link to. """ - self.data_id = data_id + self.id = asset_id def __bool__(self): - return self.data_id is not None + return self.id is not None def __eq__(self, other): return isinstance(other, AssetLink) and \ @@ -514,12 +508,14 @@ class AssetLink(Asset): Returns: (dict|None): The link as an alternative serialization format. + Returns None if the link is empty (i.e. is not linking to + an asset). """ - if self.data_id is None: + if self.id is None: return None else: return { - 'id': self.data_id + 'id': self.id } @@ -537,6 +533,10 @@ class Transaction(object): spend. conditions (:obj:`list` of :class:`~bigchaindb.common. transaction.Condition`, optional): Define the assets to lock. + asset (:class:`~.Asset`|:class:`~.AssetLink`): Asset or Asset link + associated with this Transaction. ``CREATE`` and ``GENESIS`` + Transactions require an Asset while ``TRANSFER`` Transactions + require an AssetLink. metadata (dict): Metadata to be stored along with the Transaction. version (int): Defines the version number of a Transaction. @@ -557,8 +557,8 @@ class Transaction(object): Args: operation (str): Defines the operation of the Transaction. - asset (:class:`~bigchaindb.common.transaction.Asset`): An Asset - to be transferred or created in a Transaction. + asset (:class:`~.Asset`|:class:`~.AssetLink`): An Asset to be + created or an AssetLink linking an asset to be transferred. fulfillments (:obj:`list` of :class:`~bigchaindb.common. transaction.Fulfillment`, optional): Define the assets to spend. @@ -575,10 +575,17 @@ class Transaction(object): raise ValueError('`operation` must be one of {}' .format(allowed_ops)) - # Only assets for 'CREATE' operations can be un-defined. - if (asset and not isinstance(asset, Asset) or - not asset and operation != Transaction.CREATE): - raise TypeError('`asset` must be an Asset instance') + # Assets for 'CREATE' and 'GENESIS' operations must be None or of Asset + # type and Assets for 'TRANSFER' operations must be of AssetLink type. + if (operation in [Transaction.CREATE, Transaction.GENESIS] and + asset is not None and + not isinstance(asset, Asset)): + raise TypeError(("`asset` must be an Asset instance for " + "'{}' Transactions".format(operation))) + elif (operation == Transaction.TRANSFER and + not (asset and isinstance(asset, AssetLink))): + raise TypeError(("`asset` must be an valid AssetLink instance for " + "'TRANSFER' Transactions".format(operation))) if conditions and not isinstance(conditions, list): raise TypeError('`conditions` must be a list instance or None') @@ -591,9 +598,9 @@ class Transaction(object): self.version = version if version is not None else self.VERSION self.operation = operation - self.asset = asset if asset else Asset() - self.conditions = conditions if conditions else [] - self.fulfillments = fulfillments if fulfillments else [] + self.asset = asset or Asset() + self.conditions = conditions or [] + self.fulfillments = fulfillments or [] self.metadata = metadata # validate asset @@ -659,7 +666,7 @@ class Transaction(object): return cls(cls.CREATE, asset, fulfillments, conditions, metadata) @classmethod - def transfer(cls, inputs, owners_after, asset, metadata=None): + def transfer(cls, inputs, owners_after, asset_link, metadata=None): """A simple way to generate a `TRANSFER` transaction. Note: @@ -689,8 +696,9 @@ class Transaction(object): generate. owners_after (:obj:`list` of :obj:`str`): A list of keys that represent the receivers of this Transaction. - asset (:class:`~bigchaindb.common.transaction.Asset`): An Asset - to be transferred in this Transaction. + asset_link (:class:`~bigchaindb.common.transaction.AssetLink`): + An AssetLink linking an asset to be transferred in this + Transaction. metadata (dict): Python dictionary to be stored along with the Transaction. @@ -716,7 +724,7 @@ class Transaction(object): conditions.append(Condition.generate(pub_keys, amount)) inputs = deepcopy(inputs) - return cls(cls.TRANSFER, asset, inputs, conditions, metadata) + return cls(cls.TRANSFER, asset_link, inputs, conditions, metadata) def __eq__(self, other): try: @@ -1056,12 +1064,6 @@ class Transaction(object): Returns: dict: The Transaction as an alternative serialization format. """ - if self.operation in (self.__class__.GENESIS, self.__class__.CREATE): - asset = self.asset.to_dict() - else: - # NOTE: An `asset` in a `TRANSFER` only contains the asset's id - asset = {'id': self.asset.data_id} - tx = { 'fulfillments': [fulfillment.to_dict() for fulfillment in self.fulfillments], @@ -1069,7 +1071,7 @@ class Transaction(object): in self.conditions], 'operation': str(self.operation), 'metadata': self.metadata, - 'asset': asset, + 'asset': self.asset.to_dict(), 'version': self.version, } diff --git a/bigchaindb/models.py b/bigchaindb/models.py index 4c6efb4b..8917c1e2 100644 --- a/bigchaindb/models.py +++ b/bigchaindb/models.py @@ -82,7 +82,7 @@ class Transaction(Transaction): # validate asset id asset_id = Asset.get_asset_id(input_txs) - if asset_id != self.asset.data_id: + if asset_id != self.asset.id: raise AssetIdMismatch(('The asset id of the input does not' ' match the asset id of the' ' transaction')) diff --git a/docs/server/generate_http_server_api_documentation.py b/docs/server/generate_http_server_api_documentation.py index 80b47cf2..43fd5f4b 100644 --- a/docs/server/generate_http_server_api_documentation.py +++ b/docs/server/generate_http_server_api_documentation.py @@ -62,7 +62,7 @@ def main(): """ Main function """ privkey = 'CfdqtD7sS7FgkMoGPXw55MVGGFwQLAoHYTcBhZDtF99Z' pubkey = '4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD' - asset = Asset(None, 'e6969f87-4fc9-4467-b62a-f0dfa1c85002') + asset = Asset(None) tx = Transaction.create([pubkey], [([pubkey], 1)], asset=asset) tx = tx.sign([privkey]) tx_json = json.dumps(tx.to_dict(), indent=2, sort_keys=True) diff --git a/docs/server/source/data-models/asset-model.md b/docs/server/source/data-models/asset-model.md index 7f1afebc..312c6765 100644 --- a/docs/server/source/data-models/asset-model.md +++ b/docs/server/source/data-models/asset-model.md @@ -5,18 +5,17 @@ To avoid redundant data in transactions, the digital asset model is different fo A digital asset's properties are defined in a `CREATE` transaction with the following model: ```json { - "id": "", "data": "" } ``` -For `TRANSFER` transactions we only keep the asset id. +For `TRANSFER` transactions we only keep the asset ID: ```json { - "id": "" + "id": "" } ``` -- `id`: UUID version 4 (random) converted to a string of hex digits in standard form. Added server side. +- `id`: The ID of the `CREATE` transaction that created the asset. - `data`: A user supplied JSON document with custom information about the asset. Defaults to null. diff --git a/tests/assets/test_digital_assets.py b/tests/assets/test_digital_assets.py index d55c8e22..efb15fc1 100644 --- a/tests/assets/test_digital_assets.py +++ b/tests/assets/test_digital_assets.py @@ -1,20 +1,22 @@ import pytest +import random from unittest.mock import patch @pytest.mark.usefixtures('inputs') def test_asset_transfer(b, user_pk, user_sk): + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction tx_input = b.get_owned_ids(user_pk).pop() tx_create = b.get_transaction(tx_input.txid) tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([user_pk], 1)], - tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) assert tx_transfer_signed.validate(b) == tx_transfer_signed - assert tx_transfer_signed.asset.data_id == tx_create.asset.data_id + assert tx_transfer_signed.asset.id == tx_create.id def test_validate_bad_asset_creation(b, user_pk): @@ -32,13 +34,14 @@ def test_validate_bad_asset_creation(b, user_pk): @pytest.mark.usefixtures('inputs') def test_validate_transfer_asset_id_mismatch(b, user_pk, user_sk): from bigchaindb.common.exceptions import AssetIdMismatch + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction tx_create = b.get_owned_ids(user_pk).pop() tx_create = b.get_transaction(tx_create.txid) tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([user_pk], 1)], - tx_create.asset) - tx_transfer.asset.data_id = 'aaa' + AssetLink(tx_create.id)) + tx_transfer.asset.id = 'aaa' tx_transfer_signed = tx_transfer.sign([user_sk]) with pytest.raises(AssetIdMismatch): tx_transfer_signed.validate(b) @@ -50,18 +53,19 @@ def test_get_asset_id_create_transaction(b, user_pk): tx_create = Transaction.create([b.me], [([user_pk], 1)]) asset_id = Asset.get_asset_id(tx_create) - assert asset_id == tx_create.asset.data_id + assert asset_id == tx_create.id @pytest.mark.usefixtures('inputs') def test_get_asset_id_transfer_transaction(b, user_pk, user_sk): + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction, Asset tx_create = b.get_owned_ids(user_pk).pop() tx_create = b.get_transaction(tx_create.txid) # create a transfer transaction tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([user_pk], 1)], - tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) # create a block block = b.create_block([tx_transfer_signed]) @@ -71,15 +75,17 @@ def test_get_asset_id_transfer_transaction(b, user_pk, user_sk): b.write_vote(vote) asset_id = Asset.get_asset_id(tx_transfer) - assert asset_id == tx_transfer.asset.data_id + assert asset_id == tx_transfer.asset.id def test_asset_id_mismatch(b, user_pk): from bigchaindb.models import Transaction, Asset from bigchaindb.common.exceptions import AssetIdMismatch - tx1 = Transaction.create([b.me], [([user_pk], 1)]) - tx2 = Transaction.create([b.me], [([user_pk], 1)]) + tx1 = Transaction.create([b.me], [([user_pk], 1)], + metadata={'msg': random.random()}) + tx2 = Transaction.create([b.me], [([user_pk], 1)], + metadata={'msg': random.random()}) with pytest.raises(AssetIdMismatch): Asset.get_asset_id([tx1, tx2]) @@ -87,20 +93,21 @@ def test_asset_id_mismatch(b, user_pk): @pytest.mark.usefixtures('inputs') def test_get_transactions_by_asset_id(b, user_pk, user_sk): + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction tx_create = b.get_owned_ids(user_pk).pop() tx_create = b.get_transaction(tx_create.txid) - asset_id = tx_create.asset.data_id + asset_id = tx_create.id txs = b.get_transactions_by_asset_id(asset_id) assert len(txs) == 1 assert txs[0].id == tx_create.id - assert txs[0].asset.data_id == asset_id + assert txs[0].id == asset_id # create a transfer transaction tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([user_pk], 1)], - tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) # create the block block = b.create_block([tx_transfer_signed]) @@ -114,26 +121,28 @@ def test_get_transactions_by_asset_id(b, user_pk, user_sk): assert len(txs) == 2 assert tx_create.id in [t.id for t in txs] assert tx_transfer.id in [t.id for t in txs] - assert asset_id == txs[0].asset.data_id - assert asset_id == txs[1].asset.data_id + # FIXME: can I rely on the ordering here? + assert asset_id == txs[0].id + assert asset_id == txs[1].asset.id @pytest.mark.usefixtures('inputs') def test_get_transactions_by_asset_id_with_invalid_block(b, user_pk, user_sk): + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction tx_create = b.get_owned_ids(user_pk).pop() tx_create = b.get_transaction(tx_create.txid) - asset_id = tx_create.asset.data_id + asset_id = tx_create.id txs = b.get_transactions_by_asset_id(asset_id) assert len(txs) == 1 assert txs[0].id == tx_create.id - assert txs[0].asset.data_id == asset_id + assert txs[0].id == asset_id # create a transfer transaction tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([user_pk], 1)], - tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) # create the block block = b.create_block([tx_transfer_signed]) @@ -149,15 +158,15 @@ def test_get_transactions_by_asset_id_with_invalid_block(b, user_pk, user_sk): @pytest.mark.usefixtures('inputs') def test_get_asset_by_id(b, user_pk, user_sk): - from bigchaindb.models import Transaction + from bigchaindb.common.transaction import AssetLink + from bigchaindb.models import Asset, Transaction tx_create = b.get_owned_ids(user_pk).pop() tx_create = b.get_transaction(tx_create.txid) - asset_id = tx_create.asset.data_id # create a transfer transaction tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([user_pk], 1)], - tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) # create the block block = b.create_block([tx_transfer_signed]) @@ -166,6 +175,7 @@ def test_get_asset_by_id(b, user_pk, user_sk): vote = b.vote(block.id, b.get_last_voted_block().id, True) b.write_vote(vote) + asset_id = Asset.get_asset_id([tx_create, tx_transfer]) txs = b.get_transactions_by_asset_id(asset_id) assert len(txs) == 2 diff --git a/tests/assets/test_divisible_assets.py b/tests/assets/test_divisible_assets.py index 9f63af8a..5c661dd8 100644 --- a/tests/assets/test_divisible_assets.py +++ b/tests/assets/test_divisible_assets.py @@ -130,7 +130,7 @@ def test_single_in_multiple_own_single_out_single_own_create(b, user_pk, def test_single_in_single_own_single_out_single_own_transfer(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset asset = Asset() @@ -146,7 +146,7 @@ def test_single_in_single_own_single_out_single_own_transfer(b, user_pk, # TRANSFER tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 100)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) assert tx_transfer_signed.validate(b) @@ -164,7 +164,7 @@ def test_single_in_single_own_single_out_single_own_transfer(b, user_pk, def test_single_in_single_own_multiple_out_single_own_transfer(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset asset = Asset() @@ -181,7 +181,7 @@ def test_single_in_single_own_multiple_out_single_own_transfer(b, user_pk, # TRANSFER tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 50), ([b.me], 50)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) assert tx_transfer_signed.validate(b) == tx_transfer_signed @@ -200,7 +200,7 @@ def test_single_in_single_own_multiple_out_single_own_transfer(b, user_pk, def test_single_in_single_own_single_out_multiple_own_transfer(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset asset = Asset() @@ -217,7 +217,7 @@ def test_single_in_single_own_single_out_multiple_own_transfer(b, user_pk, # TRANSFER tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me, b.me], 100)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) assert tx_transfer_signed.validate(b) == tx_transfer_signed @@ -241,7 +241,7 @@ def test_single_in_single_own_single_out_multiple_own_transfer(b, user_pk, def test_single_in_single_own_multiple_out_mix_own_transfer(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset asset = Asset() @@ -258,7 +258,7 @@ def test_single_in_single_own_multiple_out_mix_own_transfer(b, user_pk, # TRANSFER tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 50), ([b.me, b.me], 50)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) assert tx_transfer_signed.validate(b) == tx_transfer_signed @@ -282,7 +282,7 @@ def test_single_in_single_own_multiple_out_mix_own_transfer(b, user_pk, def test_single_in_multiple_own_single_out_single_own_transfer(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset asset = Asset() @@ -299,7 +299,7 @@ def test_single_in_multiple_own_single_out_single_own_transfer(b, user_pk, # TRANSFER tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 100)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([b.me_private, user_sk]) assert tx_transfer_signed.validate(b) == tx_transfer_signed @@ -321,7 +321,7 @@ def test_single_in_multiple_own_single_out_single_own_transfer(b, user_pk, def test_multiple_in_single_own_single_out_single_own_transfer(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset asset = Asset() @@ -338,7 +338,7 @@ def test_multiple_in_single_own_single_out_single_own_transfer(b, user_pk, # TRANSFER tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 100)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) assert tx_transfer_signed.validate(b) @@ -356,7 +356,7 @@ def test_multiple_in_single_own_single_out_single_own_transfer(b, user_pk, def test_multiple_in_multiple_own_single_out_single_own_transfer(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset asset = Asset() @@ -375,7 +375,7 @@ def test_multiple_in_multiple_own_single_out_single_own_transfer(b, user_pk, # TRANSFER tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 100)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([b.me_private, user_sk]) assert tx_transfer_signed.validate(b) @@ -401,7 +401,7 @@ def test_multiple_in_multiple_own_single_out_single_own_transfer(b, user_pk, def test_muiltiple_in_mix_own_multiple_out_single_own_transfer(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset asset = Asset() @@ -420,7 +420,7 @@ def test_muiltiple_in_mix_own_multiple_out_single_own_transfer(b, user_pk, # TRANSFER tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 100)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([b.me_private, user_sk]) assert tx_transfer_signed.validate(b) == tx_transfer_signed @@ -446,7 +446,7 @@ def test_muiltiple_in_mix_own_multiple_out_single_own_transfer(b, user_pk, def test_muiltiple_in_mix_own_multiple_out_mix_own_transfer(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset asset = Asset() @@ -466,7 +466,7 @@ def test_muiltiple_in_mix_own_multiple_out_mix_own_transfer(b, user_pk, # TRANSFER tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 50), ([b.me, user_pk], 50)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([b.me_private, user_sk]) assert tx_transfer_signed.validate(b) == tx_transfer_signed @@ -496,7 +496,7 @@ def test_muiltiple_in_mix_own_multiple_out_mix_own_transfer(b, user_pk, @pytest.mark.usefixtures('inputs') def test_multiple_in_different_transactions(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset # `b` creates a divisible asset and assigns 50 shares to `b` and @@ -521,7 +521,7 @@ def test_multiple_in_different_transactions(b, user_pk, user_sk): # split across two different transactions tx_transfer1 = Transaction.transfer(tx_create.to_inputs([1]), [([user_pk], 50)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer1_signed = tx_transfer1.sign([b.me_private]) # create block block = b.create_block([tx_transfer1_signed]) @@ -537,7 +537,7 @@ def test_multiple_in_different_transactions(b, user_pk, user_sk): tx_transfer2 = Transaction.transfer(tx_create.to_inputs([0]) + tx_transfer1.to_inputs([0]), [([b.me], 100)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer2_signed = tx_transfer2.sign([user_sk]) assert tx_transfer2_signed.validate(b) == tx_transfer2_signed @@ -557,7 +557,7 @@ def test_multiple_in_different_transactions(b, user_pk, user_sk): @pytest.mark.usefixtures('inputs') def test_amount_error_transfer(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink from bigchaindb.common.exceptions import AmountError # CREATE divisible asset @@ -575,7 +575,7 @@ def test_amount_error_transfer(b, user_pk, user_sk): # TRANSFER # output amount less than input amount tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 50)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) with pytest.raises(AmountError): tx_transfer_signed.validate(b) @@ -583,7 +583,7 @@ def test_amount_error_transfer(b, user_pk, user_sk): # TRANSFER # output amount greater than input amount tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 101)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) with pytest.raises(AmountError): tx_transfer_signed.validate(b) @@ -600,7 +600,7 @@ def test_threshold_same_public_key(b, user_pk, user_sk): # that does not mean that the code shouldn't work. from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset asset = Asset() @@ -617,7 +617,7 @@ def test_threshold_same_public_key(b, user_pk, user_sk): # TRANSFER tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 100)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk, user_sk]) assert tx_transfer_signed.validate(b) == tx_transfer_signed @@ -626,7 +626,7 @@ def test_threshold_same_public_key(b, user_pk, user_sk): @pytest.mark.usefixtures('inputs') def test_sum_amount(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset with 3 outputs with amount 1 asset = Asset() @@ -647,7 +647,7 @@ def test_sum_amount(b, user_pk, user_sk): # create a transfer transaction with one output and check if the amount # is 3 tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 3)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) assert tx_transfer_signed.validate(b) == tx_transfer_signed @@ -658,7 +658,7 @@ def test_sum_amount(b, user_pk, user_sk): @pytest.mark.usefixtures('inputs') def test_divide(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink # CREATE divisible asset with 1 output with amount 3 asset = Asset() @@ -677,7 +677,7 @@ def test_divide(b, user_pk, user_sk): # of each output is 1 tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 1), ([b.me], 1), ([b.me], 1)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) assert tx_transfer_signed.validate(b) == tx_transfer_signed @@ -690,7 +690,7 @@ def test_divide(b, user_pk, user_sk): @pytest.mark.usefixtures('inputs') def test_non_positive_amounts_on_transfer(b, user_pk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink from bigchaindb.common.exceptions import AmountError # CREATE divisible asset with 1 output with amount 3 @@ -709,14 +709,14 @@ def test_non_positive_amounts_on_transfer(b, user_pk): with pytest.raises(AmountError): Transaction.transfer(tx_create.to_inputs(), [([b.me], 4), ([b.me], -1)], - asset=tx_create.asset) + AssetLink(tx_create.id)) # Check that negative inputs are caught when validating a TRANSFER transaction @pytest.mark.usefixtures('inputs') def test_non_positive_amounts_on_transfer_validate(b, user_pk, user_sk): from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset + from bigchaindb.common.transaction import Asset, AssetLink from bigchaindb.common.exceptions import AmountError # CREATE divisible asset with 1 output with amount 3 @@ -736,7 +736,7 @@ def test_non_positive_amounts_on_transfer_validate(b, user_pk, user_sk): # of each output is 1 tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 4), ([b.me], 1)], - asset=tx_create.asset) + AssetLink(tx_create.id)) tx_transfer.conditions[1].amount = -1 tx_transfer_signed = tx_transfer.sign([user_sk]) diff --git a/tests/common/conftest.py b/tests/common/conftest.py index a54daf20..ca3194f9 100644 --- a/tests/common/conftest.py +++ b/tests/common/conftest.py @@ -17,9 +17,6 @@ CC_CONDITION_URI = 'cc:0:3:47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU:0' DATA = { 'msg': 'Hello BigchainDB!' } -DATA_ID = '872fa6e6f46246cd44afdb2ee9cfae0e72885fb0910e2bcf9a5a2a4eadb417b8' - -UUID4 = 'dc568f27-a113-46b4-9bd4-43015859e3e3' @pytest.fixture @@ -126,16 +123,6 @@ def data(): return DATA -@pytest.fixture -def data_id(): - return DATA_ID - - -@pytest.fixture -def uuid4(): - return UUID4 - - @pytest.fixture def utx(user_ffill, user_cond): from bigchaindb.common.transaction import Transaction, Asset @@ -150,12 +137,12 @@ def tx(utx, user_priv): @pytest.fixture def transfer_utx(user_cond, user2_cond, utx): from bigchaindb.common.transaction import (Fulfillment, TransactionLink, - Transaction, Asset) + Transaction, AssetLink) user_cond = user_cond.to_dict() ffill = Fulfillment(utx.conditions[0].fulfillment, user_cond['owners_after'], TransactionLink(utx.id, 0)) - return Transaction('TRANSFER', Asset(), [ffill], [user2_cond]) + return Transaction('TRANSFER', AssetLink(utx.id), [ffill], [user2_cond]) @pytest.fixture diff --git a/tests/common/test_asset.py b/tests/common/test_asset.py index a1892a3c..12951bf3 100644 --- a/tests/common/test_asset.py +++ b/tests/common/test_asset.py @@ -6,7 +6,6 @@ def test_asset_default_values(): asset = Asset() assert asset.data is None - assert asset.data_id def test_asset_creation_with_data(data): @@ -24,32 +23,30 @@ def test_asset_invalid_asset_initialization(): Asset(data='some wrong type') -def test_invalid_asset_comparison(data, data_id): +def test_invalid_asset_comparison(data): from bigchaindb.common.transaction import Asset - assert Asset(data, data_id) != 'invalid comparison' + assert Asset(data) != 'invalid comparison' -def test_asset_serialization(data, data_id): +def test_asset_serialization(data): from bigchaindb.common.transaction import Asset expected = { - 'id': data_id, 'data': data, } - asset = Asset(data, data_id) + asset = Asset(data) assert asset.to_dict() == expected -def test_asset_deserialization(data, data_id): +def test_asset_deserialization(data): from bigchaindb.common.transaction import Asset asset_dict = { - 'id': data_id, 'data': data, } asset = Asset.from_dict(asset_dict) - expected = Asset(data, data_id) + expected = Asset(data) assert asset == expected diff --git a/tests/common/test_transaction.py b/tests/common/test_transaction.py index e3a8b98c..dc8a7784 100644 --- a/tests/common/test_transaction.py +++ b/tests/common/test_transaction.py @@ -274,27 +274,17 @@ def test_invalid_transaction_initialization(): def test_create_default_asset_on_tx_initialization(): from bigchaindb.common.transaction import Transaction, Asset - from bigchaindb.common.exceptions import ValidationError - from .util import validate_transaction_model with patch.object(Asset, 'validate_asset', return_value=None): tx = Transaction(Transaction.CREATE, None) expected = Asset() asset = tx.asset - expected.data_id = None - asset.data_id = None assert asset == expected - # Fails because no asset hash - with raises(ValidationError): - validate_transaction_model(tx) - -def test_transaction_serialization(user_ffill, user_cond, data, data_id): +def test_transaction_serialization(user_ffill, user_cond, data): from bigchaindb.common.transaction import Transaction, Asset - from bigchaindb.common.exceptions import ValidationError - from .util import validate_transaction_model tx_id = 'l0l' @@ -308,30 +298,23 @@ def test_transaction_serialization(user_ffill, user_cond, data, data_id): 'operation': Transaction.CREATE, 'metadata': None, 'asset': { - 'id': data_id, 'data': data, } } - tx = Transaction(Transaction.CREATE, Asset(data, data_id), [user_ffill], + tx = Transaction(Transaction.CREATE, Asset(data), [user_ffill], [user_cond]) tx_dict = tx.to_dict() tx_dict['id'] = tx_id - tx_dict['asset']['id'] = data_id assert tx_dict == expected - # Fails because asset id is not a uuid4 - with raises(ValidationError): - validate_transaction_model(tx) - -def test_transaction_deserialization(user_ffill, user_cond, data, uuid4): +def test_transaction_deserialization(user_ffill, user_cond, data): from bigchaindb.common.transaction import Transaction, Asset from .util import validate_transaction_model - - expected_asset = Asset(data, uuid4) + expected_asset = Asset(data) expected = Transaction(Transaction.CREATE, expected_asset, [user_ffill], [user_cond], None, Transaction.VERSION) @@ -344,7 +327,6 @@ def test_transaction_deserialization(user_ffill, user_cond, data, uuid4): 'operation': Transaction.CREATE, 'metadata': None, 'asset': { - 'id': uuid4, 'data': data, } } @@ -453,11 +435,11 @@ def test_cast_transaction_link_to_boolean(): def test_asset_link_serialization(): from bigchaindb.common.transaction import AssetLink - data_id = 'a asset id' + asset_id = 'a asset id' expected = { - 'id': data_id, + 'id': asset_id, } - asset_link = AssetLink(data_id) + asset_link = AssetLink(asset_id) assert asset_link.to_dict() == expected @@ -474,10 +456,10 @@ def test_asset_link_serialization_with_empty_payload(): def test_asset_link_deserialization(): from bigchaindb.common.transaction import AssetLink - data_id = 'a asset id' - expected = AssetLink(data_id) + asset_id = 'a asset id' + expected = AssetLink(asset_id) asset_link = { - 'id': data_id + 'id': asset_id } asset_link = AssetLink.from_dict(asset_link) @@ -686,7 +668,8 @@ def test_multiple_fulfillment_validation_of_transfer_tx(user_ffill, user_cond, user3_priv): from copy import deepcopy from bigchaindb.common.transaction import (Transaction, TransactionLink, - Fulfillment, Condition, Asset) + Fulfillment, Condition, Asset, + AssetLink) from cryptoconditions import Ed25519Fulfillment from .util import validate_transaction_model @@ -702,7 +685,8 @@ def test_multiple_fulfillment_validation_of_transfer_tx(user_ffill, user_cond, [user3_pub]), Condition(Ed25519Fulfillment(public_key=user3_pub), [user3_pub])] - transfer_tx = Transaction('TRANSFER', tx.asset, fulfillments, conditions) + transfer_tx = Transaction('TRANSFER', AssetLink(tx.id), + fulfillments, conditions) transfer_tx = transfer_tx.sign([user_priv]) assert transfer_tx.fulfillments_valid(tx.conditions) is True @@ -735,7 +719,7 @@ def test_validate_fulfillments_of_transfer_tx_with_invalid_params(transfer_tx, transfer_tx.fulfillments_valid([utx.conditions[0]]) -def test_create_create_transaction_single_io(user_cond, user_pub, data, uuid4): +def test_create_create_transaction_single_io(user_cond, user_pub, data): from bigchaindb.common.transaction import Transaction, Asset from .util import validate_transaction_model @@ -743,7 +727,6 @@ def test_create_create_transaction_single_io(user_cond, user_pub, data, uuid4): 'conditions': [user_cond.to_dict()], 'metadata': data, 'asset': { - 'id': uuid4, 'data': data, }, 'fulfillments': [ @@ -759,7 +742,7 @@ def test_create_create_transaction_single_io(user_cond, user_pub, data, uuid4): 'version': 1, } - asset = Asset(data, uuid4) + asset = Asset(data) tx = Transaction.create([user_pub], [([user_pub], 1)], data, asset) tx_dict = tx.to_dict() tx_dict['fulfillments'][0]['fulfillment'] = None @@ -823,15 +806,13 @@ def test_validate_multiple_io_create_transaction(user_pub, user_priv, def test_create_create_transaction_threshold(user_pub, user2_pub, user3_pub, user_user2_threshold_cond, - user_user2_threshold_ffill, data, - uuid4): + user_user2_threshold_ffill, data): from bigchaindb.common.transaction import Transaction, Asset expected = { 'conditions': [user_user2_threshold_cond.to_dict()], 'metadata': data, 'asset': { - 'id': uuid4, 'data': data, }, 'fulfillments': [ @@ -846,7 +827,7 @@ def test_create_create_transaction_threshold(user_pub, user2_pub, user3_pub, 'operation': 'CREATE', 'version': 1 } - asset = Asset(data, uuid4) + asset = Asset(data) tx = Transaction.create([user_pub], [([user_pub, user2_pub], 1)], data, asset) tx_dict = tx.to_dict() @@ -870,7 +851,7 @@ def test_validate_threshold_create_transaction(user_pub, user_priv, user2_pub, def test_create_create_transaction_with_invalid_parameters(user_pub): - from bigchaindb.common.transaction import Transaction + from bigchaindb.common.transaction import Transaction, AssetLink with raises(TypeError): Transaction.create('not a list') @@ -884,6 +865,13 @@ def test_create_create_transaction_with_invalid_parameters(user_pub): Transaction.create([user_pub], [user_pub]) with raises(ValueError): Transaction.create([user_pub], [([user_pub],)]) + with raises(TypeError): + Transaction.create([user_pub], [([user_pub], 1)], metadata=[]) + with raises(TypeError): + Transaction.create([user_pub], + [([user_pub], 1)], + metadata=None, + asset=AssetLink('mock_asset_link')) def test_conditions_to_inputs(tx): @@ -897,10 +885,10 @@ def test_conditions_to_inputs(tx): def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub, - user2_cond, user_priv, uuid4): + user2_cond, user_priv): from copy import deepcopy from bigchaindb.common.crypto import PrivateKey - from bigchaindb.common.transaction import Transaction, Asset + from bigchaindb.common.transaction import Transaction, AssetLink from bigchaindb.common.util import serialize from .util import validate_transaction_model @@ -908,7 +896,7 @@ def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub, 'conditions': [user2_cond.to_dict()], 'metadata': None, 'asset': { - 'id': uuid4, + 'id': tx.id, }, 'fulfillments': [ { @@ -926,8 +914,8 @@ def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub, 'version': 1 } inputs = tx.to_inputs([0]) - asset = Asset(None, uuid4) - transfer_tx = Transaction.transfer(inputs, [([user2_pub], 1)], asset=asset) + transfer_tx = Transaction.transfer(inputs, [([user2_pub], 1)], + asset_link=AssetLink(tx.id)) transfer_tx = transfer_tx.sign([user_priv]) transfer_tx = transfer_tx.to_dict() @@ -949,7 +937,7 @@ def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub, def test_create_transfer_transaction_multiple_io(user_pub, user_priv, user2_pub, user2_priv, user3_pub, user2_cond): - from bigchaindb.common.transaction import Transaction, Asset + from bigchaindb.common.transaction import Transaction, Asset, AssetLink asset = Asset() tx = Transaction.create([user_pub], [([user_pub], 1), ([user2_pub], 1)], @@ -986,7 +974,7 @@ def test_create_transfer_transaction_multiple_io(user_pub, user_priv, transfer_tx = Transaction.transfer(tx.to_inputs(), [([user2_pub], 1), ([user2_pub], 1)], - asset=tx.asset) + asset_link=AssetLink(tx.id)) transfer_tx = transfer_tx.sign([user_priv, user2_priv]) assert len(transfer_tx.fulfillments) == 2 @@ -1003,21 +991,27 @@ def test_create_transfer_transaction_multiple_io(user_pub, user_priv, assert expected == transfer_tx -def test_create_transfer_with_invalid_parameters(user_pub): - from bigchaindb.common.transaction import Transaction, Asset +def test_create_transfer_with_invalid_parameters(tx, user_pub): + from bigchaindb.common.transaction import Transaction, Asset, AssetLink + mock_asset_link = AssetLink(tx.id) with raises(TypeError): - Transaction.transfer({}, [], Asset()) + Transaction.transfer({}, [], mock_asset_link) with raises(ValueError): - Transaction.transfer([], [], Asset()) + Transaction.transfer([], [], mock_asset_link) with raises(TypeError): - Transaction.transfer(['fulfillment'], {}, Asset()) + Transaction.transfer(['fulfillment'], {}, mock_asset_link) with raises(ValueError): - Transaction.transfer(['fulfillment'], [], Asset()) + Transaction.transfer(['fulfillment'], [], mock_asset_link) with raises(ValueError): - Transaction.transfer(['fulfillment'], [user_pub], Asset()) + Transaction.transfer(['fulfillment'], [user_pub], mock_asset_link) with raises(ValueError): - Transaction.transfer(['fulfillment'], [([user_pub],)], Asset()) + Transaction.transfer(['fulfillment'], [([user_pub],)], mock_asset_link) + with raises(TypeError): + Transaction.transfer(['fulfillment'], [([user_pub], 1)], + mock_asset_link, metadata=[]) + with raises(TypeError): + Transaction.transfer(['fulfillment'], [([user_pub], 1)], Asset()) def test_cant_add_empty_condition(): diff --git a/tests/conftest.py b/tests/conftest.py index b71ac9fa..57f60cce 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -8,6 +8,7 @@ Tasks: import os import copy +import random import pytest @@ -123,9 +124,12 @@ def signed_create_tx(b, create_tx): @pytest.fixture def signed_transfer_tx(signed_create_tx, user_pk, user_sk): + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction inputs = signed_create_tx.to_inputs() - tx = Transaction.transfer(inputs, [([user_pk], 1)], signed_create_tx.asset) + tx = Transaction.transfer(inputs, + [([user_pk], 1)], + AssetLink(signed_create_tx.id)) return tx.sign([user_sk]) @@ -188,8 +192,10 @@ def inputs(user_pk, setup_database): prev_block_id = g.id for block in range(4): transactions = [ - Transaction.create([b.me], [([user_pk], 1)]).sign([b.me_private]) - for i in range(10) + Transaction.create([b.me], [([user_pk], 1)], + metadata={'msg': random.random()}) + .sign([b.me_private]) + for _ in range(10) ] block = b.create_block(transactions) b.write_block(block) @@ -216,9 +222,10 @@ def inputs_shared(user_pk, user2_pk, setup_database): prev_block_id = g.id for block in range(4): transactions = [ - Transaction.create( - [b.me], [user_pk, user2_pk], payload={'i': i}).sign([b.me_private]) - for i in range(10) + Transaction.create([b.me], [user_pk, user2_pk], + metadata={'msg': random.random()}) + .sign([b.me_private]) + for _ in range(10) ] block = b.create_block(transactions) b.write_block(block) diff --git a/tests/db/test_bigchain_api.py b/tests/db/test_bigchain_api.py index e9866ce2..58952fbc 100644 --- a/tests/db/test_bigchain_api.py +++ b/tests/db/test_bigchain_api.py @@ -1,6 +1,7 @@ from time import sleep import pytest +import random @pytest.mark.skipif(reason='Some tests throw a ResourceWarning that might result in some weird ' @@ -91,6 +92,7 @@ class TestBigchainApi(object): def test_get_spent_with_double_spend(self, b, monkeypatch): from bigchaindb.common.exceptions import DoubleSpend + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction b.create_genesis_block() @@ -104,14 +106,14 @@ class TestBigchainApi(object): monkeypatch.setattr('time.time', lambda: 2) transfer_tx = Transaction.transfer(tx.to_inputs(), [([b.me], 1)], - tx.asset) + AssetLink(tx.id)) transfer_tx = transfer_tx.sign([b.me_private]) block2 = b.create_block([transfer_tx]) b.write_block(block2) monkeypatch.setattr('time.time', lambda: 3333333333) transfer_tx2 = Transaction.transfer(tx.to_inputs(), [([b.me], 1)], - tx.asset) + AssetLink(tx.id)) transfer_tx2 = transfer_tx2.sign([b.me_private]) block3 = b.create_block([transfer_tx2]) b.write_block(block3) @@ -157,13 +159,15 @@ class TestBigchainApi(object): b.create_genesis_block() monkeypatch.setattr('time.time', lambda: 1) - tx1 = Transaction.create([b.me], [([b.me], 1)]) + tx1 = Transaction.create([b.me], [([b.me], 1)], + metadata={'msg': random.random()}) tx1 = tx1.sign([b.me_private]) block1 = b.create_block([tx1]) b.write_block(block1) monkeypatch.setattr('time.time', lambda: 2222222222) - tx2 = Transaction.create([b.me], [([b.me], 1)]) + tx2 = Transaction.create([b.me], [([b.me], 1)], + metadata={'msg': random.random()}) tx2 = tx2.sign([b.me_private]) block2 = b.create_block([tx2]) b.write_block(block2) @@ -181,12 +185,14 @@ class TestBigchainApi(object): @pytest.mark.usefixtures('inputs') def test_write_transaction(self, b, user_pk, user_sk): + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction input_tx = b.get_owned_ids(user_pk).pop() input_tx = b.get_transaction(input_tx.txid) inputs = input_tx.to_inputs() - tx = Transaction.transfer(inputs, [([user_pk], 1)], input_tx.asset) + tx = Transaction.transfer(inputs, [([user_pk], 1)], + AssetLink(input_tx.id)) tx = tx.sign([user_sk]) response = b.write_transaction(tx) @@ -199,12 +205,14 @@ class TestBigchainApi(object): @pytest.mark.usefixtures('inputs') def test_read_transaction(self, b, user_pk, user_sk): + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction input_tx = b.get_owned_ids(user_pk).pop() input_tx = b.get_transaction(input_tx.txid) inputs = input_tx.to_inputs() - tx = Transaction.transfer(inputs, [([user_pk], 1)], input_tx.asset) + tx = Transaction.transfer(inputs, [([user_pk], 1)], + AssetLink(input_tx.id)) tx = tx.sign([user_sk]) b.write_transaction(tx) @@ -219,12 +227,14 @@ class TestBigchainApi(object): @pytest.mark.usefixtures('inputs') def test_read_transaction_invalid_block(self, b, user_pk, user_sk): + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction input_tx = b.get_owned_ids(user_pk).pop() input_tx = b.get_transaction(input_tx.txid) inputs = input_tx.to_inputs() - tx = Transaction.transfer(inputs, [([user_pk], 1)], input_tx.asset) + tx = Transaction.transfer(inputs, [([user_pk], 1)], + AssetLink(input_tx.id)) tx = tx.sign([user_sk]) # There's no need to b.write_transaction(tx) to the backlog @@ -243,12 +253,14 @@ class TestBigchainApi(object): @pytest.mark.usefixtures('inputs') def test_read_transaction_invalid_block_and_backlog(self, b, user_pk, user_sk): + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction input_tx = b.get_owned_ids(user_pk).pop() input_tx = b.get_transaction(input_tx.txid) inputs = input_tx.to_inputs() - tx = Transaction.transfer(inputs, [([user_pk], 1)], input_tx.asset) + tx = Transaction.transfer(inputs, [([user_pk], 1)], + AssetLink(input_tx.id)) tx = tx.sign([user_sk]) # Make sure there's a copy of tx in the backlog @@ -482,12 +494,14 @@ class TestBigchainApi(object): @pytest.mark.usefixtures('inputs') def test_assign_transaction_one_node(self, b, user_pk, user_sk): from bigchaindb.backend import query + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction input_tx = b.get_owned_ids(user_pk).pop() input_tx = b.get_transaction(input_tx.txid) inputs = input_tx.to_inputs() - tx = Transaction.transfer(inputs, [([user_pk], 1)], input_tx.asset) + tx = Transaction.transfer(inputs, [([user_pk], 1)], + AssetLink(input_tx.id)) tx = tx.sign([user_sk]) b.write_transaction(tx) @@ -501,6 +515,7 @@ class TestBigchainApi(object): def test_assign_transaction_multiple_nodes(self, b, user_pk, user_sk): from bigchaindb.backend import query from bigchaindb.common.crypto import generate_key_pair + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction # create 5 federation nodes @@ -512,7 +527,9 @@ class TestBigchainApi(object): input_tx = b.get_owned_ids(user_pk).pop() input_tx = b.get_transaction(input_tx.txid) inputs = input_tx.to_inputs() - tx = Transaction.transfer(inputs, [([user_pk], 1)], input_tx.asset) + tx = Transaction.transfer(inputs, [([user_pk], 1)], + asset_link=AssetLink(input_tx.id), + metadata={'msg': random.random()}) tx = tx.sign([user_sk]) b.write_transaction(tx) @@ -527,7 +544,7 @@ class TestBigchainApi(object): def test_non_create_input_not_found(self, b, user_pk): from cryptoconditions import Ed25519Fulfillment from bigchaindb.common.exceptions import TransactionDoesNotExist - from bigchaindb.common.transaction import (Fulfillment, Asset, + from bigchaindb.common.transaction import (AssetLink, Fulfillment, TransactionLink) from bigchaindb.models import Transaction from bigchaindb import Bigchain @@ -536,7 +553,8 @@ class TestBigchainApi(object): fulfillment = Fulfillment(Ed25519Fulfillment(public_key=user_pk), [user_pk], TransactionLink('somethingsomething', 0)) - tx = Transaction.transfer([fulfillment], [([user_pk], 1)], Asset()) + tx = Transaction.transfer([fulfillment], [([user_pk], 1)], + AssetLink('mock_asset_link')) with pytest.raises(TransactionDoesNotExist): tx.validate(Bigchain()) @@ -546,8 +564,9 @@ class TestBigchainApi(object): from bigchaindb.models import Transaction for _ in range(4): - tx = Transaction.create([b.me], - [([user_pk], 1)]).sign([b.me_private]) + tx = Transaction.create([b.me], [([user_pk], 1)], + metadata={'msg': random.random()}) \ + .sign([b.me_private]) b.write_transaction(tx) assert query.count_backlog(b.connection) == 4 @@ -585,6 +604,7 @@ class TestTransactionValidation(object): def test_non_create_valid_input_wrong_owner(self, b, user_pk): from bigchaindb.common.crypto import generate_key_pair from bigchaindb.common.exceptions import InvalidSignature + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction input_tx = b.get_owned_ids(user_pk).pop() @@ -592,7 +612,7 @@ class TestTransactionValidation(object): sk, pk = generate_key_pair() tx = Transaction.create([pk], [([user_pk], 1)]) tx.operation = 'TRANSFER' - tx.asset = input_transaction.asset + tx.asset = AssetLink(input_transaction.id) tx.fulfillments[0].tx_input = input_tx with pytest.raises(InvalidSignature): @@ -629,13 +649,14 @@ class TestTransactionValidation(object): def test_valid_non_create_transaction_after_block_creation(self, b, user_pk, user_sk): + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction input_tx = b.get_owned_ids(user_pk).pop() input_tx = b.get_transaction(input_tx.txid) inputs = input_tx.to_inputs() transfer_tx = Transaction.transfer(inputs, [([user_pk], 1)], - input_tx.asset) + AssetLink(input_tx.id)) transfer_tx = transfer_tx.sign([user_sk]) assert transfer_tx == b.validate_transaction(transfer_tx) @@ -653,6 +674,7 @@ class TestTransactionValidation(object): def test_transaction_not_in_valid_block(self, b, user_pk, user_sk): from bigchaindb.models import Transaction from bigchaindb.common.exceptions import TransactionNotInValidBlock + from bigchaindb.common.transaction import AssetLink input_tx = b.get_owned_ids(user_pk).pop() input_tx = b.get_transaction(input_tx.txid) @@ -660,7 +682,7 @@ class TestTransactionValidation(object): # create a transaction that's valid but not in a voted valid block transfer_tx = Transaction.transfer(inputs, [([user_pk], 1)], - input_tx.asset) + AssetLink(input_tx.id)) transfer_tx = transfer_tx.sign([user_sk]) assert transfer_tx == b.validate_transaction(transfer_tx) @@ -672,7 +694,7 @@ class TestTransactionValidation(object): # create transaction with the undecided input tx_invalid = Transaction.transfer(transfer_tx.to_inputs(), [([user_pk], 1)], - transfer_tx.asset) + AssetLink(transfer_tx.asset.id)) tx_invalid = tx_invalid.sign([user_sk]) with pytest.raises(TransactionNotInValidBlock): @@ -766,13 +788,15 @@ class TestMultipleInputs(object): def test_transfer_single_owner_single_input(self, b, inputs, user_pk, user_sk): from bigchaindb.common import crypto + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction user2_sk, user2_pk = crypto.generate_key_pair() tx_link = b.get_owned_ids(user_pk).pop() input_tx = b.get_transaction(tx_link.txid) inputs = input_tx.to_inputs() - tx = Transaction.transfer(inputs, [([user2_pk], 1)], input_tx.asset) + tx = Transaction.transfer(inputs, [([user2_pk], 1)], + AssetLink(input_tx.id)) tx = tx.sign([user_sk]) # validate transaction @@ -785,6 +809,7 @@ class TestMultipleInputs(object): user_pk, inputs): from bigchaindb.common import crypto + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction user2_sk, user2_pk = crypto.generate_key_pair() @@ -794,7 +819,8 @@ class TestMultipleInputs(object): tx_link = owned_inputs.pop() input_tx = b.get_transaction(tx_link.txid) tx = Transaction.transfer(input_tx.to_inputs(), - [([user2_pk, user3_pk], 1)], input_tx.asset) + [([user2_pk, user3_pk], 1)], + AssetLink(input_tx.id)) tx = tx.sign([user_sk]) assert b.is_valid_transaction(tx) == tx @@ -806,6 +832,7 @@ class TestMultipleInputs(object): user_sk, user_pk): from bigchaindb.common import crypto + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction user2_sk, user2_pk = crypto.generate_key_pair() @@ -825,7 +852,7 @@ class TestMultipleInputs(object): inputs = input_tx.to_inputs() transfer_tx = Transaction.transfer(inputs, [([user3_pk], 1)], - input_tx.asset) + AssetLink(input_tx.id)) transfer_tx = transfer_tx.sign([user_sk, user2_sk]) # validate transaction @@ -838,6 +865,7 @@ class TestMultipleInputs(object): user_sk, user_pk): from bigchaindb.common import crypto + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction user2_sk, user2_pk = crypto.generate_key_pair() @@ -858,7 +886,8 @@ class TestMultipleInputs(object): tx_input = b.get_transaction(tx_link.txid) tx = Transaction.transfer(tx_input.to_inputs(), - [([user3_pk, user4_pk], 1)], tx_input.asset) + [([user3_pk, user4_pk], 1)], + AssetLink(tx_input.id)) tx = tx.sign([user_sk, user2_sk]) assert b.is_valid_transaction(tx) == tx @@ -868,7 +897,7 @@ class TestMultipleInputs(object): @pytest.mark.usefixtures('setup_database') def test_get_owned_ids_single_tx_single_output(self, b, user_sk, user_pk): from bigchaindb.common import crypto - from bigchaindb.common.transaction import TransactionLink + from bigchaindb.common.transaction import AssetLink, TransactionLink from bigchaindb.models import Transaction user2_sk, user2_pk = crypto.generate_key_pair() @@ -883,7 +912,8 @@ class TestMultipleInputs(object): assert owned_inputs_user1 == [TransactionLink(tx.id, 0)] assert owned_inputs_user2 == [] - tx = Transaction.transfer(tx.to_inputs(), [([user2_pk], 1)], tx.asset) + tx = Transaction.transfer(tx.to_inputs(), [([user2_pk], 1)], + AssetLink(tx.id)) tx = tx.sign([user_sk]) block = b.create_block([tx]) b.write_block(block) @@ -898,7 +928,7 @@ class TestMultipleInputs(object): user_sk, user_pk): from bigchaindb.common import crypto - from bigchaindb.common.transaction import TransactionLink + from bigchaindb.common.transaction import AssetLink, TransactionLink from bigchaindb.models import Transaction genesis = b.create_genesis_block() @@ -921,7 +951,7 @@ class TestMultipleInputs(object): # NOTE: The transaction itself is valid, still will mark the block # as invalid to mock the behavior. tx_invalid = Transaction.transfer(tx.to_inputs(), [([user2_pk], 1)], - tx.asset) + AssetLink(tx.id)) tx_invalid = tx_invalid.sign([user_sk]) block = b.create_block([tx_invalid]) b.write_block(block) @@ -941,7 +971,8 @@ class TestMultipleInputs(object): def test_get_owned_ids_single_tx_multiple_outputs(self, b, user_sk, user_pk): from bigchaindb.common import crypto - from bigchaindb.common.transaction import TransactionLink, Asset + from bigchaindb.common.transaction import (TransactionLink, Asset, + AssetLink) from bigchaindb.models import Transaction user2_sk, user2_pk = crypto.generate_key_pair() @@ -967,7 +998,7 @@ class TestMultipleInputs(object): # transfer divisible asset divided in two outputs tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([user2_pk], 1), ([user2_pk], 1)], - asset=tx_create.asset) + asset_link=AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) block = b.create_block([tx_transfer_signed]) b.write_block(block) @@ -981,7 +1012,7 @@ class TestMultipleInputs(object): @pytest.mark.usefixtures('setup_database') def test_get_owned_ids_multiple_owners(self, b, user_sk, user_pk): from bigchaindb.common import crypto - from bigchaindb.common.transaction import TransactionLink + from bigchaindb.common.transaction import AssetLink, TransactionLink from bigchaindb.models import Transaction user2_sk, user2_pk = crypto.generate_key_pair() @@ -999,7 +1030,8 @@ class TestMultipleInputs(object): assert owned_inputs_user1 == owned_inputs_user2 assert owned_inputs_user1 == expected_owned_inputs_user1 - tx = Transaction.transfer(tx.to_inputs(), [([user3_pk], 1)], tx.asset) + tx = Transaction.transfer(tx.to_inputs(), [([user3_pk], 1)], + AssetLink(tx.id)) tx = tx.sign([user_sk, user2_sk]) block = b.create_block([tx]) b.write_block(block) @@ -1012,6 +1044,7 @@ class TestMultipleInputs(object): @pytest.mark.usefixtures('setup_database') def test_get_spent_single_tx_single_output(self, b, user_sk, user_pk): from bigchaindb.common import crypto + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction user2_sk, user2_pk = crypto.generate_key_pair() @@ -1030,7 +1063,8 @@ class TestMultipleInputs(object): assert spent_inputs_user1 is None # create a transaction and block - tx = Transaction.transfer(tx.to_inputs(), [([user2_pk], 1)], tx.asset) + tx = Transaction.transfer(tx.to_inputs(), [([user2_pk], 1)], + AssetLink(tx.id)) tx = tx.sign([user_sk]) block = b.create_block([tx]) b.write_block(block) @@ -1041,6 +1075,7 @@ class TestMultipleInputs(object): @pytest.mark.usefixtures('setup_database') def test_get_spent_single_tx_single_output_invalid_block(self, b, user_sk, user_pk): from bigchaindb.common import crypto + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction genesis = b.create_genesis_block() @@ -1066,7 +1101,8 @@ class TestMultipleInputs(object): assert spent_inputs_user1 is None # create a transaction and block - tx = Transaction.transfer(tx.to_inputs(), [([user2_pk], 1)], tx.asset) + tx = Transaction.transfer(tx.to_inputs(), [([user2_pk], 1)], + AssetLink(tx.id)) tx = tx.sign([user_sk]) block = b.create_block([tx]) b.write_block(block) @@ -1084,8 +1120,8 @@ class TestMultipleInputs(object): @pytest.mark.usefixtures('setup_database') def test_get_spent_single_tx_multiple_outputs(self, b, user_sk, user_pk): from bigchaindb.common import crypto + from bigchaindb.common.transaction import Asset, AssetLink from bigchaindb.models import Transaction - from bigchaindb.common.transaction import Asset # create a new users user2_sk, user2_pk = crypto.generate_key_pair() @@ -1110,7 +1146,7 @@ class TestMultipleInputs(object): # transfer the first 2 inputs tx_transfer = Transaction.transfer(tx_create.to_inputs()[:2], [([user2_pk], 1), ([user2_pk], 1)], - asset=tx_create.asset) + asset_link=AssetLink(tx_create.id)) tx_transfer_signed = tx_transfer.sign([user_sk]) block = b.create_block([tx_transfer_signed]) b.write_block(block) @@ -1126,8 +1162,8 @@ class TestMultipleInputs(object): @pytest.mark.usefixtures('setup_database') def test_get_spent_multiple_owners(self, b, user_sk, user_pk): - import random from bigchaindb.common import crypto + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction user2_sk, user2_pk = crypto.generate_key_pair() @@ -1151,7 +1187,8 @@ class TestMultipleInputs(object): # create a transaction tx = Transaction.transfer(transactions[0].to_inputs(), - [([user3_pk], 1)], transactions[0].asset) + [([user3_pk], 1)], + AssetLink(transactions[0].id)) tx = tx.sign([user_sk, user2_sk]) block = b.create_block([tx]) b.write_block(block) diff --git a/tests/pipelines/test_block_creation.py b/tests/pipelines/test_block_creation.py index 85ca1d0d..85fa2d37 100644 --- a/tests/pipelines/test_block_creation.py +++ b/tests/pipelines/test_block_creation.py @@ -1,3 +1,4 @@ +import random import time from unittest.mock import patch @@ -44,8 +45,9 @@ def test_create_block(b, user_pk): block_maker = BlockPipeline() - for i in range(100): - tx = Transaction.create([b.me], [([user_pk], 1)]) + for _ in range(100): + tx = Transaction.create([b.me], [([user_pk], 1)], + metadata={'msg': random.random()}) tx = tx.sign([b.me_private]) block_maker.create(tx) @@ -63,8 +65,9 @@ def test_write_block(b, user_pk): block_maker = BlockPipeline() txs = [] - for i in range(100): - tx = Transaction.create([b.me], [([user_pk], 1)]) + for _ in range(100): + tx = Transaction.create([b.me], [([user_pk], 1)], + metadata={'msg': random.random()}) tx = tx.sign([b.me_private]) txs.append(tx) @@ -83,8 +86,9 @@ def test_duplicate_transaction(b, user_pk): block_maker = block.BlockPipeline() txs = [] - for i in range(10): - tx = Transaction.create([b.me], [([user_pk], 1)]) + for _ in range(10): + tx = Transaction.create([b.me], [([user_pk], 1)], + metadata={'msg': random.random()}) tx = tx.sign([b.me_private]) txs.append(tx) @@ -114,7 +118,8 @@ def test_delete_tx(b, user_pk): from bigchaindb.pipelines.block import BlockPipeline block_maker = BlockPipeline() for i in range(100): - tx = Transaction.create([b.me], [([user_pk], 1)]) + tx = Transaction.create([b.me], [([user_pk], 1)], + metadata={'msg': random.random()}) tx = tx.sign([b.me_private]) block_maker.create(tx) # make sure the tx appears in the backlog @@ -150,10 +155,8 @@ def test_start(create_pipeline): @pytest.mark.usefixtures('setup_database') def test_full_pipeline(b, user_pk): - import random - from bigchaindb.backend import query from bigchaindb.models import Block, Transaction - from bigchaindb.pipelines.block import create_pipeline, get_changefeed + from bigchaindb.pipelines.block import create_pipeline outpipe = Pipe() @@ -166,7 +169,7 @@ def test_full_pipeline(b, user_pk): number_assigned_to_others = 0 for i in range(100): tx = Transaction.create([b.me], [([user_pk], 1)], - {'msg': random.random()}) + metadata={'msg': random.random()}) tx = tx.sign([b.me_private]) tx = tx.to_dict() diff --git a/tests/pipelines/test_stale_monitor.py b/tests/pipelines/test_stale_monitor.py index a39447bf..6e35f0ba 100644 --- a/tests/pipelines/test_stale_monitor.py +++ b/tests/pipelines/test_stale_monitor.py @@ -1,9 +1,10 @@ +import os +import random from bigchaindb import Bigchain from bigchaindb.pipelines import stale from multipipes import Pipe, Pipeline from unittest.mock import patch from bigchaindb import config_utils -import os import pytest @@ -89,7 +90,8 @@ def test_full_pipeline(monkeypatch, user_pk): monkeypatch.setattr('time.time', lambda: 1) for i in range(100): - tx = Transaction.create([b.me], [([user_pk], 1)]) + tx = Transaction.create([b.me], [([user_pk], 1)], + metadata={'msg': random.random()}) tx = tx.sign([b.me_private]) original_txc.append(tx.to_dict()) diff --git a/tests/pipelines/test_vote.py b/tests/pipelines/test_vote.py index ad45951a..f7db7d49 100644 --- a/tests/pipelines/test_vote.py +++ b/tests/pipelines/test_vote.py @@ -1,3 +1,4 @@ +import random import time from unittest.mock import patch @@ -5,9 +6,11 @@ from multipipes import Pipe, Pipeline import pytest +# TODO: dummy_tx and dummy_block could be fixtures def dummy_tx(b): from bigchaindb.models import Transaction - tx = Transaction.create([b.me], [([b.me], 1)]) + tx = Transaction.create([b.me], [([b.me], 1)], + metadata={'msg': random.random()}) tx = tx.sign([b.me_private]) return tx @@ -275,6 +278,7 @@ def test_valid_block_voting_with_create_transaction(b, monkeypatch): def test_valid_block_voting_with_transfer_transactions(monkeypatch, b): from bigchaindb.backend import query from bigchaindb.common import crypto, util + from bigchaindb.common.transaction import AssetLink from bigchaindb.models import Transaction from bigchaindb.pipelines import vote @@ -292,7 +296,7 @@ def test_valid_block_voting_with_transfer_transactions(monkeypatch, b): # create a `TRANSFER` transaction test_user2_priv, test_user2_pub = crypto.generate_key_pair() tx2 = Transaction.transfer(tx.to_inputs(), [([test_user2_pub], 1)], - tx.asset) + AssetLink(tx.id)) tx2 = tx2.sign([test_user_priv]) monkeypatch.setattr('time.time', lambda: 2222222222) diff --git a/tests/web/test_transactions.py b/tests/web/test_transactions.py index 8664d0e1..743843dd 100644 --- a/tests/web/test_transactions.py +++ b/tests/web/test_transactions.py @@ -124,13 +124,15 @@ def test_post_invalid_transaction(client, exc, msg, monkeypatch): def test_post_transfer_transaction_endpoint(b, client, user_pk, user_sk): sk, pk = crypto.generate_key_pair() from bigchaindb.models import Transaction + from bigchaindb.common.transaction import AssetLink user_priv, user_pub = crypto.generate_key_pair() input_valid = b.get_owned_ids(user_pk).pop() create_tx = b.get_transaction(input_valid.txid) transfer_tx = Transaction.transfer(create_tx.to_inputs(), - [([user_pub], 1)], create_tx.asset) + [([user_pub], 1)], + AssetLink(create_tx.id)) transfer_tx = transfer_tx.sign([user_sk]) res = client.post(TX_ENDPOINT, data=json.dumps(transfer_tx.to_dict())) @@ -142,13 +144,15 @@ def test_post_transfer_transaction_endpoint(b, client, user_pk, user_sk): @pytest.mark.usefixtures('inputs') def test_post_invalid_transfer_transaction_returns_400(b, client, user_pk, user_sk): from bigchaindb.models import Transaction + from bigchaindb.common.transaction import AssetLink user_priv, user_pub = crypto.generate_key_pair() input_valid = b.get_owned_ids(user_pk).pop() create_tx = b.get_transaction(input_valid.txid) transfer_tx = Transaction.transfer(create_tx.to_inputs(), - [([user_pub], 1)], create_tx.asset) + [([user_pub], 1)], + AssetLink(create_tx.id)) res = client.post(TX_ENDPOINT, data=json.dumps(transfer_tx.to_dict())) assert res.status_code == 400