mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Remove Asset and AssetLink (#982)
* Remove asset.validate_asset and move its validation checks to other areas * Move Asset.get_asset_id to Transaction * Remove Asset and AssetLink models * Add test against creating TRANSFER transactions with bad asset
This commit is contained in:
parent
44391da94a
commit
9319583ab4
@ -221,9 +221,12 @@ class Condition(object):
|
||||
"""
|
||||
if not isinstance(owners_after, list) and owners_after is not None:
|
||||
raise TypeError('`owners_after` must be a list instance or None')
|
||||
if not isinstance(amount, int):
|
||||
raise TypeError('`amount` must be an int')
|
||||
if amount < 1:
|
||||
raise AmountError('`amount` must be greater than 0')
|
||||
|
||||
self.fulfillment = fulfillment
|
||||
# TODO: Not sure if we should validate for value here
|
||||
self.amount = amount
|
||||
self.owners_after = owners_after
|
||||
|
||||
@ -378,147 +381,6 @@ class Condition(object):
|
||||
return cls(fulfillment, cond['owners_after'], cond['amount'])
|
||||
|
||||
|
||||
class Asset(object):
|
||||
"""An Asset is a fungible unit to spend and lock with Transactions.
|
||||
|
||||
Attributes:
|
||||
data (dict): A dictionary of data that can be added to an Asset.
|
||||
"""
|
||||
|
||||
def __init__(self, data=None):
|
||||
"""An Asset is not required to contain any extra data from outside."""
|
||||
self.data = data
|
||||
self.validate_asset()
|
||||
|
||||
def __eq__(self, other):
|
||||
try:
|
||||
other_dict = other.to_dict()
|
||||
except AttributeError:
|
||||
return False
|
||||
return self.to_dict() == other_dict
|
||||
|
||||
def to_dict(self):
|
||||
"""Transforms the object to a Python dictionary.
|
||||
|
||||
Returns:
|
||||
(dict): The Asset object as an alternative serialization
|
||||
format.
|
||||
"""
|
||||
return {
|
||||
'data': self.data,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, asset):
|
||||
"""Transforms a Python dictionary to an Asset object.
|
||||
|
||||
Args:
|
||||
asset (dict): The dictionary to be serialized.
|
||||
|
||||
Returns:
|
||||
:class:`~bigchaindb.common.transaction.Asset`
|
||||
"""
|
||||
return cls(asset.get('data'))
|
||||
|
||||
@staticmethod
|
||||
def get_asset_id(transactions):
|
||||
"""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`): A list of Transactions.
|
||||
Usually input Transactions that should have a matching
|
||||
asset ID.
|
||||
|
||||
Returns:
|
||||
str: ID of the asset.
|
||||
|
||||
Raises:
|
||||
:exc:`AssetIdMismatch`: If the inputs are related to different
|
||||
assets.
|
||||
"""
|
||||
|
||||
if not isinstance(transactions, list):
|
||||
transactions = [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
|
||||
if len(asset_ids) > 1:
|
||||
raise AssetIdMismatch(('All inputs of all transactions passed'
|
||||
' need to have the same asset id'))
|
||||
return asset_ids.pop()
|
||||
|
||||
def validate_asset(self, amount=None):
|
||||
"""Validates the asset"""
|
||||
if self.data is not None and not isinstance(self.data, dict):
|
||||
raise TypeError('`data` must be a dict instance or None')
|
||||
|
||||
# If the amount is supplied we can perform extra validations to
|
||||
# the asset
|
||||
if amount is not None:
|
||||
if not isinstance(amount, int):
|
||||
raise TypeError('`amount` must be an int')
|
||||
|
||||
if amount < 1:
|
||||
raise AmountError('`amount` must be greater than 0')
|
||||
|
||||
|
||||
class AssetLink(object):
|
||||
"""An object for unidirectional linking to a Asset.
|
||||
"""
|
||||
|
||||
def __init__(self, asset_id=None):
|
||||
"""Used to point to a specific Asset.
|
||||
|
||||
Args:
|
||||
asset_id (str): The ID of an asset to link to.
|
||||
"""
|
||||
self.id = asset_id
|
||||
|
||||
def __bool__(self):
|
||||
return self.id is not None
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, AssetLink) and \
|
||||
self.to_dict() == other.to_dict()
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, link):
|
||||
"""Transforms a Python dictionary to a AssetLink object.
|
||||
|
||||
Args:
|
||||
link (dict): The link to be transformed.
|
||||
|
||||
Returns:
|
||||
:class:`~bigchaindb.common.transaction.AssetLink`
|
||||
"""
|
||||
try:
|
||||
return cls(link['id'])
|
||||
except TypeError:
|
||||
return cls()
|
||||
|
||||
def to_dict(self):
|
||||
"""Transforms the object to a Python dictionary.
|
||||
|
||||
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.id is None:
|
||||
return None
|
||||
else:
|
||||
return {
|
||||
'id': self.id
|
||||
}
|
||||
|
||||
|
||||
class Transaction(object):
|
||||
"""A Transaction is used to create and transfer assets.
|
||||
|
||||
@ -533,10 +395,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.
|
||||
asset (dict): Asset payload for this Transaction. ``CREATE`` and
|
||||
``GENESIS`` Transactions require a dict with a ``data``
|
||||
property while ``TRANSFER`` Transactions require a dict with a
|
||||
``id`` property.
|
||||
metadata (dict):
|
||||
Metadata to be stored along with the Transaction.
|
||||
version (int): Defines the version number of a Transaction.
|
||||
@ -557,35 +419,33 @@ class Transaction(object):
|
||||
|
||||
Args:
|
||||
operation (str): Defines the operation of the Transaction.
|
||||
asset (:class:`~.Asset`|:class:`~.AssetLink`): An Asset to be
|
||||
created or an AssetLink linking an asset to be transferred.
|
||||
asset (dict): Asset payload for this Transaction.
|
||||
fulfillments (:obj:`list` of :class:`~bigchaindb.common.
|
||||
transaction.Fulfillment`, optional): Define the assets to
|
||||
spend.
|
||||
conditions (:obj:`list` of :class:`~bigchaindb.common.
|
||||
transaction.Condition`, optional): Define the assets to
|
||||
lock.
|
||||
metadata (dict):
|
||||
Metadata to be stored along with the Transaction.
|
||||
metadata (dict): Metadata to be stored along with the
|
||||
Transaction.
|
||||
version (int): Defines the version number of a Transaction.
|
||||
|
||||
"""
|
||||
if operation not in Transaction.ALLOWED_OPERATIONS:
|
||||
allowed_ops = ', '.join(self.__class__.ALLOWED_OPERATIONS)
|
||||
raise ValueError('`operation` must be one of {}'
|
||||
.format(allowed_ops))
|
||||
|
||||
# Assets for 'CREATE' and 'GENESIS' operations must be None or of Asset
|
||||
# type and Assets for 'TRANSFER' operations must be of AssetLink type.
|
||||
# Asset payloads for 'CREATE' and 'GENESIS' operations must be None or
|
||||
# dicts holding a `data` property. Asset payloads for 'TRANSFER'
|
||||
# operations must be dicts holding an `id` property.
|
||||
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)))
|
||||
asset is not None and not (isinstance(asset, dict) and 'data' in asset)):
|
||||
raise TypeError(('`asset` must be None or a dict holding a `data` '
|
||||
" property 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)))
|
||||
not (isinstance(asset, dict) and 'id' in asset)):
|
||||
raise TypeError(('`asset` must be a dict holding an `id` property '
|
||||
"for 'TRANSFER' Transactions".format(operation)))
|
||||
|
||||
if conditions and not isinstance(conditions, list):
|
||||
raise TypeError('`conditions` must be a list instance or None')
|
||||
@ -598,20 +458,11 @@ class Transaction(object):
|
||||
|
||||
self.version = version if version is not None else self.VERSION
|
||||
self.operation = operation
|
||||
self.asset = asset or Asset()
|
||||
self.asset = asset
|
||||
self.conditions = conditions or []
|
||||
self.fulfillments = fulfillments or []
|
||||
self.metadata = metadata
|
||||
|
||||
# validate asset
|
||||
# we know that each transaction relates to a single asset
|
||||
# we can sum the amount of all the conditions
|
||||
# for transactions other then CREATE we only have an id so there is
|
||||
# nothing we can validate
|
||||
if self.operation == self.CREATE:
|
||||
amount = sum([condition.amount for condition in self.conditions])
|
||||
self.asset.validate_asset(amount=amount)
|
||||
|
||||
@classmethod
|
||||
def create(cls, owners_before, owners_after, metadata=None, asset=None):
|
||||
"""A simple way to generate a `CREATE` transaction.
|
||||
@ -631,10 +482,10 @@ class Transaction(object):
|
||||
represent the creators of this asset.
|
||||
owners_after (:obj:`list` of :obj:`str`): A list of keys that
|
||||
represent the receivers of this Transaction.
|
||||
metadata (dict): Python dictionary to be stored along with the
|
||||
metadata (dict): The metadata to be stored along with the
|
||||
Transaction.
|
||||
asset (:class:`~bigchaindb.common.transaction.Asset`): An Asset
|
||||
to be created in this Transaction.
|
||||
asset (dict): The metadata associated with the asset that will
|
||||
be created in this Transaction.
|
||||
|
||||
Returns:
|
||||
:class:`~bigchaindb.common.transaction.Transaction`
|
||||
@ -647,6 +498,8 @@ class Transaction(object):
|
||||
raise ValueError('`owners_before` list cannot be empty')
|
||||
if len(owners_after) == 0:
|
||||
raise ValueError('`owners_after` list cannot be empty')
|
||||
if not (asset is None or isinstance(asset, dict)):
|
||||
raise TypeError('`asset` must be a dict or None')
|
||||
|
||||
fulfillments = []
|
||||
conditions = []
|
||||
@ -663,10 +516,10 @@ class Transaction(object):
|
||||
# generate fulfillments
|
||||
fulfillments.append(Fulfillment.generate(owners_before))
|
||||
|
||||
return cls(cls.CREATE, asset, fulfillments, conditions, metadata)
|
||||
return cls(cls.CREATE, {'data': asset}, fulfillments, conditions, metadata)
|
||||
|
||||
@classmethod
|
||||
def transfer(cls, inputs, owners_after, asset_link, metadata=None):
|
||||
def transfer(cls, inputs, owners_after, asset_id, metadata=None):
|
||||
"""A simple way to generate a `TRANSFER` transaction.
|
||||
|
||||
Note:
|
||||
@ -696,9 +549,8 @@ class Transaction(object):
|
||||
generate.
|
||||
owners_after (:obj:`list` of :obj:`str`): A list of keys that
|
||||
represent the receivers of this Transaction.
|
||||
asset_link (:class:`~bigchaindb.common.transaction.AssetLink`):
|
||||
An AssetLink linking an asset to be transferred in this
|
||||
Transaction.
|
||||
asset_id (str): The asset ID of the asset to be transferred in
|
||||
this Transaction.
|
||||
metadata (dict): Python dictionary to be stored along with the
|
||||
Transaction.
|
||||
|
||||
@ -713,6 +565,8 @@ class Transaction(object):
|
||||
raise TypeError('`owners_after` must be a list instance')
|
||||
if len(owners_after) == 0:
|
||||
raise ValueError('`owners_after` list cannot be empty')
|
||||
if not isinstance(asset_id, str):
|
||||
raise TypeError('`asset_id` must be a string')
|
||||
|
||||
conditions = []
|
||||
for owner_after in owners_after:
|
||||
@ -724,7 +578,7 @@ class Transaction(object):
|
||||
conditions.append(Condition.generate(pub_keys, amount))
|
||||
|
||||
inputs = deepcopy(inputs)
|
||||
return cls(cls.TRANSFER, asset_link, inputs, conditions, metadata)
|
||||
return cls(cls.TRANSFER, {'id': asset_id}, inputs, conditions, metadata)
|
||||
|
||||
def __eq__(self, other):
|
||||
try:
|
||||
@ -1071,7 +925,7 @@ class Transaction(object):
|
||||
in self.conditions],
|
||||
'operation': str(self.operation),
|
||||
'metadata': self.metadata,
|
||||
'asset': self.asset.to_dict(),
|
||||
'asset': self.asset,
|
||||
'version': self.version,
|
||||
}
|
||||
|
||||
@ -1125,6 +979,40 @@ class Transaction(object):
|
||||
tx = Transaction._remove_signatures(self.to_dict())
|
||||
return Transaction._to_str(tx)
|
||||
|
||||
@staticmethod
|
||||
def get_asset_id(transactions):
|
||||
"""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`): A list of Transactions.
|
||||
Usually input Transactions that should have a matching
|
||||
asset ID.
|
||||
|
||||
Returns:
|
||||
str: ID of the asset.
|
||||
|
||||
Raises:
|
||||
:exc:`AssetIdMismatch`: If the inputs are related to different
|
||||
assets.
|
||||
"""
|
||||
|
||||
if not isinstance(transactions, list):
|
||||
transactions = [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
|
||||
if len(asset_ids) > 1:
|
||||
raise AssetIdMismatch(('All inputs of all transactions passed'
|
||||
' need to have the same asset id'))
|
||||
return asset_ids.pop()
|
||||
|
||||
@staticmethod
|
||||
def validate_structure(tx_body):
|
||||
"""Validate the transaction ID of a transaction
|
||||
@ -1163,10 +1051,6 @@ class Transaction(object):
|
||||
in tx['fulfillments']]
|
||||
conditions = [Condition.from_dict(condition) for condition
|
||||
in tx['conditions']]
|
||||
if tx['operation'] in [cls.CREATE, cls.GENESIS]:
|
||||
asset = Asset.from_dict(tx['asset'])
|
||||
else:
|
||||
asset = AssetLink.from_dict(tx['asset'])
|
||||
|
||||
return cls(tx['operation'], asset, fulfillments, conditions,
|
||||
return cls(tx['operation'], tx['asset'], fulfillments, conditions,
|
||||
tx['metadata'], tx['version'])
|
||||
|
@ -6,7 +6,7 @@ from time import time
|
||||
from itertools import compress
|
||||
from bigchaindb.common import crypto, exceptions
|
||||
from bigchaindb.common.util import gen_timestamp, serialize
|
||||
from bigchaindb.common.transaction import TransactionLink, Asset
|
||||
from bigchaindb.common.transaction import TransactionLink
|
||||
|
||||
import bigchaindb
|
||||
|
||||
@ -348,13 +348,12 @@ class Bigchain(object):
|
||||
asset_id (str): The asset id.
|
||||
|
||||
Returns:
|
||||
:class:`~bigchaindb.common.transaction.Asset` if the asset
|
||||
exists else None.
|
||||
dict if the asset exists else None.
|
||||
"""
|
||||
cursor = backend.query.get_asset_by_id(self.connection, asset_id)
|
||||
cursor = list(cursor)
|
||||
if cursor:
|
||||
return Asset.from_dict(cursor[0]['asset'])
|
||||
return cursor[0]['asset']
|
||||
|
||||
def get_spent(self, txid, cid):
|
||||
"""Check if a `txid` was already used as an input.
|
||||
|
@ -4,7 +4,7 @@ from bigchaindb.common.exceptions import (InvalidHash, InvalidSignature,
|
||||
TransactionDoesNotExist,
|
||||
TransactionNotInValidBlock,
|
||||
AssetIdMismatch, AmountError)
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from bigchaindb.common.util import gen_timestamp, serialize
|
||||
from bigchaindb.common.schema import validate_transaction_schema
|
||||
|
||||
@ -39,21 +39,30 @@ class Transaction(Transaction):
|
||||
input_conditions = []
|
||||
inputs_defined = all([ffill.tx_input for ffill in self.fulfillments])
|
||||
|
||||
# validate amounts
|
||||
if any(condition.amount < 1 for condition in self.conditions):
|
||||
raise AmountError('`amount` needs to be greater than zero')
|
||||
|
||||
if self.operation in (Transaction.CREATE, Transaction.GENESIS):
|
||||
# validate asset
|
||||
if self.asset['data'] is not None and not isinstance(self.asset['data'], dict):
|
||||
raise TypeError(('`asset.data` must be a dict instance or '
|
||||
'None for `CREATE` transactions'))
|
||||
# validate inputs
|
||||
if inputs_defined:
|
||||
raise ValueError('A CREATE operation has no inputs')
|
||||
# validate asset
|
||||
amount = sum([condition.amount for condition in self.conditions])
|
||||
self.asset.validate_asset(amount=amount)
|
||||
elif self.operation == Transaction.TRANSFER:
|
||||
# validate asset
|
||||
if not isinstance(self.asset['id'], str):
|
||||
raise ValueError(('`asset.id` must be a string for '
|
||||
'`TRANSFER` transations'))
|
||||
# check inputs
|
||||
if not inputs_defined:
|
||||
raise ValueError('Only `CREATE` transactions can have null '
|
||||
'inputs')
|
||||
# check inputs
|
||||
|
||||
# store the inputs so that we can check if the asset ids match
|
||||
input_txs = []
|
||||
input_amount = 0
|
||||
for ffill in self.fulfillments:
|
||||
input_txid = ffill.tx_input.txid
|
||||
input_cid = ffill.tx_input.cid
|
||||
@ -74,29 +83,20 @@ class Transaction(Transaction):
|
||||
raise DoubleSpend('input `{}` was already spent'
|
||||
.format(input_txid))
|
||||
|
||||
input_conditions.append(input_tx.conditions[input_cid])
|
||||
input_condition = input_tx.conditions[input_cid]
|
||||
input_conditions.append(input_condition)
|
||||
|
||||
input_txs.append(input_tx)
|
||||
if input_tx.conditions[input_cid].amount < 1:
|
||||
raise AmountError('`amount` needs to be greater than zero')
|
||||
input_amount += input_tx.conditions[input_cid].amount
|
||||
|
||||
# validate asset id
|
||||
asset_id = Asset.get_asset_id(input_txs)
|
||||
if asset_id != self.asset.id:
|
||||
asset_id = Transaction.get_asset_id(input_txs)
|
||||
if asset_id != self.asset['id']:
|
||||
raise AssetIdMismatch(('The asset id of the input does not'
|
||||
' match the asset id of the'
|
||||
' transaction'))
|
||||
|
||||
# get the asset creation
|
||||
asset = bigchain.get_asset_by_id(asset_id)
|
||||
# validate the asset
|
||||
asset.validate_asset(amount=input_amount)
|
||||
# validate the amounts
|
||||
output_amount = 0
|
||||
for condition in self.conditions:
|
||||
if condition.amount < 1:
|
||||
raise AmountError('`amount` needs to be greater than zero')
|
||||
output_amount += condition.amount
|
||||
input_amount = sum([input_condition.amount for input_condition in input_conditions])
|
||||
output_amount = sum([output_condition.amount for output_condition in self.conditions])
|
||||
|
||||
if output_amount != input_amount:
|
||||
raise AmountError(('The amount used in the inputs `{}`'
|
||||
@ -111,8 +111,8 @@ class Transaction(Transaction):
|
||||
|
||||
if not self.fulfillments_valid(input_conditions):
|
||||
raise InvalidSignature()
|
||||
else:
|
||||
return self
|
||||
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, tx_body):
|
||||
|
@ -4,7 +4,7 @@ import json
|
||||
import os
|
||||
import os.path
|
||||
|
||||
from bigchaindb.common.transaction import Asset, Transaction
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
|
||||
|
||||
TPLS = {}
|
||||
@ -62,8 +62,7 @@ def main():
|
||||
""" Main function """
|
||||
privkey = 'CfdqtD7sS7FgkMoGPXw55MVGGFwQLAoHYTcBhZDtF99Z'
|
||||
pubkey = '4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD'
|
||||
asset = Asset(None)
|
||||
tx = Transaction.create([pubkey], [([pubkey], 1)], asset=asset)
|
||||
tx = Transaction.create([pubkey], [([pubkey], 1)])
|
||||
tx = tx.sign([privkey])
|
||||
tx_json = json.dumps(tx.to_dict(), indent=2, sort_keys=True)
|
||||
|
||||
|
@ -1,33 +1,31 @@
|
||||
import pytest
|
||||
import random
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
@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)],
|
||||
AssetLink(tx_create.id))
|
||||
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.id == tx_create.id
|
||||
assert tx_transfer_signed.asset['id'] == tx_create.id
|
||||
|
||||
|
||||
def test_validate_bad_asset_creation(b, user_pk):
|
||||
from bigchaindb.models import Transaction, Asset
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
# `data` needs to be a dictionary
|
||||
tx = Transaction.create([b.me], [([user_pk], 1)])
|
||||
tx.asset.data = 'a'
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx_signed = tx.sign([b.me_private])
|
||||
tx.asset['data'] = 'a'
|
||||
tx_signed = tx.sign([b.me_private])
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
b.validate_transaction(tx_signed)
|
||||
|
||||
@ -36,24 +34,23 @@ 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)],
|
||||
AssetLink(tx_create.id))
|
||||
tx_transfer.asset.id = 'aaa'
|
||||
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)
|
||||
|
||||
|
||||
def test_get_asset_id_create_transaction(b, user_pk):
|
||||
from bigchaindb.models import Transaction, Asset
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 1)])
|
||||
asset_id = Asset.get_asset_id(tx_create)
|
||||
asset_id = Transaction.get_asset_id(tx_create)
|
||||
|
||||
assert asset_id == tx_create.id
|
||||
|
||||
@ -61,14 +58,13 @@ def test_get_asset_id_create_transaction(b, user_pk):
|
||||
@pytest.mark.bdb
|
||||
@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
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
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)],
|
||||
AssetLink(tx_create.id))
|
||||
tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
# create a block
|
||||
block = b.create_block([tx_transfer_signed])
|
||||
@ -76,13 +72,13 @@ def test_get_asset_id_transfer_transaction(b, user_pk, user_sk):
|
||||
# vote the block valid
|
||||
vote = b.vote(block.id, b.get_last_voted_block().id, True)
|
||||
b.write_vote(vote)
|
||||
asset_id = Asset.get_asset_id(tx_transfer)
|
||||
asset_id = Transaction.get_asset_id(tx_transfer)
|
||||
|
||||
assert asset_id == tx_transfer.asset.id
|
||||
assert asset_id == tx_transfer.asset['id']
|
||||
|
||||
|
||||
def test_asset_id_mismatch(b, user_pk):
|
||||
from bigchaindb.models import Transaction, Asset
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.exceptions import AssetIdMismatch
|
||||
|
||||
tx1 = Transaction.create([b.me], [([user_pk], 1)],
|
||||
@ -91,13 +87,12 @@ def test_asset_id_mismatch(b, user_pk):
|
||||
metadata={'msg': random.random()})
|
||||
|
||||
with pytest.raises(AssetIdMismatch):
|
||||
Asset.get_asset_id([tx1, tx2])
|
||||
Transaction.get_asset_id([tx1, tx2])
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
@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()
|
||||
@ -111,7 +106,7 @@ def test_get_transactions_by_asset_id(b, user_pk, user_sk):
|
||||
|
||||
# create a transfer transaction
|
||||
tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([user_pk], 1)],
|
||||
AssetLink(tx_create.id))
|
||||
tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
# create the block
|
||||
block = b.create_block([tx_transfer_signed])
|
||||
@ -127,13 +122,12 @@ def test_get_transactions_by_asset_id(b, user_pk, user_sk):
|
||||
assert tx_transfer.id in [t.id for t in txs]
|
||||
# FIXME: can I rely on the ordering here?
|
||||
assert asset_id == txs[0].id
|
||||
assert asset_id == txs[1].asset.id
|
||||
assert asset_id == txs[1].asset['id']
|
||||
|
||||
|
||||
@pytest.mark.bdb
|
||||
@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()
|
||||
@ -147,7 +141,7 @@ def test_get_transactions_by_asset_id_with_invalid_block(b, user_pk, user_sk):
|
||||
|
||||
# create a transfer transaction
|
||||
tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([user_pk], 1)],
|
||||
AssetLink(tx_create.id))
|
||||
tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
# create the block
|
||||
block = b.create_block([tx_transfer_signed])
|
||||
@ -164,15 +158,14 @@ def test_get_transactions_by_asset_id_with_invalid_block(b, user_pk, user_sk):
|
||||
@pytest.mark.bdb
|
||||
@pytest.mark.usefixtures('inputs')
|
||||
def test_get_asset_by_id(b, user_pk, user_sk):
|
||||
from bigchaindb.common.transaction import AssetLink
|
||||
from bigchaindb.models import Asset, Transaction
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
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)],
|
||||
AssetLink(tx_create.id))
|
||||
tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
# create the block
|
||||
block = b.create_block([tx_transfer_signed])
|
||||
@ -181,7 +174,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])
|
||||
asset_id = Transaction.get_asset_id([tx_create, tx_transfer])
|
||||
txs = b.get_transactions_by_asset_id(asset_id)
|
||||
assert len(txs) == 2
|
||||
|
||||
@ -190,32 +183,21 @@ def test_get_asset_by_id(b, user_pk, user_sk):
|
||||
|
||||
|
||||
def test_create_invalid_divisible_asset(b, user_pk, user_sk):
|
||||
from bigchaindb.models import Transaction, Asset
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.exceptions import AmountError
|
||||
|
||||
# Asset amount must be more than 0
|
||||
asset = Asset()
|
||||
tx = Transaction.create([user_pk], [([user_pk], 1)], asset=asset)
|
||||
tx = Transaction.create([user_pk], [([user_pk], 1)])
|
||||
tx.conditions[0].amount = 0
|
||||
with pytest.raises(AmountError):
|
||||
tx.sign([user_sk])
|
||||
tx.sign([user_sk])
|
||||
|
||||
# even if a transaction is badly constructed the server should raise the
|
||||
# exception
|
||||
asset = Asset()
|
||||
tx = Transaction.create([user_pk], [([user_pk], 1)], asset=asset)
|
||||
tx.conditions[0].amount = 0
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx_signed = tx.sign([user_sk])
|
||||
with pytest.raises(AmountError):
|
||||
tx_signed.validate(b)
|
||||
assert b.is_valid_transaction(tx_signed) is False
|
||||
b.validate_transaction(tx)
|
||||
|
||||
|
||||
def test_create_valid_divisible_asset(b, user_pk, user_sk):
|
||||
from bigchaindb.models import Transaction, Asset
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
asset = Asset()
|
||||
tx = Transaction.create([user_pk], [([user_pk], 2)], asset=asset)
|
||||
tx = Transaction.create([user_pk], [([user_pk], 2)])
|
||||
tx_signed = tx.sign([user_sk])
|
||||
assert b.is_valid_transaction(tx_signed)
|
||||
|
@ -1,7 +1,5 @@
|
||||
import pytest
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
# CREATE divisible asset
|
||||
# Single input
|
||||
@ -10,10 +8,8 @@ from unittest.mock import patch
|
||||
# Single owners_after
|
||||
def test_single_in_single_own_single_out_single_own_create(b, user_pk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
asset = Asset()
|
||||
tx = Transaction.create([b.me], [([user_pk], 100)], asset=asset)
|
||||
tx = Transaction.create([b.me], [([user_pk], 100)])
|
||||
tx_signed = tx.sign([b.me_private])
|
||||
|
||||
assert tx_signed.validate(b) == tx_signed
|
||||
@ -29,11 +25,8 @@ def test_single_in_single_own_single_out_single_own_create(b, user_pk):
|
||||
# Single owners_after per output
|
||||
def test_single_in_single_own_multiple_out_single_own_create(b, user_pk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
asset = Asset()
|
||||
tx = Transaction.create([b.me], [([user_pk], 50), ([user_pk], 50)],
|
||||
asset=asset)
|
||||
tx = Transaction.create([b.me], [([user_pk], 50), ([user_pk], 50)])
|
||||
tx_signed = tx.sign([b.me_private])
|
||||
|
||||
assert tx_signed.validate(b) == tx_signed
|
||||
@ -50,10 +43,8 @@ def test_single_in_single_own_multiple_out_single_own_create(b, user_pk):
|
||||
# Multiple owners_after
|
||||
def test_single_in_single_own_single_out_multiple_own_create(b, user_pk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
asset = Asset()
|
||||
tx = Transaction.create([b.me], [([user_pk, user_pk], 100)], asset=asset)
|
||||
tx = Transaction.create([b.me], [([user_pk, user_pk], 100)])
|
||||
tx_signed = tx.sign([b.me_private])
|
||||
|
||||
assert tx_signed.validate(b) == tx_signed
|
||||
@ -75,12 +66,8 @@ def test_single_in_single_own_single_out_multiple_own_create(b, user_pk):
|
||||
# owners_after
|
||||
def test_single_in_single_own_multiple_out_mix_own_create(b, user_pk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
asset = Asset()
|
||||
tx = Transaction.create([b.me],
|
||||
[([user_pk], 50), ([user_pk, user_pk], 50)],
|
||||
asset=asset)
|
||||
tx = Transaction.create([b.me], [([user_pk], 50), ([user_pk, user_pk], 50)])
|
||||
tx_signed = tx.sign([b.me_private])
|
||||
|
||||
assert tx_signed.validate(b) == tx_signed
|
||||
@ -102,10 +89,8 @@ def test_single_in_single_own_multiple_out_mix_own_create(b, user_pk):
|
||||
def test_single_in_multiple_own_single_out_single_own_create(b, user_pk,
|
||||
user_sk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
asset = Asset()
|
||||
tx = Transaction.create([b.me, user_pk], [([user_pk], 100)], asset=asset)
|
||||
tx = Transaction.create([b.me, user_pk], [([user_pk], 100)])
|
||||
tx_signed = tx.sign([b.me_private, user_sk])
|
||||
assert tx_signed.validate(b) == tx_signed
|
||||
assert len(tx_signed.conditions) == 1
|
||||
@ -131,11 +116,9 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 100)], asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 100)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -147,7 +130,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b)
|
||||
@ -166,11 +149,9 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 100)], asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 100)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -183,7 +164,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
||||
@ -203,11 +184,9 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 100)], asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 100)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -220,7 +199,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
||||
@ -245,11 +224,9 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 100)], asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 100)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -262,7 +239,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
||||
@ -287,12 +264,9 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me], [([b.me, user_pk], 100)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([b.me, user_pk], 100)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -304,7 +278,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([b.me_private, user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
||||
@ -327,12 +301,9 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 50), ([user_pk], 50)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 50), ([user_pk], 50)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -344,7 +315,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b)
|
||||
@ -363,14 +334,9 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me],
|
||||
[([user_pk, b.me], 50),
|
||||
([user_pk, b.me], 50)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk, b.me], 50), ([user_pk, b.me], 50)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -382,7 +348,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([b.me_private, user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b)
|
||||
@ -409,14 +375,9 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me],
|
||||
[([user_pk], 50),
|
||||
([user_pk, b.me], 50)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 50), ([user_pk, b.me], 50)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -428,7 +389,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([b.me_private, user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
||||
@ -455,14 +416,9 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me],
|
||||
[([user_pk], 50),
|
||||
([user_pk, b.me], 50)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 50), ([user_pk, b.me], 50)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -475,7 +431,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([b.me_private, user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
||||
@ -506,16 +462,11 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset
|
||||
# `b` creates a divisible asset and assigns 50 shares to `b` and
|
||||
# 50 shares to `user_pk`
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me],
|
||||
[([user_pk], 50),
|
||||
([b.me], 50)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 50), ([b.me], 50)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -531,7 +482,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer1_signed = tx_transfer1.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_transfer1_signed])
|
||||
@ -547,7 +498,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer2_signed = tx_transfer2.sign([user_sk])
|
||||
|
||||
assert tx_transfer2_signed.validate(b) == tx_transfer2_signed
|
||||
@ -568,12 +519,10 @@ 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, AssetLink
|
||||
from bigchaindb.common.exceptions import AmountError
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 100)], asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 100)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -586,7 +535,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
with pytest.raises(AmountError):
|
||||
tx_transfer_signed.validate(b)
|
||||
@ -594,7 +543,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
with pytest.raises(AmountError):
|
||||
tx_transfer_signed.validate(b)
|
||||
@ -612,12 +561,9 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me], [([user_pk, user_pk], 100)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk, user_pk], 100)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -629,7 +575,7 @@ def test_threshold_same_public_key(b, user_pk, user_sk):
|
||||
|
||||
# TRANSFER
|
||||
tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([b.me], 100)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk, user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
||||
@ -639,15 +585,9 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset with 3 outputs with amount 1
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me],
|
||||
[([user_pk], 1),
|
||||
([user_pk], 1),
|
||||
([user_pk], 1)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 1), ([user_pk], 1), ([user_pk], 1)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -660,7 +600,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
||||
@ -672,12 +612,9 @@ 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, AssetLink
|
||||
|
||||
# CREATE divisible asset with 1 output with amount 3
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 3)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 3)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -691,7 +628,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
|
||||
assert tx_transfer_signed.validate(b) == tx_transfer_signed
|
||||
@ -705,13 +642,10 @@ 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, AssetLink
|
||||
from bigchaindb.common.exceptions import AmountError
|
||||
|
||||
# CREATE divisible asset with 1 output with amount 3
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 3)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 3)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -724,7 +658,7 @@ 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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
|
||||
|
||||
# Check that negative inputs are caught when validating a TRANSFER transaction
|
||||
@ -732,13 +666,10 @@ def test_non_positive_amounts_on_transfer(b, user_pk):
|
||||
@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, AssetLink
|
||||
from bigchaindb.common.exceptions import AmountError
|
||||
|
||||
# CREATE divisible asset with 1 output with amount 3
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 3)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 3)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
# create block
|
||||
block = b.create_block([tx_create_signed])
|
||||
@ -752,7 +683,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)],
|
||||
AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer.conditions[1].amount = -1
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
|
||||
@ -765,14 +696,11 @@ def test_non_positive_amounts_on_transfer_validate(b, user_pk, user_sk):
|
||||
@pytest.mark.usefixtures('inputs')
|
||||
def test_non_positive_amounts_on_create(b, user_pk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import Asset
|
||||
from bigchaindb.common.exceptions import AmountError
|
||||
|
||||
# CREATE divisible asset with 1 output with amount 3
|
||||
asset = Asset()
|
||||
with pytest.raises(AmountError):
|
||||
Transaction.create([b.me], [([user_pk], -3)],
|
||||
asset=asset)
|
||||
Transaction.create([b.me], [([user_pk], -3)])
|
||||
|
||||
|
||||
# Check that negative inputs are caught when validating a CREATE transaction
|
||||
@ -780,16 +708,12 @@ def test_non_positive_amounts_on_create(b, user_pk):
|
||||
@pytest.mark.usefixtures('inputs')
|
||||
def test_non_positive_amounts_on_create_validate(b, user_pk):
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb.common.transaction import Asset
|
||||
from bigchaindb.common.exceptions import AmountError
|
||||
|
||||
# CREATE divisible asset with 1 output with amount 3
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 3)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 3)])
|
||||
tx_create.conditions[0].amount = -3
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
|
||||
with pytest.raises(AmountError):
|
||||
tx_create_signed.validate(b)
|
||||
|
@ -14,6 +14,16 @@ USER3_PUBLIC_KEY = 'Gbrg7JtxdjedQRmr81ZZbh1BozS7fBW88ZyxNDy7WLNC'
|
||||
CC_FULFILLMENT_URI = 'cf:0:'
|
||||
CC_CONDITION_URI = 'cc:0:3:47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU:0'
|
||||
|
||||
ASSET_DEFINITION = {
|
||||
'data': {
|
||||
'definition': 'Asset definition'
|
||||
}
|
||||
}
|
||||
|
||||
ASSET_LINK = {
|
||||
'id': 'a' * 64
|
||||
}
|
||||
|
||||
DATA = {
|
||||
'msg': 'Hello BigchainDB!'
|
||||
}
|
||||
@ -118,6 +128,16 @@ def user2_cond(user2_Ed25519, user2_pub):
|
||||
return Condition(user2_Ed25519, [user2_pub])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def asset_definition():
|
||||
return ASSET_DEFINITION
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def asset_link():
|
||||
return ASSET_LINK
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def data():
|
||||
return DATA
|
||||
@ -125,8 +145,8 @@ def data():
|
||||
|
||||
@pytest.fixture
|
||||
def utx(user_ffill, user_cond):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
return Transaction(Transaction.CREATE, Asset(), [user_ffill], [user_cond])
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
return Transaction(Transaction.CREATE, {'data': None}, [user_ffill], [user_cond])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -137,12 +157,12 @@ def tx(utx, user_priv):
|
||||
@pytest.fixture
|
||||
def transfer_utx(user_cond, user2_cond, utx):
|
||||
from bigchaindb.common.transaction import (Fulfillment, TransactionLink,
|
||||
Transaction, AssetLink)
|
||||
Transaction)
|
||||
user_cond = user_cond.to_dict()
|
||||
ffill = Fulfillment(utx.conditions[0].fulfillment,
|
||||
user_cond['owners_after'],
|
||||
TransactionLink(utx.id, 0))
|
||||
return Transaction('TRANSFER', AssetLink(utx.id), [ffill], [user2_cond])
|
||||
return Transaction('TRANSFER', {'id': utx.id}, [ffill], [user2_cond])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -1,59 +0,0 @@
|
||||
from pytest import raises
|
||||
|
||||
|
||||
def test_asset_default_values():
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
asset = Asset()
|
||||
assert asset.data is None
|
||||
|
||||
|
||||
def test_asset_creation_with_data(data):
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
asset = Asset(data)
|
||||
assert asset.data == data
|
||||
|
||||
|
||||
def test_asset_invalid_asset_initialization():
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
# check types
|
||||
with raises(TypeError):
|
||||
Asset(data='some wrong type')
|
||||
|
||||
|
||||
def test_invalid_asset_comparison(data):
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
assert Asset(data) != 'invalid comparison'
|
||||
|
||||
|
||||
def test_asset_serialization(data):
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
expected = {
|
||||
'data': data,
|
||||
}
|
||||
asset = Asset(data)
|
||||
assert asset.to_dict() == expected
|
||||
|
||||
|
||||
def test_asset_deserialization(data):
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
asset_dict = {
|
||||
'data': data,
|
||||
}
|
||||
asset = Asset.from_dict(asset_dict)
|
||||
expected = Asset(data)
|
||||
assert asset == expected
|
||||
|
||||
|
||||
def test_validate_asset():
|
||||
from bigchaindb.common.transaction import Asset
|
||||
|
||||
# test amount errors
|
||||
asset = Asset()
|
||||
with raises(TypeError):
|
||||
asset.validate_asset(amount='a')
|
@ -1,5 +1,4 @@
|
||||
from pytest import raises
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
def test_fulfillment_serialization(ffill_uri, user_pub):
|
||||
@ -146,9 +145,14 @@ def test_condition_hashlock_deserialization():
|
||||
|
||||
def test_invalid_condition_initialization(cond_uri, user_pub):
|
||||
from bigchaindb.common.transaction import Condition
|
||||
from bigchaindb.common.exceptions import AmountError
|
||||
|
||||
with raises(TypeError):
|
||||
Condition(cond_uri, user_pub)
|
||||
with raises(TypeError):
|
||||
Condition(cond_uri, [user_pub], 'amount')
|
||||
with raises(AmountError):
|
||||
Condition(cond_uri, [user_pub], 0)
|
||||
|
||||
|
||||
def test_generate_conditions_split_half_recursive(user_pub, user2_pub,
|
||||
@ -242,49 +246,50 @@ def test_generate_conditions_invalid_parameters(user_pub, user2_pub,
|
||||
Condition.generate([[user_pub]], 1)
|
||||
|
||||
|
||||
def test_invalid_transaction_initialization():
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
def test_invalid_transaction_initialization(asset_definition):
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
|
||||
with raises(ValueError):
|
||||
Transaction(operation='invalid operation', asset=Asset())
|
||||
Transaction(operation='invalid operation', asset=asset_definition)
|
||||
with raises(TypeError):
|
||||
Transaction(operation='CREATE', asset='invalid asset')
|
||||
with raises(TypeError):
|
||||
Transaction(operation='TRANSFER', asset={})
|
||||
with raises(TypeError):
|
||||
Transaction(
|
||||
operation='CREATE',
|
||||
asset=Asset(),
|
||||
asset=asset_definition,
|
||||
conditions='invalid conditions'
|
||||
)
|
||||
with raises(TypeError):
|
||||
Transaction(
|
||||
operation='CREATE',
|
||||
asset=Asset(),
|
||||
asset=asset_definition,
|
||||
conditions=[],
|
||||
fulfillments='invalid fulfillments'
|
||||
)
|
||||
with raises(TypeError):
|
||||
Transaction(
|
||||
operation='CREATE',
|
||||
asset=Asset(),
|
||||
asset=asset_definition,
|
||||
conditions=[],
|
||||
fulfillments=[],
|
||||
metadata='invalid metadata'
|
||||
)
|
||||
|
||||
|
||||
def test_create_default_asset_on_tx_initialization():
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
def test_create_default_asset_on_tx_initialization(asset_definition):
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, None)
|
||||
expected = Asset()
|
||||
expected = {'data': None}
|
||||
tx = Transaction(Transaction.CREATE, asset=expected)
|
||||
asset = tx.asset
|
||||
|
||||
assert asset == expected
|
||||
|
||||
|
||||
def test_transaction_serialization(user_ffill, user_cond, data):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
|
||||
tx_id = 'l0l'
|
||||
|
||||
@ -302,7 +307,7 @@ def test_transaction_serialization(user_ffill, user_cond, data):
|
||||
}
|
||||
}
|
||||
|
||||
tx = Transaction(Transaction.CREATE, Asset(data), [user_ffill],
|
||||
tx = Transaction(Transaction.CREATE, {'data': data}, [user_ffill],
|
||||
[user_cond])
|
||||
tx_dict = tx.to_dict()
|
||||
tx_dict['id'] = tx_id
|
||||
@ -311,10 +316,10 @@ def test_transaction_serialization(user_ffill, user_cond, data):
|
||||
|
||||
|
||||
def test_transaction_deserialization(user_ffill, user_cond, data):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from .util import validate_transaction_model
|
||||
|
||||
expected_asset = Asset(data)
|
||||
expected_asset = {'data': data}
|
||||
expected = Transaction(Transaction.CREATE, expected_asset, [user_ffill],
|
||||
[user_cond], None, Transaction.VERSION)
|
||||
|
||||
@ -432,92 +437,28 @@ def test_cast_transaction_link_to_boolean():
|
||||
assert bool(TransactionLink(False, False)) is True
|
||||
|
||||
|
||||
def test_asset_link_serialization():
|
||||
from bigchaindb.common.transaction import AssetLink
|
||||
def test_add_fulfillment_to_tx(user_ffill, asset_definition):
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
|
||||
asset_id = 'a asset id'
|
||||
expected = {
|
||||
'id': asset_id,
|
||||
}
|
||||
asset_link = AssetLink(asset_id)
|
||||
|
||||
assert asset_link.to_dict() == expected
|
||||
|
||||
|
||||
def test_asset_link_serialization_with_empty_payload():
|
||||
from bigchaindb.common.transaction import AssetLink
|
||||
|
||||
expected = None
|
||||
asset_link = AssetLink()
|
||||
|
||||
assert asset_link.to_dict() == expected
|
||||
|
||||
|
||||
def test_asset_link_deserialization():
|
||||
from bigchaindb.common.transaction import AssetLink
|
||||
|
||||
asset_id = 'a asset id'
|
||||
expected = AssetLink(asset_id)
|
||||
asset_link = {
|
||||
'id': asset_id
|
||||
}
|
||||
asset_link = AssetLink.from_dict(asset_link)
|
||||
|
||||
assert asset_link == expected
|
||||
|
||||
|
||||
def test_asset_link_deserialization_with_empty_payload():
|
||||
from bigchaindb.common.transaction import AssetLink
|
||||
|
||||
expected = AssetLink()
|
||||
asset_link = AssetLink.from_dict(None)
|
||||
|
||||
assert asset_link == expected
|
||||
|
||||
|
||||
def test_cast_asset_link_to_boolean():
|
||||
from bigchaindb.common.transaction import AssetLink
|
||||
|
||||
assert bool(AssetLink()) is False
|
||||
assert bool(AssetLink('a')) is True
|
||||
assert bool(AssetLink(False)) is True
|
||||
|
||||
|
||||
def test_eq_asset_link():
|
||||
from bigchaindb.common.transaction import AssetLink
|
||||
|
||||
asset_id_1 = 'asset_1'
|
||||
asset_id_2 = 'asset_2'
|
||||
|
||||
assert AssetLink(asset_id_1) == AssetLink(asset_id_1)
|
||||
assert AssetLink(asset_id_1) != AssetLink(asset_id_2)
|
||||
|
||||
|
||||
def test_add_fulfillment_to_tx(user_ffill):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, Asset(), [], [])
|
||||
tx = Transaction(Transaction.CREATE, asset_definition, [], [])
|
||||
tx.add_fulfillment(user_ffill)
|
||||
|
||||
assert len(tx.fulfillments) == 1
|
||||
|
||||
|
||||
def test_add_fulfillment_to_tx_with_invalid_parameters():
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
def test_add_fulfillment_to_tx_with_invalid_parameters(asset_definition):
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
tx = Transaction(Transaction.CREATE, asset_definition)
|
||||
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, Asset())
|
||||
with raises(TypeError):
|
||||
tx.add_fulfillment('somewronginput')
|
||||
|
||||
|
||||
def test_add_condition_to_tx(user_cond):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
def test_add_condition_to_tx(user_cond, asset_definition):
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from .util import validate_transaction_model
|
||||
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, Asset())
|
||||
tx = Transaction(Transaction.CREATE, asset_definition)
|
||||
tx.add_condition(user_cond)
|
||||
|
||||
assert len(tx.conditions) == 1
|
||||
@ -525,11 +466,10 @@ def test_add_condition_to_tx(user_cond):
|
||||
validate_transaction_model(tx)
|
||||
|
||||
|
||||
def test_add_condition_to_tx_with_invalid_parameters():
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
def test_add_condition_to_tx_with_invalid_parameters(asset_definition):
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
tx = Transaction(Transaction.CREATE, asset_definition, [], [])
|
||||
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, Asset(), [], [])
|
||||
with raises(TypeError):
|
||||
tx.add_condition('somewronginput')
|
||||
|
||||
@ -541,13 +481,14 @@ def test_sign_with_invalid_parameters(utx, user_priv):
|
||||
utx.sign(user_priv)
|
||||
|
||||
|
||||
def test_validate_tx_simple_create_signature(user_ffill, user_cond, user_priv):
|
||||
def test_validate_tx_simple_create_signature(user_ffill, user_cond, user_priv,
|
||||
asset_definition):
|
||||
from copy import deepcopy
|
||||
from bigchaindb.common.crypto import PrivateKey
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from .util import validate_transaction_model
|
||||
|
||||
tx = Transaction(Transaction.CREATE, Asset(), [user_ffill], [user_cond])
|
||||
tx = Transaction(Transaction.CREATE, asset_definition, [user_ffill], [user_cond])
|
||||
expected = deepcopy(user_cond)
|
||||
expected.fulfillment.sign(str(tx).encode(), PrivateKey(user_priv))
|
||||
tx.sign([user_priv])
|
||||
@ -601,14 +542,15 @@ def test_validate_fulfillment_with_invalid_parameters(utx):
|
||||
input_conditions) is False
|
||||
|
||||
|
||||
def test_validate_multiple_fulfillments(user_ffill, user_cond, user_priv):
|
||||
def test_validate_multiple_fulfillments(user_ffill, user_cond, user_priv,
|
||||
asset_definition):
|
||||
from copy import deepcopy
|
||||
|
||||
from bigchaindb.common.crypto import PrivateKey
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from .util import validate_transaction_model
|
||||
|
||||
tx = Transaction(Transaction.CREATE, Asset(),
|
||||
tx = Transaction(Transaction.CREATE, asset_definition,
|
||||
[user_ffill, deepcopy(user_ffill)],
|
||||
[user_cond, deepcopy(user_cond)])
|
||||
|
||||
@ -639,14 +581,16 @@ def test_validate_tx_threshold_create_signature(user_user2_threshold_ffill,
|
||||
user_pub,
|
||||
user2_pub,
|
||||
user_priv,
|
||||
user2_priv):
|
||||
user2_priv,
|
||||
asset_definition):
|
||||
from copy import deepcopy
|
||||
|
||||
from bigchaindb.common.crypto import PrivateKey
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from .util import validate_transaction_model
|
||||
|
||||
tx = Transaction(Transaction.CREATE, Asset(), [user_user2_threshold_ffill],
|
||||
tx = Transaction(Transaction.CREATE, asset_definition,
|
||||
[user_user2_threshold_ffill],
|
||||
[user_user2_threshold_cond])
|
||||
expected = deepcopy(user_user2_threshold_cond)
|
||||
expected.fulfillment.subconditions[0]['body'].sign(str(tx).encode(),
|
||||
@ -665,15 +609,15 @@ def test_validate_tx_threshold_create_signature(user_user2_threshold_ffill,
|
||||
def test_multiple_fulfillment_validation_of_transfer_tx(user_ffill, user_cond,
|
||||
user_priv, user2_pub,
|
||||
user2_priv, user3_pub,
|
||||
user3_priv):
|
||||
user3_priv,
|
||||
asset_definition):
|
||||
from copy import deepcopy
|
||||
from bigchaindb.common.transaction import (Transaction, TransactionLink,
|
||||
Fulfillment, Condition, Asset,
|
||||
AssetLink)
|
||||
Fulfillment, Condition)
|
||||
from cryptoconditions import Ed25519Fulfillment
|
||||
from .util import validate_transaction_model
|
||||
|
||||
tx = Transaction(Transaction.CREATE, Asset(),
|
||||
tx = Transaction(Transaction.CREATE, asset_definition,
|
||||
[user_ffill, deepcopy(user_ffill)],
|
||||
[user_cond, deepcopy(user_cond)])
|
||||
tx.sign([user_priv])
|
||||
@ -685,7 +629,7 @@ 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', AssetLink(tx.id),
|
||||
transfer_tx = Transaction('TRANSFER', {'id': tx.id},
|
||||
fulfillments, conditions)
|
||||
transfer_tx = transfer_tx.sign([user_priv])
|
||||
|
||||
@ -720,7 +664,7 @@ def test_validate_fulfillments_of_transfer_tx_with_invalid_params(transfer_tx,
|
||||
|
||||
|
||||
def test_create_create_transaction_single_io(user_cond, user_pub, data):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from .util import validate_transaction_model
|
||||
|
||||
expected = {
|
||||
@ -742,8 +686,8 @@ def test_create_create_transaction_single_io(user_cond, user_pub, data):
|
||||
'version': 1,
|
||||
}
|
||||
|
||||
asset = Asset(data)
|
||||
tx = Transaction.create([user_pub], [([user_pub], 1)], data, asset)
|
||||
tx = Transaction.create([user_pub], [([user_pub], 1)], metadata=data,
|
||||
asset=data)
|
||||
tx_dict = tx.to_dict()
|
||||
tx_dict['fulfillments'][0]['fulfillment'] = None
|
||||
tx_dict.pop('id')
|
||||
@ -753,17 +697,18 @@ def test_create_create_transaction_single_io(user_cond, user_pub, data):
|
||||
validate_transaction_model(tx)
|
||||
|
||||
|
||||
def test_validate_single_io_create_transaction(user_pub, user_priv, data):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
def test_validate_single_io_create_transaction(user_pub, user_priv, data,
|
||||
asset_definition):
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
|
||||
tx = Transaction.create([user_pub], [([user_pub], 1)], data, Asset())
|
||||
tx = Transaction.create([user_pub], [([user_pub], 1)], metadata=data)
|
||||
tx = tx.sign([user_priv])
|
||||
assert tx.fulfillments_valid() is True
|
||||
|
||||
|
||||
def test_create_create_transaction_multiple_io(user_cond, user2_cond, user_pub,
|
||||
user2_pub):
|
||||
from bigchaindb.common.transaction import Transaction, Asset, Fulfillment
|
||||
user2_pub, asset_definition):
|
||||
from bigchaindb.common.transaction import Transaction, Fulfillment
|
||||
|
||||
# a fulfillment for a create transaction with multiple `owners_before`
|
||||
# is a fulfillment for an implicit threshold condition with
|
||||
@ -778,10 +723,8 @@ def test_create_create_transaction_multiple_io(user_cond, user2_cond, user_pub,
|
||||
'operation': 'CREATE',
|
||||
'version': 1
|
||||
}
|
||||
asset = Asset()
|
||||
tx = Transaction.create([user_pub, user2_pub],
|
||||
[([user_pub], 1), ([user2_pub], 1)],
|
||||
asset=asset,
|
||||
metadata={'message': 'hello'}).to_dict()
|
||||
tx.pop('id')
|
||||
tx.pop('asset')
|
||||
@ -790,14 +733,14 @@ def test_create_create_transaction_multiple_io(user_cond, user2_cond, user_pub,
|
||||
|
||||
|
||||
def test_validate_multiple_io_create_transaction(user_pub, user_priv,
|
||||
user2_pub, user2_priv):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
user2_pub, user2_priv,
|
||||
asset_definition):
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from .util import validate_transaction_model
|
||||
|
||||
tx = Transaction.create([user_pub, user2_pub],
|
||||
[([user_pub], 1), ([user2_pub], 1)],
|
||||
metadata={'message': 'hello'},
|
||||
asset=Asset())
|
||||
metadata={'message': 'hello'})
|
||||
tx = tx.sign([user_priv, user2_priv])
|
||||
assert tx.fulfillments_valid() is True
|
||||
|
||||
@ -807,7 +750,7 @@ 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):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
|
||||
expected = {
|
||||
'conditions': [user_user2_threshold_cond.to_dict()],
|
||||
@ -827,9 +770,8 @@ def test_create_create_transaction_threshold(user_pub, user2_pub, user3_pub,
|
||||
'operation': 'CREATE',
|
||||
'version': 1
|
||||
}
|
||||
asset = Asset(data)
|
||||
tx = Transaction.create([user_pub], [([user_pub, user2_pub], 1)],
|
||||
data, asset)
|
||||
metadata=data, asset=data)
|
||||
tx_dict = tx.to_dict()
|
||||
tx_dict.pop('id')
|
||||
tx_dict['fulfillments'][0]['fulfillment'] = None
|
||||
@ -838,12 +780,12 @@ def test_create_create_transaction_threshold(user_pub, user2_pub, user3_pub,
|
||||
|
||||
|
||||
def test_validate_threshold_create_transaction(user_pub, user_priv, user2_pub,
|
||||
data):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
data, asset_definition):
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from .util import validate_transaction_model
|
||||
|
||||
tx = Transaction.create([user_pub], [([user_pub, user2_pub], 1)],
|
||||
data, Asset())
|
||||
metadata=data)
|
||||
tx = tx.sign([user_priv])
|
||||
assert tx.fulfillments_valid() is True
|
||||
|
||||
@ -851,7 +793,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, AssetLink
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
|
||||
with raises(TypeError):
|
||||
Transaction.create('not a list')
|
||||
@ -866,12 +808,12 @@ def test_create_create_transaction_with_invalid_parameters(user_pub):
|
||||
with raises(ValueError):
|
||||
Transaction.create([user_pub], [([user_pub],)])
|
||||
with raises(TypeError):
|
||||
Transaction.create([user_pub], [([user_pub], 1)], metadata=[])
|
||||
Transaction.create([user_pub], [([user_pub], 1)],
|
||||
metadata='not a dict or none')
|
||||
with raises(TypeError):
|
||||
Transaction.create([user_pub],
|
||||
[([user_pub], 1)],
|
||||
metadata=None,
|
||||
asset=AssetLink('mock_asset_link'))
|
||||
asset='not a dict or none')
|
||||
|
||||
|
||||
def test_conditions_to_inputs(tx):
|
||||
@ -888,7 +830,7 @@ def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub,
|
||||
user2_cond, user_priv):
|
||||
from copy import deepcopy
|
||||
from bigchaindb.common.crypto import PrivateKey
|
||||
from bigchaindb.common.transaction import Transaction, AssetLink
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
from bigchaindb.common.util import serialize
|
||||
from .util import validate_transaction_model
|
||||
|
||||
@ -915,7 +857,7 @@ def test_create_transfer_transaction_single_io(tx, user_pub, user2_pub,
|
||||
}
|
||||
inputs = tx.to_inputs([0])
|
||||
transfer_tx = Transaction.transfer(inputs, [([user2_pub], 1)],
|
||||
asset_link=AssetLink(tx.id))
|
||||
asset_id=tx.id)
|
||||
transfer_tx = transfer_tx.sign([user_priv])
|
||||
transfer_tx = transfer_tx.to_dict()
|
||||
|
||||
@ -936,12 +878,12 @@ 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, AssetLink
|
||||
user3_pub, user2_cond,
|
||||
asset_definition):
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
|
||||
asset = Asset()
|
||||
tx = Transaction.create([user_pub], [([user_pub], 1), ([user2_pub], 1)],
|
||||
asset=asset, metadata={'message': 'hello'})
|
||||
metadata={'message': 'hello'})
|
||||
tx = tx.sign([user_priv])
|
||||
|
||||
expected = {
|
||||
@ -974,7 +916,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_link=AssetLink(tx.id))
|
||||
asset_id=tx.id)
|
||||
transfer_tx = transfer_tx.sign([user_priv, user2_priv])
|
||||
|
||||
assert len(transfer_tx.fulfillments) == 2
|
||||
@ -992,41 +934,39 @@ def test_create_transfer_transaction_multiple_io(user_pub, user_priv,
|
||||
|
||||
|
||||
def test_create_transfer_with_invalid_parameters(tx, user_pub):
|
||||
from bigchaindb.common.transaction import Transaction, Asset, AssetLink
|
||||
mock_asset_link = AssetLink(tx.id)
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
|
||||
with raises(TypeError):
|
||||
Transaction.transfer({}, [], mock_asset_link)
|
||||
Transaction.transfer({}, [], tx.id)
|
||||
with raises(ValueError):
|
||||
Transaction.transfer([], [], mock_asset_link)
|
||||
Transaction.transfer([], [], tx.id)
|
||||
with raises(TypeError):
|
||||
Transaction.transfer(['fulfillment'], {}, mock_asset_link)
|
||||
Transaction.transfer(['fulfillment'], {}, tx.id)
|
||||
with raises(ValueError):
|
||||
Transaction.transfer(['fulfillment'], [], mock_asset_link)
|
||||
Transaction.transfer(['fulfillment'], [], tx.id)
|
||||
with raises(ValueError):
|
||||
Transaction.transfer(['fulfillment'], [user_pub], mock_asset_link)
|
||||
Transaction.transfer(['fulfillment'], [user_pub], tx.id)
|
||||
with raises(ValueError):
|
||||
Transaction.transfer(['fulfillment'], [([user_pub],)], mock_asset_link)
|
||||
Transaction.transfer(['fulfillment'], [([user_pub],)], tx.id)
|
||||
with raises(TypeError):
|
||||
Transaction.transfer(['fulfillment'], [([user_pub], 1)],
|
||||
mock_asset_link, metadata=[])
|
||||
tx.id, metadata='not a dict or none')
|
||||
with raises(TypeError):
|
||||
Transaction.transfer(['fulfillment'], [([user_pub], 1)], Asset())
|
||||
Transaction.transfer(['fulfillment'], [([user_pub], 1)],
|
||||
['not a string'])
|
||||
|
||||
|
||||
def test_cant_add_empty_condition():
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
tx = Transaction(Transaction.CREATE, None)
|
||||
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, None)
|
||||
with raises(TypeError):
|
||||
tx.add_condition(None)
|
||||
|
||||
|
||||
def test_cant_add_empty_fulfillment():
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
tx = Transaction(Transaction.CREATE, None)
|
||||
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, None)
|
||||
with raises(TypeError):
|
||||
tx.add_fulfillment(None)
|
||||
|
@ -234,12 +234,9 @@ 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)],
|
||||
AssetLink(signed_create_tx.id))
|
||||
tx = Transaction.transfer(inputs, [([user_pk], 1)], asset_id=signed_create_tx.id)
|
||||
return tx.sign([user_sk])
|
||||
|
||||
|
||||
|
@ -92,7 +92,6 @@ class TestBigchainApi(object):
|
||||
@pytest.mark.genesis
|
||||
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
|
||||
|
||||
tx = Transaction.create([b.me], [([b.me], 1)])
|
||||
@ -104,14 +103,14 @@ class TestBigchainApi(object):
|
||||
|
||||
monkeypatch.setattr('time.time', lambda: 2)
|
||||
transfer_tx = Transaction.transfer(tx.to_inputs(), [([b.me], 1)],
|
||||
AssetLink(tx.id))
|
||||
asset_id=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)],
|
||||
AssetLink(tx.id))
|
||||
asset_id=tx.id)
|
||||
transfer_tx2 = transfer_tx2.sign([b.me_private])
|
||||
block3 = b.create_block([transfer_tx2])
|
||||
b.write_block(block3)
|
||||
@ -181,14 +180,13 @@ 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)],
|
||||
AssetLink(input_tx.id))
|
||||
asset_id=input_tx.id)
|
||||
tx = tx.sign([user_sk])
|
||||
response = b.write_transaction(tx)
|
||||
|
||||
@ -201,14 +199,13 @@ 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)],
|
||||
AssetLink(input_tx.id))
|
||||
asset_id=input_tx.id)
|
||||
tx = tx.sign([user_sk])
|
||||
b.write_transaction(tx)
|
||||
|
||||
@ -223,14 +220,13 @@ 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)],
|
||||
AssetLink(input_tx.id))
|
||||
asset_id=input_tx.id)
|
||||
tx = tx.sign([user_sk])
|
||||
# There's no need to b.write_transaction(tx) to the backlog
|
||||
|
||||
@ -249,14 +245,13 @@ 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)],
|
||||
AssetLink(input_tx.id))
|
||||
asset_id=input_tx.id)
|
||||
tx = tx.sign([user_sk])
|
||||
|
||||
# Make sure there's a copy of tx in the backlog
|
||||
@ -489,14 +484,13 @@ 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)],
|
||||
AssetLink(input_tx.id))
|
||||
asset_id=input_tx.id)
|
||||
tx = tx.sign([user_sk])
|
||||
b.write_transaction(tx)
|
||||
|
||||
@ -510,7 +504,6 @@ 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
|
||||
@ -523,7 +516,7 @@ class TestBigchainApi(object):
|
||||
input_tx = b.get_transaction(input_tx.txid)
|
||||
inputs = input_tx.to_inputs()
|
||||
tx = Transaction.transfer(inputs, [([user_pk], 1)],
|
||||
asset_link=AssetLink(input_tx.id),
|
||||
asset_id=input_tx.id,
|
||||
metadata={'msg': random.random()})
|
||||
tx = tx.sign([user_sk])
|
||||
b.write_transaction(tx)
|
||||
@ -539,8 +532,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 (AssetLink, Fulfillment,
|
||||
TransactionLink)
|
||||
from bigchaindb.common.transaction import Fulfillment, TransactionLink
|
||||
from bigchaindb.models import Transaction
|
||||
from bigchaindb import Bigchain
|
||||
|
||||
@ -549,7 +541,7 @@ class TestBigchainApi(object):
|
||||
[user_pk],
|
||||
TransactionLink('somethingsomething', 0))
|
||||
tx = Transaction.transfer([fulfillment], [([user_pk], 1)],
|
||||
AssetLink('mock_asset_link'))
|
||||
asset_id='mock_asset_link')
|
||||
|
||||
with pytest.raises(TransactionDoesNotExist):
|
||||
tx.validate(Bigchain())
|
||||
@ -599,7 +591,6 @@ 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()
|
||||
@ -607,7 +598,7 @@ class TestTransactionValidation(object):
|
||||
sk, pk = generate_key_pair()
|
||||
tx = Transaction.create([pk], [([user_pk], 1)])
|
||||
tx.operation = 'TRANSFER'
|
||||
tx.asset = AssetLink(input_transaction.id)
|
||||
tx.asset = {'id': input_transaction.id}
|
||||
tx.fulfillments[0].tx_input = input_tx
|
||||
|
||||
with pytest.raises(InvalidSignature):
|
||||
@ -644,14 +635,13 @@ 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)],
|
||||
AssetLink(input_tx.id))
|
||||
asset_id=input_tx.id)
|
||||
transfer_tx = transfer_tx.sign([user_sk])
|
||||
|
||||
assert transfer_tx == b.validate_transaction(transfer_tx)
|
||||
@ -669,7 +659,6 @@ 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)
|
||||
@ -677,7 +666,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)],
|
||||
AssetLink(input_tx.id))
|
||||
asset_id=input_tx.id)
|
||||
transfer_tx = transfer_tx.sign([user_sk])
|
||||
|
||||
assert transfer_tx == b.validate_transaction(transfer_tx)
|
||||
@ -689,7 +678,7 @@ class TestTransactionValidation(object):
|
||||
# create transaction with the undecided input
|
||||
tx_invalid = Transaction.transfer(transfer_tx.to_inputs(),
|
||||
[([user_pk], 1)],
|
||||
AssetLink(transfer_tx.asset.id))
|
||||
asset_id=transfer_tx.asset['id'])
|
||||
tx_invalid = tx_invalid.sign([user_sk])
|
||||
|
||||
with pytest.raises(TransactionNotInValidBlock):
|
||||
@ -783,7 +772,6 @@ 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()
|
||||
|
||||
@ -791,7 +779,7 @@ class TestMultipleInputs(object):
|
||||
input_tx = b.get_transaction(tx_link.txid)
|
||||
inputs = input_tx.to_inputs()
|
||||
tx = Transaction.transfer(inputs, [([user2_pk], 1)],
|
||||
AssetLink(input_tx.id))
|
||||
asset_id=input_tx.id)
|
||||
tx = tx.sign([user_sk])
|
||||
|
||||
# validate transaction
|
||||
@ -804,7 +792,6 @@ 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()
|
||||
@ -815,7 +802,7 @@ class TestMultipleInputs(object):
|
||||
input_tx = b.get_transaction(tx_link.txid)
|
||||
tx = Transaction.transfer(input_tx.to_inputs(),
|
||||
[([user2_pk, user3_pk], 1)],
|
||||
AssetLink(input_tx.id))
|
||||
asset_id=input_tx.id)
|
||||
tx = tx.sign([user_sk])
|
||||
|
||||
assert b.is_valid_transaction(tx) == tx
|
||||
@ -827,7 +814,6 @@ 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()
|
||||
@ -847,7 +833,7 @@ class TestMultipleInputs(object):
|
||||
inputs = input_tx.to_inputs()
|
||||
|
||||
transfer_tx = Transaction.transfer(inputs, [([user3_pk], 1)],
|
||||
AssetLink(input_tx.id))
|
||||
asset_id=input_tx.id)
|
||||
transfer_tx = transfer_tx.sign([user_sk, user2_sk])
|
||||
|
||||
# validate transaction
|
||||
@ -860,7 +846,6 @@ 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()
|
||||
@ -882,7 +867,7 @@ class TestMultipleInputs(object):
|
||||
|
||||
tx = Transaction.transfer(tx_input.to_inputs(),
|
||||
[([user3_pk, user4_pk], 1)],
|
||||
AssetLink(tx_input.id))
|
||||
asset_id=tx_input.id)
|
||||
tx = tx.sign([user_sk, user2_sk])
|
||||
|
||||
assert b.is_valid_transaction(tx) == tx
|
||||
@ -891,7 +876,7 @@ class TestMultipleInputs(object):
|
||||
|
||||
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 AssetLink, TransactionLink
|
||||
from bigchaindb.common.transaction import TransactionLink
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
user2_sk, user2_pk = crypto.generate_key_pair()
|
||||
@ -907,7 +892,7 @@ class TestMultipleInputs(object):
|
||||
assert owned_inputs_user2 == []
|
||||
|
||||
tx = Transaction.transfer(tx.to_inputs(), [([user2_pk], 1)],
|
||||
AssetLink(tx.id))
|
||||
asset_id=tx.id)
|
||||
tx = tx.sign([user_sk])
|
||||
block = b.create_block([tx])
|
||||
b.write_block(block)
|
||||
@ -922,7 +907,7 @@ class TestMultipleInputs(object):
|
||||
user_pk,
|
||||
genesis_block):
|
||||
from bigchaindb.common import crypto
|
||||
from bigchaindb.common.transaction import AssetLink, TransactionLink
|
||||
from bigchaindb.common.transaction import TransactionLink
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
user2_sk, user2_pk = crypto.generate_key_pair()
|
||||
@ -944,7 +929,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)],
|
||||
AssetLink(tx.id))
|
||||
asset_id=tx.id)
|
||||
tx_invalid = tx_invalid.sign([user_sk])
|
||||
block = b.create_block([tx_invalid])
|
||||
b.write_block(block)
|
||||
@ -963,17 +948,13 @@ 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,
|
||||
AssetLink)
|
||||
from bigchaindb.common.transaction import TransactionLink
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
user2_sk, user2_pk = crypto.generate_key_pair()
|
||||
|
||||
# create divisible asset
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me],
|
||||
[([user_pk], 1), ([user_pk], 1)],
|
||||
asset=asset)
|
||||
tx_create = Transaction.create([b.me], [([user_pk], 1), ([user_pk], 1)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
block = b.create_block([tx_create_signed])
|
||||
b.write_block(block)
|
||||
@ -990,7 +971,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_link=AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
block = b.create_block([tx_transfer_signed])
|
||||
b.write_block(block)
|
||||
@ -1003,7 +984,7 @@ class TestMultipleInputs(object):
|
||||
|
||||
def test_get_owned_ids_multiple_owners(self, b, user_sk, user_pk):
|
||||
from bigchaindb.common import crypto
|
||||
from bigchaindb.common.transaction import AssetLink, TransactionLink
|
||||
from bigchaindb.common.transaction import TransactionLink
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
user2_sk, user2_pk = crypto.generate_key_pair()
|
||||
@ -1022,7 +1003,7 @@ class TestMultipleInputs(object):
|
||||
assert owned_inputs_user1 == expected_owned_inputs_user1
|
||||
|
||||
tx = Transaction.transfer(tx.to_inputs(), [([user3_pk], 1)],
|
||||
AssetLink(tx.id))
|
||||
asset_id=tx.id)
|
||||
tx = tx.sign([user_sk, user2_sk])
|
||||
block = b.create_block([tx])
|
||||
b.write_block(block)
|
||||
@ -1034,7 +1015,6 @@ class TestMultipleInputs(object):
|
||||
|
||||
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()
|
||||
@ -1054,7 +1034,7 @@ class TestMultipleInputs(object):
|
||||
|
||||
# create a transaction and block
|
||||
tx = Transaction.transfer(tx.to_inputs(), [([user2_pk], 1)],
|
||||
AssetLink(tx.id))
|
||||
asset_id=tx.id)
|
||||
tx = tx.sign([user_sk])
|
||||
block = b.create_block([tx])
|
||||
b.write_block(block)
|
||||
@ -1067,7 +1047,6 @@ class TestMultipleInputs(object):
|
||||
user_pk,
|
||||
genesis_block):
|
||||
from bigchaindb.common import crypto
|
||||
from bigchaindb.common.transaction import AssetLink
|
||||
from bigchaindb.models import Transaction
|
||||
|
||||
# create a new users
|
||||
@ -1092,7 +1071,7 @@ class TestMultipleInputs(object):
|
||||
|
||||
# create a transaction and block
|
||||
tx = Transaction.transfer(tx.to_inputs(), [([user2_pk], 1)],
|
||||
AssetLink(tx.id))
|
||||
asset_id=tx.id)
|
||||
tx = tx.sign([user_sk])
|
||||
block = b.create_block([tx])
|
||||
b.write_block(block)
|
||||
@ -1109,19 +1088,16 @@ class TestMultipleInputs(object):
|
||||
|
||||
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
|
||||
|
||||
# create a new users
|
||||
user2_sk, user2_pk = crypto.generate_key_pair()
|
||||
|
||||
# create a divisible asset with 3 outputs
|
||||
asset = Asset()
|
||||
tx_create = Transaction.create([b.me],
|
||||
[([user_pk], 1),
|
||||
([user_pk], 1),
|
||||
([user_pk], 1)],
|
||||
asset=asset)
|
||||
([user_pk], 1)])
|
||||
tx_create_signed = tx_create.sign([b.me_private])
|
||||
block = b.create_block([tx_create_signed])
|
||||
b.write_block(block)
|
||||
@ -1135,7 +1111,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_link=AssetLink(tx_create.id))
|
||||
asset_id=tx_create.id)
|
||||
tx_transfer_signed = tx_transfer.sign([user_sk])
|
||||
block = b.create_block([tx_transfer_signed])
|
||||
b.write_block(block)
|
||||
@ -1151,7 +1127,6 @@ class TestMultipleInputs(object):
|
||||
|
||||
def test_get_spent_multiple_owners(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()
|
||||
@ -1176,7 +1151,7 @@ class TestMultipleInputs(object):
|
||||
# create a transaction
|
||||
tx = Transaction.transfer(transactions[0].to_inputs(),
|
||||
[([user3_pk], 1)],
|
||||
AssetLink(transactions[0].id))
|
||||
asset_id=transactions[0].id)
|
||||
tx = tx.sign([user_sk, user2_sk])
|
||||
block = b.create_block([tx])
|
||||
b.write_block(block)
|
||||
|
@ -271,7 +271,6 @@ def test_valid_block_voting_with_transfer_transactions(monkeypatch,
|
||||
b, genesis_block):
|
||||
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
|
||||
|
||||
@ -287,7 +286,7 @@ def test_valid_block_voting_with_transfer_transactions(monkeypatch,
|
||||
# create a `TRANSFER` transaction
|
||||
test_user2_priv, test_user2_pub = crypto.generate_key_pair()
|
||||
tx2 = Transaction.transfer(tx.to_inputs(), [([test_user2_pub], 1)],
|
||||
AssetLink(tx.id))
|
||||
asset_id=tx.id)
|
||||
tx2 = tx2.sign([test_user_priv])
|
||||
|
||||
monkeypatch.setattr('time.time', lambda: 2222222222)
|
||||
|
@ -127,7 +127,6 @@ 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()
|
||||
|
||||
@ -135,7 +134,7 @@ def test_post_transfer_transaction_endpoint(b, client, user_pk, user_sk):
|
||||
create_tx = b.get_transaction(input_valid.txid)
|
||||
transfer_tx = Transaction.transfer(create_tx.to_inputs(),
|
||||
[([user_pub], 1)],
|
||||
AssetLink(create_tx.id))
|
||||
asset_id=create_tx.id)
|
||||
transfer_tx = transfer_tx.sign([user_sk])
|
||||
|
||||
res = client.post(TX_ENDPOINT, data=json.dumps(transfer_tx.to_dict()))
|
||||
@ -148,7 +147,6 @@ 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()
|
||||
|
||||
@ -156,7 +154,7 @@ def test_post_invalid_transfer_transaction_returns_400(b, client, user_pk, user_
|
||||
create_tx = b.get_transaction(input_valid.txid)
|
||||
transfer_tx = Transaction.transfer(create_tx.to_inputs(),
|
||||
[([user_pub], 1)],
|
||||
AssetLink(create_tx.id))
|
||||
asset_id=create_tx.id)
|
||||
|
||||
res = client.post(TX_ENDPOINT, data=json.dumps(transfer_tx.to_dict()))
|
||||
assert res.status_code == 400
|
||||
|
Loading…
x
Reference in New Issue
Block a user