added tarantool exception catching and raising as well as logging

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>
This commit is contained in:
Jürgen Eckel 2023-01-11 17:20:37 +01:00
parent 0d375b6b60
commit 86f9d07f8f
No known key found for this signature in database
3 changed files with 108 additions and 58 deletions

View File

@ -18,5 +18,9 @@ class OperationError(BackendError):
"""Exception raised when a backend operation fails.""" """Exception raised when a backend operation fails."""
class OperationDataInsertionError(BackendError):
"""Exception raised when a Database operation fails."""
class DuplicateKeyError(OperationError): class DuplicateKeyError(OperationError):
"""Exception raised when an insert fails because the key is not unique""" """Exception raised when an insert fails because the key is not unique"""

View File

@ -5,6 +5,7 @@
"""Query implementation for Tarantool""" """Query implementation for Tarantool"""
import json import json
import logging
from uuid import uuid4 from uuid import uuid4
from hashlib import sha256 from hashlib import sha256
from operator import itemgetter from operator import itemgetter
@ -12,6 +13,7 @@ from operator import itemgetter
from planetmint.backend import query from planetmint.backend import query
from planetmint.backend.models.dbtransaction import DbTransaction from planetmint.backend.models.dbtransaction import DbTransaction
from planetmint.backend.exceptions import OperationDataInsertionError
from planetmint.backend.tarantool.const import ( from planetmint.backend.tarantool.const import (
TARANT_TABLE_META_DATA, TARANT_TABLE_META_DATA,
TARANT_TABLE_ASSETS, TARANT_TABLE_ASSETS,
@ -30,6 +32,8 @@ from planetmint.backend.utils import module_dispatch_registrar
from planetmint.backend.models import Asset, Block, MetaData, Input, Script, Output from planetmint.backend.models import Asset, Block, MetaData, Input, Script, Output
from planetmint.backend.tarantool.connection import TarantoolDBConnection from planetmint.backend.tarantool.connection import TarantoolDBConnection
logger = logging.getLogger(__name__)
register_query = module_dispatch_registrar(query) register_query = module_dispatch_registrar(query)
@ -82,19 +86,23 @@ def get_transactions_by_metadata(connection, metadata: str, limit: int = 1000) -
def store_transaction_outputs(connection, output: Output, index: int) -> str: def store_transaction_outputs(connection, output: Output, index: int) -> str:
output_id = uuid4().hex output_id = uuid4().hex
connection.run( try:
connection.space(TARANT_TABLE_OUTPUT).insert( connection.run(
( connection.space(TARANT_TABLE_OUTPUT).insert(
output_id, (
int(output.amount), output_id,
output.public_keys, int(output.amount),
output.condition.to_dict(), output.public_keys,
index, output.condition.to_dict(),
output.transaction_id, index,
output.transaction_id,
)
) )
) )
) return output_id
return output_id except Exception as e:
logger.info(f"Could not insert Output: {e}")
raise OperationDataInsertionError()
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
@ -121,7 +129,11 @@ def store_transaction(connection, transaction):
transaction["inputs"], transaction["inputs"],
scripts, scripts,
) )
connection.run(connection.space(TARANT_TABLE_TRANSACTION).insert(tx), only_data=False) try:
connection.run(connection.space(TARANT_TABLE_TRANSACTION).insert(tx), only_data=False)
except Exception as e:
logger.info(f"Could not insert transactions: {e}")
raise OperationDataInsertionError()
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
@ -148,7 +160,11 @@ def store_governance_transaction(connection, transaction):
transaction["inputs"], transaction["inputs"],
scripts, scripts,
) )
connection.run(connection.space(TARANT_TABLE_GOVERNANCE).insert(tx), only_data=False) try:
connection.run(connection.space(TARANT_TABLE_GOVERNANCE).insert(tx), only_data=False)
except Exception as e:
logger.info(f"Could not insert governance transaction: {e}")
raise OperationDataInsertionError()
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
@ -223,12 +239,16 @@ def get_latest_block(connection):
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
def store_block(connection, block: dict): def store_block(connection, block: dict):
block_unique_id = uuid4().hex block_unique_id = uuid4().hex
connection.run( try:
connection.space("blocks").insert( connection.run(
(block_unique_id, block["app_hash"], block["height"], block[TARANT_TABLE_TRANSACTION]) connection.space("blocks").insert(
), (block_unique_id, block["app_hash"], block["height"], block[TARANT_TABLE_TRANSACTION])
only_data=False, ),
) only_data=False,
)
except Exception as e:
logger.info(f"Could not insert block: {e}")
raise OperationDataInsertionError()
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
@ -337,10 +357,14 @@ def store_unspent_outputs(connection, *unspent_outputs: list):
result = [] result = []
if unspent_outputs: if unspent_outputs:
for utxo in unspent_outputs: for utxo in unspent_outputs:
output = connection.run( try:
connection.space("utxos").insert((uuid4().hex, utxo["transaction_id"], utxo["output_index"], utxo)) output = connection.run(
) connection.space("utxos").insert((uuid4().hex, utxo["transaction_id"], utxo["output_index"], utxo))
result.append(output) )
result.append(output)
except Exception as e:
logger.info(f"Could not insert unspent output: {e}")
raise OperationDataInsertionError()
return result return result
@ -372,12 +396,18 @@ def store_pre_commit_state(connection, state: dict):
if _precommit is None or len(_precommit) == 0 if _precommit is None or len(_precommit) == 0
else _precommit[0] else _precommit[0]
) )
connection.run( try:
connection.space("pre_commits").upsert( connection.run(
_precommitTuple, op_list=[("=", 1, state["height"]), ("=", 2, state[TARANT_TABLE_TRANSACTION])], limit=1 connection.space("pre_commits").upsert(
), _precommitTuple,
only_data=False, op_list=[("=", 1, state["height"]), ("=", 2, state[TARANT_TABLE_TRANSACTION])],
) limit=1,
),
only_data=False,
)
except Exception as e:
logger.info(f"Could not insert pre commit state: {e}")
raise OperationDataInsertionError()
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
@ -393,14 +423,18 @@ def get_pre_commit_state(connection):
def store_validator_set(conn, validators_update: dict): def store_validator_set(conn, validators_update: dict):
_validator = conn.run(conn.space("validator_sets").select(validators_update["height"], index="height", limit=1)) _validator = conn.run(conn.space("validator_sets").select(validators_update["height"], index="height", limit=1))
unique_id = uuid4().hex if _validator is None or len(_validator) == 0 else _validator[0][0] unique_id = uuid4().hex if _validator is None or len(_validator) == 0 else _validator[0][0]
conn.run( try:
conn.space("validator_sets").upsert( conn.run(
(unique_id, validators_update["height"], validators_update["validators"]), conn.space("validator_sets").upsert(
op_list=[("=", 1, validators_update["height"]), ("=", 2, validators_update["validators"])], (unique_id, validators_update["height"], validators_update["validators"]),
limit=1, op_list=[("=", 1, validators_update["height"]), ("=", 2, validators_update["validators"])],
), limit=1,
only_data=False, ),
) only_data=False,
)
except Exception as e:
logger.info(f"Could not insert validator set: {e}")
raise OperationDataInsertionError()
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
@ -412,23 +446,31 @@ def delete_validator_set(connection, height: int):
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
def store_election(connection, election_id: str, height: int, is_concluded: bool): def store_election(connection, election_id: str, height: int, is_concluded: bool):
connection.run( try:
connection.space("elections").upsert( connection.run(
(election_id, height, is_concluded), op_list=[("=", 1, height), ("=", 2, is_concluded)], limit=1 connection.space("elections").upsert(
), (election_id, height, is_concluded), op_list=[("=", 1, height), ("=", 2, is_concluded)], limit=1
only_data=False, ),
) only_data=False,
)
except Exception as e:
logger.info(f"Could not insert election: {e}")
raise OperationDataInsertionError()
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
def store_elections(connection, elections: list): def store_elections(connection, elections: list):
for election in elections: try:
_election = connection.run( # noqa: F841 for election in elections:
connection.space("elections").insert( _election = connection.run( # noqa: F841
(election["election_id"], election["height"], election["is_concluded"]) connection.space("elections").insert(
), (election["election_id"], election["height"], election["is_concluded"])
only_data=False, ),
) only_data=False,
)
except Exception as e:
logger.info(f"Could not insert elections: {e}")
raise OperationDataInsertionError()
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
@ -483,13 +525,17 @@ def get_asset_tokens_for_public_key(connection, asset_id: str, public_key: str)
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)
def store_abci_chain(connection, height: int, chain_id: str, is_synced: bool = True): def store_abci_chain(connection, height: int, chain_id: str, is_synced: bool = True):
connection.run( try:
connection.space("abci_chains").upsert( connection.run(
(chain_id, height, is_synced), connection.space("abci_chains").upsert(
op_list=[("=", 0, chain_id), ("=", 1, height), ("=", 2, is_synced)], (chain_id, height, is_synced),
), op_list=[("=", 0, chain_id), ("=", 1, height), ("=", 2, is_synced)],
only_data=False, ),
) only_data=False,
)
except Exception as e:
logger.info(f"Could not insert abci-chain: {e}")
raise OperationDataInsertionError()
@register_query(TarantoolDBConnection) @register_query(TarantoolDBConnection)

View File

@ -208,7 +208,7 @@ def test_valid_election_conclude(b_mock, valid_upsert_validator_election, ed2551
# so any invocation of `.has_concluded` for that election should return False # so any invocation of `.has_concluded` for that election should return False
assert not b_mock.has_election_concluded(valid_upsert_validator_election) assert not b_mock.has_election_concluded(valid_upsert_validator_election)
# Vote is still valid but the election cannot be.has_concludedd as it it assmed that it has # Vote is still valid but the election cannot be.has_concluded as it it assumed that it has
# been.has_concludedd before # been.has_concludedd before
assert b_mock.validate_transaction(tx_vote3) assert b_mock.validate_transaction(tx_vote3)
assert not b_mock.has_election_concluded(valid_upsert_validator_election, [tx_vote3]) assert not b_mock.has_election_concluded(valid_upsert_validator_election, [tx_vote3])