This commit is contained in:
Scott Sadler 2017-01-26 13:39:06 +01:00
parent 05fdcef670
commit 9762b4b968
2 changed files with 35 additions and 0 deletions

View File

@ -88,6 +88,11 @@ class Transaction(Transaction):
if output.amount < 1:
raise AmountError('`amount` needs to be greater than zero')
# Validate that all inputs are distinct
links = [i.fulfills.to_uri() for i in self.inputs]
if len(links) != len(set(links)):
raise DoubleSpend('tx "{}" spends inputs twice'.format(self.id))
# validate asset id
asset_id = Transaction.get_asset_id(input_txs)
if asset_id != self.asset['id']:

View File

@ -1192,3 +1192,33 @@ def test_get_outputs_filtered():
get_outputs.assert_called_once_with('abc')
get_spent.assert_not_called()
assert out == get_outputs.return_value
@pytest.mark.bdb
def test_cant_spend_same_input_twice_in_tx(b, genesis_block):
"""
Recreate duplicated fulfillments bug
https://github.com/bigchaindb/bigchaindb/issues/1099
"""
from bigchaindb.models import Transaction
from bigchaindb.common.exceptions import DoubleSpend
# create a divisible asset
tx_create = Transaction.create([b.me], [([b.me], 100)])
tx_create_signed = tx_create.sign([b.me_private])
assert b.validate_transaction(tx_create_signed) == tx_create_signed
# create a block and valid vote
block = b.create_block([tx_create_signed])
b.write_block(block)
vote = b.vote(block.id, genesis_block.id, True)
b.write_vote(vote)
# Create a transfer transaction with duplicated fulfillments
dup_inputs = tx_create.to_inputs() + tx_create.to_inputs()
tx_transfer = Transaction.transfer(dup_inputs, [([b.me], 200)],
asset_id=tx_create.id)
tx_transfer_signed = tx_transfer.sign([b.me_private])
assert b.is_valid_transaction(tx_transfer_signed) is False
with pytest.raises(DoubleSpend):
tx_transfer_signed.validate(b)