import { TypedEventEmitter, serviceCapabilities, serviceDependencies } from '@libp2p/interface'; import { StrictNoSign, StrictSign, TopicValidatorResult } from './index.ts'; import { RPC } from './message/rpc.ts'; import { PeerScore } from './score/index.ts'; import { InboundStream, OutboundStream } from './stream.ts'; import { IWantTracer } from './tracer.ts'; import type { GossipSubComponents, GossipSubEvents, GossipsubOpts, PublishResult, TopicValidatorFn } from './index.ts'; import type { PeerScoreParams, PeerScoreThresholds, PeerScoreStatsDump } from './score/index.ts'; import type { TopicStr, MsgIdStr, PeerIdStr, PublishOpts } from './types.ts'; import type { PeerId, Logger, TypedEventTarget } from '@libp2p/interface'; interface GossipOptions extends GossipsubOpts { scoreParams: PeerScoreParams; scoreThresholds: PeerScoreThresholds; } export declare class GossipSub extends TypedEventEmitter implements TypedEventTarget { /** * The signature policy to follow by default */ readonly globalSignaturePolicy: typeof StrictSign | typeof StrictNoSign; protocols: string[]; private publishConfig; private readonly dataTransform; readonly peers: Map; readonly streamsInbound: Map; readonly streamsOutbound: Map; /** Ensures outbound streams are created sequentially */ private outboundInflightQueue; /** Direct peers */ readonly direct: Set; /** Floodsub peers */ private readonly floodsubPeers; /** Cache of seen messages */ private readonly seenCache; /** * Map of peer id and AcceptRequestWhileListEntry */ private readonly acceptFromWhitelist; /** * Map of topics to which peers are subscribed to */ private readonly topics; /** * List of our subscriptions */ private readonly subscriptions; /** * Map of topic meshes * topic => peer id set */ readonly mesh: Map>; /** * Map of topics to set of peers. These mesh peers are the ones to which we are publishing without a topic membership * topic => peer id set */ readonly fanout: Map>; /** * Map of last publish time for fanout topics * topic => last publish time */ private readonly fanoutLastpub; /** * Map of pending messages to gossip * peer id => control messages */ readonly gossip: Map; /** * Map of control messages * peer id => control message */ readonly control: Map; /** * Number of IHAVEs received from peer in the last heartbeat */ private readonly peerhave; /** Number of messages we have asked from peer in the last heartbeat */ private readonly iasked; /** Prune backoff map */ private readonly backoff; /** * Connection direction cache, marks peers with outbound connections * peer id => direction */ private readonly outbound; private readonly msgIdFn; /** * A fast message id function used for internal message de-duplication */ private readonly fastMsgIdFn; private readonly msgIdToStrFn; /** Maps fast message-id to canonical message-id */ private readonly fastMsgIdCache; /** * Short term cache for published message ids. This is used for penalizing peers sending * our own messages back if the messages are anonymous or use a random author. */ private readonly publishedMessageIds; /** * A message cache that contains the messages for last few heartbeat ticks */ private readonly mcache; /** Peer score tracking */ readonly score: PeerScore; /** * Custom validator function per topic. * Must return or resolve quickly (< 100ms) to prevent causing penalties for late messages. * If you need to apply validation that may require longer times use `asyncValidation` option and callback the * validation result through `Gossipsub.reportValidationResult` */ readonly topicValidators: Map; /** * Make this protected so child class may want to redirect to its own log. */ protected readonly log: Logger; /** * Number of heartbeats since the beginning of time * This allows us to amortize some resource cleanup -- eg: backoff cleanup */ private heartbeatTicks; /** * Tracks IHAVE/IWANT promises broken by peers */ readonly gossipTracer: IWantTracer; /** * Tracks IDONTWANT messages received by peers in the current heartbeat */ private readonly idontwantCounts; /** * Tracks IDONTWANT messages received by peers and the heartbeat they were received in * * idontwants are stored for `mcacheLength` heartbeats before being pruned, * so this map is bounded by peerCount * idontwantMaxMessages * mcacheLength */ private readonly idontwants; private readonly components; private directPeerInitial; static multicodec: string; readonly opts: Required; private readonly decodeRpcLimits; private readonly metrics; private status; private readonly maxInboundStreams?; private readonly maxOutboundStreams?; private readonly runOnLimitedConnection?; private readonly allowedTopics; private heartbeatTimer; constructor(components: GossipSubComponents, options?: Partial); readonly [Symbol.toStringTag] = "@chainsafe/libp2p-gossipsub"; readonly [serviceCapabilities]: string[]; readonly [serviceDependencies]: string[]; getPeers(): PeerId[]; isStarted(): boolean; /** * Mounts the gossipsub protocol onto the libp2p node and sends our * our subscriptions to every peer connected */ start(): Promise; /** * Unmounts the gossipsub protocol and shuts down every connection */ stop(): Promise; /** FOR DEBUG ONLY - Dump peer stats for all peers. Data is cloned, safe to mutate */ dumpPeerScoreStats(): PeerScoreStatsDump; /** * On an inbound stream opened */ private onIncomingStream; /** * Registrar notifies an established connection with pubsub protocol */ private onPeerConnected; /** * Registrar notifies a closing connection with pubsub protocol */ private onPeerDisconnected; private createOutboundStream; private createInboundStream; /** * Add a peer to the router */ private addPeer; /** * Removes a peer from the router */ private removePeer; get started(): boolean; /** * Get a the peer-ids in a topic mesh */ getMeshPeers(topic: TopicStr): PeerIdStr[]; /** * Get a list of the peer-ids that are subscribed to one topic. */ getSubscribers(topic: TopicStr): PeerId[]; /** * Get the list of topics which the peer is subscribed to. */ getTopics(): TopicStr[]; /** * Responsible for processing each RPC message received by other peers. */ private pipePeerReadStream; /** * Handle error when read stream pipe throws, less of the functional use but more * to for testing purposes to spy on the error handling */ private handlePeerReadStreamError; /** * Handles an rpc request from a peer */ handleReceivedRpc(from: PeerId, rpc: RPC): Promise; /** * Handles a subscription change from a peer */ private handleReceivedSubscription; /** * Handles a newly received message from an RPC. * May forward to all peers in the mesh. */ private handleReceivedMessage; /** * Handles a newly received message from an RPC. * May forward to all peers in the mesh. */ private validateReceivedMessage; /** * Return score of a peer. */ getScore(peerId: PeerIdStr): number; /** * Send an rpc object to a peer with subscriptions */ private sendSubscriptions; /** * Handles an rpc control message from a peer */ private handleControlMessage; /** * Whether to accept a message from a peer */ acceptFrom(id: PeerIdStr): boolean; /** * Handles IHAVE messages */ private handleIHave; /** * Handles IWANT messages * Returns messages to send back to peer */ private handleIWant; /** * Handles Graft messages */ private handleGraft; /** * Handles Prune messages */ private handlePrune; private handleIdontwant; /** * Add standard backoff log for a peer in a topic */ private addBackoff; /** * Add backoff expiry interval for a peer in a topic * * @param id * @param topic * @param intervalMs - backoff duration in milliseconds */ private doAddBackoff; /** * Apply penalties from broken IHAVE/IWANT promises */ private applyIwantPenalties; /** * Clear expired backoff expiries */ private clearBackoff; /** * Maybe reconnect to direct peers */ private directConnect; /** * Maybe attempt connection given signed peer records */ private pxConnect; /** * Connect to a peer using the gossipsub protocol */ private connect; /** * Subscribes to a topic */ subscribe(topic: TopicStr): void; /** * Unsubscribe to a topic */ unsubscribe(topic: TopicStr): void; /** * Join topic */ private join; /** * Leave topic */ private leave; private selectPeersToForward; private selectPeersToPublish; /** * Forwards a message from our peers. * * For messages published by us (the app layer), this class uses `publish` */ private forwardMessage; /** * App layer publishes a message to peers, return number of peers this message is published to * Note: `async` due to crypto only if `StrictSign`, otherwise it's a sync fn. * * For messages not from us, this class uses `forwardMessage`. */ publish(topic: TopicStr, data: Uint8Array, opts?: PublishOpts): Promise; /** * Send the same data in batch to tosend list without considering cached control messages * This is not only faster but also avoid allocating memory for each peer * see https://github.com/ChainSafe/js-libp2p-gossipsub/issues/344 */ private sendRpcInBatch; /** * This function should be called when `asyncValidation` is `true` after * the message got validated by the caller. Messages are stored in the `mcache` and * validation is expected to be fast enough that the messages should still exist in the cache. * There are three possible validation outcomes and the outcome is given in acceptance. * * If acceptance = `MessageAcceptance.Accept` the message will get propagated to the * network. The `propagation_source` parameter indicates who the message was received by and * will not be forwarded back to that peer. * * If acceptance = `MessageAcceptance.Reject` the message will be deleted from the memcache * and the P₄ penalty will be applied to the `propagationSource`. * * If acceptance = `MessageAcceptance.Ignore` the message will be deleted from the memcache * but no P₄ penalty will be applied. * * This function will return true if the message was found in the cache and false if was not * in the cache anymore. * * This should only be called once per message. */ reportMessageValidationResult(msgId: MsgIdStr, propagationSource: PeerIdStr, acceptance: TopicValidatorResult): void; /** * Sends a GRAFT message to a peer */ private sendGraft; /** * Sends a PRUNE message to a peer */ private sendPrune; private sendIDontWants; /** * Send an rpc object to a peer */ private sendRpc; /** Mutates `outRpc` adding graft and prune control messages */ piggybackControl(id: PeerIdStr, outRpc: RPC, ctrl: RPC.ControlMessage): void; /** Mutates `outRpc` adding ihave control messages */ private piggybackGossip; /** * Send graft and prune messages * * @param tograft - peer id => topic[] * @param toprune - peer id => topic[] */ private sendGraftPrune; /** * Emits gossip - Send IHAVE messages to a random set of gossip peers */ private emitGossip; /** * Send gossip messages to GossipFactor peers above threshold with a minimum of D_lazy * Peers are randomly selected from the heartbeat which exclude mesh + fanout peers * We also exclude direct peers, as there is no reason to emit gossip to them * * @param topic * @param candidateToGossip - peers to gossip * @param messageIDs - message ids to gossip */ private doEmitGossip; /** * Flush gossip and control messages */ private flush; /** * Adds new IHAVE messages to pending gossip */ private pushGossip; /** * Make a PRUNE control message for a peer in a topic */ private makePrune; private readonly runHeartbeat; /** * Maintains the mesh and fanout maps in gossipsub. */ heartbeat(): Promise; /** * Given a topic, returns up to count peers subscribed to that topic * that pass an optional filter function * * @param topic * @param count * @param filter - a function to filter acceptable peers */ private getRandomGossipPeers; private onScrapeMetrics; private readonly tagMeshPeer; private readonly untagMeshPeer; } export {}; //# sourceMappingURL=gossipsub.d.ts.map