Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release-candidate v0.60.0-rc.1 #995

Merged
merged 28 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
eb8f521
Merge pull request #961 from HathorNetwork/release-candidate
jansegre Mar 1, 2024
b1e8d35
feat(unrecoverable-error): implement halting of full node execution (…
glevco Mar 5, 2024
d800b72
feat(feature-activation): add feature settings validation (#894)
glevco Mar 5, 2024
4ccc883
Merge branch 'release' into master
jansegre Mar 7, 2024
a2ee438
fix(indexes): Fix wrong order in MemoryTxGroupIndex
msbrogli Mar 14, 2024
8ed3e4b
refactor: create non-null hash property (#967)
glevco Mar 19, 2024
2b32edc
refactor(mypy): add stricter rules to specific modules (#969)
glevco Mar 19, 2024
8efb6d4
refactor(indexes): Optimize RocksDBAddressIndex to handle pagination …
pedroferreira1 Mar 20, 2024
53e837f
refactor(mypy): add stricter rules to some test modules (#971)
glevco Mar 20, 2024
a715e0b
refactor(mypy): add stricter rules to more test modules (#972)
glevco Mar 20, 2024
7d061a1
docs: fix OpenAPI url of cpu profiler endpoint
jansegre Mar 7, 2024
7bcc669
Merge pull request #979 from HathorNetwork/docs/fix-top-openapi-url
jansegre Mar 20, 2024
f273716
fix(util): division by zero when logging progress in some cases
jansegre Mar 20, 2024
74b7251
Merge pull request #980 from HathorNetwork/fix/division-by-zero-on-pr…
jansegre Mar 21, 2024
443604f
refactor(mypy): add stricter rules to p2p tests (#973)
glevco Mar 22, 2024
466550d
refactor(daa): externalize block dependencies (#895)
glevco Mar 22, 2024
ded7fef
refactor(mypy): add stricter rules to unittest and utils (#974)
glevco Mar 22, 2024
08590e3
fix: improve unnecessary alerts (#965)
glevco Mar 22, 2024
947db7b
refactor(mypy): unify hathor and test modules strictness (#975)
glevco Mar 22, 2024
881c5ff
tests(verification): add missing assertions (#983)
glevco Apr 2, 2024
3ff748d
feat(feature-activation): implement bit signaling sysctl (#962)
glevco Apr 2, 2024
c28737a
chore: bump version to v0.60.0
jansegre Mar 28, 2024
f76b6b4
Merge pull request #984 from HathorNetwork/chore/v0.60.0
jansegre Apr 2, 2024
e889e7a
feat(feature-activation): automatically enable support in MUST_SIGNAL…
glevco Apr 2, 2024
929d88b
refactor: remove deprecated resource method from address history API …
pedroferreira1 Apr 4, 2024
23f764d
fix(events): add missing signal_bits to event schema (#985)
glevco Apr 8, 2024
b9abf07
feat(p2p): add ability to update peer_id.json with SIGUSR1
glevco Mar 21, 2024
39a22fe
Merge pull request #981 from HathorNetwork/feat/p2p/update-peer-id
jansegre Apr 17, 2024
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
35 changes: 32 additions & 3 deletions hathor/builder/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from typing import Any, Callable, NamedTuple, Optional, TypeAlias

from structlog import get_logger
from typing_extensions import assert_never

from hathor.checkpoint import Checkpoint
from hathor.conf.get_settings import get_global_settings
Expand All @@ -25,9 +26,11 @@
from hathor.event import EventManager
from hathor.event.storage import EventMemoryStorage, EventRocksDBStorage, EventStorage
from hathor.event.websocket import EventWebsocketFactory
from hathor.execution_manager import ExecutionManager
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.feature_activation.storage.feature_activation_storage import FeatureActivationStorage
from hathor.indexes import IndexesManager, MemoryIndexesManager, RocksDBIndexesManager
from hathor.manager import HathorManager
from hathor.mining.cpu_mining_service import CpuMiningService
Expand All @@ -44,7 +47,8 @@
TransactionStorage,
)
from hathor.util import Random, get_environment_info, not_none
from hathor.verification.verification_service import VerificationService, VertexVerifiers
from hathor.verification.verification_service import VerificationService
from hathor.verification.vertex_verifiers import VertexVerifiers
from hathor.wallet import BaseWallet, Wallet

logger = get_logger()
Expand All @@ -67,6 +71,7 @@ class BuildArtifacts(NamedTuple):
consensus: ConsensusAlgorithm
tx_storage: TransactionStorage
feature_service: FeatureService
bit_signaling_service: BitSignalingService
indexes: Optional[IndexesManager]
wallet: Optional[BaseWallet]
rocksdb_storage: Optional[RocksDBStorage]
Expand Down Expand Up @@ -150,6 +155,8 @@ def __init__(self) -> None:

self._soft_voided_tx_ids: Optional[set[bytes]] = None

self._execution_manager: ExecutionManager | None = None

def build(self) -> BuildArtifacts:
if self.artifacts is not None:
raise ValueError('cannot call build twice')
Expand All @@ -163,8 +170,9 @@ def build(self) -> BuildArtifacts:

peer_id = self._get_peer_id()

execution_manager = self._get_or_create_execution_manager()
soft_voided_tx_ids = self._get_soft_voided_tx_ids()
consensus_algorithm = ConsensusAlgorithm(soft_voided_tx_ids, pubsub)
consensus_algorithm = ConsensusAlgorithm(soft_voided_tx_ids, pubsub, execution_manager=execution_manager)

p2p_manager = self._get_p2p_manager()

Expand Down Expand Up @@ -215,6 +223,7 @@ def build(self) -> BuildArtifacts:
bit_signaling_service=bit_signaling_service,
verification_service=verification_service,
cpu_mining_service=cpu_mining_service,
execution_manager=execution_manager,
**kwargs
)

Expand All @@ -239,6 +248,7 @@ def build(self) -> BuildArtifacts:
rocksdb_storage=self._rocksdb_storage,
stratum_factory=stratum_factory,
feature_service=feature_service,
bit_signaling_service=bit_signaling_service
)

return self.artifacts
Expand Down Expand Up @@ -306,6 +316,13 @@ def _get_peer_id(self) -> PeerId:
return self._peer_id
raise ValueError('peer_id not set')

def _get_or_create_execution_manager(self) -> ExecutionManager:
if self._execution_manager is None:
reactor = self._get_reactor()
self._execution_manager = ExecutionManager(reactor)

return self._execution_manager

def _get_or_create_pubsub(self) -> PubSubManager:
if self._pubsub is None:
self._pubsub = PubSubManager(self._get_reactor())
Expand Down Expand Up @@ -438,7 +455,8 @@ def _get_or_create_event_manager(self) -> EventManager:
reactor=reactor,
pubsub=self._get_or_create_pubsub(),
event_storage=storage,
event_ws_factory=factory
event_ws_factory=factory,
execution_manager=self._get_or_create_execution_manager()
)

return self._event_manager
Expand All @@ -460,12 +478,14 @@ def _get_or_create_bit_signaling_service(self) -> BitSignalingService:
settings = self._get_or_create_settings()
tx_storage = self._get_or_create_tx_storage()
feature_service = self._get_or_create_feature_service()
feature_storage = self._get_or_create_feature_storage()
self._bit_signaling_service = BitSignalingService(
feature_settings=settings.FEATURE_ACTIVATION,
feature_service=feature_service,
tx_storage=tx_storage,
support_features=self._support_features,
not_support_features=self._not_support_features,
feature_storage=feature_storage,
)

return self._bit_signaling_service
Expand All @@ -477,6 +497,15 @@ def _get_or_create_verification_service(self) -> VerificationService:

return self._verification_service

def _get_or_create_feature_storage(self) -> FeatureActivationStorage | None:
match self._storage_type:
case StorageType.MEMORY: return None
case StorageType.ROCKSDB: return FeatureActivationStorage(
settings=self._get_or_create_settings(),
rocksdb_storage=self._get_or_create_rocksdb_storage()
)
case _: assert_never(self._storage_type)

def _get_or_create_vertex_verifiers(self) -> VertexVerifiers:
if self._vertex_verifiers is None:
settings = self._get_or_create_settings()
Expand Down
35 changes: 19 additions & 16 deletions hathor/builder/cli_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.

import getpass
import json
import os
import platform
import sys
Expand All @@ -27,8 +26,10 @@
from hathor.daa import DifficultyAdjustmentAlgorithm
from hathor.event import EventManager
from hathor.exception import BuilderError
from hathor.execution_manager import ExecutionManager
from hathor.feature_activation.bit_signaling_service import BitSignalingService
from hathor.feature_activation.feature_service import FeatureService
from hathor.feature_activation.storage.feature_activation_storage import FeatureActivationStorage
from hathor.indexes import IndexesManager, MemoryIndexesManager, RocksDBIndexesManager
from hathor.manager import HathorManager
from hathor.mining.cpu_mining_service import CpuMiningService
Expand Down Expand Up @@ -94,8 +95,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
self.log = logger.new()
self.reactor = reactor

peer_id = self.create_peer_id()

peer_id = PeerId.create_from_json_path(self._args.peer) if self._args.peer else PeerId()
python = f'{platform.python_version()}-{platform.python_implementation()}'

self.log.info(
Expand All @@ -119,6 +119,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
tx_storage: TransactionStorage
event_storage: EventStorage
indexes: IndexesManager
feature_storage: FeatureActivationStorage | None = None
self.rocksdb_storage: Optional[RocksDBStorage] = None
self.event_ws_factory: Optional[EventWebsocketFactory] = None

Expand Down Expand Up @@ -151,6 +152,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
kwargs['indexes'] = indexes
tx_storage = TransactionRocksDBStorage(self.rocksdb_storage, **kwargs)
event_storage = EventRocksDBStorage(self.rocksdb_storage)
feature_storage = FeatureActivationStorage(settings=settings, rocksdb_storage=self.rocksdb_storage)

self.log.info('with storage', storage_class=type(tx_storage).__name__, path=self._args.data)
if self._args.cache:
Expand Down Expand Up @@ -212,11 +214,14 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
event_storage=event_storage
)

execution_manager = ExecutionManager(reactor)

event_manager = EventManager(
event_storage=event_storage,
event_ws_factory=self.event_ws_factory,
pubsub=pubsub,
reactor=reactor
reactor=reactor,
execution_manager=execution_manager,
)

if self._args.wallet_index and tx_storage.indexes is not None:
Expand All @@ -236,7 +241,11 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
full_verification = True

soft_voided_tx_ids = set(settings.SOFT_VOIDED_TX_IDS)
consensus_algorithm = ConsensusAlgorithm(soft_voided_tx_ids, pubsub=pubsub)
consensus_algorithm = ConsensusAlgorithm(
soft_voided_tx_ids,
pubsub=pubsub,
execution_manager=execution_manager
)

if self._args.x_enable_event_queue:
self.log.info('--x-enable-event-queue flag provided. '
Expand All @@ -252,7 +261,8 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
feature_service=self.feature_service,
tx_storage=tx_storage,
support_features=self._args.signal_support,
not_support_features=self._args.signal_not_support
not_support_features=self._args.signal_not_support,
feature_storage=feature_storage,
)

test_mode = TestMode.DISABLED
Expand Down Expand Up @@ -308,7 +318,8 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
feature_service=self.feature_service,
bit_signaling_service=bit_signaling_service,
verification_service=verification_service,
cpu_mining_service=cpu_mining_service
cpu_mining_service=cpu_mining_service,
execution_manager=execution_manager,
)

if self._args.x_ipython_kernel:
Expand Down Expand Up @@ -354,7 +365,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
self.log.warn('--memory-indexes is implied for memory storage or JSON storage')

for description in self._args.listen:
p2p_manager.add_listen_address(description)
p2p_manager.add_listen_address_description(description)

if self._args.peer_id_blacklist:
self.log.info('with peer id blacklist', blacklist=self._args.peer_id_blacklist)
Expand Down Expand Up @@ -384,14 +395,6 @@ def get_hostname(self) -> Optional[str]:
print('Hostname discovered and set to {}'.format(hostname))
return hostname

def create_peer_id(self) -> PeerId:
if not self._args.peer:
peer_id = PeerId()
else:
data = json.load(open(self._args.peer, 'r'))
peer_id = PeerId.create_from_json(data)
return peer_id

def create_wallet(self) -> BaseWallet:
if self._args.wallet == 'hd':
kwargs: dict[str, Any] = {
Expand Down
14 changes: 12 additions & 2 deletions hathor/builder/sysctl_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@
# limitations under the License.

from hathor.builder import BuildArtifacts
from hathor.sysctl import ConnectionsManagerSysctl, HathorManagerSysctl, Sysctl, WebsocketManagerSysctl
from hathor.sysctl import (
ConnectionsManagerSysctl,
FeatureActivationSysctl,
HathorManagerSysctl,
Sysctl,
WebsocketManagerSysctl,
)


class SysctlBuilder:
Expand All @@ -25,7 +31,11 @@ def __init__(self, artifacts: BuildArtifacts) -> None:
def build(self) -> Sysctl:
"""Build the sysctl tree."""
root = Sysctl()
root.put_child('core', HathorManagerSysctl(self.artifacts.manager))

core = HathorManagerSysctl(self.artifacts.manager)
core.put_child('features', FeatureActivationSysctl(self.artifacts.bit_signaling_service))

root.put_child('core', core)
root.put_child('p2p', ConnectionsManagerSysctl(self.artifacts.p2p_manager))

ws_factory = self.artifacts.manager.metrics.websocket_factory
Expand Down
3 changes: 3 additions & 0 deletions hathor/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def __init__(self) -> None:
quick_test,
replay_logs,
reset_event_queue,
reset_feature_settings,
run_node,
shell,
stratum_mining,
Expand Down Expand Up @@ -81,6 +82,8 @@ def __init__(self) -> None:
self.add_cmd('oracle', 'oracle-encode-data', oracle_encode_data, 'Encode data and sign it with a private key')
self.add_cmd('events', 'reset-event-queue', reset_event_queue, 'Delete all events and related data from the '
'database')
self.add_cmd('features', 'reset-feature-settings', reset_feature_settings, 'Delete existing Feature '
'Activation settings from the database')
self.add_cmd('dev', 'shell', shell, 'Run a Python shell')
self.add_cmd('dev', 'quick_test', quick_test, 'Similar to run_node but will quit after receiving a tx')
self.add_cmd('dev', 'generate_nginx_config', nginx_config, 'Generate nginx config from OpenAPI json')
Expand Down
3 changes: 2 additions & 1 deletion hathor/cli/mining.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ def execute(args: Namespace) -> None:

from hathor.conf.get_settings import get_global_settings
from hathor.daa import DifficultyAdjustmentAlgorithm
from hathor.verification.verification_service import VerificationService, VertexVerifiers
from hathor.verification.verification_service import VerificationService
from hathor.verification.vertex_verifiers import VertexVerifiers
settings = get_global_settings()
daa = DifficultyAdjustmentAlgorithm(settings=settings)
verifiers = VertexVerifiers.create_defaults(settings=settings, daa=daa, feature_service=Mock())
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.59.0"
"version": "0.60.0"
},
"consumes": [
"application/json"
Expand Down
49 changes: 49 additions & 0 deletions hathor/cli/reset_feature_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright 2023 Hathor Labs
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from argparse import ArgumentParser, Namespace

from structlog import get_logger

logger = get_logger()


def create_parser() -> ArgumentParser:
from hathor.cli.util import create_parser

parser = create_parser()
parser.add_argument('--data', help='Data directory')

return parser


def execute(args: Namespace) -> None:
from hathor.conf.get_settings import get_global_settings
from hathor.feature_activation.storage.feature_activation_storage import FeatureActivationStorage
from hathor.storage import RocksDBStorage

assert args.data is not None, '--data is required'

rocksdb_storage = RocksDBStorage(path=args.data)
feature_storage = FeatureActivationStorage(settings=get_global_settings(), rocksdb_storage=rocksdb_storage)

logger.info('removing feature activation settings...')
feature_storage.reset_settings()
logger.info('reset complete')


def main():
parser = create_parser()
args = parser.parse_args()
execute(args)
8 changes: 4 additions & 4 deletions hathor/cli/run_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ 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=self.manager._feature_service
feature_service=self.manager._feature_service,
bit_signaling_service=self.manager._bit_signaling_service,
)

def start_sentry_if_possible(self) -> None:
Expand Down Expand Up @@ -264,9 +265,8 @@ def register_signal_handlers(self) -> None:
def signal_usr1_handler(self, sig: int, frame: Any) -> None:
"""Called when USR1 signal is received."""
try:
self.log.warn('USR1 received. Killing all connections...')
if self.manager and self.manager.connections:
self.manager.connections.disconnect_all_peers(force=True)
self.log.warn('USR1 received.')
self.manager.connections.reload_entrypoints_and_connections()
except Exception:
# see: https://docs.python.org/3/library/signal.html#note-on-signal-handlers-and-exceptions
self.log.error('prevented exception from escaping the signal handler', exc_info=True)
Expand Down
4 changes: 4 additions & 0 deletions hathor/conf/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,10 @@ def GENESIS_TX2_TIMESTAMP(self) -> int:
OLD_MAX_MERKLE_PATH_LENGTH: int = 12
NEW_MAX_MERKLE_PATH_LENGTH: int = 20

# Maximum number of tx tips to accept in the initial phase of the mempool sync 1000 is arbitrary, but it should be
# more than enough for the forseeable future
MAX_MEMPOOL_RECEIVING_TIPS: int = 1000

# Used to enable nano contracts.
#
# This should NEVER be enabled for mainnet and testnet, since both networks will
Expand Down
Loading
Loading