import { Direction, PeerId } from "@libp2p/interface";
import { SubnetID, altair, phase0 } from "@lodestar/types";
import { RequestedSubnet } from "./subnetMap.js";
type SubnetDiscvQuery = {
    subnet: SubnetID;
    toSlot: number;
    maxPeersToDiscover: number;
};
/**
 * Comparison of our status vs a peer's status.
 *
 * The main usage of this score is to feed into peer priorization during syncing, and especially when the node is having trouble finding data during syncing
 *
 * For network stability, we DON'T distinguish peers that are far behind us vs peers that are close to us.
 */
declare enum StatusScore {
    /** The peer is close to our chain */
    CLOSE_TO_US = -1,
    /** The peer is far ahead of chain */
    FAR_AHEAD = 0
}
type PeerInfo = {
    id: PeerId;
    direction: Direction | null;
    statusScore: StatusScore;
    attnets: phase0.AttestationSubnets;
    syncnets: altair.SyncSubnets;
    attnetsTrueBitIndices: number[];
    syncnetsTrueBitIndices: number[];
    score: number;
};
export interface PrioritizePeersOpts {
    targetPeers: number;
    maxPeers: number;
    status: phase0.Status;
    starved: boolean;
    starvationPruneRatio: number;
    starvationThresholdSlots: number;
    outboundPeersRatio?: number;
    targetSubnetPeers?: number;
}
export declare enum ExcessPeerDisconnectReason {
    LOW_SCORE = "low_score",
    NO_LONG_LIVED_SUBNET = "no_long_lived_subnet",
    TOO_GROUPED_SUBNET = "too_grouped_subnet",
    FIND_BETTER_PEERS = "find_better_peers"
}
/**
 * Prioritize which peers to disconect and which to connect. Conditions:
 * - Reach `targetPeers`
 *   - If we're starved for data, prune additional peers
 * - Don't exceed `maxPeers`
 * - Ensure there are enough peers per active subnet
 * - Prioritize peers with good score
 */
export declare function prioritizePeers(connectedPeersInfo: {
    id: PeerId;
    direction: Direction | null;
    status: phase0.Status | null;
    attnets: phase0.AttestationSubnets | null;
    syncnets: altair.SyncSubnets | null;
    score: number;
}[], activeAttnets: RequestedSubnet[], activeSyncnets: RequestedSubnet[], opts: PrioritizePeersOpts): {
    peersToConnect: number;
    peersToDisconnect: Map<ExcessPeerDisconnectReason, PeerId[]>;
    attnetQueries: SubnetDiscvQuery[];
    syncnetQueries: SubnetDiscvQuery[];
};
/**
 * Sort peers ascending, peer-0 has the most chance to prune, peer-n has the least.
 * Shuffling first to break ties.
 * prefer sorting by status score (applicable during syncing), then dutied subnets, then number of long lived subnets, then peer score
 * peer score is the last criteria since they are supposed to be in the same score range,
 * bad score peers are removed by peer manager anyway
 */
export declare function sortPeersToPrune(connectedPeers: PeerInfo[], dutiesByPeer: Map<PeerInfo, number>): PeerInfo[];
export {};
//# sourceMappingURL=prioritizePeers.d.ts.map