libp2p / libp2p/jvm-libp2p

Smart-dialing feature (address ranking + staggered dials)

Open
#529 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Kotlin
Stars
366
Forks
85
Avg merge
2d 39m
Merged PRs (30d)
6

Description

Description

Implement smart-dialling feature in parity with go-libp2p and rust-libp2p.

Motivation

Today NetworkImpl.connect() fires a dial at every address of a peer simultaneously and keeps the first one that completes (NetworkImpl.kt:79-88). A peer that advertises /ip4 + /ip6 x /tcp + /quic-v1 costs us four concurrent dials, four sockets, four security/muxer handshakes started, and three of them thrown away. Consequences:

  1. Wasted resources on both sides. Every discarded dial still consumes a file descriptor, a Netty channel, CPU for the Noise/TLS handshake, and - importantly - the remote peer’s connection slots and handshake CPU. At Teku’s peer counts (100+ peers, constant churn from discv5) this is a meaningful and entirely avoidable multiplier.

  2. Non-deterministic transport selection. Whichever dial wins the race wins the connection. On a fast LAN, TCP often beats QUIC because QUIC’s handshake does more crypto work up front, so we end up on the worse long-lived transport for the sake of a few ms in connection setup. We want QUIC when QUIC is available; that is a policy decision, not a race outcome.

  3. Simultaneous-connect / dedup churn. Parallel unranked dials increase the chance both sides open connections that are then torn down, plus transient duplicate connections to the same peer.

  4. No IPv4/IPv6 fallback discipline. RFC 8305 (Happy Eyeballs) exists precisely because naive “dial everything” and naive “dial IPv6 then fall back on timeout” are both wrong. We currently do the former.

  5. Ecosystem alignment. go-libp2p has shipped this for two years and rust-libp2p just merged it. jvm-libp2p is the remaining major implementation still doing unranked fan-out; matching the others makes cross-client behaviour on Ethereum networks (Teku <-> Prysm/Lighthouse) more predictable.

Key claim from go-libp2p, which is the whole point of the feature: ranking with short staggered delays dramatically reduces the number of simultaneous dial attempts while adding no additional latency in the vast majority of cases - because the highest-ranked address is dialed at t=0 and almost always wins.

Requirements

N/A

Open questions

N/A

Are you planning to do it yourself in a pull request ?

Yes

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with NetworkImpl.kt lines 79-88, where connect() currently dials every peer address simultaneously. Compare the smart-dialing behavior in go-libp2p and rust-libp2p, focusing on address ranking and staggered fallback. Done should reduce concurrent attempts, prefer higher-ranked transports such as QUIC, and retain IPv4/IPv6 fallback behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
kotlin
Domain
networking
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.