diff --git a/hathor/builder.py b/hathor/builder.py index b569ab888..6da0adfe2 100644 --- a/hathor/builder.py +++ b/hathor/builder.py @@ -26,6 +26,7 @@ from twisted.web import server from twisted.web.resource import Resource +from hathor.consensus import ConsensusAlgorithm from hathor.event import EventManager from hathor.event.resources.event import EventResource from hathor.exception import BuilderError @@ -163,6 +164,9 @@ def create_manager(self, reactor: PosixReactorBase, args: Namespace) -> HathorMa self.log.debug('enable utxo index') tx_storage.indexes.enable_utxo_index() + soft_voided_tx_ids = set(settings.SOFT_VOIDED_TX_IDS) + consensus_algorithm = ConsensusAlgorithm(soft_voided_tx_ids, pubsub=pubsub) + self.manager = HathorManager( reactor, pubsub=pubsub, @@ -177,7 +181,7 @@ def create_manager(self, reactor: PosixReactorBase, args: Namespace) -> HathorMa checkpoints=settings.CHECKPOINTS, enable_sync_v1=enable_sync_v1, enable_sync_v2=enable_sync_v2, - soft_voided_tx_ids=set(settings.SOFT_VOIDED_TX_IDS), + consensus_algorithm=consensus_algorithm, environment_info=get_environment_info(args=str(args), peer_id=peer_id.id), ) diff --git a/hathor/manager.py b/hathor/manager.py index ef04a2a7e..24e8a3dc1 100644 --- a/hathor/manager.py +++ b/hathor/manager.py @@ -16,7 +16,7 @@ import sys import time from enum import Enum -from typing import Any, Iterable, Iterator, List, NamedTuple, Optional, Set, Tuple, Union +from typing import Any, Iterable, Iterator, List, NamedTuple, Optional, Tuple, Union from hathorlib.base_transaction import tx_or_block_from_bytes as lib_tx_or_block_from_bytes from structlog import get_logger @@ -80,15 +80,25 @@ class UnhealthinessReason(str, Enum): # This is the interval to be used by the task to check if the node is synced CHECK_SYNC_STATE_INTERVAL = 30 # seconds - def __init__(self, reactor: Reactor, *, pubsub: PubSubManager, peer_id: Optional[PeerId] = None, - network: Optional[str] = None, hostname: Optional[str] = None, - wallet: Optional[BaseWallet] = None, tx_storage: Optional[TransactionStorage] = None, + def __init__(self, + reactor: Reactor, + *, + pubsub: PubSubManager, + consensus_algorithm: ConsensusAlgorithm, + peer_id: Optional[PeerId] = None, + network: Optional[str] = None, + hostname: Optional[str] = None, + wallet: Optional[BaseWallet] = None, + tx_storage: Optional[TransactionStorage] = None, event_manager: Optional[EventManager] = None, - stratum_port: Optional[int] = None, ssl: bool = True, - enable_sync_v1: bool = True, enable_sync_v2: bool = False, - capabilities: Optional[List[str]] = None, checkpoints: Optional[List[Checkpoint]] = None, - rng: Optional[Random] = None, soft_voided_tx_ids: Optional[Set[bytes]] = None, - environment_info: Optional[EnvironmentInfo] = None) -> None: + stratum_port: Optional[int] = None, + ssl: bool = True, + enable_sync_v1: bool = True, + enable_sync_v2: bool = False, + capabilities: Optional[List[str]] = None, + checkpoints: Optional[List[Checkpoint]] = None, + rng: Optional[Random] = None, + environment_info: Optional[EnvironmentInfo] = None): """ :param reactor: Twisted reactor which handles the mainloop and the events. :param peer_id: Id of this node. If not given, a new one is created. @@ -166,8 +176,7 @@ def __init__(self, reactor: Reactor, *, pubsub: PubSubManager, peer_id: Optional self.tx_storage.indexes.enable_deps_index() self.tx_storage.indexes.enable_mempool_index() - self.soft_voided_tx_ids = soft_voided_tx_ids or set() - self.consensus_algorithm = ConsensusAlgorithm(self.soft_voided_tx_ids, pubsub=self.pubsub) + self.consensus_algorithm = consensus_algorithm self.peer_discoveries: List[PeerDiscovery] = [] @@ -402,7 +411,7 @@ def _initialize_components(self) -> None: # a database that already has the soft voided transaction before marking them in the metadata # Any new sync from the beginning should work fine or starting with the latest snapshot # that already has the soft voided transactions marked - for soft_voided_id in settings.SOFT_VOIDED_TX_IDS: + for soft_voided_id in self.consensus_algorithm.soft_voided_tx_ids: try: soft_voided_tx = self.tx_storage.get_transaction(soft_voided_id) except TransactionDoesNotExist: @@ -595,7 +604,7 @@ def _initialize_components_new(self) -> None: # a database that already has the soft voided transaction before marking them in the metadata # Any new sync from the beginning should work fine or starting with the latest snapshot # that already has the soft voided transactions marked - for soft_voided_id in settings.SOFT_VOIDED_TX_IDS: + for soft_voided_id in self.consensus_algorithm.soft_voided_tx_ids: try: soft_voided_tx = self.tx_storage.get_transaction(soft_voided_id) except TransactionDoesNotExist: diff --git a/hathor/simulator/simulator.py b/hathor/simulator/simulator.py index e21f6f4fe..329af090e 100644 --- a/hathor/simulator/simulator.py +++ b/hathor/simulator/simulator.py @@ -20,6 +20,7 @@ from mnemonic import Mnemonic from structlog import get_logger +from hathor.consensus import ConsensusAlgorithm from hathor.daa import TestMode, _set_test_mode from hathor.manager import HathorManager from hathor.p2p.peer_id import PeerId @@ -138,6 +139,10 @@ def create_peer(self, network: Optional[str] = None, peer_id: Optional[PeerId] = pubsub = PubSubManager(self._clock) + if soft_voided_tx_ids is None: + soft_voided_tx_ids = set() + consensus_algorithm = ConsensusAlgorithm(soft_voided_tx_ids, pubsub=pubsub) + assert peer_id is not None # XXX: temporary, for checking that tests are using the peer_id if peer_id is None: peer_id = PeerId() @@ -145,6 +150,7 @@ def create_peer(self, network: Optional[str] = None, peer_id: Optional[PeerId] = manager = HathorManager( self._clock, pubsub=pubsub, + consensus_algorithm=consensus_algorithm, peer_id=peer_id, network=network, wallet=wallet, @@ -152,7 +158,6 @@ def create_peer(self, network: Optional[str] = None, peer_id: Optional[PeerId] = enable_sync_v2=enable_sync_v2, tx_storage=tx_storage, rng=Random(self.rng.getrandbits(64)), - soft_voided_tx_ids=soft_voided_tx_ids, ) manager.reactor = self._clock diff --git a/tests/consensus/test_soft_voided2.py b/tests/consensus/test_soft_voided2.py index 9628fdb04..67f24d1d4 100644 --- a/tests/consensus/test_soft_voided2.py +++ b/tests/consensus/test_soft_voided2.py @@ -56,8 +56,8 @@ def do_step(self, i, manager1, tx_base): self.graphviz.labels[txF1.hash] = f'txF1-{i}' if not self.skip_asserts: - self.assertIn(txF1.hash, manager1.soft_voided_tx_ids) - self.assertIn(txF2.hash, manager1.soft_voided_tx_ids) + self.assertIn(txF1.hash, manager1.consensus_algorithm.soft_voided_tx_ids) + self.assertIn(txF2.hash, manager1.consensus_algorithm.soft_voided_tx_ids) txG = add_custom_tx(manager1, [(txF2, 0)], base_parent=tx_base, address=address) self.graphviz.labels[txG.hash] = f'txG-{i}' diff --git a/tests/others/test_init_manager.py b/tests/others/test_init_manager.py index 375f74c32..ee3e7bce8 100644 --- a/tests/others/test_init_manager.py +++ b/tests/others/test_init_manager.py @@ -1,6 +1,7 @@ from typing import Iterator from hathor.conf import HathorSettings +from hathor.consensus import ConsensusAlgorithm from hathor.manager import HathorManager from hathor.pubsub import PubSubManager from hathor.transaction import BaseTransaction @@ -41,35 +42,69 @@ def setUp(self): self.tx_storage = ModifiedTransactionMemoryStorage() self.pubsub = PubSubManager(self.clock) + soft_voided_tx_ids = set(settings.SOFT_VOIDED_TX_IDS) + self.consensus_algorithm = ConsensusAlgorithm(soft_voided_tx_ids, pubsub=self.pubsub) + def test_invalid_arguments(self): # this is a base case, it shouldn't raise any error # (otherwise we might not be testing the correct thing below) - manager = HathorManager(self.clock, pubsub=self.pubsub, tx_storage=self.tx_storage) + manager = HathorManager( + self.clock, + pubsub=self.pubsub, + consensus_algorithm=self.consensus_algorithm, + tx_storage=self.tx_storage + ) del manager # disabling both sync versions should be invalid with self.assertRaises(TypeError): - HathorManager(self.clock, pubsub=self.pubsub, tx_storage=self.tx_storage, - enable_sync_v1=False, enable_sync_v2=False) + HathorManager( + self.clock, + pubsub=self.pubsub, + consensus_algorithm=self.consensus_algorithm, + tx_storage=self.tx_storage, + enable_sync_v1=False, + enable_sync_v2=False + ) # not passing a storage should be invalid with self.assertRaises(TypeError): - HathorManager(self.clock) + HathorManager( + self.clock, + pubsub=self.pubsub, + consensus_algorithm=self.consensus_algorithm, + ) def tests_init_with_stratum(self): - manager = HathorManager(self.clock, pubsub=self.pubsub, tx_storage=self.tx_storage, stratum_port=50505) + manager = HathorManager( + self.clock, + pubsub=self.pubsub, + consensus_algorithm=self.consensus_algorithm, + tx_storage=self.tx_storage, + stratum_port=50505 + ) manager.start() manager.stop() del manager def test_double_start(self): - manager = HathorManager(self.clock, pubsub=self.pubsub, tx_storage=self.tx_storage) + manager = HathorManager( + self.clock, + pubsub=self.pubsub, + consensus_algorithm=self.consensus_algorithm, + tx_storage=self.tx_storage + ) manager.start() with self.assertRaises(Exception): manager.start() def test_wrong_stop(self): - manager = HathorManager(self.clock, pubsub=self.pubsub, tx_storage=self.tx_storage) + manager = HathorManager( + self.clock, + pubsub=self.pubsub, + consensus_algorithm=self.consensus_algorithm, + tx_storage=self.tx_storage + ) with self.assertRaises(Exception): manager.stop() manager.start() diff --git a/tests/tx/test_tx_storage.py b/tests/tx/test_tx_storage.py index 226ff08e2..f5f8ec17b 100644 --- a/tests/tx/test_tx_storage.py +++ b/tests/tx/test_tx_storage.py @@ -9,6 +9,7 @@ from twisted.trial import unittest from hathor.conf import HathorSettings +from hathor.consensus import ConsensusAlgorithm from hathor.daa import TestMode, _set_test_mode from hathor.pubsub import PubSubManager from hathor.simulator.clock import MemoryReactorHeapClock @@ -57,7 +58,17 @@ def setUp(self, tx_storage, reactor=None): self.tmpdir = tempfile.mkdtemp() wallet = Wallet(directory=self.tmpdir) wallet.unlock(b'teste') - self.manager = HathorManager(self.reactor, pubsub=self.pubsub, tx_storage=self.tx_storage, wallet=wallet) + + soft_voided_tx_ids = set(settings.SOFT_VOIDED_TX_IDS) + consensus_algorithm = ConsensusAlgorithm(soft_voided_tx_ids, pubsub=self.pubsub) + + self.manager = HathorManager( + self.reactor, + pubsub=self.pubsub, + consensus_algorithm=consensus_algorithm, + tx_storage=self.tx_storage, + wallet=wallet + ) self.tx_storage.indexes.enable_address_index(self.manager.pubsub) self.tx_storage.indexes.enable_tokens_index() diff --git a/tests/unittest.py b/tests/unittest.py index f0efcafc3..723cd918b 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -11,6 +11,7 @@ from hathor.builder import CliBuilder from hathor.conf import HathorSettings +from hathor.consensus import ConsensusAlgorithm from hathor.daa import TestMode, _set_test_mode from hathor.manager import HathorManager from hathor.p2p.peer_id import PeerId @@ -169,9 +170,13 @@ def create_peer(self, network, peer_id=None, wallet=None, tx_storage=None, unloc if utxo_index: tx_storage.indexes.enable_utxo_index() + soft_voided_tx_ids = set(settings.SOFT_VOIDED_TX_IDS) + consensus_algorithm = ConsensusAlgorithm(soft_voided_tx_ids, pubsub=pubsub) + manager = HathorManager( self.clock, pubsub=pubsub, + consensus_algorithm=consensus_algorithm, peer_id=peer_id, network=network, wallet=wallet,