Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add routing filtering to delegated routing server IPIP-484 #671

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

2color
Copy link
Member

@2color 2color commented Sep 12, 2024

What's in this PR

@2color 2color requested a review from a team as a code owner September 12, 2024 16:04
@2color 2color changed the title feat: add routing filtering to delegated routing IPIP-484 feat: add routing filtering to delegated routing server IPIP-484 Sep 13, 2024
Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

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

CI is red, so only did a quick first-pass with some feedback inline

routing/http/server/server_test.go Outdated Show resolved Hide resolved
})

t.Run("NDJSON Response", func(t *testing.T) {
runTest(t, mediaTypeNDJSON, false, true, `{"Addrs":[],"ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn","Protocols":["transport-bitswap"],"Schema":"peer"}`+"\n"+`{"Schema":"bitswap","Protocol":"transport-bitswap","ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vz"}`+"\n")
runTest(t, mediaTypeNDJSON, "", "", false, true, `{"Addrs":["/ip4/127.0.0.1/tcp/4001","/ip4/127.0.0.1/udp/4001/quic-v1","/ip4/127.0.0.1/tcp/4001/ws","/ip4/102.101.1.1/tcp/4001/p2p/12D3KooWEjsGPUQJ4Ej3d1Jcg4VckWhFbhc6mkGunMm1faeSzZMu/p2p-circuit","/ip4/102.101.1.1/udp/4001/quic-v1/webtransport/p2p/12D3KooWEjsGPUQJ4Ej3d1Jcg4VckWhFbhc6mkGunMm1faeSzZMu/p2p-circuit","/ip4/8.8.8.8/udp/4001/quic-v1/webtransport"],"ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn","Protocols":["transport-bitswap"],"Schema":"peer"}`+"\n"+`{"Schema":"bitswap","Protocol":"transport-bitswap","ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vz"}`+"\n")
Copy link
Member

Choose a reason for hiding this comment

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

@2color CI fails on this equals test (log), perhaps because iteration order on maps is not specified in golang, so these tests worked just by luck, and once we added more logic, internal hashes changed and the order changed?

Potential fix is to refactor runTest to do normalize json before comparing

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually the tests were wrong (I forgot to update the assertions after changing the test data. This was not a normalisation problem.

The last commits should fix this.

})
}
func (s *server) findProvidersNDJSON(w http.ResponseWriter, provIter iter.ResultIter[types.Record], filterAddrs, filterProtocols []string) {
Copy link
Member

@lidel lidel Sep 13, 2024

Choose a reason for hiding this comment

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

@2color Any reason why we duplicate this code other than just having filtering on /providers and not /peers?

Thoughts on adding filtering support to /peers and not having this duplicated handler? It feels useful for peer lookups too, at least filter-addrs one ("give me only /wss and /webrtc of this peer"), but supporting both for consistency allows us to be more DRY

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah that's a good idea. One challenge was doing so with generics so I just focused on making it work first.

I'll give it another look.

Copy link
Member Author

@2color 2color Sep 18, 2024

Choose a reason for hiding this comment

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

I agree we should enable filtering to the /peers.

I had another look at this and haven't been able to find a good solution to reuse the code, due to the combination of generics and the different return types (types.Record and types.PeerRecord)

The main open question I have is why FindProviders and FindPeers have a different return type if they both return a list of PeerRecord:

FindProviders(ctx context.Context, cid cid.Cid, limit int) (iter.ResultIter[types.Record], error)
FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[*types.PeerRecord], error)

Do you have an idea @lidel?

Copy link
Member

@lidel lidel Sep 18, 2024

Choose a reason for hiding this comment

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

  • /routing/v1/peers will always return results that use Peer schema.
  • /routing/v1/providers may return different schemas, Peer schema is not the only one, so a more generic type is used to allow pass-through in places like https://delegated-ipfs.dev/ which proxy results from other systems.
    • fysa cid.contact/routing/v1 switched to Peer schema some time ago, making it now confusing why we dont use Peer schema everywhere, and why we waste space for Schema field in every response, but this is [probably both true] (a) a way of having open-ended API that can be evolved by community without breaking existing clients (b) reality of different teams working on different things with different priorities.

Personally I see some value in (a), if we keep FindProviders(ctx context.Context, cid cid.Cid, limit int) (iter.ResultIter[types.Record], error) and return generic Record we ensure Schema field is not waste of space, and allow others to experiment without having to invent yet another API.

Copy link
Member

@lidel lidel Sep 18, 2024

Choose a reason for hiding this comment

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

@2color To address your task at hand, something we could do:

  • keep interface as-is, write reusable things so they return Record, and in FindPeers have a wrapper that translates Records to PeerRecord for now (this way we dont break API)
    • this one is preferable, unless we have a good reason to break api (and we dont atm)
  • make a breaking change and document in release notes: make FindPeers return generic Record as a way of deduplicating code boilerplate. Unlikely we will see different schema on /peers, but would not hurt to have that ability.

Copy link

codecov bot commented Sep 17, 2024

Codecov Report

Attention: Patch coverage is 80.51948% with 30 lines in your changes missing coverage. Please review.

Project coverage is 60.24%. Comparing base (171b0b7) to head (da4a194).

Files with missing lines Patch % Lines
routing/http/server/server.go 65.62% 17 Missing and 5 partials ⚠️
routing/http/server/filters.go 91.11% 7 Missing and 1 partial ⚠️

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #671      +/-   ##
==========================================
+ Coverage   60.18%   60.24%   +0.05%     
==========================================
  Files         241      242       +1     
  Lines       30707    30854     +147     
==========================================
+ Hits        18482    18587     +105     
- Misses      10574    10605      +31     
- Partials     1651     1662      +11     
Files with missing lines Coverage Δ
routing/http/server/filters.go 91.11% <91.11%> (ø)
routing/http/server/server.go 71.12% <65.62%> (-1.34%) ⬇️

... and 9 files with indirect coverage changes

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.

2 participants