- blackified & fixed recovery / delete transactions issues becaues of data model transitions

- reintegrated get_transaction() call in query -> delegating this to get_complete_transactions_by_ids

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>
This commit is contained in:
Jürgen Eckel 2023-01-09 13:39:15 +01:00
parent 869406d30d
commit 51ae9874d6
No known key found for this signature in database
20 changed files with 94 additions and 95 deletions

View File

@ -17,9 +17,7 @@ class Asset:
return Asset(asset_dict["data"]) if "data" in asset_dict.keys() else Asset(asset_dict["id"])
def to_dict(self) -> dict:
return {
"data": self.data
}
return {"data": self.data}
@staticmethod
def from_list_dict(asset_dict_list: list[dict]) -> list[Asset]:

View File

@ -20,8 +20,4 @@ class Block:
return Block(block_tuple[0], block_tuple[1], block_tuple[2], block_tuple[3])
def to_dict(self) -> dict:
return {
"app_hash": self.app_hash,
"height": self.height,
"transactions": self.transactions
}
return {"app_hash": self.app_hash, "height": self.height, "transactions": self.transactions}

View File

@ -12,7 +12,4 @@ class Fulfills:
output_index: int = 0
def to_dict(self) -> dict:
return {
"transaction_id": self.transaction_id,
"output_index": self.output_index
}
return {"transaction_id": self.transaction_id, "output_index": self.output_index}

View File

@ -56,5 +56,3 @@ class Input:
@staticmethod
def list_to_dict(input_list: list[Input]) -> list[dict]:
return [input.to_dict() for input in input_list or []]

View File

@ -20,6 +20,4 @@ class MetaData:
return MetaData(meta_data)
def to_dict(self) -> dict:
return {
"metadata": self.metadata
}
return {"metadata": self.metadata}

View File

@ -17,10 +17,7 @@ class SubCondition:
return self.type, self.public_key
def to_dict(self) -> dict:
return {
"type": self.type,
"public_key": self.public_key
}
return {"type": self.type, "public_key": self.public_key}
@staticmethod
def from_dict(subcondition_dict: dict) -> SubCondition:
@ -32,6 +29,7 @@ class SubCondition:
return None
return [subcondition.to_dict() for subcondition in subconditions]
@dataclass
class ConditionDetails:
type: str = ""
@ -64,12 +62,12 @@ class ConditionDetails:
sub_conditions=sub_conditions,
)
@dataclass
class Condition:
uri: str = ""
details: ConditionDetails = field(default_factory=ConditionDetails)
@staticmethod
def from_dict(data: dict) -> Condition:
return Condition(
@ -131,7 +129,6 @@ class Output:
"amount": str(self.amount),
}
@staticmethod
def list_to_dict(output_list: list[Output]) -> list[dict]:
return [output.to_dict() for output in output_list or []]

View File

@ -19,6 +19,4 @@ class Script:
return Script(script_dict["script"])
def to_dict(self) -> dict:
return {
"script": self.script
}
return {"script": self.script}

View File

@ -69,24 +69,28 @@ def store_transaction(connection, transaction):
raise NotImplementedError
@singledispatch
def store_governance_transactions(connection, transactions):
"""Store the list of governance transactions."""
raise NotImplementedError
@singledispatch
def store_governance_transaction(connection, transaction):
"""Store a single governance transaction."""
raise NotImplementedError
@singledispatch
def get_governance_transaction_by_id(connection, transaction_id):
"""Get the transaction by transaction id."""
raise NotImplementedError
@singledispatch
def get_transaction_by_id(connection, transaction_id):
"""Get the transaction by transaction id."""
@ -107,18 +111,21 @@ def get_transaction(connection, transaction_id):
raise NotImplementedError
@singledispatch
def get_transactions_by_asset(connection, asset):
"""Get a transaction by id."""
raise NotImplementedError
@singledispatch
def get_transactions_by_metadata(connection, metadata: str, limit: int = 1000) -> list[DbTransaction]:
""" Get a transaction by its metadata cid."""
"""Get a transaction by its metadata cid."""
raise NotImplementedError
@singledispatch
def get_transactions(connection, transactions_ids) -> list[DbTransaction]:
"""Get a transaction from the transactions table.
@ -513,4 +520,4 @@ def get_outputs_by_tx_id(connection, tx_id: str) -> list[Output]:
@singledispatch
def get_metadata(conn, transaction_ids):
"""Retrieve metadata for a list of transactions by their ids"""
raise NotImplementedError
raise NotImplementedError

View File

@ -118,6 +118,7 @@ def drop_database(connection, dbname):
raise NotImplementedError
@singledispatch
def init_database(connection, dbname):
"""Initialize the configured backend for use with Planetmint.

View File

@ -38,7 +38,7 @@ class TarantoolDBConnection(DBConnection):
"pre_commits",
"validator_sets",
"transactions",
"outputs"
"outputs",
]
except tarantool.error.NetworkError as network_err:
logger.info("Host cant be reached")
@ -95,12 +95,12 @@ class TarantoolDBConnection(DBConnection):
raise net_error
def drop_database(self):
self.connect().call('drop')
self.connect().call("drop")
# db_config = Config().get()["database"]
# cmd_resp = self.run_command(command=self.drop_path, config=db_config) # noqa: F841
def init_database(self):
self.connect().call('init')
self.connect().call("init")
# db_config = Config().get()["database"]
# cmd_resp = self.run_command(command=self.init_path, config=db_config) # noqa: F841

View File

@ -21,7 +21,9 @@ from planetmint.backend.tarantool.const import (
TARANT_TABLE_OUTPUT,
TARANT_TABLE_SCRIPT,
TARANT_TX_ID_SEARCH,
TARANT_ID_SEARCH, TARANT_INDEX_TX_BY_ASSET_ID, TARANT_INDEX_SPENDING_BY_ID_AND_OUTPUT_INDEX,
TARANT_ID_SEARCH,
TARANT_INDEX_TX_BY_ASSET_ID,
TARANT_INDEX_SPENDING_BY_ID_AND_OUTPUT_INDEX,
TARANT_TABLE_GOVERNANCE,
)
from planetmint.backend.utils import module_dispatch_registrar
@ -32,7 +34,7 @@ register_query = module_dispatch_registrar(query)
@register_query(TarantoolDBConnection)
def get_complete_transactions_by_ids(connection, txids: list, table = TARANT_TABLE_TRANSACTION) -> list[DbTransaction]:
def get_complete_transactions_by_ids(connection, txids: list, table=TARANT_TABLE_TRANSACTION) -> list[DbTransaction]:
_transactions = []
for txid in txids:
tx = get_transaction_by_id(connection, txid, table)
@ -53,7 +55,12 @@ def get_outputs_by_tx_id(connection, tx_id: str) -> list[Output]:
@register_query(TarantoolDBConnection)
def get_transaction(connection, tx_id: str) -> DbTransaction:
return NotImplemented
transactions = get_complete_transactions_by_ids(connection, (tx_id))
if len(transactions) > 1 or len(transactions) == 0:
return None
else:
return transactions[0]
@register_query(TarantoolDBConnection)
def get_transactions_by_asset(connection, asset: str, limit: int = 1000) -> list[DbTransaction]:
@ -72,16 +79,21 @@ def get_transactions_by_metadata(connection, metadata: str, limit: int = 1000) -
tx_ids = [tx[0] for tx in txs]
return get_complete_transactions_by_ids(connection, tx_ids)
def store_transaction_outputs(connection, output: Output, index: int) -> str:
output_id = uuid4().hex
connection.run(connection.space(TARANT_TABLE_OUTPUT).insert((
output_id,
int(output.amount),
output.public_keys,
output.condition.to_dict(),
index,
output.transaction_id,
)))
connection.run(
connection.space(TARANT_TABLE_OUTPUT).insert(
(
output_id,
int(output.amount),
output.public_keys,
output.condition.to_dict(),
index,
output.transaction_id,
)
)
)
return output_id
@ -107,9 +119,11 @@ def store_transaction(connection, transaction):
transaction["metadata"],
transaction["assets"],
transaction["inputs"],
scripts)
scripts,
)
connection.run(connection.space(TARANT_TABLE_TRANSACTION).insert(tx), only_data=False)
@register_query(TarantoolDBConnection)
def store_governance_transactions(connection, signed_transactions: list):
for transaction in signed_transactions:
@ -119,6 +133,7 @@ def store_governance_transactions(connection, signed_transactions: list):
for index, output in enumerate(transaction[TARANT_TABLE_OUTPUT])
]
@register_query(TarantoolDBConnection)
def store_governance_transaction(connection, transaction):
scripts = None
@ -131,9 +146,11 @@ def store_governance_transaction(connection, transaction):
transaction["metadata"],
transaction["assets"],
transaction["inputs"],
scripts)
scripts,
)
connection.run(connection.space(TARANT_TABLE_GOVERNANCE).insert(tx), only_data=False)
@register_query(TarantoolDBConnection)
def get_governance_transaction_by_id(connection, transaction_id):
txs = connection.run(connection.space(TARANT_TABLE_GOVERNANCE).select(transaction_id, index=TARANT_ID_SEARCH))
@ -141,8 +158,9 @@ def get_governance_transaction_by_id(connection, transaction_id):
return None
return DbTransaction.from_tuple(txs[0])
@register_query(TarantoolDBConnection)
def get_transaction_by_id(connection, transaction_id, table = TARANT_TABLE_TRANSACTION):
def get_transaction_by_id(connection, transaction_id, table=TARANT_TABLE_TRANSACTION):
txs = connection.run(connection.space(table).select(transaction_id, index=TARANT_ID_SEARCH))
if len(txs) == 0:
return None
@ -150,7 +168,7 @@ def get_transaction_by_id(connection, transaction_id, table = TARANT_TABLE_TRANS
@register_query(TarantoolDBConnection)
def get_transaction_single(connection, transaction_id, table = TARANT_TABLE_TRANSACTION) -> DbTransaction:
def get_transaction_single(connection, transaction_id, table=TARANT_TABLE_TRANSACTION) -> DbTransaction:
txs = get_complete_transactions_by_ids(txids=[transaction_id], connection=connection, table=table)
return txs[0] if len(txs) == 1 else None
@ -162,9 +180,12 @@ def get_transactions(connection, transactions_ids: list) -> list[DbTransaction]:
@register_query(TarantoolDBConnection)
def get_asset(connection, asset_id: str) -> Asset:
_data = connection.run(connection.space(TARANT_TABLE_TRANSACTION).select(asset_id, index=TARANT_INDEX_TX_BY_ASSET_ID))
_data = connection.run(
connection.space(TARANT_TABLE_TRANSACTION).select(asset_id, index=TARANT_INDEX_TX_BY_ASSET_ID)
)
return Asset.from_dict(_data[0])
@register_query(TarantoolDBConnection)
def get_assets(connection, assets_ids: list) -> list[Asset]:
_returned_data = []
@ -203,7 +224,10 @@ def get_latest_block(connection):
def store_block(connection, block: dict):
block_unique_id = uuid4().hex
connection.run(
connection.space("blocks").insert((block_unique_id, block["app_hash"], block["height"], block[TARANT_TABLE_TRANSACTION])), only_data=False
connection.space("blocks").insert(
(block_unique_id, block["app_hash"], block["height"], block[TARANT_TABLE_TRANSACTION])
),
only_data=False,
)
@ -212,7 +236,9 @@ def get_txids_filtered(connection, asset_ids: list[str], operation: str = "", la
transactions = []
if operation == "CREATE":
transactions = connection.run(
connection.space(TARANT_TABLE_TRANSACTION).select([asset_ids[0], operation], index="transactions_by_id_and_operation")
connection.space(TARANT_TABLE_TRANSACTION).select(
[asset_ids[0], operation], index="transactions_by_id_and_operation"
)
)
elif operation == "TRANSFER":
transactions = connection.run(
@ -295,34 +321,14 @@ def delete_transactions(connection, txn_ids: list):
for _id in txn_ids:
connection.run(connection.space(TARANT_TABLE_TRANSACTION).delete(_id), only_data=False)
for _id in txn_ids:
_inputs = connection.run(
connection.space(TARANT_TABLE_INPUT).select(_id, index=TARANT_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:
connection.run(
connection.space(TARANT_TABLE_KEYS).delete(_kID[0], index=TARANT_ID_SEARCH), only_data=False
)
for _inpID in _inputs:
connection.run(
connection.space(TARANT_TABLE_INPUT).delete(_inpID[5], index="delete_search"), only_data=False
)
for _outpID in _outputs:
connection.run(
connection.space(TARANT_TABLE_OUTPUT).delete(_outpID[5], index="unique_search"), only_data=False
)
for _id in txn_ids:
connection.run(connection.space(TARANT_TABLE_META_DATA).delete(_id, index=TARANT_ID_SEARCH), only_data=False)
for _id in txn_ids:
connection.run(connection.space(TARANT_TABLE_ASSETS).delete(_id, index=TARANT_TX_ID_SEARCH), only_data=False)
@register_query(TarantoolDBConnection)
def store_unspent_outputs(connection, *unspent_outputs: list):
@ -342,8 +348,9 @@ def delete_unspent_outputs(connection, *unspent_outputs: list):
if unspent_outputs:
for utxo in unspent_outputs:
output = connection.run(
connection.space("utxos")
.delete((utxo["transaction_id"], utxo["output_index"]), index="utxo_by_transaction_id_and_output_index")
connection.space("utxos").delete(
(utxo["transaction_id"], utxo["output_index"]), index="utxo_by_transaction_id_and_output_index"
)
)
result.append(output)
return result
@ -453,7 +460,7 @@ def get_election(connection, election_id: str):
@register_query(TarantoolDBConnection)
def get_asset_tokens_for_public_key(connection, asset_id: str, public_key: str) -> list[DbTransaction]:
def get_asset_tokens_for_public_key(connection, asset_id: str, public_key: str) -> list[DbTransaction]:
# FIXME Something can be wrong with this function ! (public_key) is not used # noqa: E501
# space = connection.space("keys")
# _keys = space.select([public_key], index="keys_search")
@ -461,7 +468,9 @@ def get_asset_tokens_for_public_key(connection, asset_id: str, public_key: str)
# _transactions = _transactions
# _keys = _keys.data
id_transactions = connection.run(connection.space(TARANT_TABLE_GOVERNANCE).select([asset_id]))
asset_id_transactions = connection.run(connection.space(TARANT_TABLE_GOVERNANCE).select([asset_id], index="governance_by_asset_id"))
asset_id_transactions = connection.run(
connection.space(TARANT_TABLE_GOVERNANCE).select([asset_id], index="governance_by_asset_id")
)
transactions = id_transactions + asset_id_transactions
# TODO return transaction class

View File

@ -144,15 +144,18 @@ SCHEMA_DROP_COMMANDS = {
"scripts": "box.space.scripts:drop()",
}
@register_schema(TarantoolDBConnection)
def init_database(connection, db_name=None):
print('init database tarantool schema')
connection.connect().call('init')
print("init database tarantool schema")
connection.connect().call("init")
@register_schema(TarantoolDBConnection)
def drop_database(connection, db_name=None):
print('drop database tarantool schema')
connection.connect().call('drop')
print("drop database tarantool schema")
connection.connect().call("drop")
@register_schema(TarantoolDBConnection)
def create_database(connection, dbname):
@ -180,4 +183,4 @@ def run_command_with_output(command):
@register_schema(TarantoolDBConnection)
def create_tables(connection, dbname):
connection.connect().call('init')
connection.connect().call("init")

View File

@ -7,8 +7,4 @@ CHAIN_MIGRATION_ELECTION = "CHAIN_MIGRATION_ELECTION"
VALIDATOR_ELECTION = "VALIDATOR_ELECTION"
VOTE = "VOTE"
GOVERNANCE_TRANSACTION_TYPES = [
CHAIN_MIGRATION_ELECTION,
VALIDATOR_ELECTION,
VOTE
]
GOVERNANCE_TRANSACTION_TYPES = [CHAIN_MIGRATION_ELECTION, VALIDATOR_ELECTION, VOTE]

View File

@ -202,8 +202,8 @@ class App(BaseApplication):
block_txn_hash = calculate_hash(self.block_txn_ids)
block = self.planetmint_node.get_latest_block()
logger.debug('BLOCK: ', block)
logger.debug("BLOCK: ", block)
if self.block_txn_ids:
self.block_txn_hash = calculate_hash([block["app_hash"], block_txn_hash])

View File

@ -236,7 +236,7 @@ class Planetmint(object):
transaction = backend.query.get_transaction_by_id(self.connection, transaction_id)
return bool(transaction)
def get_transaction(self, transaction_id, table = TARANT_TABLE_TRANSACTION):
def get_transaction(self, transaction_id, table=TARANT_TABLE_TRANSACTION):
return backend.query.get_transaction_single(self.connection, transaction_id, table)
def get_transactions(self, txn_ids):
@ -376,11 +376,11 @@ class Planetmint(object):
# store the inputs so that we can check if the asset ids match
input_txs = []
input_conditions = []
table = TARANT_TABLE_TRANSACTION
if tx.operation in GOVERNANCE_TRANSACTION_TYPES:
table = TARANT_TABLE_GOVERNANCE
for input_ in tx.inputs:
input_txid = input_.fulfills.txid
input_tx = self.get_transaction(input_txid, table)
@ -467,7 +467,6 @@ class Planetmint(object):
asset_txs = backend.query.get_transactions_by_asset(self.connection, asset_cid, **kwargs)
# flatten and return all found assets
return list(chain.from_iterable([Asset.list_to_dict(tx.assets) for tx in asset_txs]))
def get_metadata(self, txn_ids) -> list[MetaData]:
"""Return a list of metadata that match the transaction ids (txn_ids)

View File

@ -27,10 +27,10 @@ class AssetListApi(Resource):
del args["limit"]
pool = current_app.config["bigchain_pool"]
with pool() as planet:
assets = planet.get_assets_by_cid(cid, **args)
try:
# This only works with MongoDB as the backend
return assets

View File

@ -47,7 +47,7 @@ def test_get_owned_ids(signed_create_tx, user_pk, db_conn):
# insert a transaction
query.store_transactions(connection=db_conn, signed_transactions=[signed_create_tx.to_dict()])
txns = query.get_owned_ids(connection=db_conn, owner=user_pk)
tx_dict = signed_create_tx.to_dict()
owned_tx = remove_generated_fields(txns[0].to_dict())

View File

@ -5,6 +5,7 @@
from planetmint.backend.tarantool.connection import TarantoolDBConnection
def _check_spaces_by_list(conn, space_names):
_exists = []
for name in space_names:

View File

@ -305,7 +305,8 @@ def test_store_one_unspent_output(b, unspent_output_1, utxo_collection):
else:
utx_space = b.connection.get_space("utxos")
res = utx_space.select(
[unspent_output_1["transaction_id"], unspent_output_1["output_index"]], index="utxo_by_transaction_id_and_output_index"
[unspent_output_1["transaction_id"], unspent_output_1["output_index"]],
index="utxo_by_transaction_id_and_output_index",
)
assert len(res.data) == 1

View File

@ -32,8 +32,8 @@ def flush_localmongo_db(connection, dbname):
@flush_db.register(TarantoolDBConnection)
def flush_tarantool_db(connection, dbname):
connection.connect().call('drop')
connection.connect().call('init')
connection.connect().call("drop")
connection.connect().call("init")
def generate_block(planet):