UNPKG

@lodestar/beacon-node

Version:

A Typescript implementation of the beacon chain

160 lines 5.9 kB
import { PeerId, PrivateKey } from "@libp2p/interface"; import { BeaconConfig } from "@lodestar/config"; import { LoggerNode } from "@lodestar/logger/node"; import { Metadata, phase0 } from "@lodestar/types"; import { IClock } from "../../util/clock.js"; import { NetworkCoreMetrics } from "../core/metrics.js"; import { LodestarDiscv5Opts } from "../discv5/types.js"; import { INetworkEventBus } from "../events.js"; import { Eth2Gossipsub } from "../gossip/gossipsub.js"; import { Libp2p } from "../interface.js"; import { StatusCache } from "../statusCache.js"; import { SubnetsService } from "../subnets/index.js"; import { PeerDiscovery } from "./discover.js"; import { PeersData } from "./peersData.js"; import { IPeerRpcScoreStore, PeerAction, PeerScoreStats } from "./score/index.js"; export type PeerManagerOpts = { /** The target number of peers we would like to connect to. */ targetPeers: number; /** The maximum number of peers we allow (exceptions for subnet peers) */ maxPeers: number; /** * Delay the 1st query after starting discv5 * See https://github.com/ChainSafe/lodestar/issues/3423 */ discv5FirstQueryDelayMs?: number; /** * If null, Don't run discv5 queries, nor connect to cached peers in the peerStore */ discv5: LodestarDiscv5Opts | null; /** * If set to true, connect to Discv5 bootnodes. If not set or false, do not connect */ connectToDiscv5Bootnodes?: boolean; }; /** * ReqResp methods used only be PeerManager, so the main thread never has to call them */ export interface IReqRespBeaconNodePeerManager { sendPing(peerId: PeerId): Promise<phase0.Ping>; sendStatus(peerId: PeerId, request: phase0.Status): Promise<phase0.Status>; sendGoodbye(peerId: PeerId, request: phase0.Goodbye): Promise<void>; sendMetadata(peerId: PeerId): Promise<Metadata>; } export type PeerManagerModules = { privateKey: PrivateKey; libp2p: Libp2p; logger: LoggerNode; metrics: NetworkCoreMetrics | null; reqResp: IReqRespBeaconNodePeerManager; gossip: Eth2Gossipsub; attnetsService: SubnetsService; syncnetsService: SubnetsService; clock: IClock; config: BeaconConfig; peerRpcScores: IPeerRpcScoreStore; events: INetworkEventBus; peersData: PeersData; statusCache: StatusCache; }; type PeerIdStr = string; /** * Performs all peer management functionality in a single grouped class: * - Ping peers every `PING_INTERVAL_MS` * - Status peers every `STATUS_INTERVAL_MS` * - Execute discovery query if under target peers * - Execute discovery query if need peers on some subnet: TODO * - Disconnect peers if over target peers */ export declare class PeerManager { private readonly libp2p; private readonly logger; private readonly metrics; private readonly reqResp; private readonly gossipsub; private readonly attnetsService; private readonly syncnetsService; private readonly clock; private readonly config; private readonly peerRpcScores; /** If null, discovery is disabled */ private readonly discovery; private readonly networkEventBus; private readonly statusCache; private lastStatus; private connectedPeers; private opts; private intervals; constructor(modules: PeerManagerModules, opts: PeerManagerOpts, discovery: PeerDiscovery | null); static init(modules: PeerManagerModules, opts: PeerManagerOpts): Promise<PeerManager>; close(): Promise<void>; /** * Return peers with at least one connection in status "open" */ getConnectedPeerIds(): PeerId[]; /** * Efficiently check if there is at least one peer connected */ hasSomeConnectedPeer(): boolean; goodbyeAndDisconnectAllPeers(): Promise<void>; /** * Run after validator subscriptions request. */ onCommitteeSubscriptions(): void; reportPeer(peer: PeerId, action: PeerAction, actionName: string): void; /** * The app layer needs to refresh the status of some peers. The sync have reached a target */ reStatusPeers(peers: PeerIdStr[]): void; dumpPeerScoreStats(): PeerScoreStats; /** * Must be called when network ReqResp receives incoming requests */ private onRequest; /** * Handle a PING request + response (rpc handler responds with PONG automatically) */ private onPing; /** * Handle a METADATA request + response (rpc handler responds with METADATA automatically) */ private onMetadata; /** * Handle a GOODBYE request (rpc handler responds automatically) */ private onGoodbye; /** * Handle a STATUS request + response (rpc handler responds with STATUS automatically) */ private onStatus; private requestMetadata; private requestPing; private requestStatus; private requestStatusMany; /** * The Peer manager's heartbeat maintains the peer count and maintains peer reputations. * It will request discovery queries if the peer count has not reached the desired number of peers. * NOTE: Discovery should only add a new query if one isn't already queued. */ private heartbeat; private updateGossipsubScores; private pingAndStatusTimeouts; /** * The libp2p Upgrader has successfully upgraded a peer connection on a particular multiaddress * This event is routed through the connectionManager * * Registers a peer as connected. The `direction` parameter determines if the peer is being * dialed or connecting to us. */ private onLibp2pPeerConnect; /** * The libp2p Upgrader has ended a connection */ private onLibp2pPeerDisconnect; private disconnect; private goodbyeAndDisconnect; /** Register peer count metrics */ private runPeerCountMetrics; } export {}; //# sourceMappingURL=peerManager.d.ts.map