mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
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:
parent
54b81d3ae8
commit
44be8f572f
@ -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
|
||||||
|
@ -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
|
||||||
"""
|
"""
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
@ -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', [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user