UNPKG

@lodestar/beacon-node

Version:

A Typescript implementation of the beacon chain

161 lines 8.14 kB
import { ChainForkConfig } from "@lodestar/config"; import { IForkChoice } from "@lodestar/fork-choice"; import { ForkName } from "@lodestar/params"; import { CachedBeaconStateAllForks, EffectiveBalanceIncrements } from "@lodestar/state-transition"; import { Attestation, Epoch, RootHex, Slot, ValidatorIndex, electra, phase0 } from "@lodestar/types"; import { Metrics } from "../../metrics/metrics.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: ChainForkConfig, 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, state: CachedBeaconStateAllForks): Attestation[]; /** * Get attestations to be included in a block pre-electra. Returns up to $MAX_ATTESTATIONS items */ getAttestationsForBlockPreElectra(fork: ForkName, forkChoice: IForkChoice, state: CachedBeaconStateAllForks): phase0.Attestation[]; /** * Get attestations to be included in an electra block. Returns up to $MAX_ATTESTATIONS_ELECTRA items */ getAttestationsForBlockElectra(fork: ForkName, forkChoice: IForkChoice, state: CachedBeaconStateAllForks): 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: ChainForkConfig, 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 CachedBeaconStateAllForks, for use to check if an attestation's committee * has already attested or not. */ export declare function getNotSeenValidatorsFn(state: CachedBeaconStateAllForks): GetNotSeenValidatorsFn; export declare function extractParticipationPhase0(attestations: phase0.PendingAttestation[], state: CachedBeaconStateAllForks): Set<ValidatorIndex>; /** * 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: CachedBeaconStateAllForks): ValidateAttestationDataFn; export {}; //# sourceMappingURL=aggregatedAttestationPool.d.ts.map