Skip to content

Commit

Permalink
fix: test for subscribers to ipns pubsub topic (#584)
Browse files Browse the repository at this point in the history
IPNS interop tests for helia→pubsub→kubo did not execute the same tests as kubo→pubsub→helia.

Namely, publishing to IPNS was executed with assumption it will fail, as a convoluted way of confirming the kubo is not subscribed to the topic, and also kubo connectivity state is somehow taken on belief, rather than being programmatically verified:

```js
// first publish should fail because kubo isn't subscribed to key update channel
await expect(name.publish(peerId, cid)).to.eventually.be.rejected()
  .with.property('message', 'PublishError.NoPeersSubscribedToTopic')

// should fail to resolve the first time as kubo was not subscribed to the pubsub channel
await expect(last(kubo.api.name.resolve(peerId, {
  timeout: 100
}))).to.eventually.be.undefined()
```

Good news is that there are native APIs for inspecting subsub topic subscriptions, and this PR refactors test to use them and have tests in both directions do more-or-less the same thing with the same asserts.

This should make interop less brittle.

ipfs/kubo#10488 (comment)
  • Loading branch information
lidel authored Sep 13, 2024
1 parent e567717 commit c9c644c
Showing 1 changed file with 19 additions and 11 deletions.
30 changes: 19 additions & 11 deletions packages/interop/src/ipns-pubsub.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,31 +78,39 @@ keyTypes.filter(keyType => keyType !== 'RSA').forEach(keyType => {
throw new Error('No public key present')
}

// first publish should fail because kubo isn't subscribed to key update channel
await expect(name.publish(peerId, cid)).to.eventually.be.rejected()
.with.property('message', 'PublishError.NoPeersSubscribedToTopic')

// should fail to resolve the first time as kubo was not subscribed to the pubsub channel
// first call to pubsub resolver will fail but we should trigger subscribing pubsub for updates
await expect(last(kubo.api.name.resolve(peerId, {
timeout: 100
}))).to.eventually.be.undefined()

// magic pubsub subscription name
const subscriptionName = `/ipns/${CID.createV1(LIBP2P_KEY_CODEC, identity.digest(peerId.publicKey)).toString(base36)}`

// wait for kubo to be subscribed to updates
const kuboSubscriptionName = `/ipns/${CID.createV1(LIBP2P_KEY_CODEC, identity.digest(peerId.publicKey)).toString(base36)}`
await waitFor(async () => {
const subs = await kubo.api.name.pubsub.subs()
return subs.includes(kuboSubscriptionName)
}, {
timeout: 30000,
message: 'Kubo did not register for record updates'
})

return subs.includes(subscriptionName)
// wait for helia to see that kubo is subscribed to the topic for record updates
const heliaSubscriptionName = `/record/${uint8ArrayToString(uint8ArrayConcat([
uint8ArrayFromString('/ipns/'),
peerId.toBytes()
]), 'base64url')}`
const kuboPeerId = (await kubo.api.id()).id.toString()
await waitFor(async () => {
const peers = helia.libp2p.services.pubsub.getSubscribers(heliaSubscriptionName)
return peers.map(p => p.toString()).includes(kuboPeerId)
}, {
timeout: 30000
timeout: 30000,
message: 'Helia did not see that Kubo was registered for record updates'
})

// publish should now succeed
await name.publish(peerId, cid)

// kubo should now be able to resolve IPNS name
// kubo should now be able to resolve IPNS name instantly
const resolved = await last(kubo.api.name.resolve(peerId, {
timeout: 100
}))
Expand Down

0 comments on commit c9c644c

Please sign in to comment.