Problem: Outputs API doesn't respond with correct unspent/spent outputs

Solution: Fix fastquery such that embedded document is queried properly
This commit is contained in:
Vanshdeep Singh 2018-09-21 12:01:38 +02:00
parent 24ca0b32a9
commit dbe6c95784
3 changed files with 58 additions and 2 deletions

View File

@ -274,6 +274,15 @@ class TransactionLink(object):
'output_index': self.output, '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=''): def to_uri(self, path=''):
if self.txid is None and self.output is None: if self.txid is None and self.output is None:
return None return None

View File

@ -5,6 +5,7 @@
from bigchaindb.utils import condition_details_has_owner from bigchaindb.utils import condition_details_has_owner
from bigchaindb.backend import query from bigchaindb.backend import query
from bigchaindb.common.transaction import TransactionLink from bigchaindb.common.transaction import TransactionLink
from itertools import chain
class FastQuery(): class FastQuery():
@ -28,7 +29,7 @@ class FastQuery():
Args: Args:
outputs: list of TransactionLink 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)) txs = list(query.get_spending_transactions(self.connection, links))
spends = {TransactionLink.from_dict(input_['fulfills']) spends = {TransactionLink.from_dict(input_['fulfills'])
for tx in txs for tx in txs
@ -41,7 +42,7 @@ class FastQuery():
Args: Args:
outputs: list of TransactionLink 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)) txs = list(query.get_spending_transactions(self.connection, links))
spends = {TransactionLink.from_dict(input_['fulfills']) spends = {TransactionLink.from_dict(input_['fulfills'])
for tx in txs for tx in txs

View File

@ -73,3 +73,49 @@ def test_filter_unspent_outputs(b, user_pk, user_sk):
assert set(sp for sp in spents) == { assert set(sp for sp in spents) == {
inputs[0].fulfills, 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