From 843d65d2335de9de5797ec5b27e5674a1432a5f8 Mon Sep 17 00:00:00 2001 From: Scott Sadler Date: Wed, 22 Feb 2017 13:26:23 +0100 Subject: [PATCH] bigchain.is_new_transaction method --- bigchaindb/core.py | 16 +++++++++++++++ tests/db/test_bigchain_api.py | 37 +++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/bigchaindb/core.py b/bigchaindb/core.py index a7ed93f0..a4a65482 100644 --- a/bigchaindb/core.py +++ b/bigchaindb/core.py @@ -178,6 +178,22 @@ class Bigchain(object): exceptions.TransactionNotInValidBlock, exceptions.AmountError): return False + def is_new_transaction(self, txid, exclude_block_id=None): + """ + Return True if the transaction does not exist in any + VALID or UNDECIDED block. Return False otherwise. + + Args: + txid (str): Transaction ID + exclude_block_id (str): Exclude block from search + """ + block_statuses = self.get_blocks_status_containing_tx(txid) + block_statuses.pop(exclude_block_id, None) + for status in block_statuses.values(): + if status != self.BLOCK_INVALID: + return False + return True + def get_block(self, block_id, include_status=False): """Get the block with the specified `block_id` (and optionally its status) diff --git a/tests/db/test_bigchain_api.py b/tests/db/test_bigchain_api.py index 31abe176..c5b61c88 100644 --- a/tests/db/test_bigchain_api.py +++ b/tests/db/test_bigchain_api.py @@ -1240,3 +1240,40 @@ def test_transaction_unicode(b): assert b.get_block(block.id) == block.to_dict() assert block.validate(b) == block assert beer_json in serialize(block.to_dict()) + + +@pytest.mark.bdb +def test_is_new_transaction(b, genesis_block): + from bigchaindb.models import Transaction + + def write_tx(n): + tx = Transaction.create([b.me], [([b.me], n)]) + tx = tx.sign([b.me_private]) + # Tx is new because it's not in any block + assert b.is_new_transaction(tx.id) + + block = b.create_block([tx]) + b.write_block(block) + return tx, block + + # test VALID case + tx, block = write_tx(1) + # Tx is now in undecided block + assert not b.is_new_transaction(tx.id) + assert b.is_new_transaction(tx.id, exclude_block_id=block.id) + # After voting valid, should not be new + vote = b.vote(block.id, genesis_block.id, True) + b.write_vote(vote) + assert not b.is_new_transaction(tx.id) + assert b.is_new_transaction(tx.id, exclude_block_id=block.id) + + # test INVALID case + tx, block = write_tx(2) + # Tx is now in undecided block + assert not b.is_new_transaction(tx.id) + assert b.is_new_transaction(tx.id, exclude_block_id=block.id) + vote = b.vote(block.id, genesis_block.id, False) + b.write_vote(vote) + # Tx is new because it's only found in an invalid block + assert b.is_new_transaction(tx.id) + assert b.is_new_transaction(tx.id, exclude_block_id=block.id)