Libp2p.Gossipsub (libp2p_elixir v0.9.0)
Implements the Gossipsub v1.1 PubSub protocol.
Gossipsub is a scalable, extensible PubSub protocol that uses a mesh for efficient data dissemination and gossip for robustness. This module implements the v1.1 specification, which adds significant security and performance improvements over v1.0.
Key Features (v1.1)
- Explicit Peering: Supports direct, persistent peering agreements.
- Prune Backoff: When pruning a peer, a backoff time is enforced to prevent rapid re-grafting.
- Peer Exchange (PX): Prune messages can contain a list of alternative peers to help bootstrapping without a DHT.
- Flood Publishing: New messages from the self node are published to all peers (not just the mesh) to counter eclipse attacks.
- Adaptive Gossip: Gossip emission targets a randomized factor of peers (
0.25default). - Outbound Mesh Quotas: Maintains a minimum number of outbound connections in the mesh to prevent Sybil attacks.
Scoring
While full peer scoring is defined in the spec, this implementation currently provides the structural support for scoring parameters (Time in Mesh, First Message Deliveries, Mesh Message Delivery Rate, etc.) to allow for future tuning/enforcement.
Core Mechanisms (common to v1.0 and v1.1)
- Mesh Maintenance: Builds and maintains a mesh of peers for each topic.
- Gossip: Disseminates message identifiers (IHAVE) to random peers to ensure propagation.
- Control Messages: Handles GRAFT, PRUNE, IHAVE, and IWANT control messages.
- Deduplication: Tracks seen message IDs to prevent re-propagation.
Limitations
- Peer scoring is not yet fully implemented (only structural support).
- Opportunistic grafting is not yet implemented.
Summary
Functions
Block until an outbound gossipsub stream exists for peer_id.
Returns a specification to start this module under a supervisor.
Swarm stream router hook (3-arity), using default registered server name.
Swarm stream router hook (explicit gossipsub process).
Swarm hook: register that a peer connection exists.
Types
@type msg_id() :: binary()
@type peer_id() :: binary()
@type peer_state() :: %{ conn: pid(), inbound_stream_id: non_neg_integer() | nil, outbound_stream_id: non_neg_integer() | nil, topics: MapSet.t(topic()), buf: binary() }
@type state() :: %{ peers: %{required(peer_id()) => peer_state()}, subscriptions: MapSet.t(topic()), mesh: %{required(topic()) => MapSet.t(peer_id())}, seen: MapSet.t(msg_id()), mcache: %{required(msg_id()) => %{topic: topic(), msg: map()}}, on_message: (topic(), binary(), peer_id() -> any()) | nil, msg_id_fn: (topic(), binary() -> msg_id()), peer_waiters: %{required(peer_id()) => [GenServer.from()]}, event_sink: pid() | nil }
@type topic() :: binary()
Functions
Block until an outbound gossipsub stream exists for peer_id.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec handle_inbound(pid(), non_neg_integer(), binary()) :: :ok
Swarm stream router hook (3-arity), using default registered server name.
@spec handle_inbound(pid() | atom(), pid(), non_neg_integer(), binary()) :: :ok
Swarm stream router hook (explicit gossipsub process).
Swarm hook: register that a peer connection exists.
@spec start_link(keyword()) :: GenServer.on_start()