-
Notifications
You must be signed in to change notification settings - Fork 182
Description
Description
We aim to build an interoperability test suite for the hole punching feature in py-libp2p
. Hole punching allows peers behind NATs to establish direct connections using a relay only for coordination, improving connection efficiency and reducing relay load.
The purpose of this test suite is to verify that py-libp2p
can correctly perform hole punching with peers using other libp2p implementations, such as go-libp2p
and js-libp2p
. This includes ensuring that py-libp2p
follows the hole punching protocol as specified and behaves reliably in real-world NAT scenarios.
This effort is critical to ensure py-libp2p
is fully interoperable with the broader libp2p ecosystem and can be used confidently in production-level P2P applications.
Motivation
Hole punching is a core feature of the libp2p stack that enables direct peer-to-peer connections across NATs, which are extremely common in real-world network environments. Without hole punching, peers often have to rely on relayed connections, which introduce latency, limit bandwidth, and require ongoing relay infrastructure.
While py-libp2p
has evolving support for hole punching, it's essential to ensure that its implementation is interoperable with other widely used libp2p implementations, particularly go-libp2p
and js-libp2p
. These implementations already support hole punching and are used in production systems across IPFS, Filecoin, and other decentralized protocols.
Developing a dedicated interop test suite will help us:
- Validate that
py-libp2p
handles the hole punching coordination flow correctly, including relay setup, timing windows, and NAT traversal. - Confirm that py-libp2p can both initiate and respond to hole punching attempts from other libp2p nodes.
- Detect edge cases, bugs, or non-standard behavior early before this feature is promoted for broader use.
- Build confidence that Python-based libp2p applications can seamlessly join existing P2P networks that rely on NAT traversal.
This is also a stepping stone toward more robust interop testing practices across libp2p implementations, helping ensure long-term protocol health, developer confidence, and deployment readiness.
Requirements
To ensure robust interoperability of hole punching in py-libp2p
, the test suite and the underlying feature must satisfy the following functional and testing requirements:
1. Relay-Aware Peer Discovery & Setup
-
The Python peer must be able to discover and connect to a relay node (e.g., a
go-libp2p
relay with/p2p-circuit
support). -
The relay must support circuit v2 and participate in hole punching coordination according to the libp2p spec.
-
The Python peer must be capable of acting as both:
- Initiator: Starts the hole punching attempt.
- Receiver: Waits for an incoming punch attempt.
2. Protocol Compliance
-
Must support the relay v2 protocol and handle all required stream negotiations.
-
Must implement the DCUtR (Direct Connection Upgrade through Relay) protocol flow.
-
Should comply with Hole Punching Spec, including:
- Observed address exchange
- Timed simultaneous dial attempts
- Fallback to relayed connection if punching fails
- Proper error propagation if NAT traversal is not possible
3. Cross-Implementation Compatibility
-
Must successfully execute hole punching when interacting with:
- ✅
go-libp2p
(reference implementation) - ✅
js-libp2p
- ✅
nim-libp2p
- ✅
dotnet-libp2p
- ✅
zig-libp2p
- ✅
rust-libp2p
- 🔄 Other Python peers (self-interoperability)
- ✅
-
Must tolerate slight timing differences and implementation details in protocol behavior across platforms.
4. Test Suite Capabilities
-
Must support running in a single codebase (ideally Python) with Docker/network tooling to simulate NATs and relay environments.
-
Should:
- Start relays and peers in separate containers or subprocesses.
- Simulate NAT behavior using tools like
iptables
,netns
, orpumba
. - Validate that both peers successfully upgrade from a relayed connection to a direct connection.
- Log connection events, retries, and fallback paths.
5. Connection Verification
-
The test suite must verify:
- A successful hole punch results in a direct connection, not routed through the relay.
- The peer connections are upgraded correctly with the same muxer/security.
- No additional unwanted streams are leaked or left open.
- Round-trip latency and connection state match expectations.
6. Observability and Logging
-
Must include detailed logs of:
- Observed address exchange
- Dial attempts and timestamps
- Hole punch success/failure
- Fallbacks and retry behavior
-
Optional: Produce a test report that includes connection topology and timing diagrams.
7. Automation and CI Integration (Nice to Have)
- Should support automated execution as part of the CI pipeline, ideally triggered by a label or tag.
- Should test against known good versions of
go-libp2p
andjs-libp2p
. - Should include setup scripts (e.g., Docker Compose, shell) to launch relay + NAT + peer topology locally or in CI.
Open questions
No response
Are you planning to do it yourself in a pull request ?
Maybe