mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
addressed comments
This commit is contained in:
parent
efb5439044
commit
a2e28ae806
@ -413,7 +413,7 @@ class Asset(object):
|
||||
self.updatable = updatable
|
||||
self.refillable = refillable
|
||||
|
||||
self._validate_asset()
|
||||
self.validate_asset()
|
||||
|
||||
def __eq__(self, other):
|
||||
try:
|
||||
@ -470,8 +470,9 @@ class Asset(object):
|
||||
transaction are related to the same asset id.
|
||||
|
||||
Args:
|
||||
transactions (list): list of transaction usually inputs that should
|
||||
have a matching asset_id
|
||||
transactions (:obj:`list` of :class:`~bigchaindb.common.
|
||||
transaction.Transaction`): list of transaction usually inputs
|
||||
that should have a matching asset_id
|
||||
|
||||
Returns:
|
||||
str: uuid of the asset.
|
||||
@ -488,11 +489,11 @@ class Asset(object):
|
||||
|
||||
# check that all the transasctions have the same asset_id
|
||||
if len(asset_ids) > 1:
|
||||
raise AssetIdMismatch(('All inputs of a transaction need'
|
||||
' to have the same asset id.'))
|
||||
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):
|
||||
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')
|
||||
@ -670,11 +671,11 @@ class Transaction(object):
|
||||
|
||||
if self.operation == self.CREATE:
|
||||
amount = sum([condition.amount for condition in self.conditions])
|
||||
self.asset._validate_asset(amount=amount)
|
||||
self.asset.validate_asset(amount=amount)
|
||||
else:
|
||||
# In transactions other then `CREATE` we don't know if its a
|
||||
# divisible asset or not, so we cannot validate the amount here
|
||||
self.asset._validate_asset()
|
||||
self.asset.validate_asset()
|
||||
|
||||
@classmethod
|
||||
def create(cls, owners_before, owners_after, metadata=None, asset=None):
|
||||
@ -719,8 +720,9 @@ class Transaction(object):
|
||||
# generate_conditions
|
||||
for owner_after in owners_after:
|
||||
if not isinstance(owner_after, tuple) or len(owner_after) != 2:
|
||||
raise ValueError(('Each `owner_after` in the list is a tuple'
|
||||
' of `([<list of public keys>], <amount>)`'))
|
||||
raise ValueError(('Each `owner_after` in the list must be a'
|
||||
' tuple of `([<list of public keys>],'
|
||||
' <amount>)`'))
|
||||
pub_keys, amount = owner_after
|
||||
conds.append(Condition.generate(pub_keys, amount))
|
||||
|
||||
@ -780,8 +782,9 @@ class Transaction(object):
|
||||
conds = []
|
||||
for owner_after in owners_after:
|
||||
if not isinstance(owner_after, tuple) or len(owner_after) != 2:
|
||||
raise ValueError(('Each `owner_after` in the list is a tuple'
|
||||
' of `([<list of public keys>], <amount>)`'))
|
||||
raise ValueError(('Each `owner_after` in the list must be a'
|
||||
' tuple of `([<list of public keys>],'
|
||||
' <amount>)`'))
|
||||
pub_keys, amount = owner_after
|
||||
conds.append(Condition.generate(pub_keys, amount))
|
||||
|
||||
|
@ -345,14 +345,14 @@ class Bigchain(object):
|
||||
return [Transaction.from_dict(tx) for tx in cursor]
|
||||
|
||||
def get_asset_by_id(self, asset_id):
|
||||
"""Returns the asset associated with an asset_id
|
||||
"""Returns the asset associated with an asset_id.
|
||||
|
||||
Args:
|
||||
asset_id (str): The asset id
|
||||
asset_id (str): The asset id.
|
||||
|
||||
Returns:
|
||||
:class:`~bigchaindb.common.transaction.Asset` if the asset
|
||||
exists else None
|
||||
exists else None.
|
||||
"""
|
||||
cursor = self.backend.get_asset_by_id(asset_id)
|
||||
cursor = list(cursor)
|
||||
|
@ -182,13 +182,13 @@ class RethinkDBBackend:
|
||||
transaction['transaction']['asset']['id'] == asset_id))
|
||||
|
||||
def get_asset_by_id(self, asset_id):
|
||||
"""Returns the asset associated with an asset_id
|
||||
"""Returns the asset associated with an asset_id.
|
||||
|
||||
Args:
|
||||
asset_id (str): The asset id
|
||||
asset_id (str): The asset id.
|
||||
|
||||
Returns:
|
||||
Returns a rethinkdb cursor
|
||||
Returns a rethinkdb cursor.
|
||||
"""
|
||||
return self.connection.run(
|
||||
r.table('bigchain', read_mode=self.read_mode)
|
||||
|
@ -42,7 +42,7 @@ class Transaction(Transaction):
|
||||
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)
|
||||
self.asset.validate_asset(amount=amount)
|
||||
elif self.operation == Transaction.TRANSFER:
|
||||
if not inputs_defined:
|
||||
raise ValueError('Only `CREATE` transactions can have null '
|
||||
@ -85,7 +85,7 @@ class Transaction(Transaction):
|
||||
# get the asset creation to see if its divisible or not
|
||||
asset = bigchain.get_asset_by_id(asset_id)
|
||||
# validate the asset
|
||||
asset._validate_asset(amount=input_amount)
|
||||
asset.validate_asset(amount=input_amount)
|
||||
# validate the amounts
|
||||
output_amount = sum([condition.amount for
|
||||
condition in self.conditions])
|
||||
|
@ -25,7 +25,7 @@ def test_validate_bad_asset_creation(b, user_vk):
|
||||
# `divisible` needs to be a boolean
|
||||
tx = Transaction.create([b.me], [([user_vk], 1)])
|
||||
tx.asset.divisible = 1
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx_signed = tx.sign([b.me_private])
|
||||
with pytest.raises(TypeError):
|
||||
tx_signed.validate(b)
|
||||
@ -33,7 +33,7 @@ def test_validate_bad_asset_creation(b, user_vk):
|
||||
# `refillable` needs to be a boolean
|
||||
tx = Transaction.create([b.me], [([user_vk], 1)])
|
||||
tx.asset.refillable = 1
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx_signed = tx.sign([b.me_private])
|
||||
with pytest.raises(TypeError):
|
||||
b.validate_transaction(tx_signed)
|
||||
@ -41,7 +41,7 @@ def test_validate_bad_asset_creation(b, user_vk):
|
||||
# `updatable` needs to be a boolean
|
||||
tx = Transaction.create([b.me], [([user_vk], 1)])
|
||||
tx.asset.updatable = 1
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx_signed = tx.sign([b.me_private])
|
||||
with pytest.raises(TypeError):
|
||||
b.validate_transaction(tx_signed)
|
||||
@ -49,7 +49,7 @@ def test_validate_bad_asset_creation(b, user_vk):
|
||||
# `data` needs to be a dictionary
|
||||
tx = Transaction.create([b.me], [([user_vk], 1)])
|
||||
tx.asset.data = 'a'
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx_signed = tx.sign([b.me_private])
|
||||
with pytest.raises(TypeError):
|
||||
b.validate_transaction(tx_signed)
|
||||
@ -189,7 +189,7 @@ def test_create_invalid_divisible_asset(b, user_vk, user_sk):
|
||||
# even if a transaction is badly constructed the server should raise the
|
||||
# exception
|
||||
asset = Asset(divisible=False)
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction.create([user_vk], [([user_vk], 2)], asset=asset)
|
||||
tx_signed = tx.sign([user_sk])
|
||||
with pytest.raises(AmountError):
|
||||
@ -197,7 +197,7 @@ def test_create_invalid_divisible_asset(b, user_vk, user_sk):
|
||||
assert b.is_valid_transaction(tx_signed) is False
|
||||
|
||||
asset = Asset(divisible=True)
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction.create([user_vk], [([user_vk], 1)], asset=asset)
|
||||
tx_signed = tx.sign([user_sk])
|
||||
with pytest.raises(AmountError):
|
||||
|
@ -24,7 +24,7 @@ def test_single_in_single_own_single_out_single_own_create(b, user_vk):
|
||||
|
||||
# CREATE divisible asset
|
||||
# Single input
|
||||
# Single onwers_before
|
||||
# Single owners_before
|
||||
# Multiple outputs
|
||||
# Single owners_after per output
|
||||
def test_single_in_single_own_multiple_out_single_own_create(b, user_vk):
|
||||
@ -98,7 +98,7 @@ def test_single_in_single_own_multiple_out_mix_own_create(b, user_vk):
|
||||
# CREATE divisible asset
|
||||
# Single input
|
||||
# Multiple owners_before
|
||||
# Ouput combinations already tested above
|
||||
# Output combinations already tested above
|
||||
def test_single_in_multiple_own_single_out_single_own_create(b, user_vk,
|
||||
user_sk):
|
||||
from bigchaindb.models import Transaction
|
||||
@ -519,7 +519,7 @@ def test_multiple_in_different_transactions(b, user_vk, user_sk):
|
||||
# `b` transfers its 50 shares to `user_vk`
|
||||
# after this transaction `user_vk` will have a total of 100 shares
|
||||
# split across two different transactions
|
||||
tx_transfer1 = Transaction.transfer([tx_create.to_inputs()[1]],
|
||||
tx_transfer1 = Transaction.transfer(tx_create.to_inputs([1]),
|
||||
[([user_vk], 50)],
|
||||
asset=tx_create.asset)
|
||||
tx_transfer1_signed = tx_transfer1.sign([b.me_private])
|
||||
@ -534,8 +534,8 @@ def test_multiple_in_different_transactions(b, user_vk, user_sk):
|
||||
# TRANSFER
|
||||
# `user_vk` combines two different transaction with 50 shares each and
|
||||
# transfers a total of 100 shares back to `b`
|
||||
tx_transfer2 = Transaction.transfer([tx_create.to_inputs()[0],
|
||||
tx_transfer1.to_inputs()[0]],
|
||||
tx_transfer2 = Transaction.transfer(tx_create.to_inputs([0]) +
|
||||
tx_transfer1.to_inputs([0]),
|
||||
[([b.me], 100)],
|
||||
asset=tx_create.asset)
|
||||
tx_transfer2_signed = tx_transfer2.sign([user_sk])
|
||||
|
@ -81,12 +81,12 @@ def test_validate_asset():
|
||||
# test amount errors
|
||||
asset = Asset(divisible=False)
|
||||
with raises(AmountError):
|
||||
asset._validate_asset(amount=2)
|
||||
asset.validate_asset(amount=2)
|
||||
|
||||
asset = Asset(divisible=True)
|
||||
with raises(AmountError):
|
||||
asset._validate_asset(amount=1)
|
||||
asset.validate_asset(amount=1)
|
||||
|
||||
asset = Asset()
|
||||
with raises(TypeError):
|
||||
asset._validate_asset(amount='a')
|
||||
asset.validate_asset(amount='a')
|
||||
|
@ -228,31 +228,6 @@ def test_generate_conditions_single_owner_with_condition(user_pub):
|
||||
assert cond.fulfillment.to_dict() == expected.to_dict()
|
||||
|
||||
|
||||
# TODO FOR CC: see skip reason
|
||||
@mark.skip(reason='threshold(hashlock).to_dict() exposes secret')
|
||||
def test_generate_threshold_condition_with_hashlock(user_pub, user2_pub,
|
||||
user3_pub):
|
||||
from bigchaindb.common.transaction import Condition
|
||||
from cryptoconditions import (PreimageSha256Fulfillment,
|
||||
Ed25519Fulfillment,
|
||||
ThresholdSha256Fulfillment)
|
||||
|
||||
secret = b'much secret, wow'
|
||||
hashlock = PreimageSha256Fulfillment(preimage=secret)
|
||||
|
||||
expected_simple1 = Ed25519Fulfillment(public_key=user_pub)
|
||||
expected_simple3 = Ed25519Fulfillment(public_key=user3_pub)
|
||||
|
||||
expected = ThresholdSha256Fulfillment(threshold=2)
|
||||
expected_sub = ThresholdSha256Fulfillment(threshold=2)
|
||||
expected_sub.add_subfulfillment(expected_simple1)
|
||||
expected_sub.add_subfulfillment(hashlock)
|
||||
expected.add_subfulfillment(expected_simple3)
|
||||
|
||||
cond = Condition.generate([[user_pub, hashlock], expected_simple3], 1)
|
||||
assert cond.fulfillment.to_dict() == expected.to_dict()
|
||||
|
||||
|
||||
def test_generate_conditions_invalid_parameters(user_pub, user2_pub,
|
||||
user3_pub):
|
||||
from bigchaindb.common.transaction import Condition
|
||||
@ -300,7 +275,7 @@ def test_invalid_transaction_initialization():
|
||||
def test_create_default_asset_on_tx_initialization():
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, None)
|
||||
expected = Asset()
|
||||
asset = tx.asset
|
||||
@ -493,7 +468,7 @@ def test_cast_transaction_link_to_boolean():
|
||||
def test_add_fulfillment_to_tx(user_ffill):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, Asset(), [], [])
|
||||
tx.add_fulfillment(user_ffill)
|
||||
|
||||
@ -503,7 +478,7 @@ def test_add_fulfillment_to_tx(user_ffill):
|
||||
def test_add_fulfillment_to_tx_with_invalid_parameters():
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, Asset())
|
||||
with raises(TypeError):
|
||||
tx.add_fulfillment('somewronginput')
|
||||
@ -512,7 +487,7 @@ def test_add_fulfillment_to_tx_with_invalid_parameters():
|
||||
def test_add_condition_to_tx(user_cond):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, Asset())
|
||||
tx.add_condition(user_cond)
|
||||
|
||||
@ -522,7 +497,7 @@ def test_add_condition_to_tx(user_cond):
|
||||
def test_add_condition_to_tx_with_invalid_parameters():
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, Asset(), [], [])
|
||||
with raises(TypeError):
|
||||
tx.add_condition('somewronginput')
|
||||
@ -605,9 +580,7 @@ def test_validate_multiple_fulfillments(user_ffill, user_cond, user_priv):
|
||||
expected_first = deepcopy(tx)
|
||||
expected_second = deepcopy(tx)
|
||||
expected_first.fulfillments = [expected_first.fulfillments[0]]
|
||||
expected_first.conditions = expected_first.conditions
|
||||
expected_second.fulfillments = [expected_second.fulfillments[1]]
|
||||
expected_second.conditions = expected_second.conditions
|
||||
|
||||
expected_first_bytes = str(expected_first).encode()
|
||||
expected_first.fulfillments[0].fulfillment.sign(expected_first_bytes,
|
||||
@ -854,62 +827,6 @@ def test_validate_threshold_create_transaction(user_pub, user_priv, user2_pub,
|
||||
assert tx.fulfillments_valid() is True
|
||||
|
||||
|
||||
@mark.skip(reason='Hashlocks are not implemented')
|
||||
def test_create_create_transaction_hashlock(user_pub, data, data_id):
|
||||
from cryptoconditions import PreimageSha256Fulfillment
|
||||
from bigchaindb.common.transaction import Transaction, Condition, Asset
|
||||
|
||||
secret = b'much secret, wow'
|
||||
hashlock = PreimageSha256Fulfillment(preimage=secret).condition_uri
|
||||
cond = Condition(hashlock)
|
||||
|
||||
expected = {
|
||||
'transaction': {
|
||||
'conditions': [cond.to_dict(0)],
|
||||
'metadata': {
|
||||
'data': data,
|
||||
},
|
||||
'asset': {
|
||||
'id': data_id,
|
||||
'divisible': False,
|
||||
'updatable': False,
|
||||
'refillable': False,
|
||||
'data': data,
|
||||
},
|
||||
'fulfillments': [
|
||||
{
|
||||
'owners_before': [
|
||||
user_pub,
|
||||
],
|
||||
'fid': 0,
|
||||
'fulfillment': None,
|
||||
'input': None
|
||||
},
|
||||
],
|
||||
'operation': 'CREATE',
|
||||
},
|
||||
'version': 1
|
||||
}
|
||||
|
||||
asset = Asset(data, data_id)
|
||||
tx = Transaction.create([user_pub], [], data, asset, secret).to_dict()
|
||||
tx.pop('id')
|
||||
tx['transaction']['metadata'].pop('id')
|
||||
tx['transaction'].pop('timestamp')
|
||||
tx['transaction']['fulfillments'][0]['fulfillment'] = None
|
||||
|
||||
assert tx == expected
|
||||
|
||||
|
||||
@mark.skip(reson='Hashlocks are not implemented')
|
||||
def test_validate_hashlock_create_transaction(user_pub, user_priv, data):
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
|
||||
tx = Transaction.create([user_pub], [], data, Asset(), b'much secret, wow')
|
||||
tx = tx.sign([user_priv])
|
||||
assert tx.fulfillments_valid() is True
|
||||
|
||||
|
||||
def test_create_create_transaction_with_invalid_parameters(user_pub):
|
||||
from bigchaindb.common.transaction import Transaction
|
||||
|
||||
@ -1071,7 +988,7 @@ def test_create_transfer_with_invalid_parameters(user_pub):
|
||||
def test_cant_add_empty_condition():
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, None)
|
||||
with raises(TypeError):
|
||||
tx.add_condition(None)
|
||||
@ -1080,7 +997,7 @@ def test_cant_add_empty_condition():
|
||||
def test_cant_add_empty_fulfillment():
|
||||
from bigchaindb.common.transaction import Transaction, Asset
|
||||
|
||||
with patch.object(Asset, '_validate_asset', return_value=None):
|
||||
with patch.object(Asset, 'validate_asset', return_value=None):
|
||||
tx = Transaction(Transaction.CREATE, None)
|
||||
with raises(TypeError):
|
||||
tx.add_fulfillment(None)
|
||||
|
Loading…
x
Reference in New Issue
Block a user