Problem: Block parameters are not required anymore (#2374)

* Problem: all blocks are valid
Solution: remove the status from transactions

* Problem: changed the return type of get_transaction_filtered
Solution: return tx class instead of dict
This commit is contained in:
codegeschrei 2018-08-08 15:08:34 +02:00 committed by Vanshdeep Singh
parent 54b81d3ae8
commit 44be8f572f
5 changed files with 7 additions and 91 deletions

View File

@ -34,18 +34,6 @@ class BigchainDB(object):
Create, read, sign, write transactions to the database Create, read, sign, write transactions to the database
""" """
BLOCK_INVALID = 'invalid'
"""return if a block is invalid"""
BLOCK_VALID = TX_VALID = 'valid'
"""return if a block is valid, or tx is in valid block"""
BLOCK_UNDECIDED = TX_UNDECIDED = 'undecided'
"""return if block is undecided, or tx is in undecided block"""
TX_IN_BACKLOG = 'backlog'
"""return if transaction is in backlog"""
def __init__(self, connection=None): def __init__(self, connection=None):
"""Initialize the Bigchain instance """Initialize the Bigchain instance
@ -251,7 +239,7 @@ class BigchainDB(object):
return backend.query.delete_unspent_outputs( return backend.query.delete_unspent_outputs(
self.connection, *unspent_outputs) self.connection, *unspent_outputs)
def get_transaction(self, transaction_id, include_status=False): def get_transaction(self, transaction_id):
transaction = backend.query.get_transaction(self.connection, transaction_id) transaction = backend.query.get_transaction(self.connection, transaction_id)
if transaction: if transaction:
@ -269,10 +257,7 @@ class BigchainDB(object):
transaction = Transaction.from_dict(transaction) transaction = Transaction.from_dict(transaction)
if include_status: return transaction
return transaction, self.TX_VALID if transaction else None
else:
return transaction
def get_transactions_filtered(self, asset_id, operation=None): def get_transactions_filtered(self, asset_id, operation=None):
"""Get a list of transactions filtered on some criteria """Get a list of transactions filtered on some criteria
@ -280,9 +265,7 @@ class BigchainDB(object):
txids = backend.query.get_txids_filtered(self.connection, asset_id, txids = backend.query.get_txids_filtered(self.connection, asset_id,
operation) operation)
for txid in txids: for txid in txids:
tx, status = self.get_transaction(txid, True) yield self.get_transaction(txid)
if status == self.TX_VALID:
yield tx
def get_outputs_filtered(self, owner, spent=None): def get_outputs_filtered(self, owner, spent=None):
"""Get a list of output links filtered on some criteria """Get a list of output links filtered on some criteria
@ -421,16 +404,8 @@ class BigchainDB(object):
Returns: Returns:
iter: An iterator of assets that match the text search. iter: An iterator of assets that match the text search.
""" """
objects = backend.query.text_search(self.connection, search, limit=limit, return backend.query.text_search(self.connection, search, limit=limit,
table=table) table=table)
# TODO: This is not efficient. There may be a more efficient way to
# query by storing block ids with the assets and using fastquery.
# See https://github.com/bigchaindb/bigchaindb/issues/1496
for obj in objects:
tx, status = self.get_transaction(obj['id'], True)
if status == self.TX_VALID:
yield obj
def get_assets(self, asset_ids): def get_assets(self, asset_ids):
"""Return a list of assets that match the asset_ids """Return a list of assets that match the asset_ids

View File

@ -10,15 +10,12 @@ class Transaction(Transaction):
def validate(self, bigchain, current_transactions=[]): def validate(self, bigchain, current_transactions=[]):
"""Validate transaction spend """Validate transaction spend
Args: Args:
bigchain (BigchainDB): an instantiated bigchaindb.BigchainDB object. bigchain (BigchainDB): an instantiated bigchaindb.BigchainDB object.
Returns: Returns:
The transaction (Transaction) if the transaction is valid else it The transaction (Transaction) if the transaction is valid else it
raises an exception describing the reason why the transaction is raises an exception describing the reason why the transaction is
invalid. invalid.
Raises: Raises:
ValidationError: If the transaction is invalid ValidationError: If the transaction is invalid
""" """

View File

@ -29,9 +29,9 @@ class TransactionApi(Resource):
pool = current_app.config['bigchain_pool'] pool = current_app.config['bigchain_pool']
with pool() as bigchain: with pool() as bigchain:
tx, status = bigchain.get_transaction(tx_id, include_status=True) tx = bigchain.get_transaction(tx_id)
if not tx or status is not bigchain.TX_VALID: if not tx:
return make_error(404) return make_error(404)
return tx.to_dict() return tx.to_dict()

View File

@ -280,7 +280,6 @@ class TestBigchainApi(object):
@pytest.mark.usefixtures('inputs') @pytest.mark.usefixtures('inputs')
def test_write_transaction(self, b, user_pk, user_sk): def test_write_transaction(self, b, user_pk, user_sk):
from bigchaindb import BigchainDB
from bigchaindb.models import Transaction from bigchaindb.models import Transaction
input_tx = b.get_owned_ids(user_pk).pop() input_tx = b.get_owned_ids(user_pk).pop()
@ -294,7 +293,6 @@ class TestBigchainApi(object):
tx_from_db, status = b.get_transaction(tx.id, include_status=True) tx_from_db, status = b.get_transaction(tx.id, include_status=True)
assert tx_from_db.to_dict() == tx.to_dict() assert tx_from_db.to_dict() == tx.to_dict()
assert status == BigchainDB.TX_IN_BACKLOG
@pytest.mark.usefixtures('inputs') @pytest.mark.usefixtures('inputs')
def test_read_transaction(self, b, user_pk, user_sk): def test_read_transaction(self, b, user_pk, user_sk):
@ -315,7 +313,6 @@ class TestBigchainApi(object):
response, status = b.get_transaction(tx.id, include_status=True) response, status = b.get_transaction(tx.id, include_status=True)
# add validity information, which will be returned # add validity information, which will be returned
assert tx.to_dict() == response.to_dict() assert tx.to_dict() == response.to_dict()
assert status == b.TX_UNDECIDED
@pytest.mark.usefixtures('inputs') @pytest.mark.usefixtures('inputs')
def test_read_transaction_invalid_block(self, b, user_pk, user_sk): def test_read_transaction_invalid_block(self, b, user_pk, user_sk):
@ -342,35 +339,6 @@ class TestBigchainApi(object):
# and a copy of the tx is not in the backlog # and a copy of the tx is not in the backlog
assert response is None assert response is None
@pytest.mark.usefixtures('inputs')
def test_read_transaction_invalid_block_and_backlog(self, b, user_pk, user_sk):
from bigchaindb.models import Transaction
input_tx = b.get_owned_ids(user_pk).pop()
input_tx = b.get_transaction(input_tx.txid)
inputs = input_tx.to_inputs()
tx = Transaction.transfer(inputs, [([user_pk], 1)],
asset_id=input_tx.id)
tx = tx.sign([user_sk])
# Make sure there's a copy of tx in the backlog
b.write_transaction(tx)
# create block
block = b.create_block([tx])
b.write_block(block)
# vote the block invalid
vote = b.vote(block.id, b.get_last_voted_block().id, False)
b.write_vote(vote)
# a copy of the tx is both in the backlog and in an invalid
# block, so get_transaction should return a transaction,
# and a status of TX_IN_BACKLOG
response, status = b.get_transaction(tx.id, include_status=True)
assert tx.to_dict() == response.to_dict()
assert status == b.TX_IN_BACKLOG
@pytest.mark.usefixtures('inputs') @pytest.mark.usefixtures('inputs')
def test_genesis_block(self, b): def test_genesis_block(self, b):
from bigchaindb.backend import query from bigchaindb.backend import query

View File

@ -402,30 +402,6 @@ def test_transactions_get_list_bad(client):
assert client.get(url).status_code == 400 assert client.get(url).status_code == 400
@pytest.mark.tendermint
def test_return_only_valid_transaction(client):
from bigchaindb import BigchainDB
def get_transaction_patched(status):
def inner(self, tx_id, include_status):
return {}, status
return inner
# NOTE: `get_transaction` only returns a transaction if it's included in an
# UNDECIDED or VALID block, as well as transactions from the backlog.
# As the endpoint uses `get_transaction`, we don't have to test
# against invalid transactions here.
with patch('bigchaindb.BigchainDB.get_transaction',
get_transaction_patched(BigchainDB.TX_UNDECIDED)):
url = '{}{}'.format(TX_ENDPOINT, '123')
assert client.get(url).status_code == 404
with patch('bigchaindb.BigchainDB.get_transaction',
get_transaction_patched(BigchainDB.TX_IN_BACKLOG)):
url = '{}{}'.format(TX_ENDPOINT, '123')
assert client.get(url).status_code == 404
@pytest.mark.tendermint @pytest.mark.tendermint
@patch('requests.post') @patch('requests.post')
@pytest.mark.parametrize('mode', [ @pytest.mark.parametrize('mode', [