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