ipfs / ipfs/kubo

`ipfs routing provide` fails for pubsub routing keys that should be announcable

Open
#11,123 1 comment 0 reactions 0 assignees View on GitHub
kind/bug P2 topic/ipns topic/pubsub
Dominant language
Go
Stars
17.1k
Forks
3.2k
Avg merge
3d 18h
Merged PRs (30d)
11

Description

### Checklist

- [x] This is a bug report, not a question. Ask questions on [discuss.ipfs.tech](https://discuss.ipfs.tech/c/help/13).
- [x] I have searched on the [issue tracker](https://github.com/ipfs/kubo/issues?q=is%3Aissue) for my bug.
- [x] I am running the latest [kubo version](https://dist.ipfs.tech/#kubo) or have an issue updating.

### Installation method

dist.ipfs.tech or ipfs-update

### Version

```Text
Kubo version: 0.39.0
Repo version: 18
System version: amd64/linux
Golang version: go1.25.4
```

### Config

```json
{
"API": {
"HTTPHeaders": {}
},
"Addresses": {
"API": "/ip4/127.0.0.1/tcp/5001",
"Announce": [],
"AppendAnnounce": [],
"Gateway": "/ip4/127.0.0.1/tcp/8080",
"NoAnnounce": [],
"Swarm": [
"/ip4/0.0.0.0/tcp/4001",
"/ip6/::/tcp/4001",
"/ip4/0.0.0.0/udp/4001/webrtc-direct",
"/ip4/0.0.0.0/udp/4001/quic-v1",
"/ip4/0.0.0.0/udp/4001/quic-v1/webtransport",
"/ip6/::/udp/4001/webrtc-direct",
"/ip6/::/udp/4001/quic-v1",
"/ip6/::/udp/4001/quic-v1/webtransport"
]
},
"AutoNAT": {},
"AutoTLS": {},
"Bootstrap": [
"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
"/ip4/104.131.131.82/udp/4001/quic-v1/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt"
],
"DNS": {
"Resolvers": {}
},
"Datastore": {
"BloomFilterSize": 0,
"GCPeriod": "1h",
"HashOnRead": false,
"Spec": {
"mounts": [
{
"child": {
"path": "blocks",
"shardFunc": "/repo/flatfs/shard/v1/next-to-last/2",
"sync": true,
"type": "flatfs"
},
"mountpoint": "/blocks",
"prefix": "flatfs.datastore",
"type": "measure"
},
{
"child": {
"compression": "none",
"path": "datastore",
"type": "levelds"
},
"mountpoint": "/",
"prefix": "leveldb.datastore",
"type": "measure"
}
],
"type": "mount"
},
"StorageGCWatermark": 90,
"StorageMax": "10GB"
},
"Discovery": {
"MDNS": {
"Enabled": true
}
},
"Experimental": {
"FilestoreEnabled": false,
"Libp2pStreamMounting": false,
"OptimisticProvide": false,
"OptimisticProvideJobsPoolSize": 0,
"P2pHttpProxy": false,
"StrategicProviding": false,
"UrlstoreEnabled": false
},
"Gateway": {
"DeserializedResponses": null,
"DisableHTMLErrors": null,
"ExposeRoutingAPI": null,
"HTTPHeaders": {},
"NoDNSLink": false,
"NoFetch": false,
"PublicGateways": null,
"RootRedirect": ""
},
"Identity": {
"PeerID": "12D3KooWBJNtmfaDN1G1enLgEuWVXAHGR98fjYDH2d3wNsKqWr4s"
},
"Import": {
"CidVersion": null,
"HashFunction": null,
"UnixFSChunker": null,
"UnixFSRawLeaves": null
},
"Internal": {},
"Ipns": {
"RecordLifetime": "",
"RepublishPeriod": "24h",
"ResolveCacheSize": 128
},
"Migration": {
"DownloadSources": [],
"Keep": ""
},
"Mounts": {
"FuseAllowOther": false,
"IPFS": "/ipfs",
"IPNS": "/ipns"
},
"Peering": {
"Peers": null
},
"Pinning": {
"RemoteServices": {}
},
"Plugins": {
"Plugins": null
},
"Provider": {
"Strategy": ""
},
"Pubsub": {
"DisableSigning": false,
"Router": ""
},
"Reprovider": {},
"Routing": {
"Methods": {
"find-peers": {
"RouterName": "HttpRouterNotSupported"
},
"find-providers": {
"RouterName": "HttpRoutersParallel"
},
"get-ipns": {
"RouterName": "HttpRouterNotSupported"
},
"provide": {
"RouterName": "HttpRoutersParallel"
},
"put-ipns": {
"RouterName": "HttpRouterNotSupported"
}
},
"Routers": {
"HttpRouter1": {
"Parameters": {
"Endpoint": "http://127.0.0.1:19575"
},
"Type": "http"
},
"HttpRouter2": {
"Parameters": {
"Endpoint": "http://127.0.0.1:19576"
},
"Type": "http"
},
"HttpRouter3": {
"Parameters": {
"Endpoint": "http://127.0.0.1:19577"
},
"Type": "http"
},
"HttpRouter4": {
"Parameters": {
"Endpoint": "http://127.0.0.1:19578"
},
"Type": "http"
},
"HttpRouterNotSupported": {
"Parameters": {
"Endpoint": "http://kubohttprouternotsupported"
},
"Type": "http"
},
"HttpRoutersParallel": {
"Parameters": {
"Routers": [
{
"IgnoreErrors": true,
"RouterName": "HttpRouter1",
"Timeout": "10s"
},
{
"IgnoreErrors": true,
"RouterName": "HttpRouter2",
"Timeout": "10s"
},
{
"IgnoreErrors": true,
"RouterName": "HttpRouter3",
"Timeout": "10s"
},
{
"IgnoreErrors": true,
"RouterName": "HttpRouter4",
"Timeout": "10s"
}
]
},
"Type": "parallel"
}
},
"Type": "custom"
},
"Swarm": {
"AddrFilters": null,
"ConnMgr": {},
"DisableBandwidthMetrics": false,
"DisableNatPortMap": false,
"RelayClient": {},
"RelayService": {},
"ResourceMgr": {},
"Transports": {
"Multiplexers": {},
"Network": {},
"Security": {}
}
},
"Version": {}
}
```

### Description

We are running IPNS-over-Pubsub and want to announce provider records for pubsub routing keys (not content CIDs) without waiting for kubo to announce them. `ipfs routing provide ` fails with “block not found locally” even though these are routing keys that Kubo could technically advertise.

### What we were doing when the bug occurred
We tried to manually announce provider records for pubsub routing keys used by IPNS-over-Pubsub so peers can discover each other without DHT content.

These are standard pubsub routing keys (derived from the pubsub topic, not content):

1) `pubsubTopicRoutingCid`
- routing key: `floodsub:${pubsubTopic}`
- bytes: UTF-8
- hash: SHA-256
- CID: CIDv1, codec `0x55` (raw), multihash SHA-256
- equivalent: `CID.createV1(0x55, sha256(floodsub:))`

2) `ipnsPubsubTopicRoutingCid`
- ipns pubsub topic: `/record/` + base64url(`/ipns/` + PeerIdBytes(ipnsName))
- routing key: `floodsub:${ipnsPubsubTopic}`
- bytes: UTF-8
- hash: SHA-256
- CID: CIDv1, codec `0x55` (raw), multihash SHA-256

### Error message and where we saw it
From the CLI:
```
ipfs routing provide
ipfs routing provide
```

Result:
```
Error: block not found locally, cannot provide
```

### Steps to reliably reproduce
Run:
```
git clone https://github.com/Rinse12/providing_ipns_pubsub_topic_routing_cid_bug
cd providing_ipns_pubsub_topic_routing_cid_bug
npm i
npm run repro
```

### Expected behavior
Kubo should allow `routing provide` to advertise provider records for these pubsub routing keys even though there is no block in the blockstore (they are routing keys, not content). This is needed so peers can discover IPNS-over-Pubsub participants without needing to wait for kubo to announce them.

### Why this matters
In our case we need to announce a peer to http routers the moment its IPNS is created, and kubo is not consistent in announcing its providing of routing cids. We need to explicitly call `ipfs provide ` to make sure a provider is discoverable by the network immediately.

Contributor guide

Open the contributing guide

Research direction

Run the linked reproduction with `npm i` and `npm run repro`, then trace the implementation behind `ipfs routing provide `. Confirm where the local block requirement is enforced and verify that pubsub routing keys can be announced without a block while ordinary content providing remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, cli, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.