diff --git a/bigchaindb/core.py b/bigchaindb/core.py index cd8a013d..d6c6afc3 100644 --- a/bigchaindb/core.py +++ b/bigchaindb/core.py @@ -137,7 +137,7 @@ class Bigchain(object): response = r.table('backlog').insert(signed_transaction, durability=durability).run(self.conn) return response - def get_transaction(self, txid): + def get_transaction(self, txid, include_status=False): """Retrieve a transaction with `txid` from bigchain. Queries the bigchain for a transaction, if it's in a valid or invalid @@ -153,38 +153,40 @@ class Bigchain(object): returns `None` """ + response, tx_status = None, None + validity = self.get_blocks_status_containing_tx(txid) if validity: # Disregard invalid blocks, and return if there are no valid or undecided blocks validity = {_id: status for _id, status in validity.items() if status != Bigchain.BLOCK_INVALID} - if not validity: - return None + if validity: - # If the transaction is in a valid or any undecided block, return it. Does not check - # if transactions in undecided blocks are consistent, but selects the valid block before - # undecided ones - for _id in validity: - target_block_id = _id - if validity[_id] == Bigchain.BLOCK_VALID: - tx_status = self.TX_VALID - break - else: - tx_status = self.TX_UNDECIDED + # If the transaction is in a valid or any undecided block, return it. Does not check + # if transactions in undecided blocks are consistent, but selects the valid block before + # undecided ones + for _id in validity: + target_block_id = _id + if validity[_id] == Bigchain.BLOCK_VALID: + tx_status = self.TX_VALID + break + else: + tx_status = self.TX_UNDECIDED - # Query the transaction in the target block and return - response = r.table('bigchain', read_mode=self.read_mode).get(target_block_id)\ - .get_field('block').get_field('transactions')\ - .filter(lambda tx: tx['id'] == txid).run(self.conn)[0] - response['validity'] = tx_status - return response + # Query the transaction in the target block and return + response = r.table('bigchain', read_mode=self.read_mode).get(target_block_id)\ + .get_field('block').get_field('transactions')\ + .filter(lambda tx: tx['id'] == txid).run(self.conn)[0] else: # Otherwise, check the backlog response = r.table('backlog').get(txid).run(self.conn) if response: - response['validity'] = self.TX_IN_BACKLOG + tx_status = self.TX_IN_BACKLOG + if include_status: + return response, tx_status + else: return response def search_block_election_on_index(self, value, index): diff --git a/tests/db/test_bigchain_api.py b/tests/db/test_bigchain_api.py index b5eb44ae..26a5e4f8 100644 --- a/tests/db/test_bigchain_api.py +++ b/tests/db/test_bigchain_api.py @@ -120,10 +120,10 @@ class TestBigchainApi(object): block = b.create_block([tx_signed]) b.write_block(block, durability='hard') - response = b.get_transaction(tx_signed["id"]) + response, status = b.get_transaction(tx_signed["id"], include_status=True) # add validity information, which will be returned - tx_signed['validity'] = 'undecided' assert util.serialize(tx_signed) == util.serialize(response) + assert status == 'undecided' @pytest.mark.usefixtures('inputs') def test_read_transaction_backlog(self, b, user_vk, user_sk): @@ -132,10 +132,10 @@ class TestBigchainApi(object): tx_signed = b.sign_transaction(tx, user_sk) b.write_transaction(tx_signed) - response = b.get_transaction(tx_signed["id"]) + response, status = b.get_transaction(tx_signed["id"], include_status=True) # add validity information, which will be returned - tx_signed['validity'] = 'backlog' assert util.serialize(tx_signed) == util.serialize(response) + assert status == 'backlog' @pytest.mark.usefixtures('inputs') def test_read_transaction_invalid_block(self, b, user_vk, user_sk): @@ -171,10 +171,10 @@ class TestBigchainApi(object): vote = b.vote(block['id'], b.get_last_voted_block()['id'], True) b.write_vote(vote) - response = b.get_transaction(tx_signed["id"]) + response, status = b.get_transaction(tx_signed["id"], include_status=True) # add validity information, which will be returned - tx_signed['validity'] = 'valid' assert util.serialize(tx_signed) == util.serialize(response) + assert status == 'valid' @pytest.mark.usefixtures('inputs') def test_assign_transaction_one_node(self, b, user_vk, user_sk):