From 18e6cf2335bb8f4a4c5fa9f398574adc6e03a234 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Thu, 17 Nov 2022 16:14:17 +0100 Subject: [PATCH] simplified store_bulk_transaction and corresponding query, adjusted test cases Signed-off-by: Lorenz Herzberger --- planetmint/backend/models/metadata.py | 9 ++- planetmint/backend/query.py | 12 ++++ planetmint/backend/tarantool/query.py | 27 ++++---- .../backend/tarantool/transaction/tools.py | 26 -------- planetmint/lib.py | 34 +---------- tests/tendermint/test_lib.py | 61 +++---------------- tests/web/test_metadata.py | 2 +- 7 files changed, 45 insertions(+), 126 deletions(-) diff --git a/planetmint/backend/models/metadata.py b/planetmint/backend/models/metadata.py index 1657c7f..c645a63 100644 --- a/planetmint/backend/models/metadata.py +++ b/planetmint/backend/models/metadata.py @@ -3,9 +3,16 @@ # SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) # Code is Apache-2.0 and docs are CC-BY-4.0 +from __future__ import annotations +import json from dataclasses import dataclass +from typing import Optional @dataclass class MetaData: id: str = "" - metadata: str = "" \ No newline at end of file + metadata: Optional[str] = None + + @staticmethod + def from_tuple(meta_data_tuple: tuple) -> MetaData: + return MetaData(meta_data_tuple[0], json.loads(meta_data_tuple[1])) \ No newline at end of file diff --git a/planetmint/backend/query.py b/planetmint/backend/query.py index d1412d7..5824d91 100644 --- a/planetmint/backend/query.py +++ b/planetmint/backend/query.py @@ -174,6 +174,18 @@ def get_block_with_transaction(connection, txid): raise NotImplementedError +@singledispatch +def get_metadata_by_tx_id(connection, transaction_id: str) -> MetaData: + """Get metadata from the metadata table containing `transaction_id`. + + Args: + transaction_id (str): id for the metadata to be retrieved from + the database. + + Returns: + metadata (MetaData): the list of returned metadata. + """ + raise NotImplementedError @singledispatch def get_metadata(connection, transaction_ids) -> list[MetaData]: diff --git a/planetmint/backend/tarantool/query.py b/planetmint/backend/tarantool/query.py index 8d0b958..5e4ed0a 100644 --- a/planetmint/backend/tarantool/query.py +++ b/planetmint/backend/tarantool/query.py @@ -33,7 +33,8 @@ def _group_transaction_by_ids(connection, txids: list): _txoutputs = connection.run(connection.space(TARANT_TABLE_OUTPUT).select(txid, index=TARANT_ID_SEARCH)) _txkeys = connection.run(connection.space(TARANT_TABLE_KEYS).select(txid, index=TARANT_TX_ID_SEARCH)) _txassets = connection.run(connection.space(TARANT_TABLE_ASSETS).select(txid, index=TARANT_TX_ID_SEARCH)) - _txmeta = connection.run(connection.space(TARANT_TABLE_META_DATA).select(txid, index=TARANT_ID_SEARCH)) + _txassets = get_assets(connection, [txid]) + _txmeta = get_metadata_by_tx_id(connection, txid) _txscript = connection.run(connection.space(TARANT_TABLE_SCRIPT).select(txid, index=TARANT_TX_ID_SEARCH)) _txoutputs = sorted(_txoutputs, key=itemgetter(8), reverse=False) @@ -41,13 +42,13 @@ def _group_transaction_by_ids(connection, txids: list): TARANT_TABLE_TRANSACTION: _txobject, TARANT_TABLE_OUTPUT: _txoutputs, TARANT_TABLE_KEYS: _txkeys, - TARANT_TABLE_ASSETS: _txassets, - TARANT_TABLE_META_DATA: _txmeta, TARANT_TABLE_SCRIPT: _txscript, } tx_compose = TransactionCompose(db_results=result_map) _transaction = tx_compose.convert_to_dict() _transaction[TARANT_TABLE_INPUT] = [input.to_input_dict() for input in _txinputs] + _transaction["assets"] = [asset.data for asset in _txassets] + _transaction["metadata"] = _txmeta.metadata _transactions.append(_transaction) return _transactions @@ -76,10 +77,8 @@ def store_transactions(connection, signed_transactions: list): for transaction in signed_transactions: txprepare = TransactionDecompose(transaction) txtuples = txprepare.convert_to_tuple() - try: - connection.run(connection.space(TARANT_TABLE_TRANSACTION).insert(txtuples[TARANT_TABLE_TRANSACTION]), only_data=False) - except: # This is used for omitting duplicate error in database for test -> test_bigchain_api::test_double_inclusion # noqa: E501, E722 - continue + + connection.run(connection.space(TARANT_TABLE_TRANSACTION).insert(txtuples[TARANT_TABLE_TRANSACTION]), only_data=False) inputs = [Input.from_dict(input, transaction["id"]) for input in transaction[TARANT_TABLE_INPUT]] store_transaction_inputs(connection, inputs) @@ -90,11 +89,13 @@ def store_transactions(connection, signed_transactions: list): for _key in txtuples[TARANT_TABLE_KEYS]: connection.run(connection.space(TARANT_TABLE_KEYS).insert(_key), only_data=False) - if txtuples[TARANT_TABLE_META_DATA] is not None: - connection.run(connection.space(TARANT_TABLE_META_DATA).insert(txtuples[TARANT_TABLE_META_DATA]), only_data=False) + store_metadatas(connection, [MetaData(transaction["id"], transaction["metadata"])]) - if txtuples[TARANT_TABLE_ASSETS] is not None: - connection.run(connection.space(TARANT_TABLE_ASSETS).insert(txtuples[TARANT_TABLE_ASSETS]), only_data=False) + assets = [] + for asset in transaction[TARANT_TABLE_ASSETS]: + id = transaction["id"] if "id" not in asset else asset["id"] + assets.append(Asset(id, transaction["id"], asset)) + store_assets(connection, assets) if txtuples[TARANT_TABLE_SCRIPT] is not None: connection.run(connection.space(TARANT_TABLE_SCRIPT).insert(txtuples["script"]), only_data=False) @@ -135,6 +136,10 @@ def get_metadata(connection, transaction_ids: list) -> list[MetaData]: _returned_data.append(metadata) return _returned_data +@register_query(TarantoolDBConnection) +def get_metadata_by_tx_id(connection, transaction_id: str) -> MetaData: + metadata = connection.run(connection.space(TARANT_TABLE_META_DATA).select(transaction_id, index=TARANT_ID_SEARCH)) + return MetaData.from_tuple(metadata[0]) if len(metadata) > 0 else MetaData(transaction_id) @register_query(TarantoolDBConnection) def store_asset(connection, asset: Asset): diff --git a/planetmint/backend/tarantool/transaction/tools.py b/planetmint/backend/tarantool/transaction/tools.py index 6311349..95e847e 100644 --- a/planetmint/backend/tarantool/transaction/tools.py +++ b/planetmint/backend/tarantool/transaction/tools.py @@ -58,20 +58,6 @@ class TransactionDecompose: def __create_hash(self, n: int): return token_hex(n) - def _metadata_check(self): - metadata = self._transaction.get(TARANT_TABLE_META_DATA) - if metadata is None: - return - - self._tuple_transaction[TARANT_TABLE_META_DATA] = (self._transaction["id"], json.dumps(metadata)) - - def __asset_check(self): - _asset = self._transaction.get(TARANT_TABLE_ASSETS) - if _asset is None: - return - asset_id = _asset[0]["id"] if _asset[0].get("id") is not None else self._transaction["id"] - self._tuple_transaction[TARANT_TABLE_ASSETS] = (json.dumps(_asset), self._transaction["id"], asset_id) - def __prepare_outputs(self): _outputs = [] _keys = [] @@ -123,8 +109,6 @@ class TransactionDecompose: return None def convert_to_tuple(self): - self._metadata_check() - self.__asset_check() self._tuple_transaction[TARANT_TABLE_TRANSACTION] = self.__prepare_transaction() keys, outputs = self.__prepare_outputs() self._tuple_transaction[TARANT_TABLE_OUTPUT] = outputs @@ -147,14 +131,6 @@ class TransactionCompose: def _get_transaction_id(self): return self.db_results[TARANT_TABLE_TRANSACTION][0] - def _get_asset(self): - _asset = iter(self.db_results[TARANT_TABLE_ASSETS]) - _res_asset = next(iter(next(_asset, iter([]))), None) - return json.loads(_res_asset) - - def _get_metadata(self): - return json.loads(self.db_results[TARANT_TABLE_META_DATA][0][1]) if len(self.db_results[TARANT_TABLE_META_DATA]) == 1 else None - def _get_outputs(self): _outputs = [] for _output in self.db_results[TARANT_TABLE_OUTPUT]: @@ -184,8 +160,6 @@ class TransactionCompose: def convert_to_dict(self): transaction = {k: None for k in list(self._map.keys())} transaction["id"] = self._get_transaction_id() - transaction[TARANT_TABLE_ASSETS] = self._get_asset() - transaction["metadata"] = self._get_metadata() transaction["version"] = self._get_transaction_version() transaction["operation"] = self._get_transaction_operation() transaction[TARANT_TABLE_OUTPUT] = self._get_outputs() diff --git a/planetmint/lib.py b/planetmint/lib.py index 751ea3c..a352552 100644 --- a/planetmint/lib.py +++ b/planetmint/lib.py @@ -141,29 +141,11 @@ class Planetmint(object): def store_bulk_transactions(self, transactions): txns = [] - assets = [] - txn_metadatas = [] for t in transactions: transaction = t.tx_dict if t.tx_dict else rapidjson.loads(rapidjson.dumps(t.to_dict())) - - tx_assets = transaction.pop("assets") - metadata = transaction.pop("metadata") - - if tx_assets is not None: - for asset in tx_assets: - id = transaction["id"] if "id" not in asset else asset["id"] - tx_asset = Asset(id, transaction["id"], asset) - assets.append(tx_asset) - - metadata = MetaData(transaction["id"], metadata) - - txn_metadatas.append(metadata) txns.append(transaction) - backend.query.store_metadatas(self.connection, txn_metadatas) - if assets: - backend.query.store_assets(self.connection, assets) return backend.query.store_transactions(self.connection, txns) def delete_transactions(self, txs): @@ -251,21 +233,7 @@ class Planetmint(object): def get_transaction(self, transaction_id): transaction = backend.query.get_transaction(self.connection, transaction_id) - if transaction: - assets = backend.query.get_assets(self.connection, [transaction_id]) - metadata = backend.query.get_metadata(self.connection, [transaction_id]) - transaction["assets"] = [asset.data for asset in assets] - - if "metadata" not in transaction: - metadata = metadata[0] if metadata else None - if metadata: - metadata = metadata.metadata - - transaction.update({"metadata": metadata}) - - transaction = Transaction.from_dict(transaction, False) - - return transaction + return Transaction.from_dict(transaction, False) def get_transactions(self, txn_ids): return backend.query.get_transactions(self.connection, txn_ids) diff --git a/tests/tendermint/test_lib.py b/tests/tendermint/test_lib.py index 93a61ab..2f4d64e 100644 --- a/tests/tendermint/test_lib.py +++ b/tests/tendermint/test_lib.py @@ -173,8 +173,6 @@ def test_update_utxoset(b, signed_create_tx, signed_transfer_tx, db_conn): def test_store_transaction(mocker, b, signed_create_tx, signed_transfer_tx, db_context): from planetmint.backend.tarantool.connection import TarantoolDBConnection - mocked_store_asset = mocker.patch("planetmint.backend.query.store_assets") - mocked_store_metadata = mocker.patch("planetmint.backend.query.store_metadatas") mocked_store_transaction = mocker.patch("planetmint.backend.query.store_transactions") b.store_bulk_transactions([signed_create_tx]) if not isinstance(b.connection, TarantoolDBConnection): @@ -184,31 +182,11 @@ def test_store_transaction(mocker, b, signed_create_tx, signed_transfer_tx, db_c utxo = utxoset.find_one() assert utxo["transaction_id"] == signed_create_tx.id assert utxo["output_index"] == 0 - mocked_store_asset.assert_called_once_with( - b.connection, - [ - { - "data": signed_create_tx.assets[0]["data"], - "tx_id": signed_create_tx.id, - "asset_ids": [signed_create_tx.id], - } - ], - ) - else: - mocked_store_asset.assert_called_once_with( - b.connection, [Asset(signed_create_tx.id, signed_create_tx.id, signed_create_tx.assets[0])] - ) - mocked_store_metadata.assert_called_once_with( - b.connection, - [MetaData(signed_create_tx.id, signed_create_tx.metadata)] - ) mocked_store_transaction.assert_called_once_with( b.connection, - [{k: v for k, v in signed_create_tx.to_dict().items() if k not in ("assets", "metadata")}], + [signed_create_tx.to_dict()], ) - mocked_store_asset.reset_mock() - mocked_store_metadata.reset_mock() mocked_store_transaction.reset_mock() b.store_bulk_transactions([signed_transfer_tx]) if not isinstance(b.connection, TarantoolDBConnection): @@ -216,15 +194,10 @@ def test_store_transaction(mocker, b, signed_create_tx, signed_transfer_tx, db_c utxo = utxoset.find_one() assert utxo["transaction_id"] == signed_transfer_tx.id assert utxo["output_index"] == 0 - assert not mocked_store_asset.called - mocked_store_metadata.asser_called_once_with( - b.connection, - [{"id": signed_transfer_tx.id, "metadata": signed_transfer_tx.metadata}], - ) if not isinstance(b.connection, TarantoolDBConnection): mocked_store_transaction.assert_called_once_with( b.connection, - [{k: v for k, v in signed_transfer_tx.to_dict().items() if k != "metadata"}], + [signed_transfer_tx.to_dict()], ) @@ -232,8 +205,6 @@ def test_store_transaction(mocker, b, signed_create_tx, signed_transfer_tx, db_c def test_store_bulk_transaction(mocker, b, signed_create_tx, signed_transfer_tx, db_context): from planetmint.backend.tarantool.connection import TarantoolDBConnection - mocked_store_assets = mocker.patch("planetmint.backend.query.store_assets") - mocked_store_metadata = mocker.patch("planetmint.backend.query.store_metadatas") mocked_store_transactions = mocker.patch("planetmint.backend.query.store_transactions") b.store_bulk_transactions((signed_create_tx,)) if not isinstance(b.connection, TarantoolDBConnection): @@ -243,26 +214,12 @@ def test_store_bulk_transaction(mocker, b, signed_create_tx, signed_transfer_tx, utxo = utxoset.find_one() assert utxo["transaction_id"] == signed_create_tx.id assert utxo["output_index"] == 0 - if isinstance(b.connection, TarantoolDBConnection): - mocked_store_assets.assert_called_once_with( - b.connection, # signed_create_tx.asset['data'] this was before - [Asset(signed_create_tx.id, signed_create_tx.id, signed_create_tx.assets[0])] - ) - else: - mocked_store_assets.assert_called_once_with( - b.connection, # signed_create_tx.asset['data'] this was before - [(signed_create_tx.assets[0]["data"], signed_create_tx.id, signed_create_tx.id)], - ) - mocked_store_metadata.assert_called_once_with( - b.connection, - [MetaData(signed_create_tx.id, signed_create_tx.metadata)] - ) + mocked_store_transactions.assert_called_once_with( b.connection, - [{k: v for k, v in signed_create_tx.to_dict().items() if k not in ("assets", "metadata")}], + [signed_create_tx.to_dict()], ) - mocked_store_assets.reset_mock() - mocked_store_metadata.reset_mock() + mocked_store_transactions.reset_mock() b.store_bulk_transactions((signed_transfer_tx,)) if not isinstance(b.connection, TarantoolDBConnection): @@ -270,15 +227,11 @@ def test_store_bulk_transaction(mocker, b, signed_create_tx, signed_transfer_tx, utxo = utxoset.find_one() assert utxo["transaction_id"] == signed_transfer_tx.id assert utxo["output_index"] == 0 - assert not mocked_store_assets.called - mocked_store_metadata.asser_called_once_with( - b.connection, - [{"id": signed_transfer_tx.id, "metadata": signed_transfer_tx.metadata}], - ) + if not isinstance(b.connection, TarantoolDBConnection): mocked_store_transactions.assert_called_once_with( b.connection, - [{k: v for k, v in signed_transfer_tx.to_dict().items() if k != "metadata"}], + [signed_transfer_tx.to_dict()], ) diff --git a/tests/web/test_metadata.py b/tests/web/test_metadata.py index bf3f6c8..70cf36d 100644 --- a/tests/web/test_metadata.py +++ b/tests/web/test_metadata.py @@ -43,7 +43,7 @@ def test_get_metadata_tendermint(client, b, alice): res = client.get(METADATA_ENDPOINT + "?search=" + metadata) assert res.status_code == 200 assert len(res.json) == 1 - assert res.json[0] == {"metadata": metadata, "id": tx.id} + assert res.json[0] == {"meta_data": metadata, "id": tx.id} @pytest.mark.bdb