Handle the case where there are negative amounts.

Created tests
This commit is contained in:
Rodolphe Marques 2016-11-11 11:34:20 +01:00
parent 6d9cdd0bb5
commit 6d7392d98d
3 changed files with 103 additions and 2 deletions

View File

@ -299,6 +299,8 @@ class Condition(object):
threshold = len(owners_after)
if not isinstance(amount, int):
raise TypeError('`amount` must be a int')
if amount < 1:
raise AmountError('`amount` needs to be greater than zero')
if not isinstance(owners_after, list):
raise TypeError('`owners_after` must be an instance of list')
if len(owners_after) == 0:

View File

@ -73,6 +73,8 @@ class Transaction(Transaction):
input_conditions.append(input_tx.conditions[input_cid])
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
@ -87,8 +89,12 @@ class Transaction(Transaction):
# validate the asset
asset.validate_asset(amount=input_amount)
# validate the amounts
output_amount = sum([condition.amount for
condition in self.conditions])
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
if output_amount != input_amount:
raise AmountError(('The amount used in the inputs `{}`'
' needs to be same as the amount used'

View File

@ -1,5 +1,7 @@
import pytest
from unittest.mock import patch
from ..db.conftest import inputs # noqa
@ -684,3 +686,94 @@ def test_divide(b, user_vk, user_sk):
assert len(tx_transfer_signed.conditions) == 3
for condition in tx_transfer_signed.conditions:
assert condition.amount == 1
# Check that negative inputs are caught when creating a TRANSFER transaction
@pytest.mark.usefixtures('inputs')
def test_non_positive_amounts_on_transfer(b, user_vk):
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(divisible=True)
tx_create = Transaction.create([b.me], [([user_vk], 3)],
asset=asset)
tx_create_signed = tx_create.sign([b.me_private])
# create block
block = b.create_block([tx_create_signed])
assert block.validate(b) == block
b.write_block(block, durability='hard')
# vote
vote = b.vote(block.id, b.get_last_voted_block().id, True)
b.write_vote(vote)
with pytest.raises(AmountError):
Transaction.transfer(tx_create.to_inputs(),
[([b.me], 4), ([b.me], -1)],
asset=tx_create.asset)
# Check that negative inputs are caught when validating a TRANSFER transaction
@pytest.mark.usefixtures('inputs')
def test_non_positive_amounts_on_transfer_validate(b, user_vk, user_sk):
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(divisible=True)
tx_create = Transaction.create([b.me], [([user_vk], 3)],
asset=asset)
tx_create_signed = tx_create.sign([b.me_private])
# create block
block = b.create_block([tx_create_signed])
assert block.validate(b) == block
b.write_block(block, durability='hard')
# vote
vote = b.vote(block.id, b.get_last_voted_block().id, True)
b.write_vote(vote)
# create a transfer transaction with 3 outputs and check if the amount
# of each output is 1
tx_transfer = Transaction.transfer(tx_create.to_inputs(),
[([b.me], 4), ([b.me], 1)],
asset=tx_create.asset)
tx_transfer.conditions[1].amount = -1
tx_transfer_signed = tx_transfer.sign([user_sk])
with pytest.raises(AmountError):
tx_transfer_signed.validate(b)
# Check that negative inputs are caught when creating a CREATE transaction
@pytest.mark.usefixtures('inputs')
def test_non_positive_amounts_on_create(b, user_vk):
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(divisible=True)
with pytest.raises(AmountError):
Transaction.create([b.me], [([user_vk], -3)],
asset=asset)
# Check that negative inputs are caught when validating a CREATE transaction
@pytest.mark.usefixtures('inputs')
def test_non_positive_amounts_on_create_validate(b, user_vk):
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(divisible=True)
tx_create = Transaction.create([b.me], [([user_vk], 3)],
asset=asset)
tx_create.conditions[0].amount = -3
with patch.object(Asset, 'validate_asset', return_value=None):
tx_create_signed = tx_create.sign([b.me_private])
with pytest.raises(AmountError):
tx_create_signed.validate(b)