You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since #906, PubSubRouting can fetch an IPNS record over the libp2p/fetch protocol instead of only waiting for a gossipsub push. That's great. But get() today only fetches from peers gossipsub already reports as subscribers:
for(constpeerIdofthis.libp2p.services.pubsub.getSubscribers(topic)){promises.push(this.#fetchFromPeer(topic,routingKey,peerId, ...))}if(promises.length>0){/* Promise.any */}thrownewNotFoundError('Pubsub routing does not actively query peers')
On a cold resolve, getSubscribers(topic) is empty, so get() throws immediately. The record only becomes fetchable after the topic's peers re-announce via a subscription-change event (the #fetchFromPeer triggered from the subscription-change listener). In practice that adds a real latency floor before the first fetch can happen, even though the publisher (kubo's go-libp2p-pubsub-router, or another Helia via registerLookupFunction) will answer a libp2p/fetch request for the record regardless of the subscription handshake.
Idea
IPNS-over-pubsub publishers announce themselves as providers of the topic's rendezvous CID — the standard go-libp2p-pubsub discovery key, CID(sha256("floodsub:" + topic)). So on a cold get(), in parallel with the existing subscriber-fetch, PubSubRouting could:
fetch(peerId, routingKey) the moment the dial completes
First signature-valid record wins; losers get aborted. This skips the wait for subscription-change entirely and reuses the exact libp2p/fetch path #906 added — it just sources candidate peers from content routing instead of waiting for gossipsub to confirm them.
We've implemented exactly this downstream (fetch in parallel from both current subscribers and freshly-discovered providers of the rendezvous CID, first valid record wins) and it reliably resolves cold IPNS names well under the subscription-wait floor, then falls back to the existing path on a miss.
Question
Does this belong in @helia/ipnsPubSubRouting itself, or is it better kept as downstream orchestration around the router?
Reasons it might fit upstream:
The rendezvous CID (floodsub:<topic> → sha256 → CID) is a standard libp2p-pubsub discovery key, not app-specific.
Every Helia-over-pubsub consumer would get faster cold resolves.
Reasons it might not:
get() currently never actively queries the network ("Pubsub routing does not actively query peers") — provider discovery + dialing is a deliberate behavior/cost change and may warrant an opt-in (e.g. an init flag).
It introduces a contentRouting dependency and dial amplification into a router that today only listens.
If you'd welcome it upstream I'm happy to open a PR (likely gated behind an init option, defaulting off). Wanted to check direction before writing it.
Package
@helia/ipns(packages/ipns), current npm9.2.1Context
Since #906,
PubSubRoutingcan fetch an IPNS record over thelibp2p/fetchprotocol instead of only waiting for a gossipsub push. That's great. Butget()today only fetches from peers gossipsub already reports as subscribers:On a cold resolve,
getSubscribers(topic)is empty, soget()throws immediately. The record only becomes fetchable after the topic's peers re-announce via asubscription-changeevent (the#fetchFromPeertriggered from thesubscription-changelistener). In practice that adds a real latency floor before the first fetch can happen, even though the publisher (kubo's go-libp2p-pubsub-router, or another Helia viaregisterLookupFunction) will answer alibp2p/fetchrequest for the record regardless of the subscription handshake.Idea
IPNS-over-pubsub publishers announce themselves as providers of the topic's rendezvous CID — the standard go-libp2p-pubsub discovery key,
CID(sha256("floodsub:" + topic)). So on a coldget(), in parallel with the existing subscriber-fetch,PubSubRoutingcould:contentRouting.findProviders(rendezvousCidForTopic(topic))fetch(peerId, routingKey)the moment the dial completesFirst signature-valid record wins; losers get aborted. This skips the wait for
subscription-changeentirely and reuses the exactlibp2p/fetchpath #906 added — it just sources candidate peers from content routing instead of waiting for gossipsub to confirm them.We've implemented exactly this downstream (fetch in parallel from both current subscribers and freshly-discovered providers of the rendezvous CID, first valid record wins) and it reliably resolves cold IPNS names well under the subscription-wait floor, then falls back to the existing path on a miss.
Question
Does this belong in
@helia/ipnsPubSubRoutingitself, or is it better kept as downstream orchestration around the router?Reasons it might fit upstream:
floodsub:<topic>→ sha256 → CID) is a standard libp2p-pubsub discovery key, not app-specific.Reasons it might not:
get()currently never actively queries the network ("Pubsub routing does not actively query peers") — provider discovery + dialing is a deliberate behavior/cost change and may warrant an opt-in (e.g. an init flag).contentRoutingdependency and dial amplification into a router that today only listens.If you'd welcome it upstream I'm happy to open a PR (likely gated behind an init option, defaulting off). Wanted to check direction before writing it.