UNPKG

@lodestar/beacon-node

Version:

A Typescript implementation of the beacon chain

334 lines • 18.7 kB
import { PubkeyIndexMap } from "@chainsafe/pubkey-index-map"; import { CompositeTypeAny, TreeView, Type } from "@chainsafe/ssz"; import { BeaconConfig } from "@lodestar/config"; import { CheckpointWithHex, IForkChoice, ProtoBlock } from "@lodestar/fork-choice"; import { BeaconStateAllForks, CachedBeaconStateAllForks, EpochShuffling, Index2PubkeyCache } from "@lodestar/state-transition"; import { BeaconBlock, BlindedBeaconBlock, Epoch, Root, RootHex, SignedBeaconBlock, Slot, UintNum64, ValidatorIndex, Wei, deneb, phase0 } from "@lodestar/types"; import { Logger } from "@lodestar/utils"; import { ProcessShutdownCallback } from "@lodestar/validator"; import { IBeaconDb } from "../db/index.js"; import { IEth1ForBlockProduction } from "../eth1/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 { SerializedCache } from "../util/serializedCache.js"; import { ArchiveStore } from "./archiveStore/archiveStore.js"; import { CheckpointBalancesCache } from "./balancesCache.js"; import { BeaconProposerCache } from "./beaconProposerCache.js"; import { BlockProcessor, ImportBlockOpts } from "./blocks/index.js"; import { BlockInput } from "./blocks/types.js"; import { IBlsVerifier } from "./bls/index.js"; import { ChainEventEmitter } from "./emitter.js"; import { ForkchoiceCaller } from "./forkChoice/index.js"; import { CommonBlockBody, IBeaconChain, ProposerPreparationData, StateGetOpts } from "./interface.js"; import { LightClientServer } from "./lightClient/index.js"; import { AggregatedAttestationPool, AttestationPool, OpPool, SyncCommitteeMessagePool, SyncContributionAndProofPool } from "./opPools/index.js"; import { IChainOptions } from "./options.js"; import { AssembledBlockType, BlockType } from "./produceBlock/index.js"; import { BlockAttributes } from "./produceBlock/produceBlockBody.js"; import { QueuedStateRegenerator, RegenCaller } from "./regen/index.js"; import { ReprocessController } from "./reprocess.js"; import { AttestationsRewards } from "./rewards/attestationsRewards.js"; import { BlockRewards } from "./rewards/blockRewards.js"; import { SyncCommitteeRewards } from "./rewards/syncCommitteeRewards.js"; import { SeenAggregators, SeenAttesters, SeenBlockProposers, SeenContributionAndProof, SeenSyncCommitteeMessages } from "./seenCache/index.js"; import { SeenGossipBlockInput } from "./seenCache/index.js"; import { SeenAggregatedAttestations } from "./seenCache/seenAggregateAndProof.js"; import { SeenAttestationDatas } from "./seenCache/seenAttestationData.js"; import { SeenBlockAttesters } from "./seenCache/seenBlockAttesters.js"; import { SeenBlockInputCache } from "./seenCache/seenBlockInput.js"; import { ShufflingCache } from "./shufflingCache.js"; import { ValidatorMonitor } from "./validatorMonitor.js"; export declare class BeaconChain implements IBeaconChain { readonly genesisTime: UintNum64; readonly genesisValidatorsRoot: Root; readonly eth1: IEth1ForBlockProduction; readonly executionEngine: IExecutionEngine; readonly executionBuilder?: IExecutionBuilder; readonly config: BeaconConfig; readonly logger: Logger; readonly metrics: Metrics | null; readonly validatorMonitor: ValidatorMonitor | null; readonly bufferPool: BufferPool | null; 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 attestationPool: AttestationPool; readonly aggregatedAttestationPool: AggregatedAttestationPool; readonly syncCommitteeMessagePool: SyncCommitteeMessagePool; readonly syncContributionAndProofPool: SyncContributionAndProofPool; readonly opPool: OpPool; readonly seenAttesters: SeenAttesters; readonly seenAggregators: SeenAggregators; readonly seenAggregatedAttestations: SeenAggregatedAttestations; readonly seenBlockProposers: SeenBlockProposers; readonly seenSyncCommitteeMessages: SeenSyncCommitteeMessages; readonly seenContributionAndProof: SeenContributionAndProof; readonly seenAttestationDatas: SeenAttestationDatas; readonly seenGossipBlockInput: SeenGossipBlockInput; readonly seenBlockInputCache: SeenBlockInputCache; readonly seenBlockAttesters: SeenBlockAttesters; readonly pubkey2index: PubkeyIndexMap; readonly index2pubkey: Index2PubkeyCache; readonly beaconProposerCache: BeaconProposerCache; readonly checkpointBalancesCache: CheckpointBalancesCache; readonly shufflingCache: ShufflingCache; /** Map keyed by executionPayload.blockHash of the block for those blobs */ readonly producedContentsCache: Map<string, deneb.Contents>; readonly producedBlockRoot: Map<string, import("@chainsafe/ssz").ValueOfFields<{ transactions: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ByteListType>; parentHash: import("@chainsafe/ssz").ByteVectorType; feeRecipient: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType; stateRoot: import("@chainsafe/ssz").ByteVectorType; receiptsRoot: import("@chainsafe/ssz").ByteVectorType; logsBloom: import("@chainsafe/ssz").ByteVectorType; prevRandao: import("@chainsafe/ssz").ByteVectorType; blockNumber: import("@chainsafe/ssz").UintNumberType; gasLimit: import("@chainsafe/ssz").UintNumberType; gasUsed: import("@chainsafe/ssz").UintNumberType; timestamp: import("@chainsafe/ssz").UintNumberType; extraData: import("@chainsafe/ssz").ByteListType; baseFeePerGas: import("@chainsafe/ssz").UintBigintType; blockHash: import("@chainsafe/ssz").ByteVectorType; }> | import("@chainsafe/ssz").ValueOfFields<{ withdrawals: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ContainerType<{ index: import("@chainsafe/ssz").UintNumberType; validatorIndex: import("@chainsafe/ssz").UintNumberType; address: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType; amount: import("@chainsafe/ssz").UintBigintType; }>>; transactions: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ByteListType>; parentHash: import("@chainsafe/ssz").ByteVectorType; feeRecipient: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType; stateRoot: import("@chainsafe/ssz").ByteVectorType; receiptsRoot: import("@chainsafe/ssz").ByteVectorType; logsBloom: import("@chainsafe/ssz").ByteVectorType; prevRandao: import("@chainsafe/ssz").ByteVectorType; blockNumber: import("@chainsafe/ssz").UintNumberType; gasLimit: import("@chainsafe/ssz").UintNumberType; gasUsed: import("@chainsafe/ssz").UintNumberType; timestamp: import("@chainsafe/ssz").UintNumberType; extraData: import("@chainsafe/ssz").ByteListType; baseFeePerGas: import("@chainsafe/ssz").UintBigintType; blockHash: import("@chainsafe/ssz").ByteVectorType; }> | import("@chainsafe/ssz").ValueOfFields<{ blobGasUsed: import("@chainsafe/ssz").UintBigintType; excessBlobGas: import("@chainsafe/ssz").UintBigintType; withdrawals: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ContainerType<{ index: import("@chainsafe/ssz").UintNumberType; validatorIndex: import("@chainsafe/ssz").UintNumberType; address: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType; amount: import("@chainsafe/ssz").UintBigintType; }>>; transactions: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ByteListType>; parentHash: import("@chainsafe/ssz").ByteVectorType; feeRecipient: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType; stateRoot: import("@chainsafe/ssz").ByteVectorType; receiptsRoot: import("@chainsafe/ssz").ByteVectorType; logsBloom: import("@chainsafe/ssz").ByteVectorType; prevRandao: import("@chainsafe/ssz").ByteVectorType; blockNumber: import("@chainsafe/ssz").UintNumberType; gasLimit: import("@chainsafe/ssz").UintNumberType; gasUsed: import("@chainsafe/ssz").UintNumberType; timestamp: import("@chainsafe/ssz").UintNumberType; extraData: import("@chainsafe/ssz").ByteListType; baseFeePerGas: import("@chainsafe/ssz").UintBigintType; blockHash: import("@chainsafe/ssz").ByteVectorType; }> | import("@chainsafe/ssz").ValueOfFields<{ blobGasUsed: import("@chainsafe/ssz").UintBigintType; excessBlobGas: import("@chainsafe/ssz").UintBigintType; withdrawals: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ContainerType<{ index: import("@chainsafe/ssz").UintNumberType; validatorIndex: import("@chainsafe/ssz").UintNumberType; address: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType; amount: import("@chainsafe/ssz").UintBigintType; }>>; transactions: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ByteListType>; parentHash: import("@chainsafe/ssz").ByteVectorType; feeRecipient: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType; stateRoot: import("@chainsafe/ssz").ByteVectorType; receiptsRoot: import("@chainsafe/ssz").ByteVectorType; logsBloom: import("@chainsafe/ssz").ByteVectorType; prevRandao: import("@chainsafe/ssz").ByteVectorType; blockNumber: import("@chainsafe/ssz").UintNumberType; gasLimit: import("@chainsafe/ssz").UintNumberType; gasUsed: import("@chainsafe/ssz").UintNumberType; timestamp: import("@chainsafe/ssz").UintNumberType; extraData: import("@chainsafe/ssz").ByteListType; baseFeePerGas: import("@chainsafe/ssz").UintBigintType; blockHash: import("@chainsafe/ssz").ByteVectorType; }> | null>; readonly producedBlindedBlockRoot: Set<string>; readonly blacklistedBlocks: Map<RootHex, Slot | null>; readonly serializedCache: SerializedCache; readonly opts: IChainOptions; protected readonly blockProcessor: BlockProcessor; protected readonly db: IBeaconDb; private abortController; private processShutdownCallback; constructor(opts: IChainOptions, { config, db, dbName, dataDir, logger, processShutdownCallback, clock, metrics, validatorMonitor, anchorState, eth1, executionEngine, executionBuilder, }: { config: BeaconConfig; 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: BeaconStateAllForks; eth1: IEth1ForBlockProduction; executionEngine: IExecutionEngine; executionBuilder?: IExecutionBuilder; }); init(): Promise<void>; close(): Promise<void>; seenBlock(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(): CachedBeaconStateAllForks; getHeadStateAtCurrentEpoch(regenCaller: RegenCaller): Promise<CachedBeaconStateAllForks>; getHeadStateAtEpoch(epoch: Epoch, regenCaller: RegenCaller): Promise<CachedBeaconStateAllForks>; getStateBySlot(slot: Slot, opts?: StateGetOpts): Promise<{ state: BeaconStateAllForks; executionOptimistic: boolean; finalized: boolean; } | null>; getHistoricalStateBySlot(slot: number): Promise<{ state: Uint8Array; executionOptimistic: boolean; finalized: boolean; } | null>; getStateByStateRoot(stateRoot: RootHex, opts?: StateGetOpts): Promise<{ state: BeaconStateAllForks; executionOptimistic: boolean; finalized: boolean; } | null>; getStateByCheckpoint(checkpoint: CheckpointWithHex): { state: BeaconStateAllForks; executionOptimistic: boolean; finalized: boolean; } | null; getStateOrBytesByCheckpoint(checkpoint: CheckpointWithHex): Promise<{ state: CachedBeaconStateAllForks | 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>; 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, parentBlockRoot, parentSlot, }: BlockAttributes & { commonBlockBodyPromise?: Promise<CommonBlockBody>; }): Promise<{ block: AssembledBlockType<T>; executionPayloadValue: Wei; consensusBlockValue: Wei; shouldOverrideBuilder?: boolean; }>; /** * https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/validator.md#sidecar * def get_blobs_sidecar(block: BeaconBlock, blobs: Sequence[Blob]) -> BlobSidecars: * return BlobSidecars( * beacon_block_root=hash_tree_root(block), * beacon_block_slot=block.slot, * blobs=blobs, * kzg_aggregated_proof=compute_proof_from_blobs(blobs), * ) */ getContents(beaconBlock: deneb.BeaconBlock): deneb.Contents; processBlock(block: BlockInput, opts?: ImportBlockOpts): Promise<void>; processChainSegment(blocks: BlockInput[], opts?: ImportBlockOpts): Promise<void>; getStatus(): phase0.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: CachedBeaconStateAllForks, postState: CachedBeaconStateAllForks, block: SignedBeaconBlock): Promise<void>; persistInvalidSszValue<T>(type: Type<T>, sszObject: T, suffix?: string): void; persistInvalidSszBytes(typeName: string, sszBytes: Uint8Array, suffix?: string): void; persistInvalidSszView(view: TreeView<CompositeTypeAny>, 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 onForkChoiceFinalized; updateBeaconProposerData(epoch: Epoch, proposers: ProposerPreparationData[]): Promise<void>; updateBuilderStatus(clockSlot: Slot): void; getBlockRewards(block: BeaconBlock | BlindedBeaconBlock): Promise<BlockRewards>; getAttestationsRewards(epoch: Epoch, validatorIds?: (ValidatorIndex | string)[]): Promise<{ rewards: AttestationsRewards; executionOptimistic: boolean; finalized: boolean; }>; getSyncCommitteeRewards(block: BeaconBlock | BlindedBeaconBlock, validatorIds?: (ValidatorIndex | string)[]): Promise<SyncCommitteeRewards>; } //# sourceMappingURL=chain.d.ts.map