libp2p-hs-0.1.0.0: Haskell implementation of the libp2p networking stack
Safe HaskellNone
LanguageGHC2021

LibP2P.Protocol.GossipSub.Router

Description

GossipSub mesh management: JOIN, LEAVE, GRAFT/PRUNE, message forwarding.

The router manages the mesh overlay and handles inbound/outbound RPC messages. For testability, peer communication is injectable via gsSendRPC on GossipSubRouter.

Synopsis

Construction

newRouter Source #

Arguments

:: GossipSubParams 
-> PeerId 
-> (PeerId -> RPC -> IO ())

RPC sender

-> IO UTCTime

Time source

-> IO GossipSubRouter 

Create a new GossipSub router with empty state.

Peer management

addPeer :: GossipSubRouter -> PeerId -> PeerProtocol -> Bool -> UTCTime -> IO () Source #

Register a connected peer. If the peer already exists, preserves accumulated state (topics, scores) to avoid overwriting subscriptions.

removePeer :: GossipSubRouter -> PeerId -> IO () Source #

Remove a disconnected peer and clean up mesh/fanout membership, IP colocation tracking (P6) and outstanding IWANT promises.

setPeerIP :: GossipSubRouter -> PeerId -> ByteString -> IO () Source #

Record a peer's IP address for P6 (IP colocation) scoring. No-op for unknown peers; replaces any previously recorded address.

setSignedPeerRecord :: GossipSubRouter -> PeerId -> ByteString -> IO () Source #

Store the encoded signed peer record (RFC 0003 envelope bytes) for a peer, typically obtained via identify. It is attached to PX entries advertising that peer in outgoing PRUNEs (gossipsub-v1.1.md). Cleared by removePeer.

Topic subscription

join :: GossipSubRouter -> Topic -> IO () Source #

Subscribe to a topic (JOIN): announce, fanout→mesh transition, fill to D, GRAFT.

leave :: GossipSubRouter -> Topic -> IO () Source #

Unsubscribe from a topic (LEAVE): announce, PRUNE with backoff, delete mesh.

Publishing

publish :: GossipSubRouter -> Topic -> ByteString -> Maybe KeyPair -> IO () Source #

Publish a message to a topic. In StrictSign mode, signs the message and populates fromseqnosignature/key. With FloodPublish=True (default), sends to ALL topic peers above PublishThreshold. Otherwise, sends via mesh (or fanout if not subscribed).

Topic validation

registerValidator :: GossipSubRouter -> Topic -> TopicValidator -> IO () Source #

Attach an application validator to a topic. Messages the validator rejects are dropped without propagation and count against the sender's P4 score; ignored messages are dropped without any penalty (gossipsub-v1.1.md extended validators).

unregisterValidator :: GossipSubRouter -> Topic -> IO () Source #

Remove a topic's validator.

Inbound RPC handling

handleRPC :: GossipSubRouter -> PeerId -> RPC -> IO () Source #

Handle an inbound RPC from a peer.

Graylisted peers (score below stGraylistThreshold) have their RPCs ignored entirely (gossipsub-v1.1.md graylist). Direct peers are exempt: explicit peering agreements exchange messages unconditionally.

Control message handlers

handleGraft :: GossipSubRouter -> PeerId -> [Graft] -> IO () Source #

Handle GRAFT: accept if subscribed, non-negative score, and no backoff.

handlePrune :: GossipSubRouter -> PeerId -> [Prune] -> IO () Source #

Handle PRUNE: remove from mesh and start backoff.

handleIHave :: GossipSubRouter -> PeerId -> [IHave] -> IO () Source #

Handle IHAVE: request unseen messages via IWANT.

Gossip from peers below the gossip threshold is ignored (gossipsub-v1.1.md gossip threshold). One advertised-and-requested message ID is tracked as an IWANT promise: if the peer never delivers it before the follow-up deadline, it is a P7 behavioural violation.

IHAVE flood protection (#157): at most paramMaxIHaveMessages IHAVE batches are accepted per peer per heartbeat, and at most paramMaxIHaveLength message ids are requested from a peer per heartbeat (go-libp2p defaults 10 and 5000).

handleIWant :: GossipSubRouter -> PeerId -> [IWant] -> IO () Source #

Handle IWANT: respond with cached messages from the message cache. Requests from peers below the gossip threshold are ignored, and at most paramMaxIHaveLength messages are served per peer per heartbeat (IWANT flood protection, #157).

handleSubscriptions :: GossipSubRouter -> PeerId -> [SubOpts] -> IO () Source #

Handle subscription changes from a peer.

Message forwarding

forwardMessage :: GossipSubRouter -> PeerId -> PubSubMessage -> IO () Source #

Forward a message to mesh peers for its topic, excluding the sender. Subscribed direct peers always receive the message even though they are never mesh members (gossipsub-v1.1.md explicit peering), and so do subscribed floodsub peers, which are flooded before the mesh (gossipsub-v1.0.md: forward "to every peer in peers.floodsub[topic]").

Scoring

peerScore :: GossipSubRouter -> PeerId -> IO Double Source #

Compute peer score using Score.computeScore (P1-P7).

Peer exchange

selectPXPeers :: GossipSubRouter -> Topic -> PeerId -> IO [PeerExchangeInfo] Source #

Select peer-exchange records for a PRUNE: up to paramPrunePeers random peers subscribed to the topic with non-negative score, excluding the pruned peer itself (gossipsub-v1.1.md peer exchange). Peers whose signed peer record we hold get it attached.

Version-gated PRUNE construction

buildPrune Source #

Arguments

:: GossipSubRouter 
-> PeerId 
-> Topic 
-> Bool

Include PX records (only for v1.1 peers in good standing)

-> Word64

Backoff seconds (only encoded for v1.1 peers)

-> IO Prune 

Build a PRUNE for a peer, gated on its negotiated protocol version: meshsub1.0.0 peers receive a bare PRUNE — PX records and the backoff field are v1.1 control extensions (#157).