import { computeStartSlotAtEpoch } from "@lodestar/state-transition";
import { MapDef } from "@lodestar/utils";
/**
 * Keeps a cache to filter block proposals from the same validator in the same slot.
 *
 * This cache is not bounded and for extremely long periods of non-finality it can grow a lot. However it's practically
 * limited by the possible shufflings in those epochs, and the stored data is very cheap
 */
export class SeenBlockProposers {
    proposerIndexesBySlot = new MapDef(() => new Set());
    finalizedSlot = 0;
    isKnown(blockSlot, proposerIndex) {
        return this.proposerIndexesBySlot.get(blockSlot)?.has(proposerIndex) === true;
    }
    add(blockSlot, proposerIndex) {
        if (blockSlot < this.finalizedSlot) {
            throw Error(`blockSlot ${blockSlot} < finalizedSlot ${this.finalizedSlot}`);
        }
        this.proposerIndexesBySlot.getOrDefault(blockSlot).add(proposerIndex);
    }
    prune(finalizedSlot) {
        this.finalizedSlot = finalizedSlot;
        for (const slot of this.proposerIndexesBySlot.keys()) {
            if (slot < finalizedSlot) {
                this.proposerIndexesBySlot.delete(slot);
            }
        }
    }
    seenAtEpoch(epoch, index) {
        const fromSlot = computeStartSlotAtEpoch(epoch);
        const toSlot = computeStartSlotAtEpoch(epoch + 1);
        for (let slot = fromSlot; slot < toSlot; slot++) {
            if (this.proposerIndexesBySlot.get(slot)?.has(index) === true) {
                return true;
            }
        }
        return false;
    }
}
//# sourceMappingURL=seenBlockProposers.js.map