Skip to content

Provide: announce different CID sets to different routing systems (HTTP vs DHT), and select the target router per provide once / routing provide call #11411

Description

@Rinse12

Checklist

  • This is a feature request, not a question.
  • I have searched the issue tracker.
  • I am running the latest kubo version.

Version

Kubo version: 0.42.0

Description

There is currently no way to announce one set of CIDs to HTTP routers and a different, smaller set to the Amino DHT. Three things combine to make it impossible:

  1. Provide.Strategy is global. It produces a single key stream, and routing/composer.go has a single ProvideRouter used by both Composer.Provide and Composer.ProvideMany. Whatever Routing.Methods.provide points at receives everything.

  2. ipfs provide once / /api/v0/routing/provide cannot target a routing system. The only option is --recursive, and nd.Provider.ProvideOnce(mh) has no notion of a destination. Applications that announce explicitly, rather than relying on the reprovide cycle, cannot express the split either.

  3. The IPNS-over-pubsub rendezvous key shares that same single ProvideRouter. TopicDiscovery() builds routing.NewRoutingDiscovery(ContentRouting), so advertising a topic is an ordinary ContentRouting.Provide(CID(sha256("floodsub:<topic>"))). There is therefore no way to keep a pubsub topic discoverable in the DHT while keeping content CIDs out of it, which is precisely the case where we most want DHT reach.

Motivation

I maintain pkc-js, a pubsub-based social protocol built on kubo. Each community node publishes an IPNS record, subscribes to a pubsub topic for that community, and stores a large and constantly growing set of content blocks whose root rotates on every update.

My intention is simple: announce to the DHT only the few CIDs related to a community's IPNS and its pubsub swarm, specifically the IPNS-over-pubsub rendezvous CID for the topic and the current root, and let the HTTP routers carry everything else. Once a reader has found the swarm for a community, the peers in that topic mesh serve its blocks over bitswap, and our clients also query delegated HTTP routers, so per-block DHT provider records are not what makes content retrievable in our system. They are just the expensive part of the announce path, and they scale with the whole pinset rather than with the handful of keys that actually need global reach.

Today the only expressible options are "everything to both" or "everything to one".

No workaround exists today

I could not find any way to express this with current config or CLI:

  • Routing.Methods.provide accepts exactly one router, shared by the reprovide cycle and by topic advertisement.
  • Provide.Strategy filters which CIDs are announced, but applies identically to every routing system behind that one router.
  • Provide.Enabled=false disables the provide system wholesale, and takes application-driven announcements down with it: ipfs provide once fails outright with cannot provide: Provide.Enabled is false, and the deprecated ipfs routing provide silently succeeds while doing nothing, since nd.Provider is a NoopProvider.
  • ipfs provide once has no router or system selector.

So with a mixed DHT plus HTTP configuration there is no supported way to get a single CID into the DHT without dragging the entire strategy set along with it.

Proposed solutions

Either would work; (B) alone is sufficient for my use case, since pkc-js announces explicitly rather than relying on the reprovide cycle.

(A) Per-routing-system provide strategy. The Provide docs already state the section is "designed to support multiple routing systems in the future", so this fits the existing schema:

{
  "Provide": {
    "Strategy": "all",
    "DHT": { "Strategy": "roots" },
    "HTTP": { "Strategy": "all" }
  }
}

with Provide.Strategy remaining the default for any system that does not override it.

(B) Per-call router selection. A selector on the imperative announce path:

$ ipfs provide once <cid> --routing-system=http
$ ipfs provide once <cid> --routing-system=dht

or, under Routing.Type=custom, naming an entry from Routing.Routers:

$ ipfs provide once <cid> --routers=HttpRoutersParallel

with a matching query parameter on /api/v0/provide/once and /api/v0/routing/provide so that HTTP RPC clients can pass it through. On the JS side this would surface as a field on RoutingProvideOptions in kubo-rpc-client, which today carries only recursive.

Notes and relation to existing issues

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions