Skip to content

feat(hole-punch): add py-libp2p v0.5#813

Open
parth-soni07 wants to merge 1 commit intolibp2p:masterfrom
parth-soni07:test-plans-pylibp2p
Open

feat(hole-punch): add py-libp2p v0.5#813
parth-soni07 wants to merge 1 commit intolibp2p:masterfrom
parth-soni07:test-plans-pylibp2p

Conversation

@parth-soni07
Copy link

py-libp2p Hole-Punch Interop Testing

Overview

Added py-libp2p v0.5 implementation for DCUtR (Direct Connection Upgrade through Relay) hole-punch interoperability testing.

Changes

1. New Files (images/python/v0.5/)

File Purpose
peer.py Dialer/Listener implementation using DCUtR protocol
relay.py Circuit relay v2 server
Dockerfile.peer Docker image for peer
Dockerfile.relay Docker image for relay
run-peer.sh / run-relay.sh Entry scripts
requirements.txt Python dependencies

Key implementation details:

A. Dialer: circuit-dial + DCUtR initiation

py-libp2p’s default swarm dial path doesn’t reliably handle /p2p-circuit addresses, so the dialer uses CircuitV2Transport.dial() directly, then triggers DCUtR:

# Create circuit address to listener through relay
circuit_addr = multiaddr.Multiaddr(
    f"{relay_addr}/p2p-circuit/p2p/{listener_peer_id_str}"
)

# Use CircuitV2Transport.dial() directly for circuit addresses
conn = await transport.dial(circuit_addr)

# Initiate hole punch
result = await dcutr_protocol.initiate_hole_punch(listener_peer_id)

B. Test coordination via Redis

The containers coordinate using two Redis keys derived from TEST_KEY:

# listener publishes its peer id
redis_key = f"{self.test_key}_listener_peer_id"
self.redis_client.set(redis_key, peer_id)

# relay publishes its multiaddr
redis_key = f"{self.test_key}_relay_multiaddr"
self.redis_client.set(redis_key, relay_multiaddr)

2. Configuration (images.yaml)

Added py-v0.5 under both relays and implementations:

relays:
  - id: py-v0.5
    source:
      type: local
      path: images/python/v0.5
      dockerfile: Dockerfile.relay
    transports: [tcp]
    secureChannels: [noise]
    muxers: [yamux]

implementations:
  - id: py-v0.5
    source:
      type: local
      path: images/python/v0.5
      dockerfile: Dockerfile.peer
    transports: [tcp]
    secureChannels: [noise]
    muxers: [yamux]

3. Bug Fixes (lib/generate-tests.sh)

Fixed two issues in test matrix generation:

A. Null string handling - yq returns literal "null" for missing values:

# Before
if [ -n "${dialer_commit}" ]; then

# After
if [ -n "${dialer_commit}" ] && [ "${dialer_commit}" != "null" ]; then

B. Wrong output file - Snapshots were written to worker_selected instead of worker_ignored in the ignored tests section:

# Before (incorrect)
echo "      snapshot: snapshots/${relay_commit}.zip" >> "${worker_selected}"

# After (correct)
echo "      snapshot: snapshots/${relay_commit}.zip" >> "${worker_ignored}"

Approach

  1. Peer implementation: Bring up a libp2p host with the selected transport/security/muxer, then connect to the relay and dial the listener via a /p2p-circuit address using CircuitV2Transport.dial(). Once the relay connection is established, initiate DCUtR to upgrade to a direct connection.

  2. Test coordination: Use Redis as the rendezvous plane:

    • Relay publishes {TEST_KEY}_relay_multiaddr
    • Listener publishes {TEST_KEY}_listener_peer_id
    • Dialer waits on both, then proceeds.
  3. Async runtime: Implemented with Trio (py-libp2p runtime), using background_trio_service(...) for long-running protocol services.

Test Command

./run-tests.sh --impl-select py-v0.5 --relay-select py-v0.5

Conventions

These changes follow the same patterns as the Performance Tests README:

  • images.yaml: Same structure — id, source (type, path, dockerfile), transports, secureChannels, muxers. Hole-punch adds relays and routers; py-v0.5 uses local source (no source.commit).
  • Filtering: Two-stage SELECT/IGNORE (--impl-select, --impl-ignore, --relay-select, etc.) with the same semantics.
  • Redis coordination: Per-test 8-character hash key (TEST_KEY from compute_test_key) for namespace isolation; relay/listener publish, dialer waits (same publish/wait pattern as perf’s listener/dialer).
  • Test matrix: generate-tests.sh emits snapshot refs only when commit is present and not the literal "null" (local images), and writes ignored-test blocks (including snapshot lines) to worker_ignored — consistent with cached matrix and snapshot behaviour described in perf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant