Decoding Js-Libp2p-Gossipsub

Neha KumariNeha Kumari
5 min read
Js-Libp2p-Gossipsub
Kad-DHT
Js-Libp2p-Example
Rust-Libp2p
Universal-connectivity: js-peer
Gossipsub-v1.2

Key Components of Gossipsub

  1. Topic Meshes: For each topic, Gossipsub maintains an overlay network—a mesh—connecting peers subscribed to that topic. This mesh structure enables direct message exchange among peers.​

  2. Gossip Propagation: Beyond the mesh, Gossipsub employs gossiping to inform peers about messages they might not have received directly. Peers periodically exchange metadata about seen messages, allowing them to request any missing data.​

  3. Message Caching: To support efficient message retrieval, Gossipsub implements a message cache that temporarily stores recently seen messages. This cache aids in responding to peers' requests for messages they missed during the initial broadcast.

JS-Libp2p-Gossipsub implementation

The js-libp2p-gossipsub repository is a TypeScript implementation of the Gossipsub protocol, which is a scalable and extensible publish-subscribe (pubsub) system designed for efficient message dissemination in decentralized peer-to-peer (P2P) networks.

Message Structure Implementation:

In this implementation, message structures are defined using Protocol Buffers (protobuf), a language-neutral serialization format that ensures interoperability across different systems. The rpc.proto file within the repository outlines the core message formats used in Gossipsub communication.

The RPC message serves as the primary container for communication between peers and includes the following fields:

  • subscriptions: A list of SubOpts indicating the topics a peer wants to subscribe to or unsubscribe from.

  • msgs: A list of Message objects representing the actual messages being propagated.

  • control: A ControlMessage containing control information for mesh maintenance, such as IHave, IWant, Graft, and Prune messages.

Each Message object includes:

  • from: The sender's ID.

  • data: The payload of the message.

  • seqno: A sequence number for deduplication.

  • topic: The topic to which the message belongs.

  • signature and key: Fields used for message signing and validation.

    Message Flow in Gossipsub

    The Gossipsub protocol operates on a mesh network topology, where peers are interconnected to facilitate efficient message propagation.​

      [Peer A] -- Publishes Message --> [Mesh Network]
        |
        v
      [Peer B] <-- Receives Message -- [Peer C]
        |
        v
      [Peer D] <-- Receives Message -- [Peer E]
    

    Explanation:

    • Peer A publishes a message to the Gossipsub topic.​

    • The message is propagated through the mesh network to connected peers (Peer B, Peer C, etc.).​

    • Each peer further disseminates the message to their connected peers, ensuring widespread distribution. All subscribed peers receive and process the message.

Gossipsub Message Propagation

📌 Message Cache in Gossipsub

The Message Cache stores recent messages to avoid duplicate processing (message-cache.ts).

class MessageCache {
  constructor(params) {
    this.msgs = new Map();
  }

  put(message) {
    this.msgs.set(message.id, message);
  }

  get(messageID) {
    return this.msgs.get(messageID);
  }
}

Caches messages to avoid redundant relays.
Uses a Map structure for fast lookup.

The message-cache.ts file implements a MessageCache class responsible for storing recently seen messages. This caching mechanism aids in efficient message propagation and ensures that peers can respond to requests for messages they might have missed.

The MessageCache maintains a history of message IDs and their corresponding messages, organized by topic. This structure supports the Gossipsub protocol's ability to manage message flow and maintain the integrity of the pubsub network.

By adhering to the Gossipsub protocol specifications and utilizing protobuf for message serialization [ for more details, here — rpc.proto ], the js-libp2p-gossipsub implementation ensures efficient and reliable message dissemination within decentralized networks.

Lets understand the gossipsub mechanism as implemented in universal-connectivity/js-peer:

Key Gossipsub Configuration:

services: {
  pubsub: gossipsub({
    allowPublishToZeroTopicPeers: true,
    msgIdFn: msgIdFnStrictNoSign,
    ignoreDuplicatePublishError: true,
  }),
  // Other services...
}
  • allowPublishToZeroTopicPeers: Allows publishing messages even when no peers are subscribed to the topic.

  • msgIdFn: Specifies the message ID function for deduplication.

  • ignoreDuplicatePublishError: Prevents errors when attempting to publish duplicate messages.

Additional Insights:

  • Transports: Includes WebRTC, WebSockets, and Circuit Relay for versatile connectivity.

  • Peer Discovery: Utilizes pub-sub peer discovery to dynamically find peers.

  • Direct Messaging: Integrates a custom protocol for direct peer-to-peer communication.


2. direct-message.ts

Purpose:
Implements the Direct Message protocol, facilitating direct communication between peers using Libp2p.

Key Components:

  • Protocol Definition: Defines the protocol name and handlers for sending and receiving direct messages.

  • Message Handling: Manages encoding and decoding of messages, ensuring proper serialization and deserialization.

Relation to Gossipsub:
While primarily focused on direct peer-to-peer messaging, this module complements Gossipsub by providing an alternative communication method when pub-sub isn't suitable.


3. constants.ts

Purpose:
Defines application-wide constants used across various modules.

Relevant Constants:

  • Topics: Specifies pub-sub topics for message dissemination.
  export const CHAT_TOPIC = 'chat';
  export const CHAT_FILE_TOPIC = 'chat_file';
  • Protocol Names: Defines protocol identifiers for direct messaging and other services.

Relation to Gossipsub:
The defined topics are integral to Gossipsub's operation, as they determine the channels over which messages are published and subscribed.


4. protobuf/direct-message.proto

Purpose:
Defines the Protocol Buffers (protobuf) schema for direct messages exchanged between peers.

Key Components:

  • Message Structure: Specifies the fields and data types for direct messages, ensuring a consistent format across different implementations.

Relation to Gossipsub:
While this schema is tailored for direct messaging, understanding its structure is crucial for applications that utilize both direct messaging and Gossipsub for different communication scenarios.


5. protobuf/direct-message.ts

Purpose:
Provides TypeScript bindings and utilities for the protobuf schema defined in direct-message.proto.

Key Components:

  • Serialization/Deserialization: Functions to encode and decode messages based on the protobuf schema.

Relation to Gossipsub:
Similar to direct-message.proto, this module supports direct messaging but offers insights into message structuring that can inform Gossipsub message design.


Conclusion:

In js-peer, Gossipsub handles group messaging by:

  1. Subscribing to Topicslibp2p.services.pubsub.subscribe(CHAT_TOPIC) allows peers to join pub-sub channels.

  2. Publishing Messageslibp2p.services.pubsub.publish(CHAT_TOPIC, msg) broadcasts messages to all subscribed peers.

  3. Message DeduplicationmsgIdFnStrictNoSign ensures unique message IDs to prevent duplicate processing.

  4. Peer Discovery via PubSubpubsubPeerDiscovery helps find new peers dynamically.

This enables efficient, decentralized, and scalable message dissemination among connected peers.

0
Subscribe to my newsletter

Read articles from Neha Kumari directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Neha Kumari
Neha Kumari

Astrophile? Nerd? Tech-savvy? alchemy of heterogeneous elements, if either above matches your vibe, let's connect and talk!