import { ForkSeq } from "@lodestar/params";
import { CachedBeaconStateAllForks, EpochShuffling } from "@lodestar/state-transition";
import { Attestation, CommitteeIndex, Epoch, IndexedAttestation, RootHex, Slot } from "@lodestar/types";
import { LodestarError, Logger } from "@lodestar/utils";
import { Metrics } from "../metrics/metrics.js";
export type ShufflingCacheOpts = {
    maxShufflingCacheEpochs?: number;
};
/**
 * A shuffling cache to help:
 * - get committee quickly for attestation verification
 * - if a shuffling is not available (which does not happen with default chain option of maxSkipSlots = 32), track a promise to make sure we don't compute the same shuffling twice
 * - skip computing shuffling when loading state bytes from disk
 */
export declare class ShufflingCache {
    readonly metrics: Metrics | null;
    readonly logger: Logger | null;
    /** LRU cache implemented as a map, pruned every time we add an item */
    private readonly itemsByDecisionRootByEpoch;
    private readonly maxEpochs;
    constructor(metrics?: Metrics | null, logger?: Logger | null, opts?: ShufflingCacheOpts, precalculatedShufflings?: {
        shuffling: EpochShuffling | null;
        decisionRoot: RootHex;
    }[]);
    /**
     * Insert a promise to make sure we don't regen state for the same shuffling.
     * Bound by MAX_SHUFFLING_PROMISE to make sure our node does not blow up.
     */
    insertPromise(epoch: Epoch, decisionRoot: RootHex): void;
    /**
     * Most of the time, this should return a shuffling immediately.
     * If there's a promise, it means we are computing the same shuffling, so we wait for the promise to resolve.
     * Return null if we don't have a shuffling for this epoch and dependentRootHex.
     */
    get(epoch: Epoch, decisionRoot: RootHex): Promise<EpochShuffling | null>;
    /**
     * Get a shuffling synchronously, return null if not present.
     * The only time we have a promise cache item is when we regen shuffling for attestation, which never happens
     * with default chain option.
     */
    getSync(epoch: Epoch, decisionRoot: RootHex): EpochShuffling | null;
    /**
     * Process a state to extract and cache all shufflings (previous, current, next).
     * Uses the stored decision roots from epochCtx.
     */
    processState(state: CachedBeaconStateAllForks): void;
    getIndexedAttestation(epoch: number, decisionRoot: string, fork: ForkSeq, attestation: Attestation): IndexedAttestation;
    getAttestingIndices(epoch: number, decisionRoot: string, fork: ForkSeq, attestation: Attestation): number[];
    getBeaconCommittee(epoch: number, decisionRoot: string, slot: Slot, index: CommitteeIndex): Uint32Array;
    getBeaconCommittees(epoch: number, decisionRoot: string, slot: Slot, indices: CommitteeIndex[]): Uint32Array[];
    private getShufflingOrThrow;
    /**
     * Add an EpochShuffling to the ShufflingCache. If a promise for the shuffling is present it will
     * resolve the promise with the built shuffling
     */
    private set;
}
export declare enum ShufflingCacheErrorCode {
    NO_SHUFFLING_FOUND = "SHUFFLING_CACHE_ERROR_NO_SHUFFLING_FOUND"
}
type ShufflingCacheErrorType = {
    code: ShufflingCacheErrorCode.NO_SHUFFLING_FOUND;
    epoch: Epoch;
    decisionRoot: RootHex;
};
export declare class ShufflingCacheError extends LodestarError<ShufflingCacheErrorType> {
}
export {};
//# sourceMappingURL=shufflingCache.d.ts.map