another set of refactoring

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>
This commit is contained in:
Jürgen Eckel 2023-02-23 23:35:51 +01:00
parent 4a517f24bd
commit a8f4c53fc5
No known key found for this signature in database
18 changed files with 158 additions and 153 deletions

View File

@ -11,6 +11,8 @@ import os.path
from transactions.common.input import Input from transactions.common.input import Input
from transactions.common.transaction_link import TransactionLink from transactions.common.transaction_link import TransactionLink
import planetmint.abci.block
from planetmint import lib from planetmint import lib
from transactions.types.assets.create import Create from transactions.types.assets.create import Create
from transactions.types.assets.transfer import Transfer from transactions.types.assets.transfer import Transfer
@ -210,7 +212,7 @@ def main():
signature = "53wxrEQDYk1dXzmvNSytbCfmNVnPqPkDQaTnAe8Jf43s6ssejPxezkCvUnGTnduNUmaLjhaan1iRLi3peu6s5DzA" signature = "53wxrEQDYk1dXzmvNSytbCfmNVnPqPkDQaTnAe8Jf43s6ssejPxezkCvUnGTnduNUmaLjhaan1iRLi3peu6s5DzA"
app_hash = "f6e0c49c6d94d6924351f25bb334cf2a99af4206339bf784e741d1a5ab599056" app_hash = "f6e0c49c6d94d6924351f25bb334cf2a99af4206339bf784e741d1a5ab599056"
block = lib.Block(height=1, transactions=[tx.to_dict()], app_hash=app_hash) block = planetmint.abci.block.Block(height=1, transactions=[tx.to_dict()], app_hash=app_hash)
block_dict = block._asdict() block_dict = block._asdict()
block_dict.pop("app_hash") block_dict.pop("app_hash")
ctx["block"] = pretty_json(block_dict) ctx["block"] = pretty_json(block_dict)

3
planetmint/abci/block.py Normal file
View File

@ -0,0 +1,3 @@
from collections import namedtuple
Block = namedtuple("Block", ("app_hash", "height", "transactions"))

View File

@ -23,7 +23,7 @@ from tendermint.abci.types_pb2 import (
) )
from planetmint import Planetmint from planetmint import Planetmint
from planetmint.abci.tendermint_utils import decode_transaction, calculate_hash, decode_validator from planetmint.abci.tendermint_utils import decode_transaction, calculate_hash, decode_validator
from planetmint.lib import Block from planetmint.abci.block import Block
from planetmint.ipc.events import EventTypes, Event from planetmint.ipc.events import EventTypes, Event

35
planetmint/abci/utils.py Normal file
View File

@ -0,0 +1,35 @@
import json
from packaging import version
from transactions.common.crypto import key_pair_from_ed25519_key
from planetmint.abci.tendermint_utils import key_from_base64
from planetmint.version import __tm_supported_versions__
def load_node_key(path):
with open(path) as json_data:
priv_validator = json.load(json_data)
priv_key = priv_validator["priv_key"]["value"]
hex_private_key = key_from_base64(priv_key)
return key_pair_from_ed25519_key(hex_private_key)
def tendermint_version_is_compatible(running_tm_ver):
"""
Check Tendermint compatability with Planetmint server
:param running_tm_ver: Version number of the connected Tendermint instance
:type running_tm_ver: str
:return: True/False depending on the compatability with Planetmint server
:rtype: bool
"""
# Splitting because version can look like this e.g. 0.22.8-40d6dc2e
tm_ver = running_tm_ver.split("-")
if not tm_ver:
return False
for ver in __tm_supported_versions__:
if version.parse(ver) == version.parse(tm_ver[0]):
return True
return False

View File

@ -15,7 +15,7 @@ import sys
import planetmint import planetmint
from planetmint.abci.core import rollback from planetmint.abci.core import rollback
from planetmint.utils import load_node_key from planetmint.abci.utils import load_node_key
from transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT from transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT
from transactions.common.exceptions import DatabaseDoesNotExist, ValidationError from transactions.common.exceptions import DatabaseDoesNotExist, ValidationError
from transactions.types.elections.vote import Vote from transactions.types.elections.vote import Vote
@ -26,7 +26,7 @@ from planetmint import ValidatorElection, Planetmint
from planetmint.backend import schema from planetmint.backend import schema
from planetmint.commands import utils from planetmint.commands import utils
from planetmint.commands.utils import configure_planetmint, input_on_stderr from planetmint.commands.utils import configure_planetmint, input_on_stderr
from planetmint.log import setup_logging from planetmint.config_utils import setup_logging
from planetmint.abci.tendermint_utils import public_key_from_base64 from planetmint.abci.tendermint_utils import public_key_from_base64
from planetmint.commands.election_types import elections from planetmint.commands.election_types import elections
from planetmint.version import __tm_supported_versions__ from planetmint.version import __tm_supported_versions__

View File

@ -23,8 +23,12 @@ import logging
import collections.abc import collections.abc
from functools import lru_cache from functools import lru_cache
from logging.config import dictConfig as set_logging_config
from pkg_resources import iter_entry_points, ResolutionError from pkg_resources import iter_entry_points, ResolutionError
from planetmint.config import Config from transactions.common.exceptions import ConfigurationError
from planetmint.config import Config, DEFAULT_LOGGING_CONFIG
from planetmint.validation import BaseValidationRules from planetmint.validation import BaseValidationRules
from transactions.common import exceptions from transactions.common import exceptions
@ -306,3 +310,69 @@ def load_events_plugins(names=None):
plugins.append((name, entry_point.load())) plugins.append((name, entry_point.load()))
return plugins return plugins
def _normalize_log_level(level):
try:
return level.upper()
except AttributeError as exc:
raise ConfigurationError("Log level must be a string!") from exc
def setup_logging():
"""Function to configure log handlers.
.. important::
Configuration, if needed, should be applied before invoking this
decorator, as starting the subscriber process for logging will
configure the root logger for the child process based on the
state of :obj:`planetmint.config` at the moment this decorator
is invoked.
"""
logging_configs = DEFAULT_LOGGING_CONFIG
new_logging_configs = Config().get()["log"]
if "file" in new_logging_configs:
filename = new_logging_configs["file"]
logging_configs["handlers"]["file"]["filename"] = filename
if "error_file" in new_logging_configs:
error_filename = new_logging_configs["error_file"]
logging_configs["handlers"]["errors"]["filename"] = error_filename
if "level_console" in new_logging_configs:
level = _normalize_log_level(new_logging_configs["level_console"])
logging_configs["handlers"]["console"]["level"] = level
if "level_logfile" in new_logging_configs:
level = _normalize_log_level(new_logging_configs["level_logfile"])
logging_configs["handlers"]["file"]["level"] = level
if "fmt_console" in new_logging_configs:
fmt = new_logging_configs["fmt_console"]
logging_configs["formatters"]["console"]["format"] = fmt
if "fmt_logfile" in new_logging_configs:
fmt = new_logging_configs["fmt_logfile"]
logging_configs["formatters"]["file"]["format"] = fmt
if "datefmt_console" in new_logging_configs:
fmt = new_logging_configs["datefmt_console"]
logging_configs["formatters"]["console"]["datefmt"] = fmt
if "datefmt_logfile" in new_logging_configs:
fmt = new_logging_configs["datefmt_logfile"]
logging_configs["formatters"]["file"]["datefmt"] = fmt
log_levels = new_logging_configs.get("granular_levels", {})
for logger_name, level in log_levels.items():
level = _normalize_log_level(level)
try:
logging_configs["loggers"][logger_name]["level"] = level
except KeyError:
logging_configs["loggers"][logger_name] = {"level": level}
set_logging_config(logging_configs)

View File

@ -3,10 +3,11 @@
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) # SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
# Code is Apache-2.0 and docs are CC-BY-4.0 # Code is Apache-2.0 and docs are CC-BY-4.0
from planetmint.utils import condition_details_has_owner
from planetmint.backend import query from planetmint.backend import query
from transactions.common.transaction import TransactionLink from transactions.common.transaction import TransactionLink
from planetmint.backend.models.output import ConditionDetails
class FastQuery: class FastQuery:
"""Database queries that join on block results from a single node.""" """Database queries that join on block results from a single node."""
@ -45,3 +46,31 @@ class FastQuery:
txs = query.get_spending_transactions(self.connection, links) txs = query.get_spending_transactions(self.connection, links)
spends = {TransactionLink.from_dict(input.fulfills.to_dict()) for tx in txs for input in tx.inputs} spends = {TransactionLink.from_dict(input.fulfills.to_dict()) for tx in txs for input in tx.inputs}
return [ff for ff in outputs if ff in spends] return [ff for ff in outputs if ff in spends]
# TODO: Rename this function, it's handling fulfillments not conditions
def condition_details_has_owner(condition_details, owner):
"""Check if the public_key of owner is in the condition details
as an Ed25519Fulfillment.public_key
Args:
condition_details (dict): dict with condition details
owner (str): base58 public key of owner
Returns:
bool: True if the public key is found in the condition details, False otherwise
"""
if isinstance(condition_details, ConditionDetails) and condition_details.sub_conditions is not None:
result = condition_details_has_owner(condition_details.sub_conditions, owner)
if result:
return True
elif isinstance(condition_details, list):
for subcondition in condition_details:
result = condition_details_has_owner(subcondition, owner)
if result:
return True
else:
if condition_details.public_key is not None and owner == condition_details.public_key:
return True
return False

View File

@ -15,7 +15,7 @@ import rapidjson
import requests import requests
from itertools import chain from itertools import chain
from collections import namedtuple, OrderedDict from collections import OrderedDict
from uuid import uuid4 from uuid import uuid4
from hashlib import sha3_256 from hashlib import sha3_256
from transactions import Transaction, Vote from transactions import Transaction, Vote
@ -948,5 +948,3 @@ class Planetmint(object):
self.store_validator_set(new_height + 1, updated_validator_set) self.store_validator_set(new_height + 1, updated_validator_set)
return encode_validator(election.assets[0].data) return encode_validator(election.assets[0].data)
Block = namedtuple("Block", ("app_hash", "height", "transactions"))

View File

@ -3,73 +3,4 @@
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) # SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
# Code is Apache-2.0 and docs are CC-BY-4.0 # Code is Apache-2.0 and docs are CC-BY-4.0
from transactions.common.exceptions import ConfigurationError
from logging.config import dictConfig as set_logging_config
from planetmint.config import Config, DEFAULT_LOGGING_CONFIG
def _normalize_log_level(level):
try:
return level.upper()
except AttributeError as exc:
raise ConfigurationError("Log level must be a string!") from exc
def setup_logging():
"""Function to configure log hadlers.
.. important::
Configuration, if needed, should be applied before invoking this
decorator, as starting the subscriber process for logging will
configure the root logger for the child process based on the
state of :obj:`planetmint.config` at the moment this decorator
is invoked.
"""
logging_configs = DEFAULT_LOGGING_CONFIG
new_logging_configs = Config().get()["log"]
if "file" in new_logging_configs:
filename = new_logging_configs["file"]
logging_configs["handlers"]["file"]["filename"] = filename
if "error_file" in new_logging_configs:
error_filename = new_logging_configs["error_file"]
logging_configs["handlers"]["errors"]["filename"] = error_filename
if "level_console" in new_logging_configs:
level = _normalize_log_level(new_logging_configs["level_console"])
logging_configs["handlers"]["console"]["level"] = level
if "level_logfile" in new_logging_configs:
level = _normalize_log_level(new_logging_configs["level_logfile"])
logging_configs["handlers"]["file"]["level"] = level
if "fmt_console" in new_logging_configs:
fmt = new_logging_configs["fmt_console"]
logging_configs["formatters"]["console"]["format"] = fmt
if "fmt_logfile" in new_logging_configs:
fmt = new_logging_configs["fmt_logfile"]
logging_configs["formatters"]["file"]["format"] = fmt
if "datefmt_console" in new_logging_configs:
fmt = new_logging_configs["datefmt_console"]
logging_configs["formatters"]["console"]["datefmt"] = fmt
if "datefmt_logfile" in new_logging_configs:
fmt = new_logging_configs["datefmt_logfile"]
logging_configs["formatters"]["file"]["datefmt"] = fmt
log_levels = new_logging_configs.get("granular_levels", {})
for logger_name, level in log_levels.items():
level = _normalize_log_level(level)
try:
logging_configs["loggers"][logger_name]["level"] = level
except KeyError:
logging_configs["loggers"][logger_name] = {"level": level}
set_logging_config(logging_configs)

View File

@ -7,15 +7,8 @@ import contextlib
import threading import threading
import queue import queue
import multiprocessing import multiprocessing
import json
import setproctitle import setproctitle
from packaging import version
from planetmint.version import __tm_supported_versions__
from planetmint.abci.tendermint_utils import key_from_base64
from planetmint.backend.models.output import ConditionDetails
from transactions.common.crypto import key_pair_from_ed25519_key
class ProcessGroup(object): class ProcessGroup(object):
def __init__(self, concurrency=None, group=None, target=None, name=None, args=None, kwargs=None, daemon=None): def __init__(self, concurrency=None, group=None, target=None, name=None, args=None, kwargs=None, daemon=None):
@ -108,34 +101,6 @@ def pool(builder, size, timeout=None):
return pooled return pooled
# TODO: Rename this function, it's handling fulfillments not conditions
def condition_details_has_owner(condition_details, owner):
"""Check if the public_key of owner is in the condition details
as an Ed25519Fulfillment.public_key
Args:
condition_details (dict): dict with condition details
owner (str): base58 public key of owner
Returns:
bool: True if the public key is found in the condition details, False otherwise
"""
if isinstance(condition_details, ConditionDetails) and condition_details.sub_conditions is not None:
result = condition_details_has_owner(condition_details.sub_conditions, owner)
if result:
return True
elif isinstance(condition_details, list):
for subcondition in condition_details:
result = condition_details_has_owner(subcondition, owner)
if result:
return True
else:
if condition_details.public_key is not None and owner == condition_details.public_key:
return True
return False
class Lazy: class Lazy:
"""Lazy objects are useful to create chains of methods to """Lazy objects are useful to create chains of methods to
execute later. execute later.
@ -181,31 +146,3 @@ class Lazy:
self.stack = [] self.stack = []
return last return last
# Load Tendermint's public and private key from the file path
def load_node_key(path):
with open(path) as json_data:
priv_validator = json.load(json_data)
priv_key = priv_validator["priv_key"]["value"]
hex_private_key = key_from_base64(priv_key)
return key_pair_from_ed25519_key(hex_private_key)
def tendermint_version_is_compatible(running_tm_ver):
"""
Check Tendermint compatability with Planetmint server
:param running_tm_ver: Version number of the connected Tendermint instance
:type running_tm_ver: str
:return: True/False depending on the compatability with Planetmint server
:rtype: bool
"""
# Splitting because version can look like this e.g. 0.22.8-40d6dc2e
tm_ver = running_tm_ver.split("-")
if not tm_ver:
return False
for ver in __tm_supported_versions__:
if version.parse(ver) == version.parse(tm_ver[0]):
return True
return False

View File

@ -48,7 +48,7 @@ def test_get_owned_ids(signed_create_tx, user_pk, db_conn):
def test_store_block(db_conn): def test_store_block(db_conn):
from planetmint.lib import Block from planetmint.abci.block import Block
from planetmint.backend.tarantool import query from planetmint.backend.tarantool import query
block = Block(app_hash="random_utxo", height=3, transactions=[]) block = Block(app_hash="random_utxo", height=3, transactions=[])
@ -59,7 +59,7 @@ def test_store_block(db_conn):
def test_get_block(db_conn): def test_get_block(db_conn):
from planetmint.lib import Block from planetmint.abci.block import Block
from planetmint.backend.tarantool import query from planetmint.backend.tarantool import query
block = Block(app_hash="random_utxo", height=3, transactions=[]) block = Block(app_hash="random_utxo", height=3, transactions=[])

View File

@ -63,7 +63,7 @@ def run_start_args(request):
@pytest.fixture @pytest.fixture
def mocked_setup_logging(mocker): def mocked_setup_logging(mocker):
return mocker.patch( return mocker.patch(
"planetmint.log.setup_logging", "planetmint.config_utils.setup_logging",
autospec=True, autospec=True,
spec_set=True, spec_set=True,
) )

View File

@ -14,7 +14,7 @@ from planetmint import ValidatorElection
from planetmint.commands.planetmint import run_election_show from planetmint.commands.planetmint import run_election_show
from planetmint.commands.planetmint import run_election_new_chain_migration from planetmint.commands.planetmint import run_election_new_chain_migration
from planetmint.backend.connection import Connection from planetmint.backend.connection import Connection
from planetmint.lib import Block from planetmint.abci.block import Block
from transactions.types.elections.chain_migration_election import ChainMigrationElection from transactions.types.elections.chain_migration_election import ChainMigrationElection
from tests.utils import generate_election, generate_validators from tests.utils import generate_election, generate_validators
@ -62,7 +62,7 @@ def test_main_entrypoint(mock_start):
assert mock_start.called assert mock_start.called
@patch("planetmint.log.setup_logging") @patch("planetmint.config_utils.setup_logging")
@patch("planetmint.commands.planetmint._run_init") @patch("planetmint.commands.planetmint._run_init")
@patch("planetmint.config_utils.autoconfigure") @patch("planetmint.config_utils.autoconfigure")
def test_bigchain_run_start(mock_setup_logging, mock_run_init, mock_autoconfigure, mock_processes_start): def test_bigchain_run_start(mock_setup_logging, mock_run_init, mock_autoconfigure, mock_processes_start):
@ -261,7 +261,7 @@ def test_recover_db_on_start(mock_run_recover, mock_start, mocked_setup_logging)
def test_run_recover(b, alice, bob): def test_run_recover(b, alice, bob):
from planetmint.commands.planetmint import run_recover from planetmint.commands.planetmint import run_recover
from transactions.types.assets.create import Create from transactions.types.assets.create import Create
from planetmint.lib import Block from planetmint.abci.block import Block
from planetmint.backend import query from planetmint.backend import query
tx1 = Create.generate( tx1 = Create.generate(

View File

@ -27,7 +27,7 @@ from transactions.common.transaction_mode_types import BROADCAST_TX_COMMIT
from planetmint.abci.tendermint_utils import key_from_base64 from planetmint.abci.tendermint_utils import key_from_base64
from planetmint.backend import schema, query from planetmint.backend import schema, query
from transactions.common.crypto import key_pair_from_ed25519_key, public_key_from_ed25519_key from transactions.common.crypto import key_pair_from_ed25519_key, public_key_from_ed25519_key
from planetmint.lib import Block from planetmint.abci.block import Block
from tests.utils import gen_vote from tests.utils import gen_vote
from planetmint.config import Config from planetmint.config import Config
from transactions.types.elections.validator_election import ValidatorElection # noqa from transactions.types.elections.validator_election import ValidatorElection # noqa

View File

@ -1,7 +1,7 @@
import pytest import pytest
from tests.utils import generate_election, generate_validators from tests.utils import generate_election, generate_validators
from planetmint.lib import Block from planetmint.abci.block import Block
from transactions.types.elections.election import Election from transactions.types.elections.election import Election
from transactions.types.elections.chain_migration_election import ChainMigrationElection from transactions.types.elections.chain_migration_election import ChainMigrationElection
from transactions.types.elections.validator_election import ValidatorElection from transactions.types.elections.validator_election import ValidatorElection

View File

@ -18,7 +18,7 @@ from transactions.types.assets.transfer import Transfer
from planetmint import App from planetmint import App
from planetmint.backend import query from planetmint.backend import query
from planetmint.abci.core import OkCode, CodeTypeError, rollback from planetmint.abci.core import OkCode, CodeTypeError, rollback
from planetmint.lib import Block from planetmint.abci.block import Block
from planetmint.abci.tendermint_utils import new_validator_set from planetmint.abci.tendermint_utils import new_validator_set
from planetmint.abci.tendermint_utils import public_key_to_base64 from planetmint.abci.tendermint_utils import public_key_to_base64
from planetmint.version import __tm_supported_versions__ from planetmint.version import __tm_supported_versions__

View File

@ -17,7 +17,7 @@ from transactions.common.transaction_mode_types import (
BROADCAST_TX_ASYNC, BROADCAST_TX_ASYNC,
BROADCAST_TX_SYNC, BROADCAST_TX_SYNC,
) )
from planetmint.lib import Block from planetmint.abci.block import Block
from ipld import marshal, multihash from ipld import marshal, multihash
from uuid import uuid4 from uuid import uuid4
@ -72,7 +72,7 @@ def test_asset_is_separated_from_transaciton(b):
@pytest.mark.bdb @pytest.mark.bdb
def test_get_latest_block(b): def test_get_latest_block(b):
from planetmint.lib import Block from planetmint.abci.block import Block
for i in range(10): for i in range(10):
app_hash = os.urandom(16).hex() app_hash = os.urandom(16).hex()

View File

@ -6,7 +6,7 @@
import pytest import pytest
from transactions.types.assets.create import Create from transactions.types.assets.create import Create
from planetmint.lib import Block from planetmint.abci.block import Block
from ipld import marshal, multihash from ipld import marshal, multihash
BLOCKS_ENDPOINT = "/api/v1/blocks/" BLOCKS_ENDPOINT = "/api/v1/blocks/"