Skip to content

Commit

Permalink
Problem: Block parameters are not required anymore (#2374)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
codegeschrei authored and kansi committed Aug 8, 2018
1 parent 54b81d3 commit 44be8f5
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 91 deletions.
35 changes: 5 additions & 30 deletions bigchaindb/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,6 @@ class BigchainDB(object):
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):
"""Initialize the Bigchain instance
Expand Down Expand Up @@ -251,7 +239,7 @@ def delete_unspent_outputs(self, *unspent_outputs):
return backend.query.delete_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)

if transaction:
Expand All @@ -269,20 +257,15 @@ def get_transaction(self, transaction_id, include_status=False):

transaction = Transaction.from_dict(transaction)

if include_status:
return transaction, self.TX_VALID if transaction else None
else:
return transaction
return transaction

def get_transactions_filtered(self, asset_id, operation=None):
"""Get a list of transactions filtered on some criteria
"""
txids = backend.query.get_txids_filtered(self.connection, asset_id,
operation)
for txid in txids:
tx, status = self.get_transaction(txid, True)
if status == self.TX_VALID:
yield tx
yield self.get_transaction(txid)

def get_outputs_filtered(self, owner, spent=None):
"""Get a list of output links filtered on some criteria
Expand Down Expand Up @@ -421,16 +404,8 @@ def text_search(self, search, *, limit=0, table='assets'):
Returns:
iter: An iterator of assets that match the text search.
"""
objects = backend.query.text_search(self.connection, search, limit=limit,
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
return backend.query.text_search(self.connection, search, limit=limit,
table=table)

def get_assets(self, asset_ids):
"""Return a list of assets that match the asset_ids
Expand Down
3 changes: 0 additions & 3 deletions bigchaindb/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,12 @@ class Transaction(Transaction):

def validate(self, bigchain, current_transactions=[]):
"""Validate transaction spend
Args:
bigchain (BigchainDB): an instantiated bigchaindb.BigchainDB object.
Returns:
The transaction (Transaction) if the transaction is valid else it
raises an exception describing the reason why the transaction is
invalid.
Raises:
ValidationError: If the transaction is invalid
"""
Expand Down
4 changes: 2 additions & 2 deletions bigchaindb/web/views/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ def get(self, tx_id):
pool = current_app.config['bigchain_pool']

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 tx.to_dict()
Expand Down
32 changes: 0 additions & 32 deletions tests/db/test_bigchain_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ def test_text_search_returns_valid_only(self, monkeypatch, b, alice):

@pytest.mark.usefixtures('inputs')
def test_write_transaction(self, b, user_pk, user_sk):
from bigchaindb import BigchainDB
from bigchaindb.models import Transaction

input_tx = b.get_owned_ids(user_pk).pop()
Expand All @@ -294,7 +293,6 @@ def test_write_transaction(self, b, user_pk, user_sk):
tx_from_db, status = b.get_transaction(tx.id, include_status=True)

assert tx_from_db.to_dict() == tx.to_dict()
assert status == BigchainDB.TX_IN_BACKLOG

@pytest.mark.usefixtures('inputs')
def test_read_transaction(self, b, user_pk, user_sk):
Expand All @@ -315,7 +313,6 @@ def test_read_transaction(self, b, user_pk, user_sk):
response, status = b.get_transaction(tx.id, include_status=True)
# add validity information, which will be returned
assert tx.to_dict() == response.to_dict()
assert status == b.TX_UNDECIDED

@pytest.mark.usefixtures('inputs')
def test_read_transaction_invalid_block(self, b, user_pk, user_sk):
Expand All @@ -342,35 +339,6 @@ def test_read_transaction_invalid_block(self, b, user_pk, user_sk):
# and a copy of the tx is not in the backlog
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')
def test_genesis_block(self, b):
from bigchaindb.backend import query
Expand Down
24 changes: 0 additions & 24 deletions tests/web/test_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,30 +402,6 @@ def should_not_be_called():
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
@patch('requests.post')
@pytest.mark.parametrize('mode', [
Expand Down

0 comments on commit 44be8f5

Please sign in to comment.