Skip to content

Commit 007eb6e

Browse files
authored
Merge pull request #982 from HathorNetwork/feat/arg-to-make-sync-v1-unavailable
feat(cli): add argument to make sync-v1 unavailable
2 parents dc7071e + 3170851 commit 007eb6e

File tree

8 files changed

+86
-53
lines changed

8 files changed

+86
-53
lines changed

hathor/builder/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from hathor.builder.builder import BuildArtifacts, Builder
15+
from hathor.builder.builder import BuildArtifacts, Builder, SyncSupportLevel
1616
from hathor.builder.cli_builder import CliBuilder
1717
from hathor.builder.resources_builder import ResourcesBuilder
1818

@@ -21,4 +21,5 @@
2121
'Builder',
2222
'CliBuilder',
2323
'ResourcesBuilder',
24+
'SyncSupportLevel',
2425
]

hathor/builder/builder.py

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from enum import Enum
15+
from enum import Enum, IntEnum
1616
from typing import Any, Callable, NamedTuple, Optional, TypeAlias
1717

1818
from structlog import get_logger
@@ -55,6 +55,34 @@
5555
logger = get_logger()
5656

5757

58+
class SyncSupportLevel(IntEnum):
59+
UNAVAILABLE = 0 # not possible to enable at runtime
60+
DISABLED = 1 # available but disabled by default, possible to enable at runtime
61+
ENABLED = 2 # available and enabled by default, possible to disable at runtime
62+
63+
@classmethod
64+
def add_factories(cls,
65+
p2p_manager: ConnectionsManager,
66+
sync_v1_support: 'SyncSupportLevel',
67+
sync_v2_support: 'SyncSupportLevel',
68+
) -> None:
69+
"""Adds the sync factory to the manager according to the support level."""
70+
from hathor.p2p.sync_v1.factory import SyncV11Factory
71+
from hathor.p2p.sync_v2.factory import SyncV2Factory
72+
from hathor.p2p.sync_version import SyncVersion
73+
74+
# sync-v1 support:
75+
if sync_v1_support > cls.UNAVAILABLE:
76+
p2p_manager.add_sync_factory(SyncVersion.V1_1, SyncV11Factory(p2p_manager))
77+
if sync_v1_support is cls.ENABLED:
78+
p2p_manager.enable_sync_version(SyncVersion.V1_1)
79+
# sync-v2 support:
80+
if sync_v2_support > cls.UNAVAILABLE:
81+
p2p_manager.add_sync_factory(SyncVersion.V2, SyncV2Factory(p2p_manager))
82+
if sync_v2_support is cls.ENABLED:
83+
p2p_manager.enable_sync_version(SyncVersion.V2)
84+
85+
5886
class StorageType(Enum):
5987
MEMORY = 'memory'
6088
ROCKSDB = 'rocksdb'
@@ -147,8 +175,8 @@ def __init__(self) -> None:
147175
self._enable_tokens_index: bool = False
148176
self._enable_utxo_index: bool = False
149177

150-
self._enable_sync_v1: bool = True
151-
self._enable_sync_v2: bool = False
178+
self._sync_v1_support: SyncSupportLevel = SyncSupportLevel.UNAVAILABLE
179+
self._sync_v2_support: SyncSupportLevel = SyncSupportLevel.UNAVAILABLE
152180

153181
self._enable_stratum_server: Optional[bool] = None
154182

@@ -168,6 +196,9 @@ def build(self) -> BuildArtifacts:
168196
if self._network is None:
169197
raise TypeError('you must set a network')
170198

199+
if SyncSupportLevel.ENABLED not in {self._sync_v1_support, self._sync_v2_support}:
200+
raise TypeError('you must enable at least one sync version')
201+
171202
settings = self._get_or_create_settings()
172203
reactor = self._get_reactor()
173204
pubsub = self._get_or_create_pubsub()
@@ -368,10 +399,6 @@ def _get_or_create_p2p_manager(self) -> ConnectionsManager:
368399
if self._p2p_manager:
369400
return self._p2p_manager
370401

371-
from hathor.p2p.sync_v1.factory import SyncV11Factory
372-
from hathor.p2p.sync_v2.factory import SyncV2Factory
373-
from hathor.p2p.sync_version import SyncVersion
374-
375402
enable_ssl = True
376403
reactor = self._get_reactor()
377404
my_peer = self._get_peer_id()
@@ -387,12 +414,7 @@ def _get_or_create_p2p_manager(self) -> ConnectionsManager:
387414
whitelist_only=False,
388415
rng=self._rng,
389416
)
390-
self._p2p_manager.add_sync_factory(SyncVersion.V1_1, SyncV11Factory(self._p2p_manager))
391-
self._p2p_manager.add_sync_factory(SyncVersion.V2, SyncV2Factory(self._p2p_manager))
392-
if self._enable_sync_v1:
393-
self._p2p_manager.enable_sync_version(SyncVersion.V1_1)
394-
if self._enable_sync_v2:
395-
self._p2p_manager.enable_sync_version(SyncVersion.V2)
417+
SyncSupportLevel.add_factories(self._p2p_manager, self._sync_v1_support, self._sync_v2_support)
396418
return self._p2p_manager
397419

398420
def _get_or_create_indexes_manager(self) -> IndexesManager:
@@ -698,34 +720,34 @@ def set_network(self, network: str) -> 'Builder':
698720
self._network = network
699721
return self
700722

701-
def set_enable_sync_v1(self, enable_sync_v1: bool) -> 'Builder':
723+
def set_sync_v1_support(self, support_level: SyncSupportLevel) -> 'Builder':
702724
self.check_if_can_modify()
703-
self._enable_sync_v1 = enable_sync_v1
725+
self._sync_v1_support = support_level
704726
return self
705727

706-
def set_enable_sync_v2(self, enable_sync_v2: bool) -> 'Builder':
728+
def set_sync_v2_support(self, support_level: SyncSupportLevel) -> 'Builder':
707729
self.check_if_can_modify()
708-
self._enable_sync_v2 = enable_sync_v2
730+
self._sync_v2_support = support_level
709731
return self
710732

711733
def enable_sync_v1(self) -> 'Builder':
712734
self.check_if_can_modify()
713-
self._enable_sync_v1 = True
735+
self._sync_v1_support = SyncSupportLevel.ENABLED
714736
return self
715737

716738
def disable_sync_v1(self) -> 'Builder':
717739
self.check_if_can_modify()
718-
self._enable_sync_v1 = False
740+
self._sync_v1_support = SyncSupportLevel.DISABLED
719741
return self
720742

721743
def enable_sync_v2(self) -> 'Builder':
722744
self.check_if_can_modify()
723-
self._enable_sync_v2 = True
745+
self._sync_v2_support = SyncSupportLevel.ENABLED
724746
return self
725747

726748
def disable_sync_v2(self) -> 'Builder':
727749
self.check_if_can_modify()
728-
self._enable_sync_v2 = False
750+
self._sync_v2_support = SyncSupportLevel.DISABLED
729751
return self
730752

731753
def set_full_verification(self, full_verification: bool) -> 'Builder':

hathor/builder/cli_builder.py

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@
4949

5050

5151
class SyncChoice(Enum):
52-
V1_ONLY = auto()
53-
V2_ONLY = auto()
54-
BRIDGE = auto()
52+
V1_DEFAULT = auto() # v1 enabled, v2 disabled but can be enabled in runtime
53+
V2_DEFAULT = auto() # v2 enabled, v1 disabled but can be enabled in runtime
54+
BRIDGE_DEFAULT = auto() # both enabled, either can be disabled in runtime
55+
V2_ONLY = auto() # v1 is unavailable, it cannot be enabled in runtime
5556

5657

5758
class CliBuilder:
@@ -70,15 +71,13 @@ def check_or_raise(self, condition: bool, message: str) -> None:
7071

7172
def create_manager(self, reactor: Reactor) -> HathorManager:
7273
import hathor
74+
from hathor.builder import SyncSupportLevel
7375
from hathor.conf.get_settings import get_global_settings, get_settings_source
7476
from hathor.daa import TestMode
7577
from hathor.event.storage import EventMemoryStorage, EventRocksDBStorage, EventStorage
7678
from hathor.event.websocket.factory import EventWebsocketFactory
7779
from hathor.p2p.netfilter.utils import add_peer_id_blacklist
7880
from hathor.p2p.peer_discovery import BootstrapPeerDiscovery, DNSPeerDiscovery
79-
from hathor.p2p.sync_v1.factory import SyncV11Factory
80-
from hathor.p2p.sync_v2.factory import SyncV2Factory
81-
from hathor.p2p.sync_version import SyncVersion
8281
from hathor.storage import RocksDBStorage
8382
from hathor.transaction.storage import (
8483
TransactionCacheStorage,
@@ -177,34 +176,39 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
177176

178177
sync_choice: SyncChoice
179178
if self._args.sync_bridge:
180-
sync_choice = SyncChoice.BRIDGE
179+
sync_choice = SyncChoice.BRIDGE_DEFAULT
181180
elif self._args.sync_v1_only:
182-
sync_choice = SyncChoice.V1_ONLY
181+
sync_choice = SyncChoice.V1_DEFAULT
183182
elif self._args.sync_v2_only:
184183
self.log.warn('--sync-v2-only is the default, this parameter has no effect')
184+
sync_choice = SyncChoice.V2_DEFAULT
185+
elif self._args.x_remove_sync_v1:
185186
sync_choice = SyncChoice.V2_ONLY
186187
elif self._args.x_sync_bridge:
187188
self.log.warn('--x-sync-bridge is deprecated and will be removed, use --sync-bridge instead')
188-
sync_choice = SyncChoice.BRIDGE
189+
sync_choice = SyncChoice.BRIDGE_DEFAULT
189190
elif self._args.x_sync_v2_only:
190191
self.log.warn('--x-sync-v2-only is deprecated and will be removed, use --sync-v2-only instead')
191-
sync_choice = SyncChoice.V2_ONLY
192+
sync_choice = SyncChoice.V2_DEFAULT
192193
else:
193194
# XXX: this is the default behavior when no parameter is given
194-
sync_choice = SyncChoice.V2_ONLY
195+
sync_choice = SyncChoice.V2_DEFAULT
195196

196-
enable_sync_v1: bool
197-
enable_sync_v2: bool
197+
sync_v1_support: SyncSupportLevel
198+
sync_v2_support: SyncSupportLevel
198199
match sync_choice:
199-
case SyncChoice.V1_ONLY:
200-
enable_sync_v1 = True
201-
enable_sync_v2 = False
200+
case SyncChoice.V1_DEFAULT:
201+
sync_v1_support = SyncSupportLevel.ENABLED
202+
sync_v2_support = SyncSupportLevel.DISABLED
203+
case SyncChoice.V2_DEFAULT:
204+
sync_v1_support = SyncSupportLevel.DISABLED
205+
sync_v2_support = SyncSupportLevel.ENABLED
206+
case SyncChoice.BRIDGE_DEFAULT:
207+
sync_v1_support = SyncSupportLevel.ENABLED
208+
sync_v2_support = SyncSupportLevel.ENABLED
202209
case SyncChoice.V2_ONLY:
203-
enable_sync_v1 = False
204-
enable_sync_v2 = True
205-
case SyncChoice.BRIDGE:
206-
enable_sync_v1 = True
207-
enable_sync_v2 = True
210+
sync_v1_support = SyncSupportLevel.UNAVAILABLE
211+
sync_v2_support = SyncSupportLevel.ENABLED
208212

209213
pubsub = PubSubManager(reactor)
210214

@@ -293,12 +297,7 @@ def create_manager(self, reactor: Reactor) -> HathorManager:
293297
whitelist_only=False,
294298
rng=Random(),
295299
)
296-
p2p_manager.add_sync_factory(SyncVersion.V1_1, SyncV11Factory(p2p_manager))
297-
p2p_manager.add_sync_factory(SyncVersion.V2, SyncV2Factory(p2p_manager))
298-
if enable_sync_v1:
299-
p2p_manager.enable_sync_version(SyncVersion.V1_1)
300-
if enable_sync_v2:
301-
p2p_manager.enable_sync_version(SyncVersion.V2)
300+
SyncSupportLevel.add_factories(p2p_manager, sync_v1_support, sync_v2_support)
302301

303302
vertex_handler = VertexHandler(
304303
reactor=reactor,

hathor/cli/run_node.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ def create_parser(cls) -> ArgumentParser:
131131
help='Enable running both sync protocols.')
132132
sync_args.add_argument('--sync-v1-only', action='store_true', help='Disable support for running sync-v2.')
133133
sync_args.add_argument('--sync-v2-only', action='store_true', help='Disable support for running sync-v1.')
134+
sync_args.add_argument('--x-remove-sync-v1', action='store_true', help='Make sync-v1 unavailable, thus '
135+
'impossible to be enable in runtime.')
134136
sync_args.add_argument('--x-sync-v2-only', action='store_true', help=SUPPRESS) # old argument
135137
sync_args.add_argument('--x-sync-bridge', action='store_true', help=SUPPRESS) # old argument
136138
parser.add_argument('--x-localhost-only', action='store_true', help='Only connect to peers on localhost')

hathor/cli/run_node_args.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class RunNodeArgs(BaseModel, extra=Extra.allow):
6565
enable_crash_api: bool
6666
x_sync_bridge: bool
6767
x_sync_v2_only: bool
68+
x_remove_sync_v1: bool
6869
sync_bridge: bool
6970
sync_v1_only: bool
7071
sync_v2_only: bool

tests/simulation/base.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import Optional
22

3+
from hathor.builder import SyncSupportLevel
34
from hathor.manager import HathorManager
45
from hathor.simulator import Simulator
56
from hathor.types import VertexId
@@ -41,13 +42,15 @@ def create_peer( # type: ignore[override]
4142
'the test class or pass `enable_sync_v2` by argument')
4243
enable_sync_v2 = self._enable_sync_v2
4344
assert enable_sync_v1 or enable_sync_v2, 'enable at least one sync version'
45+
sync_v1_support = SyncSupportLevel.ENABLED if enable_sync_v1 else SyncSupportLevel.DISABLED
46+
sync_v2_support = SyncSupportLevel.ENABLED if enable_sync_v2 else SyncSupportLevel.DISABLED
4447
if simulator is None:
4548
simulator = self.simulator
4649

4750
builder = simulator.get_default_builder() \
4851
.set_peer_id(self.get_random_peer_id_from_pool(rng=simulator.rng)) \
4952
.set_soft_voided_tx_ids(soft_voided_tx_ids) \
50-
.set_enable_sync_v1(enable_sync_v1) \
51-
.set_enable_sync_v2(enable_sync_v2)
53+
.set_sync_v1_support(sync_v1_support) \
54+
.set_sync_v2_support(sync_v2_support)
5255

5356
return simulator.create_peer(builder)

tests/simulation/test_simulator_itself.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pytest
22

3+
from hathor.builder import SyncSupportLevel
34
from hathor.manager import HathorManager
45
from hathor.p2p.peer_id import PeerId
56
from hathor.simulator import FakeConnection, Simulator
@@ -54,11 +55,13 @@ def create_simulator_peer(
5455
'the test class or pass `enable_sync_v2` by argument')
5556
enable_sync_v2 = self._enable_sync_v2
5657
assert enable_sync_v1 or enable_sync_v2, 'enable at least one sync version'
58+
sync_v1_support = SyncSupportLevel.ENABLED if enable_sync_v1 else SyncSupportLevel.DISABLED
59+
sync_v2_support = SyncSupportLevel.ENABLED if enable_sync_v2 else SyncSupportLevel.DISABLED
5760

5861
builder = simulator.get_default_builder() \
5962
.set_peer_id(self.get_random_peer_id_from_pool()) \
60-
.set_enable_sync_v1(enable_sync_v1) \
61-
.set_enable_sync_v2(enable_sync_v2)
63+
.set_sync_v1_support(sync_v1_support) \
64+
.set_sync_v2_support(sync_v2_support)
6265

6366
return simulator.create_peer(builder)
6467

tests/unittest.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ class TestBuilder(Builder):
8787
def __init__(self) -> None:
8888
super().__init__()
8989
self.set_network('testnet')
90+
# default builder has sync-v2 enabled for tests
91+
self.enable_sync_v2()
9092

9193
def build(self) -> BuildArtifacts:
9294
artifacts = super().build()

0 commit comments

Comments
 (0)