Skip to content

Commit afe821b

Browse files
committed
refactor(misc): minor maintenance changes
1 parent 2c6efb3 commit afe821b

22 files changed

+55
-120
lines changed

docs/event-queue-feature.md

+3-8
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,14 @@ When the Event Queue feature is enabled, the full node will generate specific ev
1515

1616
## Enabling the Event Queue
1717

18-
To enable the Event Queue feature, you must add two CLI options when running the full node:
19-
20-
1. Add `--unsafe-mode [network_name]`
21-
2. Add `--x-enable-event-queue`
18+
To enable the Event Queue feature, you must add this CLI option when running the full node: `--enable-event-queue`.
2219

2320
For example:
2421

2522
```bash
26-
poetry run hathor-cli run_node --memory-storage --status 8080 --testnet --unsafe-mode testnet-golf --x-enable-event-queue
23+
poetry run hathor-cli run_node --memory-storage --status 8080 --testnet --enable-event-queue
2724
```
2825

29-
**ATTENTION**: While the Event Queue is in beta, it's considered unsafe. You must not use it in production environments.
30-
3126
### First run
3227

3328
If this is the first time your full node is running with the event queue enabled, there are 3 possibilities:
@@ -45,7 +40,7 @@ For case 2.2, an extra loading step will be performed during full node initializ
4540

4641
After running the full node with the Event Queue enabled, if you restart your full node (that is, stop it and then run it again), there are 2 possibilities:
4742

48-
1. You run the full node with the `--x-enable-event-queue` CLI option, that is, you keep the Event Queue enabled, or
43+
1. You run the full node with the `--enable-event-queue` CLI option, that is, you keep the Event Queue enabled, or
4944
2. You run the full node without the CLI option, that is, you don't enable it, but you **have to clear the event data in the database**.
5045

5146
For case 1, the full node will start normally, and continue to generate new events for synced vertices from where it stopped in the previous run.

hathor/builder/builder.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,7 @@ def _get_or_create_consensus(self) -> ConsensusAlgorithm:
372372
if self._consensus is None:
373373
soft_voided_tx_ids = self._get_soft_voided_tx_ids()
374374
pubsub = self._get_or_create_pubsub()
375-
execution_manager = self._get_or_create_execution_manager()
376-
self._consensus = ConsensusAlgorithm(soft_voided_tx_ids, pubsub, execution_manager=execution_manager)
375+
self._consensus = ConsensusAlgorithm(soft_voided_tx_ids, pubsub)
377376

378377
return self._consensus
379378

@@ -611,6 +610,7 @@ def _get_or_create_vertex_handler(self) -> VertexHandler:
611610
verification_service=self._get_or_create_verification_service(),
612611
consensus=self._get_or_create_consensus(),
613612
feature_service=self._get_or_create_feature_service(),
613+
execution_manager=self._get_or_create_execution_manager(),
614614
pubsub=self._get_or_create_pubsub(),
615615
wallet=self._get_or_create_wallet(),
616616
)

hathor/builder/cli_builder.py

+3-9
Original file line numberDiff line numberDiff line change
@@ -236,19 +236,12 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
236236
self.log.debug('enable utxo index')
237237
tx_storage.indexes.enable_utxo_index()
238238

239-
full_verification = False
240-
if self._args.x_full_verification:
241-
self.check_or_raise(
242-
not self._args.x_enable_event_queue and not self._args.enable_event_queue,
243-
'--x-full-verification cannot be used with --enable-event-queue'
244-
)
245-
full_verification = True
239+
self.check_or_raise(not self._args.x_full_verification, '--x-full-verification is deprecated')
246240

247241
soft_voided_tx_ids = set(settings.SOFT_VOIDED_TX_IDS)
248242
consensus_algorithm = ConsensusAlgorithm(
249243
soft_voided_tx_ids,
250244
pubsub=pubsub,
251-
execution_manager=execution_manager
252245
)
253246

254247
if self._args.x_enable_event_queue or self._args.enable_event_queue:
@@ -307,6 +300,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
307300
consensus=consensus_algorithm,
308301
feature_service=self.feature_service,
309302
pubsub=pubsub,
303+
execution_manager=execution_manager,
310304
wallet=self.wallet,
311305
log_vertex_bytes=self._args.log_vertex_bytes,
312306
)
@@ -339,7 +333,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
339333
wallet=self.wallet,
340334
checkpoints=settings.CHECKPOINTS,
341335
environment_info=get_environment_info(args=str(self._args), peer_id=str(peer.id)),
342-
full_verification=full_verification,
336+
full_verification=False,
343337
enable_event_queue=self._args.x_enable_event_queue or self._args.enable_event_queue,
344338
bit_signaling_service=bit_signaling_service,
345339
verification_service=verification_service,

hathor/cli/run_node.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def create_parser(cls) -> ArgumentParser:
125125
parser.add_argument('--recursion-limit', type=int, help='Set python recursion limit')
126126
parser.add_argument('--allow-mining-without-peers', action='store_true', help='Allow mining without peers')
127127
fvargs = parser.add_mutually_exclusive_group()
128-
fvargs.add_argument('--x-full-verification', action='store_true', help='Fully validate the local database')
128+
fvargs.add_argument('--x-full-verification', action='store_true', help=SUPPRESS) # deprecated
129129
parser.add_argument('--procname-prefix', help='Add a prefix to the process name', default='')
130130
parser.add_argument('--allow-non-standard-script', action='store_true', help='Accept non-standard scripts on '
131131
'/push-tx API')

hathor/consensus/consensus.py

+8-16
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from hathor.consensus.block_consensus import BlockConsensusAlgorithmFactory
2424
from hathor.consensus.context import ConsensusAlgorithmContext
2525
from hathor.consensus.transaction_consensus import TransactionConsensusAlgorithmFactory
26-
from hathor.execution_manager import ExecutionManager
2726
from hathor.profiler import get_cpu_profiler
2827
from hathor.pubsub import HathorEvents, PubSubManager
2928
from hathor.transaction import BaseTransaction
@@ -68,38 +67,31 @@ def __init__(
6867
self,
6968
soft_voided_tx_ids: set[bytes],
7069
pubsub: PubSubManager,
71-
*,
72-
execution_manager: ExecutionManager
7370
) -> None:
7471
self._settings = get_global_settings()
7572
self.log = logger.new()
7673
self._pubsub = pubsub
7774
self.soft_voided_tx_ids = frozenset(soft_voided_tx_ids)
7875
self.block_algorithm_factory = BlockConsensusAlgorithmFactory()
7976
self.transaction_algorithm_factory = TransactionConsensusAlgorithmFactory()
80-
self._execution_manager = execution_manager
8177

8278
def create_context(self) -> ConsensusAlgorithmContext:
8379
"""Handy method to create a context that can be used to access block and transaction algorithms."""
8480
return ConsensusAlgorithmContext(self, self._pubsub)
8581

8682
@cpu.profiler(key=lambda self, base: 'consensus!{}'.format(base.hash.hex()))
87-
def update(self, base: BaseTransaction) -> None:
83+
def unsafe_update(self, base: BaseTransaction) -> None:
84+
"""
85+
Run a consensus update with its own context, indexes will be updated accordingly.
86+
87+
It is considered unsafe because the caller is responsible for crashing the full node
88+
if this method throws any exception.
89+
"""
90+
from hathor.transaction import Block, Transaction
8891
assert base.storage is not None
8992
assert base.storage.is_only_valid_allowed()
9093
meta = base.get_metadata()
9194
assert meta.validation.is_valid()
92-
try:
93-
self._unsafe_update(base)
94-
except BaseException:
95-
meta.add_voided_by(self._settings.CONSENSUS_FAIL_ID)
96-
assert base.storage is not None
97-
base.storage.save_transaction(base, only_metadata=True)
98-
self._execution_manager.crash_and_exit(reason=f'Consensus update failed for tx {base.hash_hex}')
99-
100-
def _unsafe_update(self, base: BaseTransaction) -> None:
101-
"""Run a consensus update with its own context, indexes will be updated accordingly."""
102-
from hathor.transaction import Block, Transaction
10395

10496
# XXX: first make sure we can run the consensus update on this tx:
10597
meta = base.get_metadata()

hathor/indexes/manager.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ def del_tx(self, tx: BaseTransaction, *, remove_all: bool = False, relax_assert:
241241
self.addresses.remove_tx(tx)
242242
if self.utxo:
243243
self.utxo.del_tx(tx)
244+
if self.tokens:
245+
self.tokens.del_tx(tx)
244246
self.info.update_counts(tx, remove=True)
245247

246248
# mempool will pick-up if the transaction is voided/invalid and remove it
@@ -255,9 +257,6 @@ def del_tx(self, tx: BaseTransaction, *, remove_all: bool = False, relax_assert:
255257
self.tx_tips.del_tx(tx, relax_assert=relax_assert)
256258
self.sorted_txs.del_tx(tx)
257259

258-
if self.tokens:
259-
self.tokens.del_tx(tx)
260-
261260

262261
class MemoryIndexesManager(IndexesManager):
263262
def __init__(self, *, settings: HathorSettings | None = None) -> None:

hathor/manager.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ def _initialize_components_full_verification(self) -> None:
491491
)
492492
self.tx_storage.add_to_indexes(tx)
493493
with self.tx_storage.allow_only_valid_context():
494-
self.consensus_algorithm.update(tx)
494+
self.consensus_algorithm.unsafe_update(tx)
495495
self.tx_storage.indexes.update(tx)
496496
if self.tx_storage.indexes.mempool_tips is not None:
497497
self.tx_storage.indexes.mempool_tips.update(tx) # XXX: move to indexes.update

hathor/p2p/states/peer_id.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,12 @@ async def handle_peer_id(self, payload: str) -> None:
102102

103103
data = json_loads(payload)
104104

105-
peer = PublicPeer.create_from_json(data)
105+
try:
106+
peer = PublicPeer.create_from_json(data)
107+
except ValueError as e:
108+
protocol.send_error_and_close_connection(f'Unable to parse peer id. Reason: {str(e)}')
109+
return
110+
106111
assert peer.id is not None
107112

108113
# If the connection URL had a peer-id parameter we need to check it's the same

hathor/vertex_handler/vertex_handler.py

+23-8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from hathor.conf.settings import HathorSettings
2020
from hathor.consensus import ConsensusAlgorithm
2121
from hathor.exception import HathorError, InvalidNewTransaction
22+
from hathor.execution_manager import ExecutionManager
2223
from hathor.feature_activation.feature_service import FeatureService
2324
from hathor.profiler import get_cpu_profiler
2425
from hathor.pubsub import HathorEvents, PubSubManager
@@ -43,6 +44,7 @@ class VertexHandler:
4344
'_consensus',
4445
'_feature_service',
4546
'_pubsub',
47+
'_execution_manager',
4648
'_wallet',
4749
'_log_vertex_bytes',
4850
)
@@ -57,6 +59,7 @@ def __init__(
5759
consensus: ConsensusAlgorithm,
5860
feature_service: FeatureService,
5961
pubsub: PubSubManager,
62+
execution_manager: ExecutionManager,
6063
wallet: BaseWallet | None,
6164
log_vertex_bytes: bool = False,
6265
) -> None:
@@ -68,6 +71,7 @@ def __init__(
6871
self._consensus = consensus
6972
self._feature_service = feature_service
7073
self._pubsub = pubsub
74+
self._execution_manager = execution_manager
7175
self._wallet = wallet
7276
self._log_vertex_bytes = log_vertex_bytes
7377

@@ -95,12 +99,19 @@ def on_new_vertex(
9599
if not is_valid:
96100
return False
97101

98-
self._save_and_run_consensus(vertex)
99-
self._post_consensus(
100-
vertex,
101-
quiet=quiet,
102-
reject_locked_reward=reject_locked_reward
103-
)
102+
try:
103+
self._unsafe_save_and_run_consensus(vertex)
104+
self._post_consensus(
105+
vertex,
106+
quiet=quiet,
107+
reject_locked_reward=reject_locked_reward
108+
)
109+
except BaseException:
110+
self._log.error('unexpected exception in on_new_vertex()', vertex=vertex)
111+
meta = vertex.get_metadata()
112+
meta.add_voided_by(self._settings.CONSENSUS_FAIL_ID)
113+
self._tx_storage.save_transaction(vertex, only_metadata=True)
114+
self._execution_manager.crash_and_exit(reason=f'on_new_vertex() failed for tx {vertex.hash_hex}')
104115

105116
return True
106117

@@ -158,15 +169,19 @@ def _validate_vertex(
158169

159170
return True
160171

161-
def _save_and_run_consensus(self, vertex: BaseTransaction) -> None:
172+
def _unsafe_save_and_run_consensus(self, vertex: BaseTransaction) -> None:
173+
"""
174+
This method is considered unsafe because the caller is responsible for crashing the full node
175+
if this method throws any exception.
176+
"""
162177
# The method below adds the tx as a child of the parents
163178
# This needs to be called right before the save because we were adding the children
164179
# in the tx parents even if the tx was invalid (failing the verifications above)
165180
# then I would have a children that was not in the storage
166181
vertex.update_initial_metadata(save=False)
167182
self._tx_storage.save_transaction(vertex)
168183
self._tx_storage.add_to_indexes(vertex)
169-
self._consensus.update(vertex)
184+
self._consensus.unsafe_update(vertex)
170185

171186
def _post_consensus(
172187
self,

tests/cli/test_shell.py

-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import tempfile
22

3-
import pytest
4-
53
from hathor.cli.shell import Shell
64
from tests import unittest
7-
from tests.utils import HAS_ROCKSDB
85

96

107
class ShellTest(unittest.TestCase):
@@ -14,7 +11,6 @@ def test_shell_execution_memory_storage(self):
1411
shell = Shell(argv=['--memory-storage', '--', '--extra-arg'])
1512
self.assertTrue(shell is not None)
1613

17-
@pytest.mark.skipif(not HAS_ROCKSDB, reason='requires python-rocksdb')
1814
def test_shell_execution_default_storage(self):
1915
temp_data = tempfile.TemporaryDirectory()
2016
shell = Shell(argv=['--data', temp_data.name])

tests/consensus/test_consensus.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ class MyError(Exception):
3131
pass
3232

3333
execution_manager_mock = Mock(spec_set=ExecutionManager)
34-
manager.consensus_algorithm._execution_manager = execution_manager_mock
35-
manager.consensus_algorithm._unsafe_update = MagicMock(side_effect=MyError)
34+
manager.vertex_handler._execution_manager = execution_manager_mock
35+
manager.consensus_algorithm.unsafe_update = MagicMock(side_effect=MyError)
3636

3737
manager.propagate_tx(tx, fails_silently=False)
3838

3939
execution_manager_mock.crash_and_exit.assert_called_once_with(
40-
reason=f"Consensus update failed for tx {tx.hash_hex}"
40+
reason=f"on_new_vertex() failed for tx {tx.hash_hex}"
4141
)
4242

4343
tx2 = manager.tx_storage.get_transaction(tx.hash)

tests/event/event_simulation_tester.py

-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from typing import Any, Iterable
1717
from unittest.mock import Mock
1818

19-
import pytest
2019
from twisted.internet.testing import StringTransport
2120

2221
from hathor.builder import Builder
@@ -27,7 +26,6 @@
2726
from hathor.transaction.util import unpack, unpack_len
2827
from hathor.util import json_loadb
2928
from tests.simulation.base import SimulatorTestCase
30-
from tests.utils import HAS_ROCKSDB
3129

3230

3331
class BaseEventSimulationTester(SimulatorTestCase):
@@ -101,7 +99,6 @@ def setUp(self) -> None:
10199
self._create_artifacts()
102100

103101

104-
@pytest.mark.skipif(not HAS_ROCKSDB, reason='requires python-rocksdb')
105102
class RocksDBEventSimulationTester(BaseEventSimulationTester):
106103
def setUp(self) -> None:
107104
super().setUp()

tests/event/test_event_storage.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import tempfile
22

3-
import pytest
4-
53
from hathor.event.model.base_event import BaseEvent
64
from hathor.event.model.node_state import NodeState
75
from hathor.event.storage import EventStorage
86
from hathor.event.storage.memory_storage import EventMemoryStorage
97
from hathor.event.storage.rocksdb_storage import EventRocksDBStorage
108
from hathor.storage.rocksdb_storage import RocksDBStorage
119
from tests import unittest
12-
from tests.utils import HAS_ROCKSDB, EventMocker
10+
from tests.utils import EventMocker
1311

1412

1513
class EventStorageBaseTest(unittest.TestCase):
@@ -237,7 +235,6 @@ def test_reset_all_full_database(self) -> None:
237235
assert event_queue_state is False
238236

239237

240-
@pytest.mark.skipif(not HAS_ROCKSDB, reason='requires python-rocksdb')
241238
class EventStorageRocksDBTest(EventStorageBaseTest):
242239
__test__ = True
243240

tests/feature_activation/test_feature_simulation.py

-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
from hathor.util import not_none
3232
from tests.resources.base_resource import StubSite
3333
from tests.simulation.base import SimulatorTestCase
34-
from tests.utils import HAS_ROCKSDB
3534

3635

3736
class BaseFeatureSimulationTest(SimulatorTestCase):
@@ -671,7 +670,6 @@ def get_simulator_builder(self) -> Builder:
671670
return self.simulator.get_default_builder()
672671

673672

674-
@pytest.mark.skipif(not HAS_ROCKSDB, reason='requires python-rocksdb')
675673
class RocksDBStorageFeatureSimulationTest(BaseFeatureSimulationTest):
676674
__test__ = True
677675

0 commit comments

Comments
 (0)