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

IPIP-484: Opt-in Filtering on Routing V1 HTTP API #484

Merged
merged 25 commits into from
Oct 29, 2024
Merged
Changes from 12 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f9a6e76
feat: delegated routing filtering for transports
2color Sep 6, 2024
e2b9fdb
fix: lint error
2color Sep 6, 2024
cc38163
fix: introduce unkown filtering
2color Sep 6, 2024
1eb4b65
Apply suggestions from code review
2color Sep 6, 2024
eab124c
fix: linting error
2color Sep 10, 2024
0407320
feat: rename query params
2color Sep 10, 2024
0245392
feat: add unknown to filter addrs
2color Sep 11, 2024
f6aceee
fix: clarify that filter-protocols will not modify record
2color Sep 11, 2024
36cb4e3
Merge branch 'main' into feat/routing-v1-protocols-param
2color Sep 11, 2024
b078e12
Update src/ipips/ipip-0484.md
2color Sep 12, 2024
3da9d87
correct nuances around negative addr filtering
2color Sep 13, 2024
1d58c19
add additional clarifications
2color Sep 13, 2024
7e7071a
feat: include peer routing endpoint
2color Sep 24, 2024
ce76561
Update src/ipips/ipip-0484.md
2color Sep 25, 2024
f585210
fix: name Graphsync consisently
2color Sep 25, 2024
eb7add8
fix: refine only negative address filter behaviour
2color Sep 25, 2024
afdda72
Update ipip-0484.md
2color Sep 25, 2024
37cd8eb
Update ipip-0484.md
2color Sep 25, 2024
601a497
fix: linting
2color Sep 27, 2024
ee9b62e
fix: linting
2color Sep 27, 2024
4a1f33b
Apply suggestions from code review
2color Sep 27, 2024
89d5d45
Update src/ipips/ipip-0484.md
2color Sep 27, 2024
2171e9c
docs: add filtering to the http routing spec
2color Sep 27, 2024
3f4a430
chore: ratification and final editorials
lidel Oct 29, 2024
74d0d8d
Merge branch 'main' into feat/routing-v1-protocols-param
lidel Oct 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions src/ipips/ipip-0484.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
title: 'IPIP-0484: Delegated Routing V1 Support for Querying Specific Network Transport and Transfer Protocols'
2color marked this conversation as resolved.
Show resolved Hide resolved
date: 2024-09-03
ipip: proposal
editors:
- name: Daniel Norman
github: 2color
affiliation:
name: Shipyard
url: https://ipshipyard.com
relatedIssues:
- https://github.com/ipfs-shipyard/someguy/issues/13
order: 484
tags: ['ipips']
---

## Summary

Add opt-in support for filtering specific network transports and/or transfer protocols to the Delegated Routing v1 HTTP endpoint via HTTP GET parameters.

## Motivation

IPFS aims to allow ubiquitous data exchange across different runtimes and platforms. One of the most challenging aspects of this goal is the diversity of network conditions and capabilities across different environments. Web browsers have a very limited network stack, and most web browsers do not support the full range of network transport protocols that are commonly used in other IPFS implementations.

The Delegated Routing v1 API empowers resource constrained clients like web browsers by significantly reducing the number of network connections necessary to fetch content addressed data directly from provider peers.

However, there are many cases where most of the results from the Delegated Routing v1 API are not actionable by clients, because the client does not support either the **network transport protocol** or the **transfer protocol** of the provider.

For instance, web browsers are limited to a specific set of network transport protocols, namely HTTPS, Secure WebSockets, WebTransport (emerging), and WebRTC. Consequently, providing information about providers that exclusively support TCP and/or UDP is not beneficial for browser-based clients, as they are unable to utilize such connections.

Moreover, [Helia](https://github.com/ipfs/helia/), the most actively maintained browser IPFS implementation, supports block retrieval by CID with Bitswap and Trustless Gateways, but does not support GraphSync.
2color marked this conversation as resolved.
Show resolved Hide resolved
2color marked this conversation as resolved.
Show resolved Hide resolved

This means that returning providers that only support raw TCP, raw UDP/QUIC, or GraphSync from the Delegated Routing API is not useful for browser clients, and results in unnecessary network traffic for browser clients.

## Note on terminology
2color marked this conversation as resolved.
Show resolved Hide resolved

The term **"transport"** is overloaded in the IPFS ecosystem.

In the context of this IPIP, we refer to the network layer transport protocol, e.g. TCP, QUIC, WebTransport, as **"network transport protocol"** to avoid ambiguity.

**"Transfer protocol"** refers to data transfer protocols, i.e. content-addressed block retrieval protocols, e.g. Bitswap, GraphSync, HTTP.

## Detailed design

### Network Transport Protocol Filtering
2color marked this conversation as resolved.
Show resolved Hide resolved

The proposed change is to add a `?filter-addrs` parameter to the `GET /routing/v1/providers/{cid}` endpoint of :cite[http-routing-v1]:

- Add a `?filter-addrs=<comma-separated-list>` optional parameter to `GET /routing/v1/providers/{CID}` that indicates which network transports to return by filtering the multiaddrs in the `Addrs` field of the [Peer schema].
- The value of the `filter-addrs` parameter is a comma-separated list of network transport protocol _name strings_ as defined in the [multiaddr protocol registry](https://github.com/multiformats/multiaddr/blob/master/protocols.csv), e.g. `?filter-addrs=webtransport`.
- `unknown` can be be passed to include providers whose multiaddrs are unknown, e.g. `?filter-addrs=unknown`. This allows filtering providers whose multiaddrs are unknown at the time of filtering.
- Multiaddrs are filtered by checking if the protocol name appears in any of the multiaddrs (logical OR).
- Negative filtering is done by prefixing the protocol name with `!`, e.g. `?filter-addrs=!quic-v1,!tcp`. Note that negative filtering is done by checking if the protocol name does not appear in any of the multiaddrs (logical AND).
2color marked this conversation as resolved.
Show resolved Hide resolved
- For an address to pass the filter, it must pass all negative filters AND match at least one positive filter.
- Only multiaddrs that pass the filter are included in the response.
- If there are no multiaddrs that match the passed transports, the provider is omitted from the response.
- Filtering is case-insensitive.
- If no parameter is passed, the default behavior is to not apply filtering by network transports.

### Transfer Protocol Filtering
2color marked this conversation as resolved.
Show resolved Hide resolved

The proposed change is to add a `?filter-protocols` parameter to the `GET /routing/v1/providers/{cid}` endpoint of :cite[http-routing-v1]:

- Add a `?filter-protocols=<comma-separated-list>` optional parameter to `GET /routing/v1/providers/{CID}` to filter providers based on the `Protocol` field of the [Peer schema] .
- The `filter-protocols` parameter is a comma-separated list of transfer protocol names, e.g. `?filter-protocols=transport-bitswap`.
- Transfer protocols names should be treated as opaque strings and have a max length of 63 characters. A non-exhaustive list of transfer protocols are defined per convention in the [multicodec registry](https://github.com/multiformats/multicodec/blob/3b7b52deb31481790bc4bae984d8675bda4e0c82/table.csv#L149-L151). Implementations should not break when encountering unknown transfer protocol names.
2color marked this conversation as resolved.
Show resolved Hide resolved
- `unknown` can be be passed to include providers whose transfer protocol is unknown, e.g. `?filter-protocols=unknown`. This allows filtering providers returned from the DHT that do not contain explicit transfer protocol information.
2color marked this conversation as resolved.
Show resolved Hide resolved
- Providers are filtered by checking if the transfer protocol name appears in the `Protocols` array (logical OR).
- If the provider doesn't match any of the passed transfer protocols, the provider is omitted from the response.
- If a provider passes the filter, it is returned unchanged, i.e. the full set of protocols is returned including protocols that not included in the filter. (note that this is different from `filter-addrs` where only the multiaddrs that pass the filter are returned)
- Filtering is case-insensitive.
- If no parameter is passed, the default behavior is to not filter by transfer protocol.

:::note
Even though existing transfer protocol names start with `transport`, e.g. `transport-bitswap`, `transport-graphsync-filecoinv1`, and `transport-ipfs-gateway-http`. This is not to be confused with the network transport protocols, which are filtered using the `filter-addrs` parameter.
2color marked this conversation as resolved.
Show resolved Hide resolved
:::

## Design rationale

- Using these query parameters improves cache efficiency, as the response will be smaller and more specific to the client's needs.
- Backward compatibility is maintained by not changing the default behavior of the API.
- Use of protocol name rather than codes makes it easier for human debugging.
- DHT providers currently do not contain any transfer protocol information. `unknown` can be passed to `filter-protocols` to include such providers.
- Since provider records are independent of peer records, and it's pretty common to have provider records without up-to-date multiaddrs for that peer, `unknown` can be passed to `filter-addrs` to include such providers.
- Combining transfer protocol and transport protocol filters is done by ANDing the results of the filters, e.g. `?filter-addrs=webtransport&filter-protocols=transport-bitswap` will return providers that support bitswap and have a webtransport multiaddr.

### User benefit

By filtering out providers that do not support the desired network transport protocol and/or transfer protocol, the client can reduce the traffic necessary in order to fetch the data.

Moreover, it makes it much easier to determine whether there are any browser-usable providers for a given CID, which is a common use case for clients.

### Compatibility

This should not effect existing clients or servers.

The default behavior when `?filter-addrs` and `?filter-protocols` is not passed is left unspecified, this IPIP is limited to opt-in behavior.

### Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

[Peer schema]: https://specs.ipfs.tech/routing/http-routing-v1/#peer-schema
Loading