Skip to content

fix(service-disco): initialise the network size estimator - #2920

Merged
gmelodie merged 1 commit into
masterfrom
fix/service-disco/missing-field
Aug 8, 2026
Merged

fix(service-disco): initialise the network size estimator#2920
gmelodie merged 1 commit into
masterfrom
fix/service-disco/missing-field

Conversation

@gmelodie

@gmelodie gmelodie commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

ServiceDiscovery.new built the KadDHT base object field by field and missed nsEstimator. KadDHT.new set that field, so only a node that mounts service discovery carried a nil estimator.

Every provider path reads the estimator, so a provide on such a node segfaults:

  • addProvider calls kad.nsEstimator.networkSize() at libp2p/protocols/kademlia/provider.nim:314.
  • maybeTrackNetsize calls kad.nsEstimator.track() at libp2p/protocols/kademlia/provider.nim:252.

The crash happens with optimisticProvide on and off, because maybeTrackNetsize runs on both branches. This is the downstream trace, from the logos-libp2p-module tutorial job, which calls startProviding through the C bindings on a node that mounts service discovery:

cbind/libp2p.nim(852) libp2pKadStartProviding
libp2p/protocols/kademlia/provider.nim(339) startProviding
libp2p/protocols/kademlia/provider.nim(314) addProvider
libp2p/protocols/kademlia/netsize.nim(89) networkSize
SIGSEGV: Illegal storage access. (Attempt to read from nil?)

Two constructors that build the same base object are the reason one field went missing, so the fix removes the duplication instead of patching one line. initKadBase in libp2p/protocols/kademlia.nim now sets every shared field, including the routing table both constructors built from the same three config values. KadDHT.new and ServiceDiscovery.new both call it, and ServiceDiscovery.new keeps only its own fields. The next base field reaches both protocols on its own.

Affected Areas

  • Peer Management / Discovery
  • Protocol Logic

KadDHT and ServiceDiscovery construction, and the Kademlia provider paths a service discovery node reaches.

Compatibility & Downstream Validation

The signatures of KadDHT.new and ServiceDiscovery.new do not change, and initKadBase sets the same fields to the same values the two constructors set before, so no downstream project needs an adaptation.

Impact on Library Users

No API change. A ServiceDiscovery node now provides keys instead of crashing. A user who avoided startProviding and addProvider on a service discovery node to dodge the crash can drop that workaround.

Risk Assessment

Low. initKadBase assigns the fields the two constructors assigned inline, with the same expressions. The estimator starts empty, so networkSize returns "not enough data" until enough lookups converge, which is the state a plain KadDHT node already starts in. The new indirection runs one time per node, at construction.

The refactor touches KadDHT.new, which every Kademlia user reaches, so the field-by-field diff is worth a close read.

References

Additional Notes

tests/libp2p/service_discovery/component/test_add_provider.nim provides a key between two service discovery nodes, which is the shortest path to the same crash. It reproduces the SIGSEGV on master and passes with the fix.

@codecov-commenter

codecov-commenter commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.20%. Comparing base (00cab64) to head (5ad6b88).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2920      +/-   ##
==========================================
- Coverage   82.21%   82.20%   -0.02%     
==========================================
  Files         175      175              
  Lines       31559    31585      +26     
  Branches       13       12       -1     
==========================================
+ Hits        25945    25963      +18     
- Misses       5614     5622       +8     
Files with missing lines Coverage Δ
libp2p/protocols/kademlia.nim 67.71% <100.00%> (-1.68%) ⬇️
libp2p/protocols/service_discovery.nim 84.91% <100.00%> (+0.93%) ⬆️

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gmelodie
gmelodie force-pushed the fix/service-disco/missing-field branch from 830bd9b to 5ad6b88 Compare August 7, 2026 19:06
@gmelodie
gmelodie marked this pull request as ready for review August 7, 2026 19:07
@gmelodie
gmelodie requested review from a team, richard-ramos and vladopajic August 7, 2026 19:07
@gmelodie
gmelodie enabled auto-merge August 7, 2026 19:08
@gmelodie
gmelodie added this pull request to the merge queue Aug 8, 2026
@github-project-automation github-project-automation Bot moved this from new to In Progress in nim-libp2p Aug 8, 2026
discoConfig: discoConfig,
xprPublishing: xprPublishing,
)
disco.initKadBase(switch, config, rng, isServer = not client)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isServer = not isClient

in general code shouldn't really do twists like this,

Merged via the queue into master with commit 91abb9c Aug 8, 2026
40 checks passed
@gmelodie
gmelodie deleted the fix/service-disco/missing-field branch August 8, 2026 16:58
@github-project-automation github-project-automation Bot moved this from In Progress to done in nim-libp2p Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: done

Development

Successfully merging this pull request may close these issues.

4 participants