mirror of
https://github.com/planetmint/planetmint.git
synced 2025-11-24 14:35:45 +00:00
Add transaction data class
Signed-off-by: cybnon <stefan.weber93@googlemail.com>
This commit is contained in:
parent
b4eb882b1e
commit
2028eb449d
@ -24,12 +24,14 @@ class Keys:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def from_tuple(output: tuple) -> Keys:
|
def from_tuple(output: tuple) -> Keys:
|
||||||
return Keys(
|
return Keys(
|
||||||
tx_id=output[0],
|
tx_id=output[1],
|
||||||
public_keys=output[1],
|
output_id=output[2],
|
||||||
|
public_keys=output[3],
|
||||||
)
|
)
|
||||||
|
|
||||||
def to_output_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
return {
|
return {
|
||||||
"tx_id": self.tx_id,
|
"tx_id": self.tx_id,
|
||||||
|
"output_id": self.output_id,
|
||||||
"public_keys": self.public_keys,
|
"public_keys": self.public_keys,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,13 +55,14 @@ class Output:
|
|||||||
def from_tuple(output: tuple) -> Output:
|
def from_tuple(output: tuple) -> Output:
|
||||||
return Output(
|
return Output(
|
||||||
tx_id=output[0],
|
tx_id=output[0],
|
||||||
|
amount=output[1],
|
||||||
condition=Condition(
|
condition=Condition(
|
||||||
uri=output[1],
|
uri=output[2],
|
||||||
details=ConditionDetails(
|
details=ConditionDetails(
|
||||||
type=output[2],
|
type=output[3],
|
||||||
public_key=output[3],
|
public_key=output[4],
|
||||||
threshold=output[4],
|
threshold=output[6],
|
||||||
sub_conditions=output[5],
|
sub_conditions=output[7],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
38
planetmint/backend/models/transaction.py
Normal file
38
planetmint/backend/models/transaction.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# 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 Transaction:
|
||||||
|
id: str = ""
|
||||||
|
operation: str = ""
|
||||||
|
version: str = ""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_dict(transaction: dict) -> Transaction:
|
||||||
|
return Transaction(
|
||||||
|
id=transaction["id"],
|
||||||
|
operation=transaction["operation"],
|
||||||
|
version=transaction["version"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_tuple(transaction: tuple) -> Transaction:
|
||||||
|
return Transaction(
|
||||||
|
id=transaction[0],
|
||||||
|
operation=transaction[1],
|
||||||
|
version=transaction[2],
|
||||||
|
)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict:
|
||||||
|
return {
|
||||||
|
"id": self.id,
|
||||||
|
"operation": self.operation,
|
||||||
|
"version": self.version,
|
||||||
|
}
|
||||||
@ -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, Output
|
from planetmint.backend.interfaces import Asset, Block, MetaData, Input, Script, Output, Transaction
|
||||||
from planetmint.backend.models.keys import Keys
|
from planetmint.backend.models.keys import Keys
|
||||||
|
|
||||||
|
|
||||||
@ -59,27 +59,26 @@ def store_transactions(connection, signed_transactions):
|
|||||||
|
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
@singledispatch
|
@singledispatch
|
||||||
def get_transaction(connection, transaction_id):
|
def store_transaction(connection, transaction):
|
||||||
"""Get a transaction from the transactions table.
|
"""Store a single transaction."""
|
||||||
|
|
||||||
Args:
|
|
||||||
transaction_id (str): the id of the transaction.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The result of the operation.
|
|
||||||
"""
|
|
||||||
|
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
@singledispatch
|
@singledispatch
|
||||||
def get_transactions(connection, transaction_ids):
|
def get_transaction(conn, transaction_id):
|
||||||
"""Get transactions from the transactions table.
|
"""Get a transaction from the database."""
|
||||||
|
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
@singledispatch
|
||||||
|
def get_transactions(connection, transactions_ids) -> list[Transaction]:
|
||||||
|
"""Get a transaction from the transactions table.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
transaction_ids (list): list of transaction ids to fetch
|
transaction_id (str): the id of the transaction.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The result of the operation.
|
The result of the operation.
|
||||||
|
|||||||
@ -11,13 +11,13 @@ from operator import itemgetter
|
|||||||
from tarantool.error import DatabaseError
|
from tarantool.error import DatabaseError
|
||||||
from planetmint.backend import query
|
from planetmint.backend import query
|
||||||
from planetmint.backend.models.keys import Keys
|
from planetmint.backend.models.keys import Keys
|
||||||
|
from planetmint.backend.models.transaction import Transaction
|
||||||
from planetmint.backend.tarantool.const import TARANT_TABLE_META_DATA, TARANT_TABLE_ASSETS, TARANT_TABLE_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_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, Output
|
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
|
|
||||||
|
|
||||||
register_query = module_dispatch_registrar(query)
|
register_query = module_dispatch_registrar(query)
|
||||||
|
|
||||||
@ -26,10 +26,11 @@ register_query = module_dispatch_registrar(query)
|
|||||||
def _group_transaction_by_ids(connection, txids: list):
|
def _group_transaction_by_ids(connection, txids: list):
|
||||||
_transactions = []
|
_transactions = []
|
||||||
for txid in txids:
|
for txid in txids:
|
||||||
_txobject = connection.run(connection.space(TARANT_TABLE_TRANSACTION).select(txid, index=TARANT_ID_SEARCH))
|
_txobject = connection.run(connection.space(TARANT_TABLE_TRANSACTION).get(txid, index=TARANT_ID_SEARCH))
|
||||||
if len(_txobject) == 0:
|
|
||||||
|
if _txobject is None:
|
||||||
continue
|
continue
|
||||||
_txobject = _txobject[0]
|
|
||||||
_txinputs = get_inputs_by_tx_id(connection, txid)
|
_txinputs = get_inputs_by_tx_id(connection, txid)
|
||||||
_txoutputs = get_outputs_by_tx_id(connection, txid)
|
_txoutputs = get_outputs_by_tx_id(connection, txid)
|
||||||
_txkeys = get_keys_by_tx_id(connection, txid)
|
_txkeys = get_keys_by_tx_id(connection, txid)
|
||||||
@ -37,17 +38,14 @@ def _group_transaction_by_ids(connection, txids: list):
|
|||||||
_txmeta = get_metadata_by_tx_id(connection, txid)
|
_txmeta = get_metadata_by_tx_id(connection, txid)
|
||||||
_txscript = get_script_by_tx_id(connection, txid)
|
_txscript = get_script_by_tx_id(connection, txid)
|
||||||
|
|
||||||
_txoutputs = sorted(_txoutputs, key=itemgetter(8), reverse=False)
|
_transaction = get_transaction(connection, txid)
|
||||||
result_map = {
|
_transaction[TARANT_TABLE_TRANSACTION] = [tx.to_dict for tx in _transactions]
|
||||||
TARANT_TABLE_TRANSACTION: _txobject,
|
_transaction[TARANT_TABLE_INPUT] + [input.to_input_dict() for input in _txinputs]
|
||||||
TARANT_TABLE_OUTPUT: _txoutputs,
|
_transaction[TARANT_TABLE_OUTPUT] = [output.to_output_dict() for output in _txoutputs]
|
||||||
TARANT_TABLE_KEYS: _txkeys,
|
_transaction[TARANT_TABLE_KEYS] = [key.to_dict() for key in _txkeys]
|
||||||
}
|
|
||||||
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["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)
|
||||||
@ -64,14 +62,14 @@ def get_inputs_by_tx_id(connection, tx_id: str) -> list[Input]:
|
|||||||
@register_query(TarantoolDBConnection)
|
@register_query(TarantoolDBConnection)
|
||||||
def get_outputs_by_tx_id(connection, tx_id: str) -> list[Output]:
|
def get_outputs_by_tx_id(connection, tx_id: str) -> list[Output]:
|
||||||
_outputs = connection.run(connection.space(TARANT_TABLE_OUTPUT).select(tx_id, index=TARANT_ID_SEARCH))
|
_outputs = connection.run(connection.space(TARANT_TABLE_OUTPUT).select(tx_id, index=TARANT_ID_SEARCH))
|
||||||
_sorted_inputs = sorted(_outputs, key=itemgetter(6))
|
_sorted_outputs = sorted(_outputs, key=itemgetter(8))
|
||||||
return [Output.from_tuple(output) for output in _sorted_inputs]
|
return [Output.from_tuple(output) for output in _sorted_outputs]
|
||||||
|
|
||||||
|
|
||||||
@register_query(TarantoolDBConnection)
|
@register_query(TarantoolDBConnection)
|
||||||
def get_keys_by_tx_id(connection, tx_id: str) -> list[Keys]:
|
def get_keys_by_tx_id(connection, tx_id: str) -> list[Keys]:
|
||||||
_keys = connection.run(connection.space(TARANT_TABLE_KEYS).select(tx_id, index=TARANT_ID_SEARCH))
|
_keys = connection.run(connection.space(TARANT_TABLE_KEYS).select(tx_id, index=TARANT_TX_ID_SEARCH))
|
||||||
_sorted_keys = sorted(_keys, key=itemgetter(6))
|
_sorted_keys = sorted(_keys, key=itemgetter(4))
|
||||||
return [Keys.from_tuple(key) for key in _sorted_keys]
|
return [Keys.from_tuple(key) for key in _sorted_keys]
|
||||||
|
|
||||||
|
|
||||||
@ -166,15 +164,26 @@ def store_transactions(connection, signed_transactions: list):
|
|||||||
|
|
||||||
|
|
||||||
@register_query(TarantoolDBConnection)
|
@register_query(TarantoolDBConnection)
|
||||||
def get_transaction(connection, transaction_id: str):
|
def store_transaction(connection, transaction):
|
||||||
_transactions = _group_transaction_by_ids(txids=[transaction_id], connection=connection)
|
tx = Transaction(id=transaction["id"], operation=transaction["operation"], version=transaction["version"])
|
||||||
return next(iter(_transactions), None)
|
connection.run(connection.space(TARANT_TABLE_TRANSACTION).insert(
|
||||||
|
tx.id,
|
||||||
|
tx.operation,
|
||||||
|
tx.version,
|
||||||
|
),
|
||||||
|
only_data=False)
|
||||||
|
|
||||||
|
|
||||||
@register_query(TarantoolDBConnection)
|
@register_query(TarantoolDBConnection)
|
||||||
def get_transactions(connection, transactions_ids: list):
|
def get_transaction(connection, transaction_id: str) -> Transaction:
|
||||||
|
return Transaction.from_tuple(
|
||||||
|
connection.run(connection.space(TARANT_TABLE_TRANSACTION).get(transaction_id, index=TARANT_ID_SEARCH)))
|
||||||
|
|
||||||
|
|
||||||
|
@register_query(TarantoolDBConnection)
|
||||||
|
def get_transactions(connection, transactions_ids: list) -> list[Transaction]:
|
||||||
_transactions = _group_transaction_by_ids(txids=transactions_ids, connection=connection)
|
_transactions = _group_transaction_by_ids(txids=transactions_ids, connection=connection)
|
||||||
return _transactions
|
return [Transaction.from_tuple(_transaction) for _transaction in _transactions]
|
||||||
|
|
||||||
|
|
||||||
@register_query(TarantoolDBConnection)
|
@register_query(TarantoolDBConnection)
|
||||||
|
|||||||
@ -1,7 +1,3 @@
|
|||||||
import copy
|
|
||||||
import json
|
|
||||||
|
|
||||||
from secrets import token_hex
|
|
||||||
from transactions.common.memoize import HDict
|
from transactions.common.memoize import HDict
|
||||||
|
|
||||||
from planetmint.backend.tarantool.const import TARANT_TABLE_META_DATA, TARANT_TABLE_ASSETS, TARANT_TABLE_KEYS, \
|
from planetmint.backend.tarantool.const import TARANT_TABLE_META_DATA, TARANT_TABLE_ASSETS, TARANT_TABLE_KEYS, \
|
||||||
@ -55,58 +51,12 @@ class TransactionDecompose:
|
|||||||
else _save_keys_order(dictionary=self._transaction)
|
else _save_keys_order(dictionary=self._transaction)
|
||||||
)
|
)
|
||||||
|
|
||||||
def __create_hash(self, n: int):
|
|
||||||
return token_hex(n)
|
|
||||||
|
|
||||||
def __prepare_outputs(self):
|
|
||||||
_outputs = []
|
|
||||||
_keys = []
|
|
||||||
output_index = 0
|
|
||||||
for _output in self._transaction[TARANT_TABLE_OUTPUT]:
|
|
||||||
output_id = self.__create_hash(7)
|
|
||||||
if _output["condition"]["details"].get("subconditions") is None:
|
|
||||||
tmp_output = (
|
|
||||||
self._transaction["id"],
|
|
||||||
_output["amount"],
|
|
||||||
_output["condition"]["uri"],
|
|
||||||
_output["condition"]["details"]["type"],
|
|
||||||
_output["condition"]["details"]["public_key"],
|
|
||||||
output_id,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
output_index,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
tmp_output = (
|
|
||||||
self._transaction["id"],
|
|
||||||
_output["amount"],
|
|
||||||
_output["condition"]["uri"],
|
|
||||||
_output["condition"]["details"]["type"],
|
|
||||||
None,
|
|
||||||
output_id,
|
|
||||||
_output["condition"]["details"]["threshold"],
|
|
||||||
_output["condition"]["details"]["subconditions"],
|
|
||||||
output_index,
|
|
||||||
)
|
|
||||||
|
|
||||||
_outputs.append(tmp_output)
|
|
||||||
output_index = output_index + 1
|
|
||||||
key_index = 0
|
|
||||||
for _key in _output["public_keys"]:
|
|
||||||
key_id = self.__create_hash(7)
|
|
||||||
_keys.append((key_id, self._transaction["id"], output_id, _key, key_index))
|
|
||||||
key_index = key_index + 1
|
|
||||||
return _keys, _outputs
|
|
||||||
|
|
||||||
def __prepare_transaction(self):
|
def __prepare_transaction(self):
|
||||||
_map = self.get_map()
|
_map = self.get_map()
|
||||||
return (self._transaction["id"], self._transaction["operation"], self._transaction["version"], _map)
|
return (self._transaction["id"], self._transaction["operation"], self._transaction["version"], _map)
|
||||||
|
|
||||||
def convert_to_tuple(self):
|
def convert_to_tuple(self):
|
||||||
self._tuple_transaction[TARANT_TABLE_TRANSACTION] = self.__prepare_transaction()
|
self._tuple_transaction[TARANT_TABLE_TRANSACTION] = self.__prepare_transaction()
|
||||||
keys, outputs = self.__prepare_outputs()
|
|
||||||
self._tuple_transaction[TARANT_TABLE_OUTPUT] = outputs
|
|
||||||
self._tuple_transaction[TARANT_TABLE_KEYS] = keys
|
|
||||||
return self._tuple_transaction
|
return self._tuple_transaction
|
||||||
|
|
||||||
|
|
||||||
@ -124,30 +74,9 @@ class TransactionCompose:
|
|||||||
def _get_transaction_id(self):
|
def _get_transaction_id(self):
|
||||||
return self.db_results[TARANT_TABLE_TRANSACTION][0]
|
return self.db_results[TARANT_TABLE_TRANSACTION][0]
|
||||||
|
|
||||||
def _get_outputs(self):
|
|
||||||
_outputs = []
|
|
||||||
for _output in self.db_results[TARANT_TABLE_OUTPUT]:
|
|
||||||
_out = copy.deepcopy(self._map[TARANT_TABLE_OUTPUT][_output[-1]])
|
|
||||||
_out["amount"] = _output[1]
|
|
||||||
_tmp_keys = [(_key[3], _key[4]) for _key in self.db_results[TARANT_TABLE_KEYS] if _key[2] == _output[5]]
|
|
||||||
_sorted_keys = sorted(_tmp_keys, key=lambda tup: (tup[1]))
|
|
||||||
_out["public_keys"] = [_key[0] for _key in _sorted_keys]
|
|
||||||
|
|
||||||
_out["condition"]["uri"] = _output[2]
|
|
||||||
if _output[7] is None:
|
|
||||||
_out["condition"]["details"]["type"] = _output[3]
|
|
||||||
_out["condition"]["details"]["public_key"] = _output[4]
|
|
||||||
else:
|
|
||||||
_out["condition"]["details"]["subconditions"] = _output[7]
|
|
||||||
_out["condition"]["details"]["type"] = _output[3]
|
|
||||||
_out["condition"]["details"]["threshold"] = _output[6]
|
|
||||||
_outputs.append(_out)
|
|
||||||
return _outputs
|
|
||||||
|
|
||||||
def convert_to_dict(self):
|
def convert_to_dict(self):
|
||||||
transaction = {k: None for k in list(self._map.keys())}
|
transaction = {k: None for k in list(self._map.keys())}
|
||||||
transaction["id"] = self._get_transaction_id()
|
transaction["id"] = self._get_transaction_id()
|
||||||
transaction["version"] = self._get_transaction_version()
|
transaction["version"] = self._get_transaction_version()
|
||||||
transaction["operation"] = self._get_transaction_operation()
|
transaction["operation"] = self._get_transaction_operation()
|
||||||
transaction[TARANT_TABLE_OUTPUT] = self._get_outputs()
|
|
||||||
return transaction
|
return transaction
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user