feat(config): single-purpose deleagted routing endpoints

this is poc of optional configuration that would allow for
IPNS-only and Peer-only endpoints.

unsure how useful this would be in real world, my assumption is that
single config is better and also encourages people to
decentralize/federate routing systems with tools like
https://github.com/ipfs-shipyard/someguy
which exposes providers+peers+ipns
This commit is contained in:
Marcin Rataj 2025-05-15 15:26:28 +02:00
parent 6f37df7787
commit c8fdc01cd2
No known key found for this signature in database
GPG Key ID: 222B6784D5A79E42
3 changed files with 121 additions and 9 deletions

View File

@ -48,10 +48,14 @@ type Routing struct {
IgnoreProviders []string `json:",omitempty"`
DelegatedRouters []string `json:",omitempty"`
// Simplified configuration used when Routing.Type=auto (or autoclient)
DelegatedRouters []string `json:",omitempty"`
DelegatedProviderRouters []string `json:",omitempty"`
DelegatedPeerRouters []string `json:",omitempty"`
DelegatedIPNSRouters []string `json:",omitempty"`
// Advanced configuration used when Routing.Type=custom
Routers Routers `json:",omitempty"`
Methods Methods `json:",omitempty"`
}

View File

@ -45,12 +45,19 @@ func constructDefaultHTTPRouters(cfg *config.Config) ([]*routinghelpers.Parallel
httpRouterEndpoints = cfg.Routing.DelegatedRouters
}
// Append HTTP routers for additional speed
// Settings for delegated http routers
ignoreError := true // assuming DHT is always present as a fallback: https://github.com/ipfs/kubo/pull/9475#discussion_r1042507387
routerTimeout := 15 * time.Second // 5x server value from https://github.com/ipfs/kubo/pull/9475#discussion_r1042428529
doNotWaitForSearchValue := true
executeAfter := 0 * time.Second
// Append General-purpose HTTP routers for additional speed
for _, endpoint := range httpRouterEndpoints {
httpRouter, err := irouting.ConstructHTTPRouter(endpoint, cfg.Identity.PeerID, httpAddrsFromConfig(cfg.Addresses), cfg.Identity.PrivKey, httpRetrievalEnabled)
if err != nil {
return nil, err
}
// Mapping router to /routing/v1/* endpoints
// https://specs.ipfs.tech/routing/http-routing-v1/
r := &irouting.Composer{
@ -61,6 +68,7 @@ func constructDefaultHTTPRouters(cfg *config.Config) ([]*routinghelpers.Parallel
FindProvidersRouter: httpRouter, // /routing/v1/providers
}
// TODO: we do this here for legacy reasons
if endpoint == config.CidContactRoutingURL {
// Special-case: cid.contact only supports /routing/v1/providers/cid
// we disable other endpoints to avoid sending requests that always fail
@ -72,12 +80,79 @@ func constructDefaultHTTPRouters(cfg *config.Config) ([]*routinghelpers.Parallel
routers = append(routers, &routinghelpers.ParallelRouter{
Router: r,
IgnoreError: true, // https://github.com/ipfs/kubo/pull/9475#discussion_r1042507387
Timeout: 15 * time.Second, // 5x server value from https://github.com/ipfs/kubo/pull/9475#discussion_r1042428529
DoNotWaitForSearchValue: true,
ExecuteAfter: 0,
IgnoreError: ignoreError,
Timeout: routerTimeout,
DoNotWaitForSearchValue: doNotWaitForSearchValue,
ExecuteAfter: executeAfter,
})
}
// Append Provider-only HTTP routers
for _, endpoint := range cfg.Routing.DelegatedProviderRouters {
httpRouter, err := irouting.ConstructHTTPRouter(endpoint, cfg.Identity.PeerID, httpAddrsFromConfig(cfg.Addresses), cfg.Identity.PrivKey, httpRetrievalEnabled)
if err != nil {
return nil, err
}
r := &irouting.Composer{
GetValueRouter: noopRouter,
PutValueRouter: noopRouter,
ProvideRouter: noopRouter,
FindPeersRouter: noopRouter,
FindProvidersRouter: httpRouter, // GET /routing/v1/providers
}
routers = append(routers, &routinghelpers.ParallelRouter{
Router: r,
IgnoreError: ignoreError,
Timeout: routerTimeout,
DoNotWaitForSearchValue: doNotWaitForSearchValue,
ExecuteAfter: executeAfter,
})
}
// Append Peer-only HTTP routers
for _, endpoint := range cfg.Routing.DelegatedPeerRouters {
httpRouter, err := irouting.ConstructHTTPRouter(endpoint, cfg.Identity.PeerID, httpAddrsFromConfig(cfg.Addresses), cfg.Identity.PrivKey, httpRetrievalEnabled)
if err != nil {
return nil, err
}
r := &irouting.Composer{
GetValueRouter: noopRouter,
PutValueRouter: noopRouter,
ProvideRouter: noopRouter,
FindPeersRouter: httpRouter, // GET /routing/v1/peers
FindProvidersRouter: noopRouter,
}
routers = append(routers, &routinghelpers.ParallelRouter{
Router: r,
IgnoreError: ignoreError,
Timeout: routerTimeout,
DoNotWaitForSearchValue: doNotWaitForSearchValue,
ExecuteAfter: executeAfter,
})
}
// Append IPNS-only HTTP routers
for _, endpoint := range cfg.Routing.DelegatedIPNSRouters {
httpRouter, err := irouting.ConstructHTTPRouter(endpoint, cfg.Identity.PeerID, httpAddrsFromConfig(cfg.Addresses), cfg.Identity.PrivKey, httpRetrievalEnabled)
if err != nil {
return nil, err
}
r := &irouting.Composer{
GetValueRouter: httpRouter, // GET /routing/v1/ipns
PutValueRouter: httpRouter, // PUT /routing/v1/ipns
ProvideRouter: noopRouter,
FindPeersRouter: noopRouter,
FindProvidersRouter: noopRouter,
}
routers = append(routers, &routinghelpers.ParallelRouter{
Router: r,
IgnoreError: ignoreError,
Timeout: routerTimeout,
DoNotWaitForSearchValue: doNotWaitForSearchValue,
ExecuteAfter: executeAfter,
})
}
return routers, nil
}

View File

@ -129,6 +129,9 @@ config file at runtime.
- [`Routing.LoopbackAddressesOnLanDHT`](#routingloopbackaddressesonlandht)
- [`Routing.IgnoreProviders`](#routingignoreproviders)
- [`Routing.DelegatedRouters`](#routingdelegatedrouters)
- [`Routing.DelegatedProviderRouters`](#routingdelegatedproviderrouters)
- [`Routing.DelegatedPeerRouters`](#routingdelegatedpeerrouters)
- [`Routing.DelegatedIPNSRouters`](#routingdelegatedipnsrouters)
- [`Routing.Routers`](#routingrouters)
- [`Routing.Routers: Type`](#routingrouters-type)
- [`Routing.Routers: Parameters`](#routingrouters-parameters)
@ -1868,7 +1871,7 @@ Type: `array[string]`
### `Routing.DelegatedRouters`
This is an array of URL hostnames that support the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) which are used alongside the DHT when [`Routing.Type`](#routingtype) is set to `auto` or `autoclient`.
This is an array of URL hostnames that support all endpoints from the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) which are used alongside the DHT when [`Routing.Type`](#routingtype) is set to `auto` or `autoclient`.
> [!TIP]
> Delegated routing allows IPFS implementations to offload tasks like content routing, peer routing, and naming to a separate process or server while also benefiting from HTTP caching.
@ -1879,11 +1882,38 @@ Default: `["https://cid.contact"]` (empty or `nil` will also use this default; t
Type: `array[string]`
### `Routing.DelegatedProviderRouters`
Same as `Routing.DelegatedRouters` but limited to `GET /routing/v1/providers`.
Default: `[]`
Type: `array[string]`
### `Routing.DelegatedPeerRouters`
Same as `Routing.DelegatedRouters` but limited to `GET /routing/v1/peers`.
Default: `[]`
Type: `array[string]`
### `Routing.DelegatedIPNSRouters`
Same as `Routing.DelegatedRouters` but limited to `GET|PUT /routing/v1/ipns`.
Default: `[]`
Type: `array[string]`
### `Routing.Routers`
**EXPERIMENTAL: `Routing.Routers` configuration may change in future release**
Map of additional Routers.
Map of additional Routers used when `Routing.Type=custom`.
> [!TIP]
> Most users should use `Routing.Type=auto` or `autoclient` and set simplified config in `Routing.DelegatedRouters` instead.
Allows for extending the default routing (Amino DHT) with alternative Router
implementations.
@ -1947,6 +1977,9 @@ Type: `object[string->string]`
`Methods:map` will define which routers will be executed per method. The key will be the name of the method: `"provide"`, `"find-providers"`, `"find-peers"`, `"put-ipns"`, `"get-ipns"`. All methods must be added to the list.
> [!TIP]
> Most users should use `Routing.Type=auto` or `autoclient` and set simplified config in `Routing.DelegatedRouters` instead.
The value will contain:
- `RouterName:string`: Name of the router. It should be one of the previously added to `Routing.Routers` list.