diff --git a/bigchaindb/backend/localmongodb/query.py b/bigchaindb/backend/localmongodb/query.py index 825e23f5..619da384 100644 --- a/bigchaindb/backend/localmongodb/query.py +++ b/bigchaindb/backend/localmongodb/query.py @@ -29,6 +29,26 @@ def get_transaction(conn, transaction_id): pass +@register_query(LocalMongoDBConnection) +def store_asset(conn, asset): + try: + return conn.run( + conn.collection('assets') + .insert_one(asset)) + except DuplicateKeyError: + pass + + +@register_query(LocalMongoDBConnection) +def get_asset(conn, asset_id): + try: + return conn.run( + conn.collection('assets') + .find_one({'id': asset_id}, {'_id': 0, 'id': 0})) + except IndexError: + pass + + @register_query(LocalMongoDBConnection) def get_spent(conn, transaction_id, output): try: diff --git a/bigchaindb/backend/query.py b/bigchaindb/backend/query.py index 7dcb2de6..7d9a9e68 100644 --- a/bigchaindb/backend/query.py +++ b/bigchaindb/backend/query.py @@ -19,6 +19,20 @@ def write_transaction(connection, signed_transaction): raise NotImplementedError +@singledispatch +def store_asset(connection, asset): + """Write an asset to the asset table. + + Args: + asset (dict): the asset. + + Returns: + The result of the operation. + """ + + raise NotImplementedError + + @singledispatch def store_transaction(connection, signed_transaction): """Same as write_transaction.""" @@ -27,11 +41,25 @@ def store_transaction(connection, signed_transaction): @singledispatch -def get_transaction(connection, signed_transaction): +def get_transaction(connection, transaction_id): """Get a transaction from the transactions table. Args: - signed_transaction (dict): a signed transaction. + transaction_id (str): the id of the transaction. + + Returns: + The result of the operation. + """ + + raise NotImplementedError + + +@singledispatch +def get_asset(connection, asset_id): + """Get a transaction from the transactions table. + + Args: + asset_id (str): the id of the asset Returns: The result of the operation. diff --git a/bigchaindb/tendermint/lib.py b/bigchaindb/tendermint/lib.py index e92877bb..6adb5486 100644 --- a/bigchaindb/tendermint/lib.py +++ b/bigchaindb/tendermint/lib.py @@ -1,5 +1,6 @@ -import logging +from copy import deepcopy from uuid import uuid4 +import logging import requests @@ -38,18 +39,31 @@ class BigchainDB(Bigchain): def store_transaction(self, transaction): """Store a valid transaction to the transactions collection.""" - return backend.query.store_transaction(self.connection, transaction.to_dict()) + transaction = deepcopy(transaction.to_dict()) + if transaction['operation'] == 'CREATE': + asset = transaction.pop('asset') + asset['id'] = transaction['id'] + if asset['data']: + backend.query.store_asset(self.connection, asset) - def get_transaction(self, transaction, include_status=False): - result = backend.query.get_transaction(self.connection, transaction) + return backend.query.store_transaction(self.connection, transaction) - if result: - result = Transaction.from_dict(result) + def get_transaction(self, transaction_id, include_status=False): + transaction = backend.query.get_transaction(self.connection, transaction_id) + asset = backend.query.get_asset(self.connection, transaction_id) + + if transaction: + if asset: + transaction['asset'] = asset + else: + transaction['asset'] = {'data': None} + + transaction = Transaction.from_dict(transaction) if include_status: - return result, self.TX_VALID if result else None + return transaction, self.TX_VALID if transaction else None else: - return result + return transaction def get_spent(self, txid, output): transaction = backend.query.get_spent(self.connection, txid, diff --git a/tests/tendermint/test_lib.py b/tests/tendermint/test_lib.py new file mode 100644 index 00000000..8e41aa19 --- /dev/null +++ b/tests/tendermint/test_lib.py @@ -0,0 +1,29 @@ +from bigchaindb import backend + + +def test_asset_is_separated_from_transaciton(b): + from bigchaindb.models import Transaction + from bigchaindb.common.crypto import generate_key_pair + + alice = generate_key_pair() + bob = generate_key_pair() + + asset = {'Never gonna': ['give you up', + 'let you down', + 'run around' + 'desert you', + 'make you cry', + 'say goodbye', + 'tell a lie', + 'hurt you']} + + tx = Transaction.create([alice.public_key], + [([bob.public_key], 1)], + metadata=None, + asset=asset)\ + .sign([alice.private_key]) + + b.store_transaction(tx) + assert 'asset' not in backend.query.get_transaction(b.connection, tx.id) + assert backend.query.get_asset(b.connection, tx.id)['data'] == asset + assert b.get_transaction(tx.id) == tx