From 7796d5c615ab9752324acaf2d9f38a9d47caa2c4 Mon Sep 17 00:00:00 2001 From: cybnon Date: Thu, 24 Nov 2022 09:08:52 +0100 Subject: [PATCH] Further fixes --- planetmint/backend/models/{key.py => keys.py} | 9 ++- planetmint/backend/models/output.py | 43 +++++++---- planetmint/backend/query.py | 24 ++++++ planetmint/backend/tarantool/query.py | 75 ++++++++++++++----- 4 files changed, 114 insertions(+), 37 deletions(-) rename planetmint/backend/models/{key.py => keys.py} (81%) diff --git a/planetmint/backend/models/key.py b/planetmint/backend/models/keys.py similarity index 81% rename from planetmint/backend/models/key.py rename to planetmint/backend/models/keys.py index 9103d01..28ca5a5 100644 --- a/planetmint/backend/models/key.py +++ b/planetmint/backend/models/keys.py @@ -10,14 +10,15 @@ from typing import Optional @dataclass class Keys: tx_id: str = "" - public_key: str = "" + output_id: str = "" + public_keys: [str] = "" @staticmethod def from_dict(output: dict, tx_id: str = "") -> Keys: if output["condition"]["details"].get("subconditions") is None: return Keys( tx_id=tx_id, - public_key=output["condition"]["details"]["public_key"], + public_keys=output["public_keys"], ) @@ -25,11 +26,11 @@ class Keys: def from_tuple(output: tuple) -> Keys: return Keys( tx_id=output[0], - public_key=output[1], + public_keys=output[1], ) def to_output_dict(self) -> dict: return { "tx_id": self.tx_id, - "public_keys": self.public_key, + "public_keys": self.public_keys, } diff --git a/planetmint/backend/models/output.py b/planetmint/backend/models/output.py index 3ca0a55..d2a8c92 100644 --- a/planetmint/backend/models/output.py +++ b/planetmint/backend/models/output.py @@ -5,6 +5,9 @@ from __future__ import annotations from dataclasses import dataclass, field +from typing import List + +from planetmint.backend.models.keys import Keys @dataclass @@ -31,15 +34,17 @@ class Condition: class Output: tx_id: str = "" amount: int = 0 + public_keys: List[str] = field(default_factory=list) condition: Condition = field(default_factory=Condition) @staticmethod - def from_dict(output: dict, tx_id: str = "") -> Output: + def outputs_and_keys_dict(output: dict, tx_id: str = "") -> (Output, Keys): + out_dict: Output if output["condition"]["details"].get("subconditions") is None: - return output_with_public_key(output, tx_id) + out_dict = output_with_public_key(output, tx_id) else: - print(output) - return output_with_sub_conditions(output, tx_id) + out_dict = output_with_sub_conditions(output, tx_id) + return out_dict, Keys.from_dict(output, tx_id) @staticmethod def from_tuple(output: tuple) -> Output: @@ -59,6 +64,7 @@ class Output: def to_output_dict(self) -> dict: return { "id": self.tx_id, + "amount": self.amount, "public_keys": self.public_keys, "condition": { "uri": self.condition.uri, @@ -72,9 +78,25 @@ class Output: } +def output_with_public_key(output, tx_id) -> Output: + return Output( + tx_id=tx_id, + public_keys=output["public_keys"], + amount=output["amount"], + condition=Condition( + uri=output["condition"]["uri"], + details=ConditionDetails( + type=output["condition"]["details"]["type"], + public_key=output["condition"]["details"]["public_key"], + ), + ), + ) + + def output_with_sub_conditions(output, tx_id) -> Output: return Output( tx_id=tx_id, + public_keys=output["public_keys"], amount=output["amount"], condition=Condition( uri=output["condition"]["uri"], @@ -95,15 +117,4 @@ def output_with_sub_conditions(output, tx_id) -> Output: ) -def output_with_public_key(output, tx_id) -> Output: - return Output( - tx_id=tx_id, - amount=output["amount"], - condition=Condition( - uri=output["condition"]["uri"], - details=ConditionDetails( - type=output["condition"]["details"]["type"], - public_key=output["condition"]["details"]["public_key"], - ), - ), - ) \ No newline at end of file + diff --git a/planetmint/backend/query.py b/planetmint/backend/query.py index 1762753..47b2f2c 100644 --- a/planetmint/backend/query.py +++ b/planetmint/backend/query.py @@ -8,6 +8,8 @@ from functools import singledispatch from planetmint.backend.exceptions import OperationError from planetmint.backend.interfaces import Asset, Block, MetaData, Input, Script, Output +from planetmint.backend.models.keys import Keys + @singledispatch def store_asset(connection, asset: dict) -> Asset: @@ -187,6 +189,17 @@ def get_metadata_by_tx_id(connection, transaction_id: str) -> MetaData: """ raise NotImplementedError +@singledispatch +def store_transaction_outputs_and_keys(connection, output: Output, index: int): + """Store the transaction outputs. + + Args: + output (Output): the output to store. + index (int): the index of the output in the transaction. + """ + raise NotImplementedError + + @singledispatch def store_transaction_outputs(connection, output: Output, index: int): """Store the transaction outputs. @@ -197,6 +210,17 @@ def store_transaction_outputs(connection, output: Output, index: int): """ raise NotImplementedError +@singledispatch +def store_transaction_keys(connection, keys: [Keys], output_id: str, index: int): + """Store the transaction keys. + + Args: + input (Input): the input to store. + index (int): the index of the input in the transaction. + """ + raise NotImplementedError + + @singledispatch def get_metadata(connection, transaction_ids) -> list[MetaData]: """Get a list of metadata from the metadata table. diff --git a/planetmint/backend/tarantool/query.py b/planetmint/backend/tarantool/query.py index b4a7940..a546d7f 100644 --- a/planetmint/backend/tarantool/query.py +++ b/planetmint/backend/tarantool/query.py @@ -10,6 +10,7 @@ from hashlib import sha256 from operator import itemgetter from tarantool.error import DatabaseError from planetmint.backend import query +from planetmint.backend.models.keys import Keys from planetmint.backend.tarantool.const import TARANT_TABLE_META_DATA, TARANT_TABLE_ASSETS, TARANT_TABLE_KEYS, \ TARANT_TABLE_TRANSACTION, TARANT_TABLE_INPUT, TARANT_TABLE_OUTPUT, TARANT_TABLE_SCRIPT, TARANT_TX_ID_SEARCH, \ TARANT_ID_SEARCH @@ -76,18 +77,54 @@ def store_transaction_inputs(connection, input: Input, index: int): @register_query(TarantoolDBConnection) -def store_transaction_outputs(connection, output: Output, index: int): +def store_transaction_outputs_and_keys(connection, output_key: (Output, Keys), index: int): + output_id = store_transaction_outputs(connection, output_key[0], index) + store_transaction_keys(connection, output_key[1], output_id, index) + + +def store_transaction_outputs(connection, output: Output, index: int) -> str: + output_id = uuid4().hex + if output.condition.details.sub_conditions is None: + tmp_output = ( + output.tx_id, + output.amount, + output.condition.uri if output.condition else "", + output.condition.details.type if output.condition.details else "", + output.condition.details.public_key if output.condition.details else "", + output_id, + None, + None, + index, + ) + else: + tmp_output = ( + output.tx_id, + output.amount, + output.condition.uri if output.condition else "", + output.condition.details.type if output.condition.details else "", + None, + output_id, + output.condition.details.threshold if output.condition.details else "", + json.dumps(output.condition.details.sub_conditions, default=) if output.condition.details.sub_conditions else "", + index, + ) + connection.run(connection.space(TARANT_TABLE_OUTPUT).insert(( - output.tx_id, - output.amount, - output.condition.uri if output.condition else "", - output.condition.details.type if output.condition.details else "", - output.condition.details.public_key if output.condition.details else "", - uuid4().hex, - output.condition.details.threshold if output.condition.details else "", - output.condition.details.sub_conditions if output.condition.details else "", - index + tmp_output ))) + return output_id + + +@register_query(TarantoolDBConnection) +def store_transaction_keys(connection, keys: Keys, output_id: str, index: int): + for key in keys.public_keys: + connection.run(connection.space(TARANT_TABLE_KEYS).insert(( + uuid4().hex, + keys.tx_id, + output_id, + key, + index + ))) @register_query(TarantoolDBConnection) @@ -96,17 +133,16 @@ def store_transactions(connection, signed_transactions: list): txprepare = TransactionDecompose(transaction) txtuples = txprepare.convert_to_tuple() - connection.run(connection.space(TARANT_TABLE_TRANSACTION).insert(txtuples[TARANT_TABLE_TRANSACTION]), only_data=False) + connection.run(connection.space(TARANT_TABLE_TRANSACTION).insert(txtuples[TARANT_TABLE_TRANSACTION]), + only_data=False) [store_transaction_inputs(connection, Input.from_dict(input, transaction["id"]), index) for index, input in enumerate(transaction[TARANT_TABLE_INPUT])] - [store_transaction_outputs(connection, Output.from_dict(output, transaction["id"]), index) for index, output in + [store_transaction_outputs_and_keys(connection, Output.outputs_and_keys_dict(output, transaction["id"]), index) + for index, output in enumerate(transaction[TARANT_TABLE_OUTPUT])] - for _key in txtuples[TARANT_TABLE_KEYS]: - connection.run(connection.space(TARANT_TABLE_KEYS).insert(_key), only_data=False) - store_metadatas(connection, [MetaData(transaction["id"], transaction["metadata"])]) assets = [] @@ -116,7 +152,9 @@ def store_transactions(connection, signed_transactions: list): store_assets(connection, assets) if TARANT_TABLE_SCRIPT in transaction: - connection.run(connection.space(TARANT_TABLE_SCRIPT).insert((transaction["id"], transaction[TARANT_TABLE_SCRIPT])), only_data=False) + connection.run( + connection.space(TARANT_TABLE_SCRIPT).insert((transaction["id"], transaction[TARANT_TABLE_SCRIPT])), + only_data=False) @register_query(TarantoolDBConnection) @@ -154,11 +192,13 @@ 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): tuple_asset = (json.dumps(asset.data), asset.tx_id, asset.id) @@ -521,7 +561,8 @@ def get_latest_abci_chain(connection): _chain = sorted(_all_chains, key=itemgetter(0), reverse=True)[0] return {"height": _chain[0], "is_synced": _chain[1], "chain_id": _chain[2]} + @register_query(TarantoolDBConnection) def get_script_by_tx_id(connection, tx_id: str) -> Script: script = connection.run(connection.space(TARANT_TABLE_SCRIPT).select(tx_id, index=TARANT_TX_ID_SEARCH)) - return Script.from_tuple(script[0]) if len(script) < 0 else Script(tx_id) \ No newline at end of file + return Script.from_tuple(script[0]) if len(script) < 0 else Script(tx_id)