Skip to content

Conversation

@hsanjuan
Copy link
Contributor

@hsanjuan hsanjuan commented Sep 1, 2025

Server side

Since FindPeers also returns PeerRecords, it is essentially a copy-paste, minus things like addrFilters which don't apply here, plus count and closerThan parsing from the query URL. The tests as well. We leave all logic regarding count/closerThan to the ContentRouter (the DHT, or the Kubo wrapper around it).

Client side

As the server part, this is heavily inspired in FindPeers.

Content router side:

Added GetClosestPeers support, depends on libp2p/go-libp2p-routing-helpers#93

@hsanjuan hsanjuan self-assigned this Sep 1, 2025
@hsanjuan hsanjuan force-pushed the feat/1004-get-closest-peers branch from bd45b83 to c70f108 Compare September 3, 2025 12:44
@codecov
Copy link

codecov bot commented Sep 3, 2025

Codecov Report

❌ Patch coverage is 81.39535% with 32 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.82%. Comparing base (0f1ebac) to head (3256401).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
routing/http/client/client.go 77.41% 11 Missing and 3 partials ⚠️
routing/http/server/server.go 85.71% 9 Missing and 3 partials ⚠️
routing/http/contentrouter/contentrouter.go 76.92% 5 Missing and 1 partial ⚠️

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1021      +/-   ##
==========================================
+ Coverage   60.75%   60.82%   +0.06%     
==========================================
  Files         268      268              
  Lines       33593    33741     +148     
==========================================
+ Hits        20411    20522     +111     
- Misses      11510    11538      +28     
- Partials     1672     1681       +9     
Files with missing lines Coverage Δ
routing/http/contentrouter/contentrouter.go 53.92% <76.92%> (+3.35%) ⬆️
routing/http/server/server.go 75.55% <85.71%> (+1.38%) ⬆️
routing/http/client/client.go 75.10% <77.41%> (+0.33%) ⬆️

... 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.

@hsanjuan hsanjuan force-pushed the feat/1004-get-closest-peers branch 2 times, most recently from 6ddfda9 to 3bb649c Compare September 4, 2025 11:39
@hsanjuan hsanjuan marked this pull request as ready for review September 4, 2025 11:41
@hsanjuan hsanjuan requested a review from a team as a code owner September 4, 2025 11:41
@guillaumemichel guillaumemichel self-requested a review September 4, 2025 11:57
Copy link
Contributor

@guillaumemichel guillaumemichel left a comment

Choose a reason for hiding this comment

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

IIUC this PR isn't linked with the DHT yet, and there is no implementation of GetClosestPeers(ctx, pid, closerThanPid, count) (that doesn't depend on another GetClosestPeers(ctx, pid, closerThanPid, count)).

Is the bridge to the DHT going to be implemented in Kubo? I would like to see how everything fits together before merging this one.

@hsanjuan
Copy link
Contributor Author

hsanjuan commented Sep 4, 2025

Is the bridge to the DHT going to be implemented in Kubo? I would like to see how everything fits together before merging this one.

Right. Yes, it is in Kubo where the bridge to an actual content routing thing happens. At which point we will need to call the DHT method with the DHT we have in Kubo. Perfectly fine to wait for that before merging.

hsanjuan added a commit to ipfs/kubo that referenced this pull request Sep 5, 2025
This allows Kubo to respond to the GetClosestPeers() http routing v1 endpoint
as spec'ed here: ipfs/specs#476

It is based on work from ipfs/boxo#1021

We let IpfsNode implmement the contentRouter.Client interface with the new
method.  We use our DHTs to get the closest peers. We try to respect the
count/closerThan options here.  We then trigger FindPeers lookups to fill-in
information about the peers (addresses) and return the result.

Tests are missing and will come up once discussions around the spec and the
boxo pr have settled.
hsanjuan added a commit to ipfs/kubo that referenced this pull request Sep 5, 2025
This allows Kubo to respond to the GetClosestPeers() http routing v1 endpoint
as spec'ed here: ipfs/specs#476

It is based on work from ipfs/boxo#1021

We let IpfsNode implmement the contentRouter.Client interface with the new
method.  We use our DHTs to get the closest peers. We try to respect the
count/closerThan options here.  We then trigger FindPeers lookups to fill-in
information about the peers (addresses) and return the result.

Tests are missing and will come up once discussions around the spec and the
boxo pr have settled.
@hsanjuan
Copy link
Contributor Author

Triage:

  • @hsanjuan will circle-back on this and related PRs.

hsanjuan and others added 9 commits September 26, 2025 14:09
I see no reason for it to be exported.
This adds the SERVER-side for GetClosestPeers.

Since FindPeers also returns PeerRecords, it is essentially a copy-paste, minus things like addrFilters which don't apply here, plus `count` and `closerThan` parsing from the query URL. The tests as well. We leave all logic regarding count/closerThan to the ContentRouter (the DHT, or the Kubo wrapper around it).

Spec: ipfs/specs#476
As the server part, this is heavily inspired in FindPeers.
Changes query parameter from 'closerThan' to 'closer-than' in routing/http
client and server to match IPIP-0476 specification.
- clarified parameter behavior in godoc
- documented amino dht limitation of 20 peers max
- use amino.DefaultBucketSize constant for default count
- introduce DelegatedRouter interface for delegated routing operations
- keep ContentRouter as deprecated alias for backward compatibility
- update internal server struct to use DelegatedRouter
- clarify interface focuses on querying with IPNS publishing support
- note that additional publishing methods may be added via IPIP process

this better aligns with the Delegated Routing V1 HTTP API spec
and clarifies that this interface handles all routing operations
(content, peers, values, DHT), not just content routing
This aligns it with latest version of the spec.
@hsanjuan hsanjuan force-pushed the feat/1004-get-closest-peers branch from dbed850 to 0a8bc14 Compare September 26, 2025 12:14
hsanjuan added a commit to ipfs/kubo that referenced this pull request Sep 26, 2025
This allows Kubo to respond to the GetClosestPeers() http routing v1 endpoint
as spec'ed here: ipfs/specs#476

It is based on work from ipfs/boxo#1021

We let IpfsNode implmement the contentRouter.Client interface with the new
method.  We use our DHTs to get the closest peers. We try to respect the
count/closerThan options here.  We then trigger FindPeers lookups to fill-in
information about the peers (addresses) and return the result.

Tests are missing and will come up once discussions around the spec and the
boxo pr have settled.
@guillaumemichel guillaumemichel self-requested a review September 26, 2025 22:42
@lidel
Copy link
Member

lidel commented Sep 30, 2025

Triage notes:

  • before merging, open a PR for someguy to see how this behaves end-to-end

@lidel lidel added the status/blocked Unable to be worked further until needs are met label Sep 30, 2025
@lidel lidel self-requested a review September 30, 2025 14:58
_ routing.ValueStore = (*contentRouter)(nil)
_ routinghelpers.ProvideManyRouter = (*contentRouter)(nil)
_ routinghelpers.ReadyAbleRouter = (*contentRouter)(nil)
_ routinghelpers.DHTRouter = (*contentRouter)(nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be the only use case of routinghelpers.DHTRouter (introduced in libp2p/go-libp2p-routing-helpers#93). The kubo PR isn't using it.

Since Client (above) implements GetClosestPeers() it should be enough, I don't think we need a DHTRouter interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It breaks consistency? do we need a ReadyAbleRouter etc? IUUC the contentRouter is not a Client, but a Router implementation, the problem being that Router doesn't have a unified interface, which is ugly, but placing this new interface in a different place than the others is also weird.

hsanjuan added a commit to ipfs/kubo that referenced this pull request Oct 16, 2025
This allows Kubo to respond to the GetClosestPeers() http routing v1 endpoint
as spec'ed here: ipfs/specs#476

It is based on work from ipfs/boxo#1021

We let IpfsNode implmement the contentRouter.Client interface with the new
method.  We use our DHTs to get the closest peers. We try to respect the
count/closerThan options here.  We then trigger FindPeers lookups to fill-in
information about the peers (addresses) and return the result.

Tests are missing and will come up once discussions around the spec and the
boxo pr have settled.
lidel added 3 commits October 17, 2025 17:42
- parseKey() utility tries peer.Decode() first, then cid.Decode()
- tests use hardcoded examples from libp2p specs
- tests verify digest matching (not exact CID) via hex-encoded values
- only the multihash digest matters for DHT operations, not CID codec
- error messages include both parse failures for better debugging
- routing/http/server accepts CID or PeerID for GetClosestPeers
- references IPIP-476
fixes copy-paste error where GetClosestPeers endpoint was logging errors
as "FindPeers" instead of "GetClosestPeers"
@lidel lidel changed the title routing/http: add support for GetClosestPeers() feat: support IPIP-476 and Gateway.ExposeRoutingAPI=true by default Oct 17, 2025
@lidel lidel changed the title feat: support IPIP-476 and Gateway.ExposeRoutingAPI=true by default feat: support IPIP-476 and ExposeRoutingAPI by default Oct 17, 2025
@lidel lidel changed the title feat: support IPIP-476 and ExposeRoutingAPI by default routing/http: add support for GetClosestPeers (IPIP-476) Oct 17, 2025
@hsanjuan hsanjuan removed the status/blocked Unable to be worked further until needs are met label Oct 20, 2025
@hsanjuan
Copy link
Contributor Author

Thank you @lidel . Latest changes LGTM. Would you be so kind to call the shot regarding the DHTRouter interface in libp2p-routing-helpers (commit above from @guillaumemichel)? We can move it here or leave it there. Probably it is the last thing to resolve.

// GetClosestPeers returns the DHT closest peers to the given peer ID.
// If empty, it will use the content router's peer ID (self). `closerThan` (optional) forces resulting records to be closer to `PeerID` than to `closerThan`. `count` specifies how many records to return ([1,100], with 20 as default when set to 0).
// GetClosestPeers returns the DHT closest peers to the given key (CID or Peer ID).
GetClosestPeers(ctx context.Context, key cid.Cid) (iter.ResultIter[*types.PeerRecord], error)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the key argument be a cid.Cid or a string? Seems like it needs to be a string if accepting cid or peer id.

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.

http-routing: add "get closest peers" operation

5 participants