@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
168 lines • 6.21 kB
TypeScript
import { PeerId, PrivateKey } from "@libp2p/interface";
import { LoggerNode } from "@lodestar/logger/node";
import { Metadata, Status, 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 { SubnetType } from "../metadata.js";
import { NetworkConfig } from "../networkConfig.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;
/** Target peer per PeerDAS group */
targetGroupPeers: 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: Status): Promise<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;
peerRpcScores: IPeerRpcScoreStore;
events: INetworkEventBus;
networkConfig: NetworkConfig;
peersData: PeersData;
statusCache: StatusCache;
};
export type PeerRequestedSubnetType = SubnetType | "column";
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 nodeId;
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 networkConfig;
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;
private bootstrapAlreadyOpenConnections;
private trackLibp2pConnection;
/**
* 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 identifyPeer;
private goodbyeAndDisconnect;
private runPeerCountMetrics;
}
export {};
//# sourceMappingURL=peerManager.d.ts.map