Gossipsub subscribe handler not called after publish

Hello,

From the gossip example, I am learning libp2p by building a local network of peers exchanging messages. For now, peers are well discovered, and each one subscribes to the same topic. Each peer can publish a short message, but the gossip handler does not receive anything. I don’t see if I’ve misunderstood or forgotten anything (all libs are latest current version).

this is how each node joins the p2p network

      const libp2p = await Libp2p.create({
        peerId: state.peerid,
        addresses: {
          listen: ['/ip4/0.0.0.0/tcp/0'],
        },
        modules: {
          transport: [TCP],
          streamMuxer: [Mplex],
          connEncryption: [NOISE, SECIO],
          peerDiscovery: [MulticastDNS],
          pubsub: Gossipsub,
        },
        config: {
          peerDiscovery: {
            autoDial: true,
            mdns: {
              interval: 20e3,
              enabled: true,
            },
          },
          pubsub: {
            enabled: true,
            emitSelf: false,
          },
        },
      });

      libp2p.connectionManager.on('peer:connect', (connection) => { 
        // cf https://github.com/libp2p/js-libp2p/blob/master/examples/pubsub/1.js
        libp2p.peerStore.addressBook.set(connection.remotePeer, connection.remoteAddr);
      });

      await libp2p.start();

      await libp2p.pubsub.subscribe("messages", (msg) => {
        debug(`pubsub messages received: ${msg.data.toString()}`)
      });

This code works on several computers on my local network, and I can see other peers are well connected. Fine.

But now, when I do :

libp2p.pubsub.publish("messages", Buffer.from("test"));

the pubsub.subscribe handler is never called.

By looking further in the pubsub code, it looks like it comes from the fact that peersInTopic is void on line 507 in js-libp2p-gossipsub… but I can not manage to find out why, as peers are connected and should have subscribed to the same topic.

thanks for any clue.

Hello @olivier

My initial observation is that it takes some time to propagate the subscribe messages and if you do a pubsub.publish immediately after a pubsub.subcribe, that message might not be propagated for all the subscribers as their subscribe message is still being propagated. The configuration looks good to me.

For getting a clear picture, you are subscribing in all of the peers connected and then publish from one of them and expect the others to receive the message. Is that your goal? I noticed you set emitSelf to false, so the peer who publishes does not receive the message if it subscribes in that topic.

I would start by reference you to the libp2p pubsub tests as an example, since you already looked into the example: https://github.com/libp2p/js-libp2p/blob/master/test/pubsub/operation.node.js

As a small detail, you don’t need to do the following:

libp2p.connectionManager.on('peer:connect', (connection) => { 
    // cf https://github.com/libp2p/js-libp2p/blob/master/examples/pubsub/1.js
    libp2p.peerStore.addressBook.set(connection.remotePeer, connection.remoteAddr);
});

Once a peer is discovered, its multiaddrs are immediately added to the addressBook.

thanks @vasco-santos for your answer. It works indeed, and I think the problem came from the propagation time, and the fact I had made some tests without connEncryption. This is solved now, and it works !
But I’m faced now with the same problem with ipfs. As the example code is 3y old, I wonder if it may come from a compatibility issue.

Moreover, even if the first example works, I don’t receive anymore messages after a node.stop() / node.start(), as shown in the following code. It works at first launch, but if I stop/start one node (by functions calls or by stoping/starting the code), messages are not sent anymore between nodes (the log in sendmessage() shows that one node is well connected to 2 peers though… but the other node is only connected to itself).
And if I disable/enable wifi on node1, node2 is not informed, and only node2 can send messages to node1. node1 messages are lost.
Not so easy to make this messaging feature works in all cases :confused:

var node = null;

async function init() {
      const peerid = ...;

      node = await Libp2p.create({
        peerId: peerid,
        addresses: {
          listen: ['/ip4/0.0.0.0/tcp/0'],
        },
        modules: {
          transport: [TCP],
          streamMuxer: [Mplex],
          connEncryption: [SECIO],
          peerDiscovery: [MulticastDNS],
          pubsub: Gossipsub,
        },
        config: {
          peerDiscovery: {
            autoDial: true,
            mdns: {
              interval: 5000,
              enabled: true,
            },
          },
          pubsub: {
            enabled: true,
            emitSelf: false,
          },
        },
      });

     node.on('error', (err) => {
        debug('error', err);
      });

     node.on('peer:discovery', (peerId) => {
        debug('Discovered: %O', peerId);
      });

     node.connectionManager.on('peer:connect', (connection) => {
        debug('peer connected %O', connection);
      });

     node.connectionManager.on('peer:disconnect', (connection) => {
        debug('peer disconnected %O', connection);
      });

      start();
    }

    async function start() {
      await node.start();

      // required ? seems to not work when this line is removed.
     node.peerStore.addressBook.add(node.peerId, node.multiaddrs);

     node.pubsub.subscribe('messages', (msg) => {
        debug(`pubsub messages received: ${msg.data.toString()}`);
      });      
    }

    async function stop() {
      await node.stop();
    }

    sendmessage(msg) {
      const s = state.node.pubsub.getSubscribers('messages');
      debug('pubsub subscribers %O', s);
      node.pubsub.publish('messages', Buffer.from(msg));
    },

Thanks for reporting this @olivier

That is something that I will need to look into deeper. If you could open an issue on js-libp2p and paste that code and problem, it would be great

#done here
thanks.