Skip to content

Commit

Permalink
Merge pull request #765 from HathorNetwork/release-candidate
Browse files Browse the repository at this point in the history
Release v0.56.0
  • Loading branch information
jansegre authored Sep 5, 2023
2 parents a5ad91c + dfab19f commit dc1e978
Show file tree
Hide file tree
Showing 72 changed files with 1,541 additions and 595 deletions.
80 changes: 66 additions & 14 deletions hathor/builder/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from hathor.event import EventManager
from hathor.event.storage import EventMemoryStorage, EventRocksDBStorage, EventStorage
from hathor.event.websocket import EventWebsocketFactory
from hathor.feature_activation.bit_signaling_service import BitSignalingService
from hathor.feature_activation.feature import Feature
from hathor.feature_activation.feature_service import FeatureService
from hathor.indexes import IndexesManager, MemoryIndexesManager, RocksDBIndexesManager
from hathor.manager import HathorManager
Expand Down Expand Up @@ -64,7 +66,6 @@ class BuildArtifacts(NamedTuple):
wallet: Optional[BaseWallet]
rocksdb_storage: Optional[RocksDBStorage]
stratum_factory: Optional[StratumFactory]
feature_service: FeatureService


class Builder:
Expand All @@ -80,7 +81,7 @@ def __init__(self) -> None:
self.log = logger.new()
self.artifacts: Optional[BuildArtifacts] = None

self._settings: HathorSettingsType = HathorSettings()
self._settings: Optional[HathorSettingsType] = None
self._rng: Random = Random()
self._checkpoints: Optional[list[Checkpoint]] = None
self._capabilities: Optional[list[str]] = None
Expand All @@ -95,6 +96,11 @@ def __init__(self) -> None:
self._event_manager: Optional[EventManager] = None
self._enable_event_queue: Optional[bool] = None

self._support_features: set[Feature] = set()
self._not_support_features: set[Feature] = set()
self._feature_service: Optional[FeatureService] = None
self._bit_signaling_service: Optional[BitSignalingService] = None

self._rocksdb_path: Optional[str] = None
self._rocksdb_storage: Optional[RocksDBStorage] = None
self._rocksdb_cache_capacity: Optional[int] = None
Expand Down Expand Up @@ -134,7 +140,7 @@ def build(self) -> BuildArtifacts:
if self._network is None:
raise TypeError('you must set a network')

settings = self._get_settings()
settings = self._get_or_create_settings()
reactor = self._get_reactor()
pubsub = self._get_or_create_pubsub()

Expand All @@ -149,6 +155,8 @@ def build(self) -> BuildArtifacts:
event_manager = self._get_or_create_event_manager()
indexes = self._get_or_create_indexes_manager()
tx_storage = self._get_or_create_tx_storage(indexes)
feature_service = self._get_or_create_feature_service(tx_storage)
bit_signaling_service = self._get_or_create_bit_signaling_service(tx_storage)

if self._enable_address_index:
indexes.enable_address_index(pubsub)
Expand Down Expand Up @@ -181,6 +189,8 @@ def build(self) -> BuildArtifacts:
checkpoints=self._checkpoints,
capabilities=self._capabilities,
environment_info=get_environment_info(self._cmdline, peer_id.id),
feature_service=feature_service,
bit_signaling_service=bit_signaling_service,
**kwargs
)

Expand All @@ -190,8 +200,6 @@ def build(self) -> BuildArtifacts:
if self._enable_stratum_server:
stratum_factory = self._create_stratum_server(manager)

feature_service = self._create_feature_service(tx_storage)

self.artifacts = BuildArtifacts(
peer_id=peer_id,
settings=settings,
Expand All @@ -206,7 +214,6 @@ def build(self) -> BuildArtifacts:
wallet=wallet,
rocksdb_storage=self._rocksdb_storage,
stratum_factory=stratum_factory,
feature_service=feature_service
)

return self.artifacts
Expand All @@ -220,6 +227,16 @@ def set_event_manager(self, event_manager: EventManager) -> 'Builder':
self._event_manager = event_manager
return self

def set_feature_service(self, feature_service: FeatureService) -> 'Builder':
self.check_if_can_modify()
self._feature_service = feature_service
return self

def set_bit_signaling_service(self, bit_signaling_service: BitSignalingService) -> 'Builder':
self.check_if_can_modify()
self._bit_signaling_service = bit_signaling_service
return self

def set_rng(self, rng: Random) -> 'Builder':
self.check_if_can_modify()
self._rng = rng
Expand All @@ -240,7 +257,9 @@ def set_peer_id(self, peer_id: PeerId) -> 'Builder':
self._peer_id = peer_id
return self

def _get_settings(self) -> HathorSettingsType:
def _get_or_create_settings(self) -> HathorSettingsType:
if self._settings is None:
self._settings = HathorSettings()
return self._settings

def _get_reactor(self) -> Reactor:
Expand All @@ -252,7 +271,7 @@ def _get_soft_voided_tx_ids(self) -> set[bytes]:
if self._soft_voided_tx_ids is not None:
return self._soft_voided_tx_ids

settings = self._get_settings()
settings = self._get_or_create_settings()

return set(settings.SOFT_VOIDED_TX_IDS)

Expand All @@ -272,12 +291,6 @@ def _create_stratum_server(self, manager: HathorManager) -> StratumFactory:
manager.metrics.stratum_factory = stratum_factory
return stratum_factory

def _create_feature_service(self, tx_storage: TransactionStorage) -> FeatureService:
return FeatureService(
feature_settings=self._settings.FEATURE_ACTIVATION,
tx_storage=tx_storage
)

def _get_or_create_rocksdb_storage(self) -> RocksDBStorage:
assert self._rocksdb_path is not None

Expand Down Expand Up @@ -388,6 +401,29 @@ def _get_or_create_event_manager(self) -> EventManager:

return self._event_manager

def _get_or_create_feature_service(self, tx_storage: TransactionStorage) -> FeatureService:
if self._feature_service is None:
settings = self._get_or_create_settings()
self._feature_service = FeatureService(
feature_settings=settings.FEATURE_ACTIVATION,
tx_storage=tx_storage
)

return self._feature_service

def _get_or_create_bit_signaling_service(self, tx_storage: TransactionStorage) -> BitSignalingService:
if self._bit_signaling_service is None:
settings = self._get_or_create_settings()
self._bit_signaling_service = BitSignalingService(
feature_settings=settings.FEATURE_ACTIVATION,
feature_service=self._get_or_create_feature_service(tx_storage),
tx_storage=tx_storage,
support_features=self._support_features,
not_support_features=self._not_support_features,
)

return self._bit_signaling_service

def use_memory(self) -> 'Builder':
self.check_if_can_modify()
self._storage_type = StorageType.MEMORY
Expand Down Expand Up @@ -559,3 +595,19 @@ def set_soft_voided_tx_ids(self, soft_voided_tx_ids: set[bytes]) -> 'Builder':
self.check_if_can_modify()
self._soft_voided_tx_ids = soft_voided_tx_ids
return self

def set_features(
self,
*,
support_features: Optional[set[Feature]],
not_support_features: Optional[set[Feature]]
) -> 'Builder':
self.check_if_can_modify()
self._support_features = support_features or set()
self._not_support_features = not_support_features or set()
return self

def set_settings(self, settings: HathorSettingsType) -> 'Builder':
self.check_if_can_modify()
self._settings = settings
return self
24 changes: 20 additions & 4 deletions hathor/builder/cli_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,21 @@
from typing import Any, Optional

from structlog import get_logger
from twisted.internet.posixbase import PosixReactorBase

from hathor.cli.run_node import RunNodeArgs
from hathor.consensus import ConsensusAlgorithm
from hathor.event import EventManager
from hathor.exception import BuilderError
from hathor.feature_activation.bit_signaling_service import BitSignalingService
from hathor.feature_activation.feature_service import FeatureService
from hathor.indexes import IndexesManager, MemoryIndexesManager, RocksDBIndexesManager
from hathor.manager import HathorManager
from hathor.p2p.manager import ConnectionsManager
from hathor.p2p.peer_id import PeerId
from hathor.p2p.utils import discover_hostname
from hathor.pubsub import PubSubManager
from hathor.stratum import StratumFactory
from hathor.util import Random
from hathor.util import Random, Reactor
from hathor.wallet import BaseWallet, HDWallet, Wallet

logger = get_logger()
Expand All @@ -53,7 +54,7 @@ def check_or_raise(self, condition: bool, message: str) -> None:
if not condition:
raise BuilderError(message)

def create_manager(self, reactor: PosixReactorBase) -> HathorManager:
def create_manager(self, reactor: Reactor) -> HathorManager:
import hathor
from hathor.conf import HathorSettings
from hathor.conf.get_settings import get_settings_source
Expand Down Expand Up @@ -189,6 +190,19 @@ def create_manager(self, reactor: PosixReactorBase) -> HathorManager:
self.log.info('--x-enable-event-queue flag provided. '
'The events detected by the full node will be stored and can be retrieved by clients')

self.feature_service = FeatureService(
feature_settings=settings.FEATURE_ACTIVATION,
tx_storage=tx_storage
)

bit_signaling_service = BitSignalingService(
feature_settings=settings.FEATURE_ACTIVATION,
feature_service=self.feature_service,
tx_storage=tx_storage,
support_features=self._args.signal_support,
not_support_features=self._args.signal_not_support
)

p2p_manager = ConnectionsManager(
reactor,
network=network,
Expand Down Expand Up @@ -216,7 +230,9 @@ def create_manager(self, reactor: PosixReactorBase) -> HathorManager:
checkpoints=settings.CHECKPOINTS,
environment_info=get_environment_info(args=str(self._args), peer_id=peer_id.id),
full_verification=full_verification,
enable_event_queue=self._args.x_enable_event_queue
enable_event_queue=self._args.x_enable_event_queue,
feature_service=self.feature_service,
bit_signaling_service=bit_signaling_service
)

p2p_manager.set_manager(self.manager)
Expand Down
16 changes: 16 additions & 0 deletions hathor/cli/nginx_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,15 @@ def generate_nginx_config(openapi: dict[str, Any], *, out_file: TextIO, rate_k:
websocket_max_conn_per_ip = 10000
mining_websocket_max_conn_global = 1000
mining_websocket_max_conn_per_ip = 1000
event_websocket_max_conn_global = 1000
event_websocket_max_conn_per_ip = 1000
else:
websocket_max_conn_global = 4000
websocket_max_conn_per_ip = 10
mining_websocket_max_conn_global = 100
mining_websocket_max_conn_per_ip = 4
event_websocket_max_conn_global = 100
event_websocket_max_conn_per_ip = 4

header = f'''# THIS FILE WAS AUTOGENERATED BY THE `hathor-cli nginx-config` TOOL AT {datetime.now()}
Expand Down Expand Up @@ -231,6 +235,8 @@ def generate_nginx_config(openapi: dict[str, Any], *, out_file: TextIO, rate_k:
limit_conn_zone $per_ip_key zone=per_ip__ws:10m;
limit_conn_zone $global_key zone=global__mining_ws:32k;
limit_conn_zone $per_ip_key zone=per_ip__mining_ws:10m;
limit_conn_zone $global_key zone=global__event_ws:32k;
limit_conn_zone $per_ip_key zone=per_ip__event_ws:10m;
'''

server_open = f'''
Expand Down Expand Up @@ -282,6 +288,16 @@ def generate_nginx_config(openapi: dict[str, Any], *, out_file: TextIO, rate_k:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://backend;
}}
location ~ ^/{api_prefix}/event_ws/?$ {{
limit_conn global__event_ws {event_websocket_max_conn_global};
limit_conn per_ip__event_ws {event_websocket_max_conn_per_ip};
include cors_params;
include proxy_params;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://backend;
}}'''
# TODO: maybe return 403 instead?
server_close = f'''
Expand Down
2 changes: 1 addition & 1 deletion hathor/cli/openapi_files/openapi_base.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
],
"info": {
"title": "Hathor API",
"version": "0.55.0"
"version": "0.56.0"
},
"consumes": [
"application/json"
Expand Down
2 changes: 2 additions & 0 deletions hathor/cli/openapi_files/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ def register_resource(resource_class: ResourceClass) -> ResourceClass:
def get_registered_resources() -> list[type[Resource]]:
""" Returns a list with all the resources registered for the docs
"""
import hathor.event.resources.event # noqa: 401
import hathor.feature_activation.resources.feature # noqa: 401
import hathor.p2p.resources # noqa: 401
import hathor.profiler.resources # noqa: 401
import hathor.stratum.resources # noqa: 401
Expand Down
40 changes: 28 additions & 12 deletions hathor/cli/run_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,21 +156,22 @@ def prepare(self, *, register_resources: bool = True) -> None:
self.start_manager()

if self._args.stratum:
assert self.manager.stratum_factory is not None
self.reactor.listenTCP(self._args.stratum, self.manager.stratum_factory)

from hathor.conf import HathorSettings
from hathor.feature_activation.feature_service import FeatureService
settings = HathorSettings()

feature_service = FeatureService(
feature_settings=settings.FEATURE_ACTIVATION,
tx_storage=self.manager.tx_storage
)

if register_resources:
resources_builder = ResourcesBuilder(self.manager, self._args, builder.event_ws_factory, feature_service)
resources_builder = ResourcesBuilder(
self.manager,
self._args,
builder.event_ws_factory,
builder.feature_service
)
status_server = resources_builder.build()
if self._args.status:
assert status_server is not None
self.reactor.listenTCP(self._args.status, status_server)

from hathor.builder.builder import BuildArtifacts
Expand All @@ -188,7 +189,6 @@ def prepare(self, *, register_resources: bool = True) -> None:
wallet=self.manager.wallet,
rocksdb_storage=getattr(builder, 'rocksdb_storage', None),
stratum_factory=self.manager.stratum_factory,
feature_service=feature_service
)

def start_sentry_if_possible(self) -> None:
Expand Down Expand Up @@ -312,11 +312,14 @@ def check_unsafe_arguments(self) -> None:
sys.exit(-1)

def check_python_version(self) -> None:
MIN_VER = (3, 8)
RECOMMENDED_VER = (3, 9)
# comments to help grep's
MIN_VER = (3, 9) # Python-3.9
MIN_STABLE = (3, 10) # Python-3.10
RECOMMENDED_VER = (3, 10) # Python-3.10
cur = sys.version_info
min_pretty = '.'.join(map(str, MIN_VER))
cur_pretty = '.'.join(map(str, cur))
min_pretty = '.'.join(map(str, MIN_VER))
min_stable_pretty = '.'.join(map(str, MIN_STABLE))
recommended_pretty = '.'.join(map(str, RECOMMENDED_VER))
if cur < MIN_VER:
self.log.critical('\n'.join([
Expand All @@ -329,6 +332,17 @@ def check_python_version(self) -> None:
'',
]))
sys.exit(-1)
elif cur < MIN_STABLE:
self.log.warning('\n'.join([
'',
'********************************************************',
f'The detected Python version {cur_pretty} is deprecated and support for it will be removed in the'
' next release.',
f'The minimum supported Python version will be {min_stable_pretty}',
f'The recommended Python version is {recommended_pretty}',
'********************************************************',
'',
]))

def __init__(self, *, argv=None):
self.log = logger.new()
Expand Down Expand Up @@ -375,11 +389,13 @@ def init_sysctl(self, description: str) -> None:

from hathor.builder.sysctl_builder import SysctlBuilder
from hathor.sysctl.factory import SysctlFactory
from hathor.sysctl.runner import SysctlRunner

builder = SysctlBuilder(self.artifacts)
root = builder.build()

factory = SysctlFactory(root)
runner = SysctlRunner(root)
factory = SysctlFactory(runner)
endpoint = serverFromString(self.reactor, description)
endpoint.listen(factory)

Expand Down
Loading

0 comments on commit dc1e978

Please sign in to comment.