@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
276 lines • 15.2 kB
TypeScript
import { PrivateKey } from "@libp2p/interface";
import { Type } from "@chainsafe/ssz";
import { BeaconConfig } from "@lodestar/config";
import { CheckpointWithHex, IForkChoice, ProtoBlock } from "@lodestar/fork-choice";
import { EpochShuffling, IBeaconStateView, PubkeyCache } from "@lodestar/state-transition";
import { BeaconBlock, BlindedBeaconBlock, DataColumnSidecar, Epoch, Root, RootHex, SignedBeaconBlock, Slot, Status, UintNum64, ValidatorIndex, Wei, deneb, electra, gloas, phase0, rewards } from "@lodestar/types";
import { Logger } from "@lodestar/utils";
import { ProcessShutdownCallback } from "@lodestar/validator";
import { IBeaconDb } from "../db/index.js";
import { IExecutionBuilder, IExecutionEngine } from "../execution/index.js";
import { Metrics } from "../metrics/index.js";
import { BufferPool } from "../util/bufferPool.js";
import { IClock } from "../util/clock.js";
import { CustodyConfig } from "../util/dataColumns.js";
import { JobItemQueue } from "../util/queue/itemQueue.js";
import { SerializedCache } from "../util/serializedCache.js";
import { ArchiveStore } from "./archiveStore/archiveStore.js";
import { CheckpointBalancesCache } from "./balancesCache.js";
import { BeaconProposerCache } from "./beaconProposerCache.js";
import { IBlockInput } from "./blocks/blockInput/index.js";
import { BlockProcessor, ImportBlockOpts } from "./blocks/index.js";
import { PayloadEnvelopeProcessor } from "./blocks/payloadEnvelopeProcessor.js";
import { ImportPayloadOpts } from "./blocks/types.js";
import { IBlsVerifier } from "./bls/index.js";
import { ColumnReconstructionTracker } from "./ColumnReconstructionTracker.js";
import { ChainEventEmitter } from "./emitter.js";
import { ForkchoiceCaller } from "./forkChoice/index.js";
import { GetBlobsTracker } from "./GetBlobsTracker.js";
import { CommonBlockBody, IBeaconChain, ProposerPreparationData, StateGetOpts } from "./interface.js";
import { LightClientServer } from "./lightClient/index.js";
import { AggregatedAttestationPool, AttestationPool, ExecutionPayloadBidPool, OpPool, PayloadAttestationPool, SyncCommitteeMessagePool, SyncContributionAndProofPool } from "./opPools/index.js";
import { IChainOptions } from "./options.js";
import { AssembledBlockType, BlockType, ProduceResult } from "./produceBlock/index.js";
import { BlockAttributes } from "./produceBlock/produceBlockBody.js";
import { QueuedStateRegenerator, RegenCaller } from "./regen/index.js";
import { ReprocessController } from "./reprocess.js";
import { PayloadEnvelopeInput, SeenAggregators, SeenAttesters, SeenBlockProposers, SeenContributionAndProof, SeenExecutionPayloadBids, SeenPayloadAttesters, SeenPayloadEnvelopeInput, SeenProposerPreferences, SeenSyncCommitteeMessages } from "./seenCache/index.js";
import { SeenAggregatedAttestations } from "./seenCache/seenAggregateAndProof.js";
import { SeenAttestationDatas } from "./seenCache/seenAttestationData.js";
import { SeenBlockAttesters } from "./seenCache/seenBlockAttesters.js";
import { SeenBlockInput } from "./seenCache/seenGossipBlockInput.js";
import { ShufflingCache } from "./shufflingCache.js";
import { ValidatorMonitor } from "./validatorMonitor.js";
export declare class BeaconChain implements IBeaconChain {
readonly genesisTime: UintNum64;
readonly genesisValidatorsRoot: Root;
readonly executionEngine: IExecutionEngine;
readonly executionBuilder?: IExecutionBuilder;
readonly config: BeaconConfig;
readonly custodyConfig: CustodyConfig;
readonly logger: Logger;
readonly metrics: Metrics | null;
readonly validatorMonitor: ValidatorMonitor | null;
readonly bufferPool: BufferPool;
readonly anchorStateLatestBlockSlot: Slot;
readonly bls: IBlsVerifier;
readonly forkChoice: IForkChoice;
readonly clock: IClock;
readonly emitter: ChainEventEmitter;
readonly regen: QueuedStateRegenerator;
readonly lightClientServer?: LightClientServer;
readonly reprocessController: ReprocessController;
readonly archiveStore: ArchiveStore;
readonly unfinalizedBlockWrites: JobItemQueue<[IBlockInput], void>;
readonly unfinalizedPayloadEnvelopeWrites: JobItemQueue<[PayloadEnvelopeInput], void>;
readonly attestationPool: AttestationPool;
readonly aggregatedAttestationPool: AggregatedAttestationPool;
readonly syncCommitteeMessagePool: SyncCommitteeMessagePool;
readonly syncContributionAndProofPool: SyncContributionAndProofPool;
readonly executionPayloadBidPool: ExecutionPayloadBidPool;
readonly payloadAttestationPool: PayloadAttestationPool;
readonly opPool: OpPool;
readonly seenAttesters: SeenAttesters;
readonly seenAggregators: SeenAggregators;
readonly seenPayloadAttesters: SeenPayloadAttesters;
readonly seenAggregatedAttestations: SeenAggregatedAttestations;
readonly seenExecutionPayloadBids: SeenExecutionPayloadBids;
readonly seenProposerPreferences: SeenProposerPreferences;
readonly seenBlockProposers: SeenBlockProposers;
readonly seenSyncCommitteeMessages: SeenSyncCommitteeMessages;
readonly seenContributionAndProof: SeenContributionAndProof;
readonly seenAttestationDatas: SeenAttestationDatas;
readonly seenBlockInputCache: SeenBlockInput;
readonly seenPayloadEnvelopeInputCache: SeenPayloadEnvelopeInput;
readonly seenBlockAttesters: SeenBlockAttesters;
readonly pubkeyCache: PubkeyCache;
readonly beaconProposerCache: BeaconProposerCache;
readonly checkpointBalancesCache: CheckpointBalancesCache;
readonly shufflingCache: ShufflingCache;
/**
* Cache produced results (ExecutionPayload, DA Data) from the local execution so that we can send
* and get signed/published blinded versions which beacon node can
* assemble into full blocks before publishing to the network.
*/
readonly blockProductionCache: Map<string, ProduceResult>;
readonly blacklistedBlocks: Map<RootHex, Slot | null>;
readonly serializedCache: SerializedCache;
readonly getBlobsTracker: GetBlobsTracker;
readonly columnReconstructionTracker: ColumnReconstructionTracker;
readonly opts: IChainOptions;
protected readonly blockProcessor: BlockProcessor;
protected readonly payloadEnvelopeProcessor: PayloadEnvelopeProcessor;
protected readonly db: IBeaconDb;
private readonly cpStateDatastore?;
private abortController;
private processShutdownCallback;
private _earliestAvailableSlot;
get earliestAvailableSlot(): Slot;
set earliestAvailableSlot(slot: Slot);
constructor(opts: IChainOptions, { privateKey, config, pubkeyCache, db, dbName, dataDir, logger, processShutdownCallback, clock, metrics, validatorMonitor, anchorState, isAnchorStateFinalized, executionEngine, executionBuilder }: {
privateKey: PrivateKey;
config: BeaconConfig;
pubkeyCache: PubkeyCache;
db: IBeaconDb;
dbName: string;
dataDir: string;
logger: Logger;
processShutdownCallback: ProcessShutdownCallback;
/** Used for testing to supply fake clock */
clock?: IClock;
metrics: Metrics | null;
validatorMonitor: ValidatorMonitor | null;
anchorState: IBeaconStateView;
isAnchorStateFinalized: boolean;
executionEngine: IExecutionEngine;
executionBuilder?: IExecutionBuilder;
});
init(): Promise<void>;
close(): Promise<void>;
seenBlock(blockRoot: RootHex): boolean;
seenPayloadEnvelope(blockRoot: RootHex): boolean;
regenCanAcceptWork(): boolean;
blsThreadPoolCanAcceptWork(): boolean;
validatorSeenAtEpoch(index: ValidatorIndex, epoch: Epoch): boolean;
/** Populate in-memory caches with persisted data. Call at least once on startup */
loadFromDisk(): Promise<void>;
/** Persist in-memory data to the DB. Call at least once before stopping the process */
persistToDisk(): Promise<void>;
getHeadState(): IBeaconStateView;
getHeadStateAtCurrentEpoch(regenCaller: RegenCaller): Promise<IBeaconStateView>;
getHeadStateAtEpoch(epoch: Epoch, regenCaller: RegenCaller): Promise<IBeaconStateView>;
getStateBySlot(slot: Slot, opts?: StateGetOpts): Promise<{
state: IBeaconStateView;
executionOptimistic: boolean;
finalized: boolean;
} | null>;
getHistoricalStateBySlot(slot: number): Promise<{
state: Uint8Array;
executionOptimistic: boolean;
finalized: boolean;
} | null>;
getStateByStateRoot(stateRoot: RootHex, opts?: StateGetOpts): Promise<{
state: IBeaconStateView | Uint8Array;
executionOptimistic: boolean;
finalized: boolean;
} | null>;
getPersistedCheckpointState(checkpoint?: phase0.Checkpoint): Promise<Uint8Array | null>;
getStateByCheckpoint(checkpoint: CheckpointWithHex): {
state: IBeaconStateView;
executionOptimistic: boolean;
finalized: boolean;
} | null;
getStateOrBytesByCheckpoint(checkpoint: CheckpointWithHex): Promise<{
state: IBeaconStateView | Uint8Array;
executionOptimistic: boolean;
finalized: boolean;
} | null>;
getCanonicalBlockAtSlot(slot: Slot): Promise<{
block: SignedBeaconBlock;
executionOptimistic: boolean;
finalized: boolean;
} | null>;
getBlockByRoot(root: string): Promise<{
block: SignedBeaconBlock;
executionOptimistic: boolean;
finalized: boolean;
} | null>;
getSerializedBlockByRoot(root: string): Promise<{
block: Uint8Array;
executionOptimistic: boolean;
finalized: boolean;
slot: Slot;
} | null>;
getBlobSidecars(blockSlot: Slot, blockRootHex: string): Promise<deneb.BlobSidecars | null>;
getSerializedBlobSidecars(blockSlot: Slot, blockRootHex: string): Promise<Uint8Array | null>;
getSerializedExecutionPayloadEnvelope(blockSlot: Slot, blockRootHex: string): Promise<Uint8Array | null>;
getExecutionPayloadEnvelope(blockSlot: Slot, blockRootHex: string): Promise<gloas.SignedExecutionPayloadEnvelope | null>;
getParentExecutionRequests(parentBlockSlot: Slot, parentBlockRootHex: RootHex): Promise<electra.ExecutionRequests>;
getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<DataColumnSidecar[]>;
getSerializedDataColumnSidecars(blockSlot: Slot, blockRootHex: string, indices: number[]): Promise<(Uint8Array | undefined)[]>;
produceCommonBlockBody(blockAttributes: BlockAttributes): Promise<CommonBlockBody>;
produceBlock(blockAttributes: BlockAttributes & {
commonBlockBodyPromise: Promise<CommonBlockBody>;
}): Promise<{
block: BeaconBlock;
executionPayloadValue: Wei;
consensusBlockValue: Wei;
shouldOverrideBuilder?: boolean;
}>;
produceBlindedBlock(blockAttributes: BlockAttributes & {
commonBlockBodyPromise: Promise<CommonBlockBody>;
}): Promise<{
block: BlindedBeaconBlock;
executionPayloadValue: Wei;
consensusBlockValue: Wei;
}>;
produceBlockWrapper<T extends BlockType>(blockType: T, { randaoReveal, graffiti, slot, feeRecipient, commonBlockBodyPromise, parentBlock }: BlockAttributes & {
commonBlockBodyPromise: Promise<CommonBlockBody>;
}): Promise<{
block: AssembledBlockType<T>;
executionPayloadValue: Wei;
consensusBlockValue: Wei;
shouldOverrideBuilder?: boolean;
}>;
processBlock(block: IBlockInput, opts?: ImportBlockOpts): Promise<void>;
processChainSegment(blocks: IBlockInput[], payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null, opts?: ImportBlockOpts): Promise<void>;
processExecutionPayload(payloadInput: PayloadEnvelopeInput, opts?: ImportPayloadOpts): Promise<void>;
getStatus(): Status;
recomputeForkChoiceHead(caller: ForkchoiceCaller): ProtoBlock;
predictProposerHead(slot: Slot): ProtoBlock;
getProposerHead(slot: Slot): ProtoBlock;
/**
* Returns Promise that resolves either on block found or once 1 slot passes.
* Used to handle unknown block root for both unaggregated and aggregated attestations.
* @returns true if blockFound
*/
waitForBlock(slot: Slot, root: RootHex): Promise<boolean>;
persistBlock(data: BeaconBlock | BlindedBeaconBlock, suffix?: string): void;
/**
* Invalid state root error is critical and it causes the node to stale most of the time so we want to always
* persist preState, postState and block for further investigation.
*/
persistInvalidStateRoot(preState: IBeaconStateView, postState: IBeaconStateView, block: SignedBeaconBlock): Promise<void>;
persistInvalidSszValue<T>(type: Type<T>, sszObject: T, suffix?: string): void;
persistInvalidSszBytes(typeName: string, sszBytes: Uint8Array, suffix?: string): void;
/**
* Regenerate state for attestation verification, this does not happen with default chain option of maxSkipSlots = 32 .
* However, need to handle just in case. Lodestar doesn't support multiple regen state requests for attestation verification
* at the same time, bounded inside "ShufflingCache.insertPromise()" function.
* Leave this function in chain instead of attestatation verification code to make sure we're aware of its performance impact.
*/
regenStateForAttestationVerification(attEpoch: Epoch, shufflingDependentRoot: RootHex, attHeadBlock: ProtoBlock, regenCaller: RegenCaller): Promise<EpochShuffling>;
/**
* `ForkChoice.onBlock` must never throw for a block that is valid with respect to the network
* `justifiedBalancesGetter()` must never throw and it should always return a state.
* @param blockState state that declares justified checkpoint `checkpoint`
*/
private justifiedBalancesGetter;
/**
* - Assumptions + invariant this function is based on:
* - Our cache can only persist X states at once to prevent OOM
* - Some old states (including to-be justified checkpoint) may / must be dropped from the cache
* - Thus, there is no guarantee that the state for a justified checkpoint will be available in the cache
* @param blockState state that declares justified checkpoint `checkpoint`
*/
private closestJustifiedBalancesStateToCheckpoint;
private persistSszObject;
private onScrapeMetrics;
private onClockSlot;
private onClockEpoch;
protected onNewHead(head: ProtoBlock): void;
private onForkChoiceJustified;
private onCheckpoint;
private onForkChoiceFinalized;
updateBeaconProposerData(epoch: Epoch, proposers: ProposerPreparationData[]): Promise<void>;
private updateValidatorsCustodyRequirement;
updateBuilderStatus(clockSlot: Slot): void;
getBlockRewards(block: BeaconBlock | BlindedBeaconBlock): Promise<rewards.BlockRewards>;
getAttestationsRewards(epoch: Epoch, validatorIds?: (ValidatorIndex | string)[]): Promise<{
rewards: rewards.AttestationsRewards;
executionOptimistic: boolean;
finalized: boolean;
}>;
getSyncCommitteeRewards(block: BeaconBlock | BlindedBeaconBlock, validatorIds?: (ValidatorIndex | string)[]): Promise<rewards.SyncCommitteeRewards>;
}
//# sourceMappingURL=chain.d.ts.map