mirror of
https://github.com/planetmint/planetmint.git
synced 2025-11-24 06:25:45 +00:00
simplified store_bulk_transaction and corresponding query, adjusted test cases
Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>
This commit is contained in:
parent
7f97f9ea4b
commit
18e6cf2335
@ -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 = ""
|
||||
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]))
|
||||
@ -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]:
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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()],
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user