From 4bb64fa0b83d337e44ba2b961ac9d8966c2fd8c6 Mon Sep 17 00:00:00 2001 From: Scott Sadler Date: Thu, 19 Jan 2017 13:02:58 +0100 Subject: [PATCH] generalise get_owned_ids to get_outputs and get_owned_ids --- bigchaindb/common/transaction.py | 2 +- bigchaindb/core.py | 27 ++++++++++++++++++++------- tests/common/test_transaction.py | 9 +++++++++ tests/db/test_bigchain_api.py | 13 +++++++++++++ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/bigchaindb/common/transaction.py b/bigchaindb/common/transaction.py index bda62663..563638ce 100644 --- a/bigchaindb/common/transaction.py +++ b/bigchaindb/common/transaction.py @@ -159,7 +159,7 @@ class TransactionLink(object): def __eq__(self, other): # TODO: If `other !== TransactionLink` return `False` - return self.to_dict() == self.to_dict() + return self.to_dict() == other.to_dict() @classmethod def from_dict(cls, link): diff --git a/bigchaindb/core.py b/bigchaindb/core.py index f9c96bed..459c4908 100644 --- a/bigchaindb/core.py +++ b/bigchaindb/core.py @@ -373,8 +373,9 @@ class Bigchain(object): else: return None - def get_owned_ids(self, owner): - """Retrieve a list of ``txid`` s that can be used as inputs. + def get_outputs(self, owner): + """Retrieve a list of links to transaction outputs for a given public + key. Args: owner (str): base58 encoded public key. @@ -383,10 +384,9 @@ class Bigchain(object): :obj:`list` of TransactionLink: list of ``txid`` s and ``output`` s pointing to another transaction's condition """ - # get all transactions in which owner is in the `owners_after` list response = backend.query.get_owned_ids(self.connection, owner) - owned = [] + links = [] for tx in response: # disregard transactions from invalid blocks @@ -411,10 +411,23 @@ class Bigchain(object): # subfulfillment for `owner` if utils.condition_details_has_owner(output['condition']['details'], owner): tx_link = TransactionLink(tx['id'], index) - # check if input was already spent - if not self.get_spent(tx_link.txid, tx_link.output): - owned.append(tx_link) + links.append(tx_link) + return links + def get_owned_ids(self, owner): + """Retrieve a list of ``txid`` s that can be used as inputs. + + Args: + owner (str): base58 encoded public key. + + Returns: + :obj:`list` of TransactionLink: list of ``txid`` s and ``output`` s + pointing to another transaction's condition + """ + owned = [] + for tx_link in self.get_outputs(owner): + if not self.get_spent(tx_link.txid, tx_link.output): + owned.append(tx_link) return owned def get_transactions_filtered(self, asset_id, operation=None): diff --git a/tests/common/test_transaction.py b/tests/common/test_transaction.py index b4ef427c..56f81262 100644 --- a/tests/common/test_transaction.py +++ b/tests/common/test_transaction.py @@ -436,6 +436,15 @@ def test_cast_transaction_link_to_boolean(): assert bool(TransactionLink(False, False)) is True +def test_transaction_link_eq(): + from bigchaindb.common.transaction import TransactionLink + + assert TransactionLink(1, 2) == TransactionLink(1, 2) + assert TransactionLink(2, 2) != TransactionLink(1, 2) + assert TransactionLink(1, 1) != TransactionLink(1, 2) + assert TransactionLink(2, 1) != TransactionLink(1, 2) + + def test_add_input_to_tx(user_input, asset_definition): from bigchaindb.common.transaction import Transaction diff --git a/tests/db/test_bigchain_api.py b/tests/db/test_bigchain_api.py index 1bf028b0..cfc2e93f 100644 --- a/tests/db/test_bigchain_api.py +++ b/tests/db/test_bigchain_api.py @@ -1,6 +1,7 @@ from time import sleep import pytest +from unittest.mock import patch pytestmark = pytest.mark.bdb @@ -1156,3 +1157,15 @@ class TestMultipleInputs(object): # check that the other remain marked as unspent for unspent in transactions[1:]: assert b.get_spent(unspent.id, 0) is None + + +def test_get_owned_ids_calls(): + from bigchaindb.common.transaction import TransactionLink as TL + from bigchaindb.core import Bigchain + with patch('bigchaindb.core.Bigchain.get_outputs') as get_outputs: + get_outputs.return_value = [TL('a', 1), TL('b', 2)] + with patch('bigchaindb.core.Bigchain.get_spent') as get_spent: + get_spent.side_effect = [True, False] + out = Bigchain().get_owned_ids('abc') + assert get_outputs.called_once_with('abc') + assert out == [TL('b', 2)]