Add Output model

Signed-off-by: cybnon <stefan.weber93@googlemail.com>
This commit is contained in:
cybnon 2022-11-21 09:53:04 +01:00
parent 198bcf46b8
commit afe740bf81
5 changed files with 140 additions and 32 deletions

View File

@ -7,12 +7,9 @@ from dataclasses import dataclass
# NOTE: only here temporarily # NOTE: only here temporarily
from planetmint.backend.models import Asset, MetaData, Input from planetmint.backend.models import Asset, MetaData, Input
from planetmint.backend.models import Output
@dataclass
class Output:
id: str = None
@dataclass @dataclass
class Block: class Block:
id: str = None id: str = None

View File

@ -7,4 +7,5 @@ from .asset import Asset
from .fulfills import Fulfills from .fulfills import Fulfills
from .input import Input from .input import Input
from .metadata import MetaData from .metadata import MetaData
from .script import Script from .script import Script
from .output import Output

View File

@ -0,0 +1,82 @@
# Copyright © 2020 Interplanetary Database Association e.V.,
# Planetmint and IPDB software contributors.
# 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
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class SubCondition:
type: str
body: str
@dataclass
class ConditionDetails:
type: str
public_key: str
threshold: int
sub_conditions: field(default_factory=list)
@dataclass
class Condition:
uri: str
details: ConditionDetails
@dataclass
class Output:
id: str
public_keys: str
condition: Optional[Condition]
@staticmethod
def from_dict(output: dict) -> Output:
return Output(
id=output["id"],
public_keys=output["public_keys"],
condition=Condition(
uri=output["condition"]["uri"],
details=ConditionDetails(
type=output["condition"]["details"]["type"],
public_key=output["condition"]["details"]["public_key"],
threshold=output["condition"]["details"]["threshold"],
sub_conditions=output["condition"]["details"]["subconditions"],
),
),
)
@staticmethod
def from_tuple(output: tuple) -> Output:
return Output(
id=output[0],
public_keys=output[1],
condition=Condition(
uri=output[2],
details=ConditionDetails(
type=output[3],
public_key=output[4],
threshold=output[5],
sub_conditions=output[6],
),
),
)
def to_output_dict(self) -> dict:
return {
"id": self.id,
"public_keys": self.public_keys,
"condition": {
"uri": self.condition.uri,
"details": {
"type": self.condition.details.type,
"public_key": self.condition.details.public_key,
"threshold": self.condition.details.threshold,
"subconditions": self.condition.details.sub_conditions,
},
},
}

View File

@ -7,7 +7,7 @@
from functools import singledispatch from functools import singledispatch
from planetmint.backend.exceptions import OperationError from planetmint.backend.exceptions import OperationError
from planetmint.backend.interfaces import Asset, Block, MetaData, Input, Script from planetmint.backend.interfaces import Asset, Block, MetaData, Input, Script, Output
@singledispatch @singledispatch
def store_asset(connection, asset: dict) -> Asset: def store_asset(connection, asset: dict) -> Asset:
@ -187,6 +187,16 @@ def get_metadata_by_tx_id(connection, transaction_id: str) -> MetaData:
""" """
raise NotImplementedError raise NotImplementedError
@singledispatch
def store_transaction_outputs(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 @singledispatch
def get_metadata(connection, transaction_ids) -> list[MetaData]: def get_metadata(connection, transaction_ids) -> list[MetaData]:
"""Get a list of metadata from the metadata table. """Get a list of metadata from the metadata table.

View File

@ -14,7 +14,7 @@ from planetmint.backend.tarantool.const import TARANT_TABLE_META_DATA, TARANT_TA
TARANT_TABLE_TRANSACTION, TARANT_TABLE_INPUT, TARANT_TABLE_OUTPUT, TARANT_TABLE_SCRIPT, TARANT_TX_ID_SEARCH, \ TARANT_TABLE_TRANSACTION, TARANT_TABLE_INPUT, TARANT_TABLE_OUTPUT, TARANT_TABLE_SCRIPT, TARANT_TX_ID_SEARCH, \
TARANT_ID_SEARCH TARANT_ID_SEARCH
from planetmint.backend.utils import module_dispatch_registrar from planetmint.backend.utils import module_dispatch_registrar
from planetmint.backend.models import Asset, MetaData, Input, Script from planetmint.backend.models import Asset, MetaData, Input, Script, Output
from planetmint.backend.tarantool.connection import TarantoolDBConnection from planetmint.backend.tarantool.connection import TarantoolDBConnection
from planetmint.backend.tarantool.transaction.tools import TransactionCompose, TransactionDecompose from planetmint.backend.tarantool.transaction.tools import TransactionCompose, TransactionDecompose
@ -47,31 +47,43 @@ def _group_transaction_by_ids(connection, txids: list):
_transaction = tx_compose.convert_to_dict() _transaction = tx_compose.convert_to_dict()
_transaction[TARANT_TABLE_INPUT] = [input.to_input_dict() for input in _txinputs] _transaction[TARANT_TABLE_INPUT] = [input.to_input_dict() for input in _txinputs]
_transaction["assets"] = [asset.data for asset in _txassets] _transaction["assets"] = [asset.data for asset in _txassets]
_transaction["metadata"] = _txmeta.metadata _transaction["metadata"] = _txmeta.metadata
if _txscript.script: if _txscript.script:
_transaction[TARANT_TABLE_SCRIPT] = _txscript.script _transaction[TARANT_TABLE_SCRIPT] = _txscript.script
_transactions.append(_transaction) _transactions.append(_transaction)
return _transactions return _transactions
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
def get_inputs_by_tx_id(connection, tx_id: str) -> list[Input]: def get_inputs_by_tx_id(connection, tx_id: str) -> list[Input]:
_inputs = connection.run(connection.space(TARANT_TABLE_INPUT).select(tx_id, index=TARANT_ID_SEARCH)) _inputs = connection.run(connection.space(TARANT_TABLE_INPUT).select(tx_id, index=TARANT_ID_SEARCH))
_sorted_inputs = sorted(_inputs, key=itemgetter(6)) _sorted_inputs = sorted(_inputs, key=itemgetter(6))
return [Input.from_tuple(input) for input in _sorted_inputs] return [Input.from_tuple(input) for input in _sorted_inputs]
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
def store_transaction_inputs(connection, inputs: list[Input]): def store_transaction_inputs(connection, input: Input, index: int):
for index, input in enumerate(inputs): connection.run(connection.space(TARANT_TABLE_INPUT).insert((
connection.run(connection.space(TARANT_TABLE_INPUT).insert(( input.tx_id,
input.tx_id, input.fulfillment,
input.fulfillment, input.owners_before,
input.owners_before, input.fulfills.transaction_id if input.fulfills else "",
input.fulfills.transaction_id if input.fulfills else "", # TODO: the output_index should be an unsigned int
# TODO: the output_index should be an unsigned int str(input.fulfills.output_index) if input.fulfills else "",
str(input.fulfills.output_index) if input.fulfills else "", uuid4().hex,
uuid4().hex, index
index )))
)))
@register_query(TarantoolDBConnection)
def store_transaction_outputs(connection, output: Output, index: int):
connection.run(connection.space(TARANT_TABLE_OUTPUT).insert((
output.public_keys,
output.condition,
output.condition,
index
)))
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
def store_transactions(connection, signed_transactions: list): def store_transactions(connection, signed_transactions: list):
@ -81,11 +93,11 @@ def store_transactions(connection, signed_transactions: list):
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)
inputs = [Input.from_dict(input, transaction["id"]) for input in transaction[TARANT_TABLE_INPUT]] [store_transaction_inputs(connection, Input.from_dict(input, transaction["id"]), index) for
store_transaction_inputs(connection, inputs) index, input in enumerate(transaction[TARANT_TABLE_INPUT])]
for _out in txtuples[TARANT_TABLE_OUTPUT]: [store_transaction_outputs(connection, Output.from_dict(output)) for index, output in
connection.run(connection.space(TARANT_TABLE_OUTPUT).insert(_out), only_data=False) enumerate(transaction[TARANT_TABLE_OUTPUT])]
for _key in txtuples[TARANT_TABLE_KEYS]: for _key in txtuples[TARANT_TABLE_KEYS]:
connection.run(connection.space(TARANT_TABLE_KEYS).insert(_key), only_data=False) connection.run(connection.space(TARANT_TABLE_KEYS).insert(_key), only_data=False)
@ -177,7 +189,8 @@ def get_assets(connection, assets_ids: list) -> list[Asset]:
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
def get_spent(connection, fullfil_transaction_id: str, fullfil_output_index: str): def get_spent(connection, fullfil_transaction_id: str, fullfil_output_index: str):
_inputs = connection.run( _inputs = connection.run(
connection.space(TARANT_TABLE_INPUT).select([fullfil_transaction_id, str(fullfil_output_index)], index="spent_search") connection.space(TARANT_TABLE_INPUT).select([fullfil_transaction_id, str(fullfil_output_index)],
index="spent_search")
) )
_transactions = _group_transaction_by_ids(txids=[inp[0] for inp in _inputs], connection=connection) _transactions = _group_transaction_by_ids(txids=[inp[0] for inp in _inputs], connection=connection)
return _transactions return _transactions
@ -212,7 +225,7 @@ def store_block(connection, block: dict):
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
def get_txids_filtered( def get_txids_filtered(
connection, asset_ids: list[str], operation: str = None, last_tx: any = None connection, asset_ids: list[str], operation: str = None, last_tx: any = None
): # TODO here is used 'OR' operator ): # TODO here is used 'OR' operator
actions = { actions = {
"CREATE": {"sets": ["CREATE", asset_ids], "index": "transaction_search"}, "CREATE": {"sets": ["CREATE", asset_ids], "index": "transaction_search"},
@ -317,15 +330,20 @@ def delete_transactions(connection, txn_ids: list):
for _id in txn_ids: for _id in txn_ids:
connection.run(connection.space(TARANT_TABLE_TRANSACTION).delete(_id), only_data=False) connection.run(connection.space(TARANT_TABLE_TRANSACTION).delete(_id), only_data=False)
for _id in txn_ids: for _id in txn_ids:
_inputs = connection.run(connection.space(TARANT_TABLE_INPUT).select(_id, index=TARANT_ID_SEARCH), only_data=False) _inputs = connection.run(connection.space(TARANT_TABLE_INPUT).select(_id, index=TARANT_ID_SEARCH),
_outputs = connection.run(connection.space(TARANT_TABLE_OUTPUT).select(_id, index=TARANT_ID_SEARCH), only_data=False) only_data=False)
_keys = connection.run(connection.space(TARANT_TABLE_KEYS).select(_id, index=TARANT_TX_ID_SEARCH), only_data=False) _outputs = connection.run(connection.space(TARANT_TABLE_OUTPUT).select(_id, index=TARANT_ID_SEARCH),
only_data=False)
_keys = connection.run(connection.space(TARANT_TABLE_KEYS).select(_id, index=TARANT_TX_ID_SEARCH),
only_data=False)
for _kID in _keys: for _kID in _keys:
connection.run(connection.space(TARANT_TABLE_KEYS).delete(_kID[0], index=TARANT_ID_SEARCH), only_data=False) connection.run(connection.space(TARANT_TABLE_KEYS).delete(_kID[0], index=TARANT_ID_SEARCH), only_data=False)
for _inpID in _inputs: for _inpID in _inputs:
connection.run(connection.space(TARANT_TABLE_INPUT).delete(_inpID[5], index="delete_search"), only_data=False) connection.run(connection.space(TARANT_TABLE_INPUT).delete(_inpID[5], index="delete_search"),
only_data=False)
for _outpID in _outputs: for _outpID in _outputs:
connection.run(connection.space(TARANT_TABLE_OUTPUT).delete(_outpID[5], index="unique_search"), only_data=False) connection.run(connection.space(TARANT_TABLE_OUTPUT).delete(_outpID[5], index="unique_search"),
only_data=False)
for _id in txn_ids: for _id in txn_ids:
connection.run(connection.space(TARANT_TABLE_META_DATA).delete(_id, index=TARANT_ID_SEARCH), only_data=False) connection.run(connection.space(TARANT_TABLE_META_DATA).delete(_id, index=TARANT_ID_SEARCH), only_data=False)
@ -461,7 +479,7 @@ def get_election(connection, election_id: str):
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
def get_asset_tokens_for_public_key( def get_asset_tokens_for_public_key(
connection, asset_id: str, public_key: str connection, asset_id: str, public_key: str
): # FIXME Something can be wrong with this function ! (public_key) is not used # noqa: E501 ): # FIXME Something can be wrong with this function ! (public_key) is not used # noqa: E501
# space = connection.space("keys") # space = connection.space("keys")
# _keys = space.select([public_key], index="keys_search") # _keys = space.select([public_key], index="keys_search")