@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
161 lines • 8.14 kB
TypeScript
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