Merge pull request #810 from bigchaindb/feat/332/get-txs-by-asset-id-ignore-invalid-blocks

get_transactions_by_asset_id now ignores invalid transactions
This commit is contained in:
Rodolphe Marques 2016-11-18 15:56:45 +01:00 committed by GitHub
commit 7b170b32c2
3 changed files with 60 additions and 21 deletions

View File

@ -359,22 +359,29 @@ class Bigchain(object):
transactions.append(tx)
return transactions
def get_txs_by_asset_id(self, asset_id):
"""Retrieves transactions related to a particular asset.
def get_transactions_by_asset_id(self, asset_id):
"""Retrieves valid or undecided transactions related to a particular
asset.
A digital asset in bigchaindb is identified by an uuid. This allows us to query all the transactions
related to a particular digital asset, knowing the id.
A digital asset in bigchaindb is identified by an uuid. This allows us
to query all the transactions related to a particular digital asset,
knowing the id.
Args:
asset_id (str): the id for this particular metadata.
Returns:
A list of transactions containing related to the asset. If no transaction exists for that asset it
returns an empty list `[]`
A list of valid or undecided transactions related to the asset.
If no transaction exists for that asset it returns an empty list
`[]`
"""
cursor = self.backend.get_transactions_by_asset_id(asset_id)
return [Transaction.from_dict(tx) for tx in cursor]
txids = self.backend.get_txids_by_asset_id(asset_id)
transactions = []
for txid in txids:
tx = self.get_transaction(txid)
if tx:
transactions.append(tx)
return transactions
def get_asset_by_id(self, asset_id):
"""Returns the asset associated with an asset_id.

View File

@ -164,26 +164,29 @@ class RethinkDBBackend:
metadata_id)
.get_field('id'))
def get_transactions_by_asset_id(self, asset_id):
"""Retrieves transactions related to a particular asset.
def get_txids_by_asset_id(self, asset_id):
"""Retrieves transactions ids related to a particular asset.
A digital asset in bigchaindb is identified by an uuid. This allows us to query all the transactions
related to a particular digital asset, knowing the id.
A digital asset in bigchaindb is identified by an uuid. This allows us
to query all the transactions related to a particular digital asset,
knowing the id.
Args:
asset_id (str): the id for this particular metadata.
Returns:
A list of transactions containing related to the asset. If no transaction exists for that asset it
returns an empty list `[]`
A list of transactions ids related to the asset. If no transaction
exists for that asset it returns an empty list `[]`
"""
# here we only want to return the transaction ids since later on when
# we are going to retrieve the transaction with status validation
return self.connection.run(
r.table('bigchain', read_mode=self.read_mode)
.get_all(asset_id, index='asset_id')
.concat_map(lambda block: block['block']['transactions'])
.filter(lambda transaction:
transaction['transaction']['asset']['id'] == asset_id))
.filter(lambda transaction: transaction['transaction']['asset']['id'] == asset_id)
.get_field('id'))
def get_asset_by_id(self, asset_id):
"""Returns the asset associated with an asset_id.

View File

@ -112,13 +112,13 @@ def test_asset_id_mismatch(b, user_pk):
@pytest.mark.usefixtures('inputs')
def test_get_txs_by_asset_id(b, user_pk, user_sk):
def test_get_transactions_by_asset_id(b, user_pk, user_sk):
from bigchaindb.models import Transaction
tx_create = b.get_owned_ids(user_pk).pop()
tx_create = b.get_transaction(tx_create.txid)
asset_id = tx_create.asset.data_id
txs = b.get_txs_by_asset_id(asset_id)
txs = b.get_transactions_by_asset_id(asset_id)
assert len(txs) == 1
assert txs[0].id == tx_create.id
@ -135,7 +135,7 @@ def test_get_txs_by_asset_id(b, user_pk, user_sk):
vote = b.vote(block.id, b.get_last_voted_block().id, True)
b.write_vote(vote)
txs = b.get_txs_by_asset_id(asset_id)
txs = b.get_transactions_by_asset_id(asset_id)
assert len(txs) == 2
assert tx_create.id in [t.id for t in txs]
@ -144,6 +144,35 @@ def test_get_txs_by_asset_id(b, user_pk, user_sk):
assert asset_id == txs[1].asset.data_id
@pytest.mark.usefixtures('inputs')
def test_get_transactions_by_asset_id_with_invalid_block(b, user_pk, user_sk):
from bigchaindb.models import Transaction
tx_create = b.get_owned_ids(user_pk).pop()
tx_create = b.get_transaction(tx_create.txid)
asset_id = tx_create.asset.data_id
txs = b.get_transactions_by_asset_id(asset_id)
assert len(txs) == 1
assert txs[0].id == tx_create.id
assert txs[0].asset.data_id == asset_id
# create a transfer transaction
tx_transfer = Transaction.transfer(tx_create.to_inputs(), [([user_pk], 1)],
tx_create.asset)
tx_transfer_signed = tx_transfer.sign([user_sk])
# create the block
block = b.create_block([tx_transfer_signed])
b.write_block(block, durability='hard')
# vote the block invalid
vote = b.vote(block.id, b.get_last_voted_block().id, False)
b.write_vote(vote)
txs = b.get_transactions_by_asset_id(asset_id)
assert len(txs) == 1
@pytest.mark.usefixtures('inputs')
def test_get_asset_by_id(b, user_pk, user_sk):
from bigchaindb.models import Transaction
@ -163,7 +192,7 @@ def test_get_asset_by_id(b, user_pk, user_sk):
vote = b.vote(block.id, b.get_last_voted_block().id, True)
b.write_vote(vote)
txs = b.get_txs_by_asset_id(asset_id)
txs = b.get_transactions_by_asset_id(asset_id)
assert len(txs) == 2
asset = b.get_asset_by_id(asset_id)