feat: improve pubsub reliability and NAT detection for small clusters#1014
Merged
mudler merged 1 commit intoMay 29, 2026
Merged
Conversation
Three additions that together address asymmetric / one-way gossipsub
delivery seen on small (2-3 node) overlay networks where the default
gossipsub mesh sits below its low-watermark and AutoNAT v1 cannot
reach a stable reachability verdict:
* libp2p AutoNAT v2 is now in defaultLibp2pOptions. v1 needs >=3 peers
to give a stable answer, leaving 2-peer clusters stuck in Unknown
reachability and degrading downstream behaviour (relay selection,
hole punching, identify). v2 produces a verdict from a single peer.
* Gossipsub now uses FloodPublish + PeerExchange by default. FloodPublish
has the publisher flood to ALL connected peers rather than just mesh
peers; in a 2-node network the mesh sits at 1 entry (Dlo=4), well
below the healthy-mesh threshold, and standard mesh-only delivery
becomes unreliable. PeerExchange lets peers gossip about each other
and helps recover from one-way mesh links.
* When bootstrap peers are configured, they are passed to gossipsub as
DirectPeers so the router holds a persistent connection and bypasses
mesh negotiation when delivering to them — guaranteeing publication
reaches known/seed peers regardless of mesh state.
The hub.NewHub signature gains a variadic Option parameter so callers
can opt in to direct-peer pinning without forcing the dependency into
the hub package's API. node.startNetwork is the only in-tree caller
and wires bootstrap peers through automatically.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three additions that together address asymmetric / one-way gossipsub delivery seen on small (2-3 node) overlay networks where the default gossipsub mesh sits below its low-watermark and AutoNAT v1 cannot reach a stable reachability verdict:
libp2p AutoNAT v2 is now in defaultLibp2pOptions. v1 needs >=3 peers to give a stable answer, leaving 2-peer clusters stuck in Unknown reachability and degrading downstream behaviour (relay selection, hole punching, identify). v2 produces a verdict from a single peer.
Gossipsub now uses FloodPublish + PeerExchange by default. FloodPublish has the publisher flood to ALL connected peers rather than just mesh peers; in a 2-node network the mesh sits at 1 entry (Dlo=4), well below the healthy-mesh threshold, and standard mesh-only delivery becomes unreliable. PeerExchange lets peers gossip about each other and helps recover from one-way mesh links.
When bootstrap peers are configured, they are passed to gossipsub as DirectPeers so the router holds a persistent connection and bypasses mesh negotiation when delivering to them — guaranteeing publication reaches known/seed peers regardless of mesh state.
The hub.NewHub signature gains a variadic Option parameter so callers can opt in to direct-peer pinning without forcing the dependency into the hub package's API. node.startNetwork is the only in-tree caller and wires bootstrap peers through automatically.