diff --git a/src/index.ts b/src/index.ts index fc89ff7a..2e7b0fb6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -239,9 +239,15 @@ export interface MeshPeer { direction: Direction } +export interface GossipIHave { + peerId: string + message: RPC.ControlIHave[] +} + export interface GossipsubEvents extends PubSubEvents { 'gossipsub:heartbeat': CustomEvent 'gossipsub:message': CustomEvent + 'gossipsub:ihave': CustomEvent 'gossipsub:graft': CustomEvent 'gossipsub:prune': CustomEvent } @@ -1483,6 +1489,10 @@ export class GossipSub extends TypedEventEmitter implements Pub return [] } + this.safeDispatchEvent('gossipsub:ihave', { + detail: { peerId: id, message: ihave } + }) + const iasked = this.iasked.get(id) ?? 0 if (iasked >= constants.GossipsubMaxIHaveLength) { this.log('IHAVE: peer %s has already advertised too many messages (%d); ignoring', id, iasked) diff --git a/test/gossip.spec.ts b/test/gossip.spec.ts index e656f4d1..f3669c6b 100644 --- a/test/gossip.spec.ts +++ b/test/gossip.spec.ts @@ -86,6 +86,29 @@ describe('gossip', () => { nodeASpy.pushGossip.restore() }) + it('should dispatch ihave event when gossiping', async function () { + this.timeout(10e4) + const nodeA = nodes[0] + const topic = 'Z' + + const subscriptionPromises = nodes.map(async (n) => pEvent(n.pubsub, 'subscription-change')) + nodes.forEach((n) => { n.pubsub.subscribe(topic) }) + + await connectAllPubSubNodes(nodes) + await Promise.all(subscriptionPromises) + await Promise.all(nodes.map(async (n) => pEvent(n.pubsub, 'gossipsub:heartbeat'))) + + // Check that nodeA has received IHAVE event + const ihavePromise = pEvent(nodeA.pubsub, 'gossipsub:ihave') + + await nodeA.pubsub.publish(topic, uint8ArrayFromString('test_ihave')) + + await pEvent(nodeA.pubsub, 'gossipsub:heartbeat') + + const ihaveEvent = await ihavePromise + expect(ihaveEvent.detail.message[0].topicID).to.equal(topic) + }) + it('should send idontwant to peers in topic', async function () { // This test checks that idontwants and idontwantsCounts are correctly incrmemented // - idontwantCounts should track the number of idontwant messages received from a peer for a single heartbeat