diff --git a/bigchaindb/web/views/transactions.py b/bigchaindb/web/views/transactions.py index 6a52dac4..e4ae5ea7 100644 --- a/bigchaindb/web/views/transactions.py +++ b/bigchaindb/web/views/transactions.py @@ -28,9 +28,9 @@ class TransactionApi(Resource): pool = current_app.config['bigchain_pool'] with pool() as bigchain: - tx = bigchain.get_transaction(tx_id) + tx, status = bigchain.get_transaction(tx_id, include_status=True) - if not tx: + if not tx or status is not bigchain.TX_VALID: return make_error(404) return tx.to_dict() diff --git a/docs/server/source/http-client-server-api.rst b/docs/server/source/http-client-server-api.rst index 9fd7aee5..543789a4 100644 --- a/docs/server/source/http-client-server-api.rst +++ b/docs/server/source/http-client-server-api.rst @@ -46,12 +46,12 @@ Transactions Get the transaction with the ID ``tx_id``. - This endpoint returns a transaction if it was included in a ``VALID`` block, - if it is still waiting to be processed (``BACKLOG``) or is still in an - undecided block (``UNDECIDED``). All instances of a transaction in invalid - blocks are ignored and treated as if they don't exist. If a request is made - for a transaction and instances of that transaction are found only in - invalid blocks, then the response will be ``404 Not Found``. + This endpoint returns a transaction if it was included in a ``VALID`` block. + All instances of a transaction in invalid/undecided blocks or the backlog + are ignored and treated as if they don't exist. If a request is made for a + transaction and instances of that transaction are found only in + invalid/undecided blocks or the backlog, then the response will be ``404 Not + Found``. :param tx_id: transaction ID :type tx_id: hex string diff --git a/tests/web/test_transactions.py b/tests/web/test_transactions.py index 4c6e76c1..8065c3b9 100644 --- a/tests/web/test_transactions.py +++ b/tests/web/test_transactions.py @@ -270,3 +270,26 @@ def test_transactions_get_list_bad(client): # Test asset ID required url = TX_ENDPOINT + '?operation=CREATE' assert client.get(url).status_code == 400 + + +def test_return_only_valid_transaction(client): + from bigchaindb import Bigchain + + def get_transaction_patched(status): + def inner(self, tx_id, include_status): + return {}, status + return inner + + # NOTE: `get_transaction` only returns a transaction if it's included in an + # UNDECIDED or VALID block, as well as transactions from the backlog. + # As the endpoint uses `get_transaction`, we don't have to test + # against invalid transactions here. + with patch('bigchaindb.core.Bigchain.get_transaction', + get_transaction_patched(Bigchain.TX_UNDECIDED)): + url = '{}{}'.format(TX_ENDPOINT, '123') + assert client.get(url).status_code == 404 + + with patch('bigchaindb.core.Bigchain.get_transaction', + get_transaction_patched(Bigchain.TX_IN_BACKLOG)): + url = '{}{}'.format(TX_ENDPOINT, '123') + assert client.get(url).status_code == 404