Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions extras/custom_checks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,38 @@ function check_do_not_import_tests_in_hathor() {
return 0
}

function check_do_not_import_from_hathor_in_entrypoints() {
PATTERN='^import .*hathor.*\|^from .*hathor.* import'

if grep -R "$PATTERN" "hathor/cli" | grep -v 'from hathor.cli.run_node import RunNode' | grep -v '# skip-cli-import-custom-check'; then
echo 'do not import from `hathor` in the module-level of a CLI entrypoint.'
echo 'instead, import locally inside the function that uses the import.'
echo 'alternatively, comment `# skip-cli-import-custom-check` to exclude a line.'
return 1
fi
return 0
}

function check_do_not_import_twisted_reactor_directly() {
EXCLUDES="--exclude=reactor.py --exclude=conftest.py"
PATTERN='\<.*from .*twisted.internet import .*reactor\>'

if grep -R $EXCLUDES "$PATTERN" "${SOURCE_DIRS[@]}"; then
echo 'do not use `from twisted.internet import reactor` directly.'
echo 'instead, use `hathor.reactor.get_global_reactor()`.'
return 1
fi
return 0
}

# List of functions to be executed
checks=(
check_version_match
check_do_not_use_builtin_random_in_tests
check_deprecated_typing
check_do_not_import_tests_in_hathor
check_do_not_import_from_hathor_in_entrypoints
check_do_not_import_twisted_reactor_directly
)

# Initialize a variable to track if any check fails
Expand Down
5 changes: 3 additions & 2 deletions hathor/builder/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from hathor.p2p.manager import ConnectionsManager
from hathor.p2p.peer_id import PeerId
from hathor.pubsub import PubSubManager
from hathor.reactor import ReactorProtocol as Reactor
from hathor.storage import RocksDBStorage
from hathor.stratum import StratumFactory
from hathor.transaction.storage import (
Expand All @@ -42,7 +43,7 @@
TransactionRocksDBStorage,
TransactionStorage,
)
from hathor.util import Random, Reactor, get_environment_info, not_none
from hathor.util import Random, get_environment_info, not_none
from hathor.verification.verification_service import VerificationService, VertexVerifiers
from hathor.wallet import BaseWallet, Wallet

Expand Down Expand Up @@ -311,7 +312,7 @@ def _get_or_create_pubsub(self) -> PubSubManager:
return self._pubsub

def _create_stratum_server(self, manager: HathorManager) -> StratumFactory:
stratum_factory = StratumFactory(manager=manager)
stratum_factory = StratumFactory(manager=manager, reactor=self._get_reactor())
manager.stratum_factory = stratum_factory
manager.metrics.stratum_factory = stratum_factory
return stratum_factory
Expand Down
8 changes: 5 additions & 3 deletions hathor/builder/cli_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

from structlog import get_logger

from hathor.cli.run_node import RunNodeArgs
from hathor.cli.run_node_args import RunNodeArgs
from hathor.consensus import ConsensusAlgorithm
from hathor.daa import DifficultyAdjustmentAlgorithm
from hathor.event import EventManager
Expand All @@ -35,8 +35,9 @@
from hathor.p2p.peer_id import PeerId
from hathor.p2p.utils import discover_hostname, get_genesis_short_hash
from hathor.pubsub import PubSubManager
from hathor.reactor import ReactorProtocol as Reactor
from hathor.stratum import StratumFactory
from hathor.util import Random, Reactor, not_none
from hathor.util import Random, not_none
from hathor.verification.verification_service import VerificationService
from hathor.verification.vertex_verifiers import VertexVerifiers
from hathor.wallet import BaseWallet, HDWallet, Wallet
Expand Down Expand Up @@ -99,6 +100,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
python=python,
platform=platform.platform(),
settings=settings_source,
reactor_type=type(reactor).__name__,
)

tx_storage: TransactionStorage
Expand Down Expand Up @@ -271,7 +273,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
p2p_manager.set_manager(self.manager)

if self._args.stratum:
stratum_factory = StratumFactory(self.manager)
stratum_factory = StratumFactory(self.manager, reactor=reactor)
self.manager.stratum_factory = stratum_factory
self.manager.metrics.stratum_factory = stratum_factory

Expand Down
6 changes: 3 additions & 3 deletions hathor/builder/resources_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,15 +224,15 @@ def create_resources(self) -> server.Site:
root.putChild(b'_debug', debug_resource)
resources.extend([
(b'log', DebugLogResource(), debug_resource),
(b'raise', DebugRaiseResource(), debug_resource),
(b'reject', DebugRejectResource(), debug_resource),
(b'raise', DebugRaiseResource(self.manager.reactor), debug_resource),
(b'reject', DebugRejectResource(self.manager.reactor), debug_resource),
(b'print', DebugPrintResource(), debug_resource),
])
if self._args.enable_crash_api:
crash_resource = Resource()
root.putChild(b'_crash', crash_resource)
resources.extend([
(b'exit', DebugCrashResource(), crash_resource),
(b'exit', DebugCrashResource(self.manager.reactor), crash_resource),
(b'mess_around', DebugMessAroundResource(self.manager), crash_resource),
])

Expand Down
2 changes: 1 addition & 1 deletion hathor/cli/db_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from argparse import ArgumentParser, FileType
from typing import TYPE_CHECKING, Iterator

from hathor.cli.db_export import MAGIC_HEADER
from hathor.cli.run_node import RunNode

if TYPE_CHECKING:
Expand Down Expand Up @@ -46,6 +45,7 @@ def prepare(self, *, register_resources: bool = True) -> None:
self.in_file = io.BufferedReader(self._args.import_file)

def run(self) -> None:
from hathor.cli.db_export import MAGIC_HEADER
from hathor.util import tx_progress

header = self.in_file.read(len(MAGIC_HEADER))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,23 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Any
from typing import TYPE_CHECKING, Any

from twisted.internet.interfaces import IAddress

from hathor.cli.events_simulator.event_forwarding_websocket_protocol import EventForwardingWebsocketProtocol
from hathor.event.websocket import EventWebsocketFactory
from hathor.simulator import Simulator
from hathor.event.websocket import EventWebsocketFactory # skip-cli-import-custom-check

if TYPE_CHECKING:
from hathor.cli.events_simulator.event_forwarding_websocket_protocol import EventForwardingWebsocketProtocol
from hathor.simulator import Simulator


class EventForwardingWebsocketFactory(EventWebsocketFactory):
def __init__(self, simulator: Simulator, *args: Any, **kwargs: Any) -> None:
def __init__(self, simulator: 'Simulator', *args: Any, **kwargs: Any) -> None:
self._simulator = simulator
super().__init__(*args, **kwargs)

def buildProtocol(self, _: IAddress) -> EventForwardingWebsocketProtocol:
def buildProtocol(self, _: IAddress) -> 'EventForwardingWebsocketProtocol':
protocol = EventForwardingWebsocketProtocol(self._simulator)
protocol.factory = self
return protocol
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@

from autobahn.websocket import ConnectionRequest

from hathor.event.websocket import EventWebsocketProtocol
from hathor.simulator import Simulator
from hathor.event.websocket import EventWebsocketProtocol # skip-cli-import-custom-check

if TYPE_CHECKING:
from hathor.cli.events_simulator.event_forwarding_websocket_factory import EventForwardingWebsocketFactory
from hathor.simulator import Simulator


class EventForwardingWebsocketProtocol(EventWebsocketProtocol):
factory: 'EventForwardingWebsocketFactory'

def __init__(self, simulator: Simulator) -> None:
def __init__(self, simulator: 'Simulator') -> None:
self._simulator = simulator
super().__init__()

Expand Down
3 changes: 2 additions & 1 deletion hathor/cli/events_simulator/events_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,16 @@ def execute(args: Namespace) -> None:
os.environ['HATHOR_CONFIG_YAML'] = UNITTESTS_SETTINGS_FILEPATH
from hathor.cli.events_simulator.event_forwarding_websocket_factory import EventForwardingWebsocketFactory
from hathor.cli.events_simulator.scenario import Scenario
from hathor.reactor import get_global_reactor
from hathor.simulator import Simulator
from hathor.util import reactor

try:
scenario = Scenario[args.scenario]
except KeyError as e:
possible_scenarios = [scenario.name for scenario in Scenario]
raise ValueError(f'Invalid scenario "{args.scenario}". Choose one of {possible_scenarios}') from e

reactor = get_global_reactor()
log = logger.new()
simulator = Simulator(args.seed)
simulator.start()
Expand Down
3 changes: 1 addition & 2 deletions hathor/cli/mining.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@

import requests

from hathor.conf.get_settings import get_settings

_SLEEP_ON_ERROR_SECONDS = 5
_MAX_CONN_RETRIES = math.inf

Expand Down Expand Up @@ -137,6 +135,7 @@ def execute(args: Namespace) -> None:
block.nonce, block.weight))

try:
from hathor.conf.get_settings import get_settings
from hathor.daa import DifficultyAdjustmentAlgorithm
from hathor.verification.verification_service import VerificationService, VertexVerifiers
settings = get_settings()
Expand Down
3 changes: 1 addition & 2 deletions hathor/cli/multisig_spend.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

from argparse import ArgumentParser, Namespace

from hathor.mining.cpu_mining_service import CpuMiningService


def create_parser() -> ArgumentParser:
from hathor.cli.util import create_parser
Expand All @@ -29,6 +27,7 @@ def create_parser() -> ArgumentParser:


def execute(args: Namespace) -> None:
from hathor.mining.cpu_mining_service import CpuMiningService
from hathor.transaction import Transaction
from hathor.transaction.scripts import MultiSig

Expand Down
3 changes: 1 addition & 2 deletions hathor/cli/nginx_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@
from enum import Enum
from typing import Any, NamedTuple, Optional, TextIO

from hathor.cli.openapi_json import get_openapi_dict

BASE_PATH = os.path.join(os.path.dirname(__file__), 'nginx_files')


def get_openapi(src_file: Optional[TextIO] = None) -> dict[str, Any]:
""" Open and parse the json file or generate OpenAPI dict on-the-fly
"""
if src_file is None:
from hathor.cli.openapi_json import get_openapi_dict
return get_openapi_dict()
else:
return json.load(src_file)
Expand Down
2 changes: 1 addition & 1 deletion hathor/cli/openapi_files/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from typing import TypeVar

from hathor.api_util import Resource
from hathor.api_util import Resource # skip-cli-import-custom-check

_registered_resources: list[type[Resource]] = []

Expand Down
27 changes: 17 additions & 10 deletions hathor/cli/run_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,26 @@
import os
import sys
from argparse import SUPPRESS, ArgumentParser, Namespace
from typing import Any, Callable, Optional
from typing import TYPE_CHECKING, Any, Callable, Optional

from pydantic import ValidationError
from structlog import get_logger

from hathor.cli.run_node_args import RunNodeArgs
from hathor.conf import TESTNET_SETTINGS_FILEPATH, HathorSettings
from hathor.exception import PreInitializationError
from hathor.feature_activation.feature import Feature

logger = get_logger()
# LOGGING_CAPTURE_STDOUT = True

if TYPE_CHECKING:
from hathor.cli.run_node_args import RunNodeArgs


class RunNode:
UNSAFE_ARGUMENTS: list[tuple[str, Callable[[RunNodeArgs], bool]]] = [
UNSAFE_ARGUMENTS: list[tuple[str, Callable[['RunNodeArgs'], bool]]] = [
('--test-mode-tx-weight', lambda args: bool(args.test_mode_tx_weight)),
('--enable-crash-api', lambda args: bool(args.enable_crash_api)),
('--x-sync-bridge', lambda args: bool(args.x_sync_bridge)),
('--x-sync-v2-only', lambda args: bool(args.x_sync_v2_only)),
('--x-enable-event-queue', lambda args: bool(args.x_enable_event_queue))
('--x-enable-event-queue', lambda args: bool(args.x_enable_event_queue)),
('--x-asyncio-reactor', lambda args: bool(args.x_asyncio_reactor))
]

@classmethod
Expand All @@ -45,6 +44,7 @@ def create_parser(cls) -> ArgumentParser:
Arguments must also be added to hathor.cli.run_node_args.RunNodeArgs
"""
from hathor.cli.util import create_parser
from hathor.feature_activation.feature import Feature
parser = create_parser()

parser.add_argument('--hostname', help='Hostname used to be accessed by other peers')
Expand Down Expand Up @@ -118,6 +118,8 @@ def create_parser(cls) -> ArgumentParser:
help=f'Signal support for a feature. One of {possible_features}')
parser.add_argument('--signal-not-support', default=[], action='append', choices=possible_features,
help=f'Signal not support for a feature. One of {possible_features}')
parser.add_argument('--x-asyncio-reactor', action='store_true',
help='Use asyncio reactor instead of Twisted\'s default.')
return parser

def prepare(self, *, register_resources: bool = True) -> None:
Expand All @@ -139,7 +141,8 @@ def prepare(self, *, register_resources: bool = True) -> None:
self.check_unsafe_arguments()
self.check_python_version()

from hathor.util import reactor
from hathor.reactor import initialize_global_reactor
reactor = initialize_global_reactor(use_asyncio_reactor=self._args.x_asyncio_reactor)
self.reactor = reactor

from hathor.builder import CliBuilder, ResourcesBuilder
Expand Down Expand Up @@ -346,6 +349,9 @@ def check_python_version(self) -> None:
]))

def __init__(self, *, argv=None):
from hathor.cli.run_node_args import RunNodeArgs
from hathor.conf import TESTNET_SETTINGS_FILEPATH
from hathor.conf.get_settings import get_settings
self.log = logger.new()

if argv is None:
Expand All @@ -363,8 +369,9 @@ def __init__(self, *, argv=None):
os.environ['HATHOR_CONFIG_YAML'] = TESTNET_SETTINGS_FILEPATH

try:
HathorSettings()
get_settings()
except (TypeError, ValidationError) as e:
from hathor.exception import PreInitializationError
raise PreInitializationError(
'An error was found while trying to initialize HathorSettings. See above for details.'
) from e
Expand Down
5 changes: 3 additions & 2 deletions hathor/cli/run_node_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

from pydantic import Extra

from hathor.feature_activation.feature import Feature
from hathor.utils.pydantic import BaseModel
from hathor.feature_activation.feature import Feature # skip-cli-import-custom-check
from hathor.utils.pydantic import BaseModel # skip-cli-import-custom-check


class RunNodeArgs(BaseModel, extra=Extra.allow):
Expand Down Expand Up @@ -72,3 +72,4 @@ class RunNodeArgs(BaseModel, extra=Extra.allow):
config_yaml: Optional[str]
signal_support: set[Feature]
signal_not_support: set[Feature]
x_asyncio_reactor: bool
5 changes: 3 additions & 2 deletions hathor/cli/stratum_mining.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ def create_parser() -> ArgumentParser:

def execute(args: Namespace) -> None:
from hathor.crypto.util import decode_address
from hathor.reactor import get_global_reactor
from hathor.stratum import StratumClient
from hathor.util import reactor
from hathor.wallet.exceptions import InvalidAddress

address = None
Expand All @@ -43,7 +43,8 @@ def execute(args: Namespace) -> None:
print('The given address is invalid')
sys.exit(-1)

miner = StratumClient(proc_count=args.nproc, address=address)
reactor = get_global_reactor()
miner = StratumClient(proc_count=args.nproc, address=address, reactor=reactor)
miner.start()
point = TCP4ClientEndpoint(reactor, args.host, args.port)
connectProtocol(point, miner)
Expand Down
Loading