import { BeaconConfig } from "@lodestar/config";
import { IForkChoice } from "@lodestar/fork-choice";
import { ForkName } from "@lodestar/params";
import { EffectiveBalanceIncrements, IBeaconStateView } from "@lodestar/state-transition";
import { Attestation, Epoch, RootHex, Slot, electra, phase0 } from "@lodestar/types";
import { Metrics } from "../../metrics/metrics.js";
import { ShufflingCache } from "../shufflingCache.js";
import { InsertOutcome } from "./types.js";
type CommitteeIndex = number;
/**
 * for electra, this is to consolidate aggregated attestations of the same attestation data into a single attestation to be included in block
 * note that this is local definition in this file and it's NOT validator consolidation
 */
export type AttestationsConsolidation = {
    byCommittee: Map<CommitteeIndex, AttestationNonParticipant>;
    attData: phase0.AttestationData;
    totalNewSeenEffectiveBalance: number;
    newSeenAttesters: number;
    notSeenAttesters: number;
    /** total number of attesters across all committees in this consolidation */
    totalAttesters: number;
};
/**
 * This function returns not seen participation for a given epoch and slot and committee index.
 * Return null if all validators are seen or no info to check.
 */
type GetNotSeenValidatorsFn = (epoch: Epoch, slot: Slot, committeeIndex: number) => Set<number> | null;
/**
 * Invalid attestation data reasons, this is useful to track in metrics.
 */
export declare enum InvalidAttestationData {
    InvalidTargetEpoch = "invalid_target_epoch",
    InvalidSourceCheckPoint = "invalid_source_checkpoint",
    BlockNotInForkChoice = "block_not_in_fork_choice",
    CannotGetShufflingDependentRoot = "cannot_get_shuffling_dependent_root",
    IncorrectDependentRoot = "incorrect_dependent_root"
}
/**
 * Validate attestation data for inclusion in a block.
 * Returns InvalidAttestationData if attestation data is invalid, null otherwise.
 */
type ValidateAttestationDataFn = (attData: phase0.AttestationData) => InvalidAttestationData | null;
export declare enum ScannedSlotsTerminationReason {
    MaxConsolidationReached = "max_consolidation_reached",
    ScannedAllSlots = "scanned_all_slots",
    SlotBeforePreviousEpoch = "slot_before_previous_epoch"
}
/**
 * Maintain a pool of aggregated attestations. Attestations can be retrieved for inclusion in a block
 * or api. The returned attestations are aggregated to maximize the number of validators that can be
 * included.
 * Note that we want to remove attestations with attesters that were included in the chain.
 */
export declare class AggregatedAttestationPool {
    private readonly config;
    private readonly metrics;
    /**
     * post electra, different committees could have the same AttData and we have to consolidate attestations of the same
     * data to be included in block, so we should group by data before index
     * // TODO: make sure it does not affect performance for pre electra forks
     */
    private readonly attestationGroupByIndexByDataHexBySlot;
    private lowestPermissibleSlot;
    constructor(config: BeaconConfig, metrics?: Metrics | null);
    add(attestation: Attestation, dataRootHex: RootHex, attestingIndicesCount: number, committee: Uint32Array): InsertOutcome;
    /** Remove attestations which are too old to be included in a block. */
    prune(clockSlot: Slot): void;
    getAttestationsForBlock(fork: ForkName, forkChoice: IForkChoice, shufflingCache: ShufflingCache, state: IBeaconStateView): Attestation[];
    /**
     * Get attestations to be included in an electra block. Returns up to $MAX_ATTESTATIONS_ELECTRA items
     */
    getAttestationsForBlockElectra(fork: ForkName, forkChoice: IForkChoice, shufflingCache: ShufflingCache, state: IBeaconStateView): electra.Attestation[];
    /**
     * Get all attestations optionally filtered by `attestation.data.slot`
     * Note this function is not fork aware and can potentially return a mix
     * of phase0.Attestations and electra.Attestations.
     * Caller of this function is expected to filtered result if they desire
     * a homogenous array.
     * @param bySlot slot to filter, `bySlot === attestation.data.slot`
     */
    getAll(bySlot?: Slot): Attestation[];
    private onScrapeMetrics;
}
interface AttestationWithIndex {
    attestation: Attestation;
    trueBitsCount: number;
}
type AttestationNonParticipant = {
    attestation: Attestation;
    newSeenEffectiveBalance: number;
    newSeenAttesters: number;
    notSeenCommitteeMembers: Set<number>;
};
type GetAttestationsGroupResult = {
    result: AttestationNonParticipant[];
    totalAttestations: number;
};
/**
 * Maintain a pool of AggregatedAttestation which all share the same AttestationData.
 * Preaggregate into smallest number of attestations.
 * When getting attestations to be included in a block, sort by number of attesters.
 * Use committee instead of aggregationBits to improve performance.
 */
export declare class MatchingDataAttestationGroup {
    private readonly config;
    readonly committee: Uint32Array;
    readonly data: phase0.AttestationData;
    private readonly attestations;
    constructor(config: BeaconConfig, committee: Uint32Array, data: phase0.AttestationData);
    getAttestationCount(): number;
    /**
     * Add an attestation.
     * Try to preaggregate to existing attestations if possible.
     * If it's a subset of an existing attestations, it's not neccesrary to add to our pool.
     * If it's a superset of an existing attestation, remove the existing attestation and add new.
     */
    add(attestation: AttestationWithIndex): InsertOutcome;
    /**
     * Get AttestationNonParticipant for this groups of same attestation data.
     * @param notSeenCommitteeMembers not seen committee members, i.e. indices in the same committee (starting from 0 till (committee.size - 1))
     * @returns an array of AttestationNonParticipant
     */
    getAttestationsForBlock(fork: ForkName, effectiveBalanceIncrements: EffectiveBalanceIncrements, notSeenCommitteeMembers: Set<number>, maxAttestation: number): GetAttestationsGroupResult;
    /**
     * Select the attestation with the highest total effective balance of not seen validators.
     */
    private getMostValuableAttestation;
    /** Get attestations for API. */
    getAttestations(): Attestation[];
}
export declare function aggregateInto(attestation1: AttestationWithIndex, attestation2: AttestationWithIndex): void;
/**
 * Electra and after: Block proposer consolidates attestations with the same
 * attestation data from different committee into a single attestation
 * https://github.com/ethereum/consensus-specs/blob/aba6345776aa876dad368cab27fbbb23fae20455/specs/_features/eip7549/validator.md?plain=1#L39
 */
export declare function aggregateConsolidation({ byCommittee, attData }: AttestationsConsolidation): electra.Attestation;
/**
 * Pre-compute participation from a IBeaconStateView, for use to check if an attestation's committee
 * has already attested or not.
 */
export declare function getNotSeenValidatorsFn(config: BeaconConfig, shufflingCache: ShufflingCache, state: IBeaconStateView): GetNotSeenValidatorsFn;
/**
 * This returns a function to validate if an attestation data is compatible to a state.
 *
 * Attestation data is validated by:
 * - Validate the source checkpoint
 * - Validate shuffling using beacon block root and target epoch
 *
 * Here we always validate the source checkpoint, and cache beacon block root + target epoch
 * to avoid running the same shuffling validation multiple times.
 *
 * See also: https://github.com/ChainSafe/lodestar/issues/4333
 */
export declare function getValidateAttestationDataFn(forkChoice: IForkChoice, state: IBeaconStateView): ValidateAttestationDataFn;
export {};
//# sourceMappingURL=aggregatedAttestationPool.d.ts.map