diff --git a/bigchaindb/common/transaction.py b/bigchaindb/common/transaction.py index a1dfc626..af3a0de3 100644 --- a/bigchaindb/common/transaction.py +++ b/bigchaindb/common/transaction.py @@ -274,6 +274,15 @@ class TransactionLink(object): 'output_index': self.output, } + def to_query(self): + if self.txid is None and self.output is None: + return None + else: + return [{'transaction_id': self.txid, + 'output_index': self.output}, + {'output_index': self.output, + 'transaction_id': self.txid}] + def to_uri(self, path=''): if self.txid is None and self.output is None: return None diff --git a/bigchaindb/fastquery.py b/bigchaindb/fastquery.py index 0cf873cf..d17fb12d 100644 --- a/bigchaindb/fastquery.py +++ b/bigchaindb/fastquery.py @@ -5,6 +5,7 @@ from bigchaindb.utils import condition_details_has_owner from bigchaindb.backend import query from bigchaindb.common.transaction import TransactionLink +from itertools import chain class FastQuery(): @@ -28,7 +29,7 @@ class FastQuery(): Args: outputs: list of TransactionLink """ - links = [o.to_dict() for o in outputs] + links = list(chain.from_iterable([o.to_query() for o in outputs])) txs = list(query.get_spending_transactions(self.connection, links)) spends = {TransactionLink.from_dict(input_['fulfills']) for tx in txs @@ -41,7 +42,7 @@ class FastQuery(): Args: outputs: list of TransactionLink """ - links = [o.to_dict() for o in outputs] + links = list(chain.from_iterable([o.to_query() for o in outputs])) txs = list(query.get_spending_transactions(self.connection, links)) spends = {TransactionLink.from_dict(input_['fulfills']) for tx in txs diff --git a/tests/tendermint/test_fastquery.py b/tests/tendermint/test_fastquery.py index bf93850f..542ae56c 100644 --- a/tests/tendermint/test_fastquery.py +++ b/tests/tendermint/test_fastquery.py @@ -73,3 +73,49 @@ def test_filter_unspent_outputs(b, user_pk, user_sk): assert set(sp for sp in spents) == { inputs[0].fulfills, } + + +def test_outputs_query_key_order(b, user_pk, user_sk, user2_pk, user2_sk): + from bigchaindb import backend + from bigchaindb.backend import connect + + tx1 = Transaction.create([user_pk], + [([user_pk], 3), ([user_pk], 2), ([user_pk], 1)])\ + .sign([user_sk]) + b.store_bulk_transactions([tx1]) + + inputs = tx1.to_inputs() + tx2 = Transaction.transfer([inputs[0]], [([user2_pk], 2)], tx1.id).sign([user_sk]) + + tx2_dict = tx2.to_dict() + fulfills = tx2_dict['inputs'][0]['fulfills'] + + tx2_dict['inputs'][0]['fulfills'] = {'transaction_id': fulfills['transaction_id'], + 'output_index': fulfills['output_index']} + + backend.query.store_transactions(b.connection, [tx2_dict]) + + outputs = b.get_outputs_filtered(user_pk, spent=False) + assert len(outputs) == 2 + + outputs = b.get_outputs_filtered(user2_pk, spent=False) + assert len(outputs) == 1 + + # clean the transaction, metdata and asset collection + conn = connect() + conn.run(conn.collection('transactions').delete_many({})) + conn.run(conn.collection('metadata').delete_many({})) + conn.run(conn.collection('assets').delete_many({})) + + b.store_bulk_transactions([tx1]) + tx2_dict = tx2.to_dict() + + tx2_dict['inputs'][0]['fulfills'] = {'output_index': fulfills['output_index'], + 'transaction_id': fulfills['transaction_id']} + + backend.query.store_transactions(b.connection, [tx2_dict]) + outputs = b.get_outputs_filtered(user_pk, spent=False) + assert len(outputs) == 2 + + outputs = b.get_outputs_filtered(user2_pk, spent=False) + assert len(outputs) == 1