From dfc0bb4ec8a7e208ac0c757f97f0b07d5cc95b64 Mon Sep 17 00:00:00 2001 From: Luca Vivona Date: Thu, 19 Jun 2025 21:24:39 -0400 Subject: [PATCH 1/7] chore(kad_dht): centralize shared values in common.py --- libp2p/kad_dht/common.py | 10 ++++++++++ libp2p/kad_dht/kad_dht.py | 12 ++++++------ libp2p/kad_dht/peer_routing.py | 8 +++++--- libp2p/kad_dht/provider_store.py | 9 ++++++--- libp2p/kad_dht/value_store.py | 10 +++++----- 5 files changed, 32 insertions(+), 17 deletions(-) create mode 100644 libp2p/kad_dht/common.py diff --git a/libp2p/kad_dht/common.py b/libp2p/kad_dht/common.py new file mode 100644 index 00000000..ccabb002 --- /dev/null +++ b/libp2p/kad_dht/common.py @@ -0,0 +1,10 @@ +from libp2p.custom_types import ( + TProtocol, +) + +# Constants for the Kademlia algorithm +ALPHA = 3 # Concurrency parameter +PROTOCOL_ID = TProtocol("/ipfs/kad/1.0.0") +QUERY_TIMEOUT = 10 + +TTL = DEFAULT_TTL = 24 * 60 * 60 # 24 hours in seconds \ No newline at end of file diff --git a/libp2p/kad_dht/kad_dht.py b/libp2p/kad_dht/kad_dht.py index 7daad4cb..8a917bda 100644 --- a/libp2p/kad_dht/kad_dht.py +++ b/libp2p/kad_dht/kad_dht.py @@ -49,16 +49,16 @@ from .routing_table import ( from .value_store import ( ValueStore, ) +from .common import ( + PROTOCOL_ID, + ALPHA, + QUERY_TIMEOUT +) logger = logging.getLogger("kademlia-example.kad_dht") # logger = logging.getLogger("libp2p.kademlia") # Default parameters -PROTOCOL_ID = TProtocol("/ipfs/kad/1.0.0") -ROUTING_TABLE_REFRESH_INTERVAL = 1 * 60 # 1 min in seconds for testing -TTL = 24 * 60 * 60 # 24 hours in seconds -ALPHA = 3 -QUERY_TIMEOUT = 10 # seconds - +ROUTING_TABLE_REFRESH_INTERVAL = 60 # 1 min in seconds for testing class DHTMode(Enum): """DHT operation modes.""" diff --git a/libp2p/kad_dht/peer_routing.py b/libp2p/kad_dht/peer_routing.py index f3689e11..2e2107a0 100644 --- a/libp2p/kad_dht/peer_routing.py +++ b/libp2p/kad_dht/peer_routing.py @@ -25,12 +25,17 @@ from libp2p.peer.peerinfo import ( PeerInfo, ) + from .pb.kademlia_pb2 import ( Message, ) from .routing_table import ( RoutingTable, ) +from .common import ( + PROTOCOL_ID, + ALPHA +) from .utils import ( sort_peer_ids_by_distance, ) @@ -38,10 +43,7 @@ from .utils import ( # logger = logging.getLogger("libp2p.kademlia.peer_routing") logger = logging.getLogger("kademlia-example.peer_routing") -# Constants for the Kademlia algorithm -ALPHA = 3 # Concurrency parameter MAX_PEER_LOOKUP_ROUNDS = 20 # Maximum number of rounds in peer lookup -PROTOCOL_ID = TProtocol("/ipfs/kad/1.0.0") class PeerRouting(IPeerRouting): diff --git a/libp2p/kad_dht/provider_store.py b/libp2p/kad_dht/provider_store.py index 00ac6010..4938be2e 100644 --- a/libp2p/kad_dht/provider_store.py +++ b/libp2p/kad_dht/provider_store.py @@ -33,6 +33,12 @@ from .pb.kademlia_pb2 import ( Message, ) +from .common import ( + PROTOCOL_ID, + ALPHA, + QUERY_TIMEOUT +) + # logger = logging.getLogger("libp2p.kademlia.provider_store") logger = logging.getLogger("kademlia-example.provider_store") @@ -40,9 +46,6 @@ logger = logging.getLogger("kademlia-example.provider_store") PROVIDER_RECORD_REPUBLISH_INTERVAL = 22 * 60 * 60 # 22 hours in seconds PROVIDER_RECORD_EXPIRATION_INTERVAL = 48 * 60 * 60 # 48 hours in seconds PROVIDER_ADDRESS_TTL = 30 * 60 # 30 minutes in seconds -PROTOCOL_ID = TProtocol("/ipfs/kad/1.0.0") -ALPHA = 3 # Number of parallel queries/advertisements -QUERY_TIMEOUT = 10 # Timeout for each query in seconds class ProviderRecord: diff --git a/libp2p/kad_dht/value_store.py b/libp2p/kad_dht/value_store.py index a2e54776..c133fd00 100644 --- a/libp2p/kad_dht/value_store.py +++ b/libp2p/kad_dht/value_store.py @@ -23,14 +23,14 @@ from .pb.kademlia_pb2 import ( Message, ) +from .common import ( + PROTOCOL_ID, + DEFAULT_TTL +) + # logger = logging.getLogger("libp2p.kademlia.value_store") logger = logging.getLogger("kademlia-example.value_store") -# Default time to live for values in seconds (24 hours) -DEFAULT_TTL = 24 * 60 * 60 -PROTOCOL_ID = TProtocol("/ipfs/kad/1.0.0") - - class ValueStore: """ Store for key-value pairs in a Kademlia DHT. From 79ac01308c492169046bc04bcd90e1f25bf4037f Mon Sep 17 00:00:00 2001 From: Luca Vivona Date: Thu, 19 Jun 2025 21:38:02 -0400 Subject: [PATCH 2/7] remove: unused custom_types TProtocol import --- libp2p/kad_dht/peer_routing.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/libp2p/kad_dht/peer_routing.py b/libp2p/kad_dht/peer_routing.py index 2e2107a0..fa938707 100644 --- a/libp2p/kad_dht/peer_routing.py +++ b/libp2p/kad_dht/peer_routing.py @@ -15,9 +15,6 @@ from libp2p.abc import ( INetStream, IPeerRouting, ) -from libp2p.custom_types import ( - TProtocol, -) from libp2p.peer.id import ( ID, ) From d03ca45bd8db31580348455b022f8fa76edb044e Mon Sep 17 00:00:00 2001 From: Luca Vivona Date: Fri, 20 Jun 2025 11:57:50 -0400 Subject: [PATCH 3/7] style: fix flake8 linting errors --- libp2p/kad_dht/common.py | 2 +- libp2p/kad_dht/kad_dht.py | 4 +--- libp2p/kad_dht/value_store.py | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/libp2p/kad_dht/common.py b/libp2p/kad_dht/common.py index ccabb002..8b82ea97 100644 --- a/libp2p/kad_dht/common.py +++ b/libp2p/kad_dht/common.py @@ -7,4 +7,4 @@ ALPHA = 3 # Concurrency parameter PROTOCOL_ID = TProtocol("/ipfs/kad/1.0.0") QUERY_TIMEOUT = 10 -TTL = DEFAULT_TTL = 24 * 60 * 60 # 24 hours in seconds \ No newline at end of file +TTL = DEFAULT_TTL = 24 * 60 * 60 # 24 hours in seconds diff --git a/libp2p/kad_dht/kad_dht.py b/libp2p/kad_dht/kad_dht.py index 8a917bda..f82c0063 100644 --- a/libp2p/kad_dht/kad_dht.py +++ b/libp2p/kad_dht/kad_dht.py @@ -18,9 +18,6 @@ import varint from libp2p.abc import ( IHost, ) -from libp2p.custom_types import ( - TProtocol, -) from libp2p.network.stream.net_stream import ( INetStream, ) @@ -60,6 +57,7 @@ logger = logging.getLogger("kademlia-example.kad_dht") # Default parameters ROUTING_TABLE_REFRESH_INTERVAL = 60 # 1 min in seconds for testing + class DHTMode(Enum): """DHT operation modes.""" diff --git a/libp2p/kad_dht/value_store.py b/libp2p/kad_dht/value_store.py index c133fd00..488735e6 100644 --- a/libp2p/kad_dht/value_store.py +++ b/libp2p/kad_dht/value_store.py @@ -31,6 +31,7 @@ from .common import ( # logger = logging.getLogger("libp2p.kademlia.value_store") logger = logging.getLogger("kademlia-example.value_store") + class ValueStore: """ Store for key-value pairs in a Kademlia DHT. From 811c217ee697cc032764e9ac722890ab6fd77e1d Mon Sep 17 00:00:00 2001 From: Luca Vivona Date: Fri, 20 Jun 2025 16:01:11 -0400 Subject: [PATCH 4/7] style: isort fix ording of imports --- libp2p/kad_dht/common.py | 4 ++++ libp2p/kad_dht/kad_dht.py | 10 +++++----- libp2p/kad_dht/peer_routing.py | 9 ++++----- libp2p/kad_dht/provider_store.py | 11 +++++------ libp2p/kad_dht/routing_table.py | 20 ++++++++------------ libp2p/kad_dht/value_store.py | 9 ++++----- 6 files changed, 30 insertions(+), 33 deletions(-) diff --git a/libp2p/kad_dht/common.py b/libp2p/kad_dht/common.py index 8b82ea97..d7fb6c76 100644 --- a/libp2p/kad_dht/common.py +++ b/libp2p/kad_dht/common.py @@ -1,3 +1,7 @@ +""" +Common Objects for Kademlia DHT implementation. +""" + from libp2p.custom_types import ( TProtocol, ) diff --git a/libp2p/kad_dht/kad_dht.py b/libp2p/kad_dht/kad_dht.py index f82c0063..b47d59e7 100644 --- a/libp2p/kad_dht/kad_dht.py +++ b/libp2p/kad_dht/kad_dht.py @@ -31,6 +31,11 @@ from libp2p.tools.async_service import ( Service, ) +from .common import ( + ALPHA, + PROTOCOL_ID, + QUERY_TIMEOUT, +) from .pb.kademlia_pb2 import ( Message, ) @@ -46,11 +51,6 @@ from .routing_table import ( from .value_store import ( ValueStore, ) -from .common import ( - PROTOCOL_ID, - ALPHA, - QUERY_TIMEOUT -) logger = logging.getLogger("kademlia-example.kad_dht") # logger = logging.getLogger("libp2p.kademlia") diff --git a/libp2p/kad_dht/peer_routing.py b/libp2p/kad_dht/peer_routing.py index fa938707..8e40ccf5 100644 --- a/libp2p/kad_dht/peer_routing.py +++ b/libp2p/kad_dht/peer_routing.py @@ -22,17 +22,16 @@ from libp2p.peer.peerinfo import ( PeerInfo, ) - +from .common import ( + ALPHA, + PROTOCOL_ID, +) from .pb.kademlia_pb2 import ( Message, ) from .routing_table import ( RoutingTable, ) -from .common import ( - PROTOCOL_ID, - ALPHA -) from .utils import ( sort_peer_ids_by_distance, ) diff --git a/libp2p/kad_dht/provider_store.py b/libp2p/kad_dht/provider_store.py index 4938be2e..5c34f0c7 100644 --- a/libp2p/kad_dht/provider_store.py +++ b/libp2p/kad_dht/provider_store.py @@ -29,16 +29,15 @@ from libp2p.peer.peerinfo import ( PeerInfo, ) +from .common import ( + ALPHA, + PROTOCOL_ID, + QUERY_TIMEOUT, +) from .pb.kademlia_pb2 import ( Message, ) -from .common import ( - PROTOCOL_ID, - ALPHA, - QUERY_TIMEOUT -) - # logger = logging.getLogger("libp2p.kademlia.provider_store") logger = logging.getLogger("kademlia-example.provider_store") diff --git a/libp2p/kad_dht/routing_table.py b/libp2p/kad_dht/routing_table.py index 4377c591..af4c7439 100644 --- a/libp2p/kad_dht/routing_table.py +++ b/libp2p/kad_dht/routing_table.py @@ -2,21 +2,16 @@ Kademlia DHT routing table implementation. """ -from collections import ( - OrderedDict, -) +from collections import OrderedDict import logging import time import trio -from libp2p.abc import ( - IHost, +from libp2p.abc import IHost +from libp2p.kad_dht.utils import ( + xor_distance, ) -from libp2p.custom_types import ( - TProtocol, -) -from libp2p.kad_dht.utils import xor_distance from libp2p.peer.id import ( ID, ) @@ -24,9 +19,10 @@ from libp2p.peer.peerinfo import ( PeerInfo, ) -from .pb.kademlia_pb2 import ( - Message, +from .common import ( + PROTOCOL_ID, ) +from .pb.kademlia_pb2 import Message # logger = logging.getLogger("libp2p.kademlia.routing_table") logger = logging.getLogger("kademlia-example.routing_table") @@ -243,7 +239,7 @@ class KBucket: raise ValueError(f"Peer {peer_id} not in bucket") # Default protocol ID for Kademlia DHT - protocol_id = TProtocol("/ipfs/kad/1.0.0") + protocol_id = PROTOCOL_ID try: # Open a stream to the peer with the DHT protocol diff --git a/libp2p/kad_dht/value_store.py b/libp2p/kad_dht/value_store.py index 488735e6..b79425fd 100644 --- a/libp2p/kad_dht/value_store.py +++ b/libp2p/kad_dht/value_store.py @@ -19,15 +19,14 @@ from libp2p.peer.id import ( ID, ) +from .common import ( + DEFAULT_TTL, + PROTOCOL_ID, +) from .pb.kademlia_pb2 import ( Message, ) -from .common import ( - PROTOCOL_ID, - DEFAULT_TTL -) - # logger = logging.getLogger("libp2p.kademlia.value_store") logger = logging.getLogger("kademlia-example.value_store") From ebdde7b5aa99bc9051756bd78dd7fccd432b0d86 Mon Sep 17 00:00:00 2001 From: Luca Vivona Date: Sat, 21 Jun 2025 15:08:11 -0400 Subject: [PATCH 5/7] style: enforce multiline import style for consistency --- libp2p/kad_dht/common.py | 2 +- libp2p/kad_dht/kad_dht.py | 4 +++- libp2p/kad_dht/routing_table.py | 13 +++++++------ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/libp2p/kad_dht/common.py b/libp2p/kad_dht/common.py index d7fb6c76..392bffd0 100644 --- a/libp2p/kad_dht/common.py +++ b/libp2p/kad_dht/common.py @@ -1,5 +1,5 @@ """ -Common Objects for Kademlia DHT implementation. +Shared constants and protocol parameters for the Kademlia DHT. """ from libp2p.custom_types import ( diff --git a/libp2p/kad_dht/kad_dht.py b/libp2p/kad_dht/kad_dht.py index b47d59e7..dcf323ba 100644 --- a/libp2p/kad_dht/kad_dht.py +++ b/libp2p/kad_dht/kad_dht.py @@ -5,7 +5,9 @@ This module provides a complete Distributed Hash Table (DHT) implementation based on the Kademlia algorithm and protocol. """ -from enum import Enum +from enum import ( + Enum, +) import logging import time diff --git a/libp2p/kad_dht/routing_table.py b/libp2p/kad_dht/routing_table.py index af4c7439..9ca59031 100644 --- a/libp2p/kad_dht/routing_table.py +++ b/libp2p/kad_dht/routing_table.py @@ -2,13 +2,17 @@ Kademlia DHT routing table implementation. """ -from collections import OrderedDict +from collections import ( + OrderedDict, +) import logging import time import trio -from libp2p.abc import IHost +from libp2p.abc import ( + IHost, +) from libp2p.kad_dht.utils import ( xor_distance, ) @@ -238,12 +242,9 @@ class KBucket: if not peer_info: raise ValueError(f"Peer {peer_id} not in bucket") - # Default protocol ID for Kademlia DHT - protocol_id = PROTOCOL_ID - try: # Open a stream to the peer with the DHT protocol - stream = await self.host.new_stream(peer_id, [protocol_id]) + stream = await self.host.new_stream(peer_id, [PROTOCOL_ID]) try: # Create ping protobuf message From feb8db6655bbbd36e876ae75620d2d9bb6c6b554 Mon Sep 17 00:00:00 2001 From: Luca Vivona Date: Sun, 22 Jun 2025 00:15:44 -0400 Subject: [PATCH 6/7] style: enforce multiline import style --- libp2p/kad_dht/routing_table.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libp2p/kad_dht/routing_table.py b/libp2p/kad_dht/routing_table.py index 9ca59031..15b6721e 100644 --- a/libp2p/kad_dht/routing_table.py +++ b/libp2p/kad_dht/routing_table.py @@ -26,7 +26,9 @@ from libp2p.peer.peerinfo import ( from .common import ( PROTOCOL_ID, ) -from .pb.kademlia_pb2 import Message +from .pb.kademlia_pb2 import ( + Message, +) # logger = logging.getLogger("libp2p.kademlia.routing_table") logger = logging.getLogger("kademlia-example.routing_table") From 3a4338e1df28842ab3bc7fd113b6acf9f0cfadef Mon Sep 17 00:00:00 2001 From: Luca Vivona Date: Sun, 22 Jun 2025 00:25:48 -0400 Subject: [PATCH 7/7] chore: eliminate self.protocol_id attribute \w in PeerRouting --- libp2p/kad_dht/peer_routing.py | 3 +-- tests/core/kad_dht/test_unit_peer_routing.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libp2p/kad_dht/peer_routing.py b/libp2p/kad_dht/peer_routing.py index 8e40ccf5..4bcdb647 100644 --- a/libp2p/kad_dht/peer_routing.py +++ b/libp2p/kad_dht/peer_routing.py @@ -60,7 +60,6 @@ class PeerRouting(IPeerRouting): """ self.host = host self.routing_table = routing_table - self.protocol_id = PROTOCOL_ID async def find_peer(self, peer_id: ID) -> PeerInfo | None: """ @@ -245,7 +244,7 @@ class PeerRouting(IPeerRouting): # Open a stream to the peer using the Kademlia protocol logger.debug(f"Opening stream to {peer} for closest peers query") try: - stream = await self.host.new_stream(peer, [self.protocol_id]) + stream = await self.host.new_stream(peer, [PROTOCOL_ID]) logger.debug(f"Stream opened to {peer}") except Exception as e: logger.warning(f"Failed to open stream to {peer}: {e}") diff --git a/tests/core/kad_dht/test_unit_peer_routing.py b/tests/core/kad_dht/test_unit_peer_routing.py index 72320b73..ffe20655 100644 --- a/tests/core/kad_dht/test_unit_peer_routing.py +++ b/tests/core/kad_dht/test_unit_peer_routing.py @@ -89,7 +89,6 @@ class TestPeerRouting: assert peer_routing.host == mock_host assert peer_routing.routing_table == mock_routing_table - assert peer_routing.protocol_id == PROTOCOL_ID @pytest.mark.trio async def test_find_peer_local_host(self, peer_routing, mock_host):