@lodestar/beacon-node 1.48.0-dev.f22c5ce63e → 1.48.0-dev.f63ac74039
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/blocks/index.js +4 -11
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js +14 -0
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/config/index.d.ts.map +1 -1
- package/lib/api/impl/config/index.js +4 -1
- package/lib/api/impl/config/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +39 -39
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +1 -0
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +5 -1
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -0
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/metrics.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/metrics.js +12 -1
- package/lib/chain/archiveStore/historicalState/metrics.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/types.d.ts +2 -0
- package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/types.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/worker.js +4 -1
- package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +9 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +68 -38
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts +5 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +12 -18
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/index.d.ts +8 -4
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +83 -17
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/types.d.ts +8 -0
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/types.js.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.d.ts +1 -1
- package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.js +26 -11
- package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js +9 -16
- package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
- package/lib/chain/chain.d.ts +11 -5
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +129 -75
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +1 -1
- package/lib/chain/emitter.js +1 -1
- package/lib/chain/errors/blockError.d.ts +14 -9
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +0 -2
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/dataColumnSidecarError.d.ts +15 -2
- package/lib/chain/errors/dataColumnSidecarError.d.ts.map +1 -1
- package/lib/chain/errors/dataColumnSidecarError.js.map +1 -1
- package/lib/chain/errors/executionPayloadBid.d.ts +4 -0
- package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadBid.js +1 -0
- package/lib/chain/errors/executionPayloadBid.js.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +10 -11
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.js +0 -2
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/errors/gossipValidation.d.ts +2 -1
- package/lib/chain/errors/gossipValidation.d.ts.map +1 -1
- package/lib/chain/errors/gossipValidation.js +1 -0
- package/lib/chain/errors/gossipValidation.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +2 -0
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +4 -4
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/lightClient/index.d.ts +3 -3
- package/lib/chain/lightClient/index.d.ts.map +1 -1
- package/lib/chain/lightClient/index.js +21 -23
- package/lib/chain/lightClient/index.js.map +1 -1
- package/lib/chain/lightClient/proofs.d.ts +2 -1
- package/lib/chain/lightClient/proofs.d.ts.map +1 -1
- package/lib/chain/lightClient/proofs.js +5 -1
- package/lib/chain/lightClient/proofs.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +16 -14
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +4 -2
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +57 -72
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +27 -55
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js +38 -13
- package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +56 -40
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +10 -29
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +5 -6
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts +7 -1
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +22 -5
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/db/beacon.d.ts +14 -5
- package/lib/db/beacon.d.ts.map +1 -1
- package/lib/db/beacon.js +17 -3
- package/lib/db/beacon.js.map +1 -1
- package/lib/db/dataColumnStore.d.ts +39 -0
- package/lib/db/dataColumnStore.d.ts.map +1 -0
- package/lib/db/dataColumnStore.js +81 -0
- package/lib/db/dataColumnStore.js.map +1 -0
- package/lib/db/flatFileStore/atomicWrite.d.ts +8 -0
- package/lib/db/flatFileStore/atomicWrite.d.ts.map +1 -0
- package/lib/db/flatFileStore/atomicWrite.js +61 -0
- package/lib/db/flatFileStore/atomicWrite.js.map +1 -0
- package/lib/db/flatFileStore/dcolFormat.d.ts +90 -0
- package/lib/db/flatFileStore/dcolFormat.d.ts.map +1 -0
- package/lib/db/flatFileStore/dcolFormat.js +286 -0
- package/lib/db/flatFileStore/dcolFormat.js.map +1 -0
- package/lib/db/flatFileStore/errors.d.ts +82 -0
- package/lib/db/flatFileStore/errors.d.ts.map +1 -0
- package/lib/db/flatFileStore/errors.js +32 -0
- package/lib/db/flatFileStore/errors.js.map +1 -0
- package/lib/db/flatFileStore/flatFileStore.d.ts +41 -0
- package/lib/db/flatFileStore/flatFileStore.d.ts.map +1 -0
- package/lib/db/flatFileStore/flatFileStore.js +251 -0
- package/lib/db/flatFileStore/flatFileStore.js.map +1 -0
- package/lib/db/flatFileStore/index.d.ts +4 -0
- package/lib/db/flatFileStore/index.d.ts.map +1 -0
- package/lib/db/flatFileStore/index.js +2 -0
- package/lib/db/flatFileStore/index.js.map +1 -0
- package/lib/db/flatFileStore/interface.d.ts +25 -0
- package/lib/db/flatFileStore/interface.d.ts.map +1 -0
- package/lib/db/flatFileStore/interface.js +2 -0
- package/lib/db/flatFileStore/interface.js.map +1 -0
- package/lib/db/flatFileStore/metrics.d.ts +24 -0
- package/lib/db/flatFileStore/metrics.d.ts.map +1 -0
- package/lib/db/flatFileStore/metrics.js +25 -0
- package/lib/db/flatFileStore/metrics.js.map +1 -0
- package/lib/db/flatFileStore/path.d.ts +9 -0
- package/lib/db/flatFileStore/path.d.ts.map +1 -0
- package/lib/db/flatFileStore/path.js +21 -0
- package/lib/db/flatFileStore/path.js.map +1 -0
- package/lib/db/flatFileStore/slotIndex.d.ts +14 -0
- package/lib/db/flatFileStore/slotIndex.d.ts.map +1 -0
- package/lib/db/flatFileStore/slotIndex.js +46 -0
- package/lib/db/flatFileStore/slotIndex.js.map +1 -0
- package/lib/db/flatFileStore/snappy.d.ts +3 -0
- package/lib/db/flatFileStore/snappy.d.ts.map +1 -0
- package/lib/db/flatFileStore/snappy.js +12 -0
- package/lib/db/flatFileStore/snappy.js.map +1 -0
- package/lib/db/index.d.ts +1 -0
- package/lib/db/index.d.ts.map +1 -1
- package/lib/db/interface.d.ts +8 -1
- package/lib/db/interface.d.ts.map +1 -1
- package/lib/db/repositories/blockArchive.d.ts +8 -1
- package/lib/db/repositories/blockArchive.d.ts.map +1 -1
- package/lib/db/repositories/blockArchive.js +65 -28
- package/lib/db/repositories/blockArchive.js.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts +1 -2
- package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.js +3 -7
- package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
- package/lib/execution/builder/validateBid.d.ts.map +1 -1
- package/lib/execution/builder/validateBid.js +8 -5
- package/lib/execution/builder/validateBid.js.map +1 -1
- package/lib/execution/engine/mock.d.ts.map +1 -1
- package/lib/execution/engine/mock.js +4 -1
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +22 -3
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +60 -6
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/monitoring/clientStats.js +1 -1
- package/lib/monitoring/clientStats.js.map +1 -1
- package/lib/network/gossip/encoding.d.ts.map +1 -1
- package/lib/network/gossip/encoding.js +0 -7
- package/lib/network/gossip/encoding.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +2 -1
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +4 -20
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/libp2p/index.d.ts +9 -1
- package/lib/network/libp2p/index.d.ts.map +1 -1
- package/lib/network/libp2p/index.js +23 -0
- package/lib/network/libp2p/index.js.map +1 -1
- package/lib/network/network.js +2 -2
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +388 -285
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/index.d.ts +49 -3
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +254 -114
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +112 -91
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +2 -0
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
- package/lib/network/reqresp/protocols.d.ts.map +1 -1
- package/lib/network/reqresp/protocols.js +6 -22
- package/lib/network/reqresp/protocols.js.map +1 -1
- package/lib/network/reqresp/rateLimit.js +2 -1
- package/lib/network/reqresp/rateLimit.js.map +1 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts +2 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts.map +1 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.js +14 -9
- package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
- package/lib/node/nodejs.d.ts +2 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +4 -2
- package/lib/node/nodejs.js.map +1 -1
- package/lib/sync/range/range.d.ts.map +1 -1
- package/lib/sync/range/range.js +24 -1
- package/lib/sync/range/range.js.map +1 -1
- package/lib/util/sszBytes.d.ts +6 -0
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +1 -1
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +19 -20
- package/src/api/impl/beacon/blocks/index.ts +8 -14
- package/src/api/impl/beacon/state/utils.ts +15 -0
- package/src/api/impl/config/index.ts +4 -1
- package/src/api/impl/validator/index.ts +44 -43
- package/src/chain/archiveStore/archiveStore.ts +12 -1
- package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +1 -0
- package/src/chain/archiveStore/historicalState/metrics.ts +14 -1
- package/src/chain/archiveStore/historicalState/types.ts +2 -0
- package/src/chain/archiveStore/historicalState/worker.ts +4 -1
- package/src/chain/archiveStore/utils/archiveBlocks.ts +73 -42
- package/src/chain/blocks/importBlock.ts +25 -20
- package/src/chain/blocks/index.ts +120 -23
- package/src/chain/blocks/types.ts +9 -0
- package/src/chain/blocks/utils/chainSegment.ts +26 -12
- package/src/chain/blocks/writeBlockInputToDb.ts +10 -17
- package/src/chain/chain.ts +153 -84
- package/src/chain/emitter.ts +1 -1
- package/src/chain/errors/blockError.ts +19 -10
- package/src/chain/errors/dataColumnSidecarError.ts +24 -8
- package/src/chain/errors/executionPayloadBid.ts +2 -0
- package/src/chain/errors/executionPayloadEnvelope.ts +14 -11
- package/src/chain/errors/gossipValidation.ts +1 -0
- package/src/chain/forkChoice/index.ts +2 -0
- package/src/chain/interface.ts +4 -4
- package/src/chain/lightClient/index.ts +32 -36
- package/src/chain/lightClient/proofs.ts +10 -0
- package/src/chain/opPools/aggregatedAttestationPool.ts +1 -1
- package/src/chain/prepareNextSlot.ts +21 -17
- package/src/chain/produceBlock/produceBlockBody.ts +62 -79
- package/src/chain/validation/block.ts +27 -72
- package/src/chain/validation/dataColumnSidecar.ts +47 -14
- package/src/chain/validation/executionPayloadBid.ts +62 -44
- package/src/chain/validation/executionPayloadEnvelope.ts +10 -37
- package/src/chain/validation/payloadAttestationMessage.ts +8 -9
- package/src/chain/validatorMonitor.ts +24 -7
- package/src/db/beacon.ts +33 -6
- package/src/db/dataColumnStore.ts +113 -0
- package/src/db/flatFileStore/atomicWrite.ts +65 -0
- package/src/db/flatFileStore/dcolFormat.ts +389 -0
- package/src/db/flatFileStore/errors.ts +53 -0
- package/src/db/flatFileStore/flatFileStore.ts +310 -0
- package/src/db/flatFileStore/index.ts +3 -0
- package/src/db/flatFileStore/interface.ts +21 -0
- package/src/db/flatFileStore/metrics.ts +48 -0
- package/src/db/flatFileStore/path.ts +32 -0
- package/src/db/flatFileStore/slotIndex.ts +56 -0
- package/src/db/flatFileStore/snappy.ts +14 -0
- package/src/db/index.ts +1 -0
- package/src/db/interface.ts +9 -1
- package/src/db/repositories/blockArchive.ts +89 -30
- package/src/db/repositories/blockArchiveIndex.ts +4 -9
- package/src/execution/builder/validateBid.ts +10 -6
- package/src/execution/engine/mock.ts +4 -1
- package/src/metrics/metrics/lodestar.ts +63 -6
- package/src/monitoring/clientStats.ts +1 -1
- package/src/network/gossip/encoding.ts +0 -7
- package/src/network/gossip/topic.ts +3 -25
- package/src/network/libp2p/index.ts +28 -1
- package/src/network/network.ts +2 -2
- package/src/network/processor/gossipHandlers.ts +500 -355
- package/src/network/processor/index.ts +287 -165
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +139 -105
- package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +2 -0
- package/src/network/reqresp/protocols.ts +7 -24
- package/src/network/reqresp/rateLimit.ts +2 -1
- package/src/network/reqresp/utils/dataColumnResponseValidation.ts +15 -7
- package/src/node/nodejs.ts +6 -1
- package/src/sync/range/range.ts +23 -1
- package/src/util/sszBytes.ts +1 -1
package/src/chain/interface.ts
CHANGED
|
@@ -35,7 +35,7 @@ import {IArchiveStore} from "./archiveStore/interface.js";
|
|
|
35
35
|
import {CheckpointBalancesCache} from "./balancesCache.js";
|
|
36
36
|
import {BeaconProposerCache, ProposerPreparationData} from "./beaconProposerCache.js";
|
|
37
37
|
import {IBlockInput} from "./blocks/blockInput/index.js";
|
|
38
|
-
import {ImportBlockOpts, ImportPayloadOpts} from "./blocks/types.js";
|
|
38
|
+
import {ImportBlockOpts, ImportPayloadOpts, ProcessBlocksResult} from "./blocks/types.js";
|
|
39
39
|
import {IBlsVerifier} from "./bls/index.js";
|
|
40
40
|
import {BuilderCircuitBreaker} from "./builderCircuitBreaker.js";
|
|
41
41
|
import {ColumnReconstructionTracker} from "./ColumnReconstructionTracker.js";
|
|
@@ -262,7 +262,7 @@ export interface IBeaconChain {
|
|
|
262
262
|
blocks: IBlockInput[],
|
|
263
263
|
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
|
|
264
264
|
opts?: ImportBlockOpts
|
|
265
|
-
): Promise<
|
|
265
|
+
): Promise<ProcessBlocksResult>;
|
|
266
266
|
|
|
267
267
|
/** Process execution payload envelope: verify, import to fork choice, and persist to DB */
|
|
268
268
|
processExecutionPayload(payloadInput: PayloadEnvelopeInput, opts?: ImportPayloadOpts): Promise<void>;
|
|
@@ -290,8 +290,8 @@ export interface IBeaconChain {
|
|
|
290
290
|
postState: IBeaconStateView,
|
|
291
291
|
block: SignedBeaconBlock
|
|
292
292
|
): Promise<void>;
|
|
293
|
-
persistInvalidSszValue<T>(type: Type<T>, sszObject: T
|
|
294
|
-
persistInvalidSszBytes(type: string, sszBytes: Uint8Array, suffix?: string): void;
|
|
293
|
+
persistInvalidSszValue<T>(type: Type<T>, sszObject: T, suffix?: string, rootHex?: RootHex): void;
|
|
294
|
+
persistInvalidSszBytes(type: string, sszBytes: Uint8Array, rootHex: RootHex, suffix?: string): void;
|
|
295
295
|
regenStateForAttestationVerification(
|
|
296
296
|
attEpoch: Epoch,
|
|
297
297
|
shufflingDependentRoot: RootHex,
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
ForkName,
|
|
6
6
|
ForkPostAltair,
|
|
7
7
|
ForkPostBellatrix,
|
|
8
|
+
ForkPostGloas,
|
|
8
9
|
ForkPreGloas,
|
|
9
10
|
ForkSeq,
|
|
10
11
|
MIN_SYNC_COMMITTEE_PARTICIPANTS,
|
|
@@ -40,7 +41,6 @@ import {
|
|
|
40
41
|
Slot,
|
|
41
42
|
SyncPeriod,
|
|
42
43
|
altair,
|
|
43
|
-
electra,
|
|
44
44
|
phase0,
|
|
45
45
|
ssz,
|
|
46
46
|
} from "@lodestar/types";
|
|
@@ -52,7 +52,12 @@ import {Metrics} from "../../metrics/index.js";
|
|
|
52
52
|
import {IClock} from "../../util/clock.js";
|
|
53
53
|
import {ChainEventEmitter} from "../emitter.js";
|
|
54
54
|
import {LightClientServerError, LightClientServerErrorCode} from "../errors/lightClientError.js";
|
|
55
|
-
import {
|
|
55
|
+
import {
|
|
56
|
+
getBlockBodyExecutionBlockHashProof,
|
|
57
|
+
getBlockBodyExecutionHeaderProof,
|
|
58
|
+
getCurrentSyncCommitteeBranch,
|
|
59
|
+
getNextSyncCommitteeBranch,
|
|
60
|
+
} from "./proofs.js";
|
|
56
61
|
|
|
57
62
|
export type LightClientServerOpts = {
|
|
58
63
|
disableLightClientServerOnImportBlockHead?: boolean;
|
|
@@ -61,6 +66,7 @@ export type LightClientServerOpts = {
|
|
|
61
66
|
|
|
62
67
|
type DependentRootHex = RootHex;
|
|
63
68
|
type BlockRooHex = RootHex;
|
|
69
|
+
type LightClientZeroFinality = Pick<LightClientUpdate, "finalityBranch" | "finalizedHeader">;
|
|
64
70
|
|
|
65
71
|
export type SyncAttestedData = {
|
|
66
72
|
attestedHeader: LightClientHeader;
|
|
@@ -199,6 +205,7 @@ export class LightClientServer {
|
|
|
199
205
|
private readonly clock: IClock;
|
|
200
206
|
private readonly signal: AbortSignal;
|
|
201
207
|
private readonly knownSyncCommittee = new MapDef<SyncPeriod, Set<DependentRootHex>>(() => new Set());
|
|
208
|
+
private readonly zeroFinalityByFork = new Map<ForkName, LightClientZeroFinality>();
|
|
202
209
|
private storedCurrentSyncCommittee = false;
|
|
203
210
|
|
|
204
211
|
/**
|
|
@@ -208,10 +215,6 @@ export class LightClientServer {
|
|
|
208
215
|
private checkpointHeaders = new Map<BlockRooHex, LightClientHeader>();
|
|
209
216
|
private latestHeadUpdate: LightClientOptimisticUpdate | null = null;
|
|
210
217
|
|
|
211
|
-
private readonly zero: Pick<
|
|
212
|
-
altair.LightClientUpdate | electra.LightClientUpdate,
|
|
213
|
-
"finalityBranch" | "finalizedHeader"
|
|
214
|
-
>;
|
|
215
218
|
private finalized: LightClientFinalityUpdate | null = null;
|
|
216
219
|
|
|
217
220
|
constructor(
|
|
@@ -227,14 +230,6 @@ export class LightClientServer {
|
|
|
227
230
|
this.logger = logger;
|
|
228
231
|
this.signal = signal;
|
|
229
232
|
|
|
230
|
-
this.zero = {
|
|
231
|
-
// Assign the highest pre-Gloas light-client header because post-Gloas light-client updates are skipped for now.
|
|
232
|
-
finalizedHeader: ssz.electra.LightClientHeader.defaultValue(),
|
|
233
|
-
// Electra finalityBranch has fixed length of 5 whereas altair has 4. The fifth element will be ignored
|
|
234
|
-
// when serializing as altair LightClientUpdate
|
|
235
|
-
finalityBranch: ssz.electra.LightClientUpdate.fields.finalityBranch.defaultValue(),
|
|
236
|
-
};
|
|
237
|
-
|
|
238
233
|
if (metrics) {
|
|
239
234
|
metrics.lightclientServer.highestSlot.addCollect(() => {
|
|
240
235
|
if (this.latestHeadUpdate) {
|
|
@@ -270,14 +265,6 @@ export class LightClientServer {
|
|
|
270
265
|
return;
|
|
271
266
|
}
|
|
272
267
|
|
|
273
|
-
// TODO GLOAS: Light client updates for gloas are not yet updated in the spec.
|
|
274
|
-
// The block body no longer contains execution payload, so `blockToLightClientHeader`
|
|
275
|
-
// cannot construct a header from a gloas block. Skip all light client processing
|
|
276
|
-
// for post-gloas blocks, revisit once there is a spec for it.
|
|
277
|
-
if (this.config.getForkSeq(block.slot) >= ForkSeq.gloas) {
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
268
|
// What is the syncAggregate signing?
|
|
282
269
|
// From the state-transition
|
|
283
270
|
// ```
|
|
@@ -695,9 +682,16 @@ export class LightClientServer {
|
|
|
695
682
|
}
|
|
696
683
|
} else {
|
|
697
684
|
isFinalized = false;
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
685
|
+
let zeroFinality = this.zeroFinalityByFork.get(attestedFork);
|
|
686
|
+
if (!zeroFinality) {
|
|
687
|
+
const {finalityBranch, finalizedHeader} = this.config
|
|
688
|
+
.getPostAltairForkTypes(attestedHeader.beacon.slot)
|
|
689
|
+
.LightClientUpdate.defaultValue();
|
|
690
|
+
zeroFinality = {finalityBranch, finalizedHeader};
|
|
691
|
+
this.zeroFinalityByFork.set(attestedFork, zeroFinality);
|
|
692
|
+
}
|
|
693
|
+
finalityBranch = zeroFinality.finalityBranch;
|
|
694
|
+
finalizedHeader = zeroFinality.finalizedHeader;
|
|
701
695
|
}
|
|
702
696
|
|
|
703
697
|
const newUpdate = {
|
|
@@ -769,22 +763,24 @@ export function sumBits(bits: BitArray): number {
|
|
|
769
763
|
return bits.getTrueBitIndexes().length;
|
|
770
764
|
}
|
|
771
765
|
|
|
772
|
-
|
|
773
|
-
// in Gloas. So we can assume any types here are pre-gloas
|
|
774
|
-
export function blockToLightClientHeader(
|
|
775
|
-
fork: ForkName,
|
|
776
|
-
block: BeaconBlock<ForkPostAltair & ForkPreGloas>
|
|
777
|
-
): LightClientHeader {
|
|
778
|
-
const blockSlot = block.slot;
|
|
766
|
+
export function blockToLightClientHeader(fork: ForkName, block: BeaconBlock<ForkPostAltair>): LightClientHeader {
|
|
779
767
|
const beacon: phase0.BeaconBlockHeader = {
|
|
780
|
-
slot:
|
|
768
|
+
slot: block.slot,
|
|
781
769
|
proposerIndex: block.proposerIndex,
|
|
782
770
|
parentRoot: block.parentRoot,
|
|
783
771
|
stateRoot: block.stateRoot,
|
|
784
|
-
bodyRoot: (ssz[fork].BeaconBlockBody as SSZTypesFor<ForkPostAltair
|
|
785
|
-
block.body
|
|
786
|
-
),
|
|
772
|
+
bodyRoot: (ssz[fork].BeaconBlockBody as SSZTypesFor<ForkPostAltair, "BeaconBlockBody">).hashTreeRoot(block.body),
|
|
787
773
|
};
|
|
774
|
+
|
|
775
|
+
if (isForkPostGloas(fork)) {
|
|
776
|
+
const blockBody = block.body as BeaconBlockBody<ForkPostGloas>;
|
|
777
|
+
return {
|
|
778
|
+
beacon,
|
|
779
|
+
executionBlockHash: blockBody.signedExecutionPayloadBid.message.parentBlockHash,
|
|
780
|
+
executionBranch: getBlockBodyExecutionBlockHashProof(fork, blockBody),
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
|
|
788
784
|
if (ForkSeq[fork] >= ForkSeq.capella) {
|
|
789
785
|
const blockBody = block.body as BeaconBlockBody<ForkPostBellatrix & ForkPreGloas>;
|
|
790
786
|
const execution = executionPayloadToPayloadHeader(ForkSeq[fork], blockBody.executionPayload);
|
|
@@ -2,11 +2,13 @@ import {Tree} from "@chainsafe/persistent-merkle-tree";
|
|
|
2
2
|
import {
|
|
3
3
|
BLOCK_BODY_EXECUTION_PAYLOAD_GINDEX,
|
|
4
4
|
CURRENT_SYNC_COMMITTEE_GINDEX_GLOAS,
|
|
5
|
+
EXECUTION_BLOCK_HASH_GINDEX_GLOAS,
|
|
5
6
|
FINALIZED_ROOT_GINDEX,
|
|
6
7
|
FINALIZED_ROOT_GINDEX_ELECTRA,
|
|
7
8
|
FINALIZED_ROOT_GINDEX_GLOAS,
|
|
8
9
|
ForkName,
|
|
9
10
|
ForkPostBellatrix,
|
|
11
|
+
ForkPostGloas,
|
|
10
12
|
NEXT_SYNC_COMMITTEE_GINDEX_GLOAS,
|
|
11
13
|
isForkPostElectra,
|
|
12
14
|
isForkPostGloas,
|
|
@@ -116,3 +118,11 @@ export function getBlockBodyExecutionHeaderProof(
|
|
|
116
118
|
const bodyView = (ssz[fork].BeaconBlockBody as SSZTypesFor<ForkPostBellatrix, "BeaconBlockBody">).toView(body);
|
|
117
119
|
return new Tree(bodyView.node).getSingleProof(BigInt(BLOCK_BODY_EXECUTION_PAYLOAD_GINDEX));
|
|
118
120
|
}
|
|
121
|
+
|
|
122
|
+
export function getBlockBodyExecutionBlockHashProof(
|
|
123
|
+
fork: ForkPostGloas,
|
|
124
|
+
body: BeaconBlockBody<ForkPostGloas>
|
|
125
|
+
): Uint8Array[] {
|
|
126
|
+
const bodyView = (ssz[fork].BeaconBlockBody as SSZTypesFor<ForkPostGloas, "BeaconBlockBody">).toView(body);
|
|
127
|
+
return new Tree(bodyView.node).getSingleProof(BigInt(EXECUTION_BLOCK_HASH_GINDEX_GLOAS));
|
|
128
|
+
}
|
|
@@ -363,7 +363,7 @@ export class AggregatedAttestationPool {
|
|
|
363
363
|
stateEpoch,
|
|
364
364
|
rootCache,
|
|
365
365
|
gloasState?.executionPayloadAvailability ?? null,
|
|
366
|
-
gloasState?.
|
|
366
|
+
gloasState?.latestBlockHeader.slot ?? null
|
|
367
367
|
);
|
|
368
368
|
|
|
369
369
|
const weight =
|
|
@@ -25,6 +25,7 @@ import {Bytes32, Slot, ValidatorIndex} from "@lodestar/types";
|
|
|
25
25
|
import {Logger, fromHex, isErrorAborted, sleep} from "@lodestar/utils";
|
|
26
26
|
import {GENESIS_SLOT} from "../constants/constants.js";
|
|
27
27
|
import {BuilderStatus} from "../execution/builder/http.js";
|
|
28
|
+
import {PayloadAttributes} from "../execution/index.js";
|
|
28
29
|
import {Metrics} from "../metrics/index.js";
|
|
29
30
|
import {ClockEvent} from "../util/clock.js";
|
|
30
31
|
import {isQueueErrorAborted} from "../util/queue/index.js";
|
|
@@ -243,6 +244,24 @@ export class PrepareNextSlotScheduler {
|
|
|
243
244
|
parentBlockHash = preparedState.latestExecutionPayloadHeader.blockHash;
|
|
244
245
|
}
|
|
245
246
|
|
|
247
|
+
let payloadAttributes: PayloadAttributes | undefined;
|
|
248
|
+
// If emitPayloadAttributes is true emit a SSE payloadAttributes event for
|
|
249
|
+
// every slot. Without the flag, only emit the event if we are proposing in the next slot.
|
|
250
|
+
if (
|
|
251
|
+
(feeRecipient || this.chain.opts.emitPayloadAttributes === true) &&
|
|
252
|
+
this.chain.emitter.listenerCount(routes.events.EventType.payloadAttributes)
|
|
253
|
+
) {
|
|
254
|
+
const data = getPayloadAttributesForSSE(fork as ForkPostBellatrix, this.chain, {
|
|
255
|
+
prepareState: stateAfterParentPayload,
|
|
256
|
+
prepareSlot,
|
|
257
|
+
parentBlockRoot: fromHex(updatedHead.blockRoot),
|
|
258
|
+
parentBlockHash,
|
|
259
|
+
feeRecipient: feeRecipient ?? "0x0000000000000000000000000000000000000000",
|
|
260
|
+
});
|
|
261
|
+
this.chain.emitter.emit(routes.events.EventType.payloadAttributes, {data, version: fork});
|
|
262
|
+
payloadAttributes = data.payloadAttributes;
|
|
263
|
+
}
|
|
264
|
+
|
|
246
265
|
if (feeRecipient) {
|
|
247
266
|
const preparationTime =
|
|
248
267
|
computeTimeAtSlot(this.config, prepareSlot, this.chain.genesisTime) - Date.now() / 1000;
|
|
@@ -263,7 +282,8 @@ export class PrepareNextSlotScheduler {
|
|
|
263
282
|
safeBlockHash,
|
|
264
283
|
finalizedBlockHash,
|
|
265
284
|
stateAfterParentPayload,
|
|
266
|
-
feeRecipient
|
|
285
|
+
feeRecipient,
|
|
286
|
+
payloadAttributes
|
|
267
287
|
);
|
|
268
288
|
this.logger.verbose("PrepareNextSlotScheduler prepared new payload", {
|
|
269
289
|
prepareSlot,
|
|
@@ -273,22 +293,6 @@ export class PrepareNextSlotScheduler {
|
|
|
273
293
|
}
|
|
274
294
|
|
|
275
295
|
this.computeStateHashTreeRoot(preparedState, isEpochTransition);
|
|
276
|
-
|
|
277
|
-
// If emitPayloadAttributes is true emit a SSE payloadAttributes event for
|
|
278
|
-
// every slot. Without the flag, only emit the event if we are proposing in the next slot.
|
|
279
|
-
if (
|
|
280
|
-
(feeRecipient || this.chain.opts.emitPayloadAttributes === true) &&
|
|
281
|
-
this.chain.emitter.listenerCount(routes.events.EventType.payloadAttributes)
|
|
282
|
-
) {
|
|
283
|
-
const data = getPayloadAttributesForSSE(fork as ForkPostBellatrix, this.chain, {
|
|
284
|
-
prepareState: stateAfterParentPayload,
|
|
285
|
-
prepareSlot,
|
|
286
|
-
parentBlockRoot: fromHex(updatedHead.blockRoot),
|
|
287
|
-
parentBlockHash,
|
|
288
|
-
feeRecipient: feeRecipient ?? "0x0000000000000000000000000000000000000000",
|
|
289
|
-
});
|
|
290
|
-
this.chain.emitter.emit(routes.events.EventType.payloadAttributes, {data, version: fork});
|
|
291
|
-
}
|
|
292
296
|
} else {
|
|
293
297
|
// Pre-bellatrix only reaches here at an epoch transition to precompute the next epoch state
|
|
294
298
|
const preparedState = await this.chain.regen.getBlockSlotState(
|
|
@@ -528,23 +528,18 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
528
528
|
}
|
|
529
529
|
}
|
|
530
530
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
throw Error(`Invalid builder getHeader response for fork=${fork}, missing blobKzgCommitments`);
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
(blockBody as deneb.BlindedBeaconBlockBody).blobKzgCommitments = blobKzgCommitments;
|
|
538
|
-
Object.assign(logMeta, {blobs: blobKzgCommitments.length});
|
|
531
|
+
const {blobKzgCommitments, executionRequests} = builderRes;
|
|
532
|
+
if (blobKzgCommitments === undefined) {
|
|
533
|
+
throw Error(`Invalid builder getHeader response for fork=${fork}, missing blobKzgCommitments`);
|
|
539
534
|
}
|
|
540
535
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
}
|
|
546
|
-
(blockBody as electra.BlindedBeaconBlockBody).executionRequests = executionRequests;
|
|
536
|
+
(blockBody as BlindedBeaconBlockBody<ForkName.fulu>).blobKzgCommitments = blobKzgCommitments;
|
|
537
|
+
Object.assign(logMeta, {blobs: blobKzgCommitments.length});
|
|
538
|
+
|
|
539
|
+
if (executionRequests === undefined) {
|
|
540
|
+
throw Error(`Invalid builder getHeader response for fork=${fork}, missing executionRequests`);
|
|
547
541
|
}
|
|
542
|
+
(blockBody as BlindedBeaconBlockBody<ForkName.fulu>).executionRequests = executionRequests;
|
|
548
543
|
}
|
|
549
544
|
|
|
550
545
|
// blockType === BlockType.Full
|
|
@@ -740,7 +735,9 @@ export async function prepareExecutionPayload(
|
|
|
740
735
|
* parent execution payload first (see `withParentPayloadApplied`).
|
|
741
736
|
*/
|
|
742
737
|
state: IBeaconStateViewBellatrix,
|
|
743
|
-
suggestedFeeRecipient: string
|
|
738
|
+
suggestedFeeRecipient: string,
|
|
739
|
+
/** Attributes already computed for the same state and fee recipient, e.g. for the SSE event */
|
|
740
|
+
payloadAttributes?: PayloadAttributes
|
|
744
741
|
): Promise<{prepType: PayloadPreparationType; payloadId: PayloadId}> {
|
|
745
742
|
const timestamp = computeTimeAtSlot(chain.config, state.slot, state.genesisTime);
|
|
746
743
|
const prevRandao = state.getRandaoMix(state.epoch);
|
|
@@ -771,13 +768,15 @@ export async function prepareExecutionPayload(
|
|
|
771
768
|
prepType = PayloadPreparationType.Fresh;
|
|
772
769
|
}
|
|
773
770
|
|
|
774
|
-
const attributes: PayloadAttributes =
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
771
|
+
const attributes: PayloadAttributes =
|
|
772
|
+
payloadAttributes ??
|
|
773
|
+
preparePayloadAttributes(fork, chain, {
|
|
774
|
+
prepareState: state,
|
|
775
|
+
prepareSlot: state.slot,
|
|
776
|
+
parentBlockRoot,
|
|
777
|
+
parentBlockHash,
|
|
778
|
+
feeRecipient: suggestedFeeRecipient,
|
|
779
|
+
});
|
|
781
780
|
|
|
782
781
|
payloadId = await chain.executionEngine.notifyForkchoiceUpdate(
|
|
783
782
|
fork,
|
|
@@ -899,45 +898,38 @@ function preparePayloadAttributes(
|
|
|
899
898
|
): SSEPayloadAttributes["payloadAttributes"] {
|
|
900
899
|
const timestamp = computeTimeAtSlot(chain.config, prepareSlot, prepareState.genesisTime);
|
|
901
900
|
const prevRandao = prepareState.getRandaoMix(prepareState.epoch);
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
suggestedFeeRecipient: feeRecipient,
|
|
906
|
-
};
|
|
907
|
-
|
|
908
|
-
if (ForkSeq[fork] >= ForkSeq.capella) {
|
|
909
|
-
if (!isStatePostCapella(prepareState)) {
|
|
910
|
-
throw new Error("Expected Capella state for withdrawals");
|
|
911
|
-
}
|
|
901
|
+
if (!isStatePostCapella(prepareState)) {
|
|
902
|
+
throw new Error("Expected Capella state for withdrawals");
|
|
903
|
+
}
|
|
912
904
|
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
(payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
|
|
922
|
-
prepareState.getExpectedWithdrawals().expectedWithdrawals;
|
|
923
|
-
} else {
|
|
924
|
-
// When the parent block is empty, state.payloadExpectedWithdrawals holds a batch
|
|
925
|
-
// already deducted from CL balances but never credited on the EL (the envelope
|
|
926
|
-
// was not delivered). The next payload must carry those same withdrawals to
|
|
927
|
-
// restore CL/EL consistency, otherwise validators permanently lose that balance.
|
|
928
|
-
(payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
|
|
929
|
-
prepareState.payloadExpectedWithdrawals;
|
|
905
|
+
let withdrawals: capella.Withdrawal[];
|
|
906
|
+
if (isStatePostGloas(prepareState)) {
|
|
907
|
+
const isExtendingPayload = byteArrayEquals(parentBlockHash, prepareState.latestExecutionPayloadBid.blockHash);
|
|
908
|
+
if (isExtendingPayload) {
|
|
909
|
+
// applyParentExecutionPayload sets latestBlockHash = parentBid.blockHash, so a mismatch
|
|
910
|
+
// here means the caller did not apply parent payload to prepareState
|
|
911
|
+
if (!byteArrayEquals(prepareState.latestBlockHash, prepareState.latestExecutionPayloadBid.blockHash)) {
|
|
912
|
+
throw new Error("Expected state with parent execution payload applied for withdrawals");
|
|
930
913
|
}
|
|
914
|
+
withdrawals = prepareState.getExpectedWithdrawals().expectedWithdrawals;
|
|
931
915
|
} else {
|
|
932
|
-
//
|
|
933
|
-
|
|
934
|
-
|
|
916
|
+
// When the parent block is empty, state.payloadExpectedWithdrawals holds a batch
|
|
917
|
+
// already deducted from CL balances but never credited on the EL (the envelope
|
|
918
|
+
// was not delivered). The next payload must carry those same withdrawals to
|
|
919
|
+
// restore CL/EL consistency, otherwise validators permanently lose that balance.
|
|
920
|
+
withdrawals = prepareState.payloadExpectedWithdrawals;
|
|
935
921
|
}
|
|
922
|
+
} else {
|
|
923
|
+
withdrawals = prepareState.getExpectedWithdrawals().expectedWithdrawals;
|
|
936
924
|
}
|
|
937
925
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
926
|
+
const payloadAttributes: deneb.SSEPayloadAttributes["payloadAttributes"] = {
|
|
927
|
+
timestamp,
|
|
928
|
+
prevRandao,
|
|
929
|
+
suggestedFeeRecipient: feeRecipient,
|
|
930
|
+
withdrawals,
|
|
931
|
+
parentBeaconBlockRoot: parentBlockRoot,
|
|
932
|
+
};
|
|
941
933
|
|
|
942
934
|
if (ForkSeq[fork] >= ForkSeq.gloas) {
|
|
943
935
|
if (!isStatePostGloas(prepareState)) {
|
|
@@ -1050,37 +1042,28 @@ export async function produceCommonBlockBody<T extends BlockType>(
|
|
|
1050
1042
|
step: BlockProductionStep.attestations,
|
|
1051
1043
|
});
|
|
1052
1044
|
|
|
1053
|
-
const
|
|
1045
|
+
const endSyncAggregate = stepsMetrics?.startTimer();
|
|
1046
|
+
const parentBlockRoot = fromHex(parentBlock.blockRoot);
|
|
1047
|
+
const previousSlot = slot - 1;
|
|
1048
|
+
const syncAggregate = this.syncContributionAndProofPool.getAggregate(previousSlot, parentBlockRoot);
|
|
1049
|
+
this.metrics?.production.producedSyncAggregateParticipants.observe(
|
|
1050
|
+
syncAggregate.syncCommitteeBits.getTrueBitIndexes().length
|
|
1051
|
+
);
|
|
1052
|
+
endSyncAggregate?.({
|
|
1053
|
+
step: BlockProductionStep.syncAggregate,
|
|
1054
|
+
});
|
|
1055
|
+
|
|
1056
|
+
// Live proposal production is supported from Fulu onward.
|
|
1057
|
+
return {
|
|
1054
1058
|
randaoReveal,
|
|
1055
1059
|
graffiti,
|
|
1056
|
-
// Eth1 data voting is no longer required since electra
|
|
1057
1060
|
eth1Data: currentState.eth1Data,
|
|
1058
1061
|
proposerSlashings: this.opts.disableProposerSlashings === true ? [] : proposerSlashings,
|
|
1059
1062
|
attesterSlashings,
|
|
1060
1063
|
attestations,
|
|
1061
|
-
// Since electra, deposits are processed by the execution layer,
|
|
1062
|
-
// we no longer support handling deposits from earlier forks.
|
|
1063
1064
|
deposits: [],
|
|
1064
1065
|
voluntaryExits,
|
|
1066
|
+
blsToExecutionChanges,
|
|
1067
|
+
syncAggregate,
|
|
1065
1068
|
};
|
|
1066
|
-
|
|
1067
|
-
if (ForkSeq[fork] >= ForkSeq.capella) {
|
|
1068
|
-
(blockBody as CommonBlockBody).blsToExecutionChanges = blsToExecutionChanges;
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
const endSyncAggregate = stepsMetrics?.startTimer();
|
|
1072
|
-
if (ForkSeq[fork] >= ForkSeq.altair) {
|
|
1073
|
-
const parentBlockRoot = fromHex(parentBlock.blockRoot);
|
|
1074
|
-
const previousSlot = slot - 1;
|
|
1075
|
-
const syncAggregate = this.syncContributionAndProofPool.getAggregate(previousSlot, parentBlockRoot);
|
|
1076
|
-
this.metrics?.production.producedSyncAggregateParticipants.observe(
|
|
1077
|
-
syncAggregate.syncCommitteeBits.getTrueBitIndexes().length
|
|
1078
|
-
);
|
|
1079
|
-
(blockBody as CommonBlockBody).syncAggregate = syncAggregate;
|
|
1080
|
-
}
|
|
1081
|
-
endSyncAggregate?.({
|
|
1082
|
-
step: BlockProductionStep.syncAggregate,
|
|
1083
|
-
});
|
|
1084
|
-
|
|
1085
|
-
return blockBody as CommonBlockBody;
|
|
1086
1069
|
}
|
|
@@ -1,22 +1,6 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
2
|
import {ExecutionStatus} from "@lodestar/fork-choice";
|
|
3
|
-
import {
|
|
4
|
-
ForkName,
|
|
5
|
-
MAX_ATTESTATIONS_ELECTRA,
|
|
6
|
-
MAX_ATTESTER_SLASHINGS_ELECTRA,
|
|
7
|
-
MAX_BLS_TO_EXECUTION_CHANGES,
|
|
8
|
-
MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD,
|
|
9
|
-
MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD,
|
|
10
|
-
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD,
|
|
11
|
-
MAX_PAYLOAD_ATTESTATIONS,
|
|
12
|
-
MAX_PROPOSER_SLASHINGS,
|
|
13
|
-
MAX_VOLUNTARY_EXITS,
|
|
14
|
-
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD,
|
|
15
|
-
MIN_SEED_LOOKAHEAD,
|
|
16
|
-
isForkPostBellatrix,
|
|
17
|
-
isForkPostDeneb,
|
|
18
|
-
isForkPostGloas,
|
|
19
|
-
} from "@lodestar/params";
|
|
3
|
+
import {ForkName, MIN_SEED_LOOKAHEAD, isForkPostBellatrix, isForkPostDeneb, isForkPostGloas} from "@lodestar/params";
|
|
20
4
|
import {
|
|
21
5
|
computeEpochAtSlot,
|
|
22
6
|
computeStartSlotAtEpoch,
|
|
@@ -150,8 +134,9 @@ export async function validateGossipBlock(
|
|
|
150
134
|
if (parentBlock.slot >= blockSlot) {
|
|
151
135
|
throw new BlockGossipError(GossipAction.REJECT, {
|
|
152
136
|
code: BlockErrorCode.NOT_LATER_THAN_PARENT,
|
|
153
|
-
parentSlot: parentBlock.slot,
|
|
154
137
|
slot: blockSlot,
|
|
138
|
+
root: blockRoot,
|
|
139
|
+
parentSlot: parentBlock.slot,
|
|
155
140
|
});
|
|
156
141
|
}
|
|
157
142
|
|
|
@@ -166,6 +151,8 @@ export async function validateGossipBlock(
|
|
|
166
151
|
if (blobKzgCommitmentsLen > maxBlobsPerBlock) {
|
|
167
152
|
throw new BlockGossipError(GossipAction.REJECT, {
|
|
168
153
|
code: BlockErrorCode.TOO_MANY_KZG_COMMITMENTS,
|
|
154
|
+
slot: blockSlot,
|
|
155
|
+
root: blockRoot,
|
|
169
156
|
blobKzgCommitmentsLen,
|
|
170
157
|
commitmentLimit: maxBlobsPerBlock,
|
|
171
158
|
});
|
|
@@ -173,7 +160,8 @@ export async function validateGossipBlock(
|
|
|
173
160
|
}
|
|
174
161
|
|
|
175
162
|
if (isForkPostGloas(fork)) {
|
|
176
|
-
const
|
|
163
|
+
const body = (block as gloas.BeaconBlock).body;
|
|
164
|
+
const bid = body.signedExecutionPayloadBid.message;
|
|
177
165
|
|
|
178
166
|
// [REJECT] The length of KZG commitments is less than or equal to the limitation defined in Consensus Layer
|
|
179
167
|
// -- i.e. validate that len(bid.blob_kzg_commitments) <= max_blobs_per_block
|
|
@@ -182,6 +170,8 @@ export async function validateGossipBlock(
|
|
|
182
170
|
if (blobKzgCommitmentsLen > maxBlobsPerBlock) {
|
|
183
171
|
throw new BlockGossipError(GossipAction.REJECT, {
|
|
184
172
|
code: BlockErrorCode.TOO_MANY_KZG_COMMITMENTS,
|
|
173
|
+
slot: blockSlot,
|
|
174
|
+
root: blockRoot,
|
|
185
175
|
blobKzgCommitmentsLen,
|
|
186
176
|
commitmentLimit: maxBlobsPerBlock,
|
|
187
177
|
});
|
|
@@ -191,61 +181,13 @@ export async function validateGossipBlock(
|
|
|
191
181
|
if (!byteArrayEquals(bid.parentBlockRoot, block.parentRoot)) {
|
|
192
182
|
throw new BlockGossipError(GossipAction.REJECT, {
|
|
193
183
|
code: BlockErrorCode.BID_PARENT_ROOT_MISMATCH,
|
|
184
|
+
slot: blockSlot,
|
|
185
|
+
root: blockRoot,
|
|
194
186
|
bidParentRoot: toRootHex(bid.parentBlockRoot),
|
|
195
187
|
blockParentRoot: parentRoot,
|
|
196
188
|
});
|
|
197
189
|
}
|
|
198
190
|
|
|
199
|
-
// [REJECT] The counts of `block.body.parent_execution_requests` are within
|
|
200
|
-
// their respective limits -- i.e. validate that
|
|
201
|
-
// `len(block.body.parent_execution_requests.withdrawals) <= MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD`,
|
|
202
|
-
// `len(block.body.parent_execution_requests.consolidations) <= MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD`,
|
|
203
|
-
// `len(block.body.parent_execution_requests.builder_deposits) <= MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD`,
|
|
204
|
-
// and
|
|
205
|
-
// `len(block.body.parent_execution_requests.builder_exits) <= MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD`.
|
|
206
|
-
// [REJECT] The counts of the block body operations are within their respective
|
|
207
|
-
// limits -- i.e. validate that
|
|
208
|
-
// `len(block.body.proposer_slashings) <= MAX_PROPOSER_SLASHINGS`,
|
|
209
|
-
// `len(block.body.attester_slashings) <= MAX_ATTESTER_SLASHINGS_ELECTRA`,
|
|
210
|
-
// `len(block.body.attestations) <= MAX_ATTESTATIONS_ELECTRA`,
|
|
211
|
-
// `len(block.body.deposits) == 0`,
|
|
212
|
-
// `len(block.body.voluntary_exits) <= MAX_VOLUNTARY_EXITS`,
|
|
213
|
-
// `len(block.body.bls_to_execution_changes) <= MAX_BLS_TO_EXECUTION_CHANGES`,
|
|
214
|
-
// and `len(block.body.payload_attestations) <= MAX_PAYLOAD_ATTESTATIONS`.
|
|
215
|
-
const body = (block as gloas.BeaconBlock).body;
|
|
216
|
-
const requests = body.parentExecutionRequests;
|
|
217
|
-
const countLimits: [string, number, number][] = [
|
|
218
|
-
["parentExecutionRequests.withdrawals", requests.withdrawals.length, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD],
|
|
219
|
-
[
|
|
220
|
-
"parentExecutionRequests.consolidations",
|
|
221
|
-
requests.consolidations.length,
|
|
222
|
-
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD,
|
|
223
|
-
],
|
|
224
|
-
[
|
|
225
|
-
"parentExecutionRequests.builderDeposits",
|
|
226
|
-
requests.builderDeposits.length,
|
|
227
|
-
MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD,
|
|
228
|
-
],
|
|
229
|
-
["parentExecutionRequests.builderExits", requests.builderExits.length, MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD],
|
|
230
|
-
["proposerSlashings", body.proposerSlashings.length, MAX_PROPOSER_SLASHINGS],
|
|
231
|
-
["attesterSlashings", body.attesterSlashings.length, MAX_ATTESTER_SLASHINGS_ELECTRA],
|
|
232
|
-
["attestations", body.attestations.length, MAX_ATTESTATIONS_ELECTRA],
|
|
233
|
-
["deposits", body.deposits.length, 0],
|
|
234
|
-
["voluntaryExits", body.voluntaryExits.length, MAX_VOLUNTARY_EXITS],
|
|
235
|
-
["blsToExecutionChanges", body.blsToExecutionChanges.length, MAX_BLS_TO_EXECUTION_CHANGES],
|
|
236
|
-
["payloadAttestations", body.payloadAttestations.length, MAX_PAYLOAD_ATTESTATIONS],
|
|
237
|
-
];
|
|
238
|
-
for (const [name, count, limit] of countLimits) {
|
|
239
|
-
if (count > limit) {
|
|
240
|
-
throw new BlockGossipError(GossipAction.REJECT, {
|
|
241
|
-
code: BlockErrorCode.TOO_MANY_BLOCK_OPERATIONS,
|
|
242
|
-
name,
|
|
243
|
-
count,
|
|
244
|
-
limit,
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
191
|
// TODO GLOAS: [REJECT] The block's execution payload parent (defined by bid.parent_block_hash) passes all validation
|
|
250
192
|
// This requires execution engine integration to verify the parent block hash
|
|
251
193
|
}
|
|
@@ -306,6 +248,8 @@ export async function validateGossipBlock(
|
|
|
306
248
|
if (executionPayload.timestamp !== computeTimeAtSlot(config, blockSlot, chain.genesisTime)) {
|
|
307
249
|
throw new BlockGossipError(GossipAction.REJECT, {
|
|
308
250
|
code: BlockErrorCode.INCORRECT_TIMESTAMP,
|
|
251
|
+
slot: blockSlot,
|
|
252
|
+
root: blockRoot,
|
|
309
253
|
timestamp: executionPayload.timestamp,
|
|
310
254
|
expectedTimestamp,
|
|
311
255
|
});
|
|
@@ -315,7 +259,12 @@ export async function validateGossipBlock(
|
|
|
315
259
|
|
|
316
260
|
// [REJECT] The proposer index is a valid validator index
|
|
317
261
|
if (proposerIndex >= state.validatorCount) {
|
|
318
|
-
throw new BlockGossipError(GossipAction.REJECT, {
|
|
262
|
+
throw new BlockGossipError(GossipAction.REJECT, {
|
|
263
|
+
code: BlockErrorCode.UNKNOWN_PROPOSER,
|
|
264
|
+
slot: blockSlot,
|
|
265
|
+
root: blockRoot,
|
|
266
|
+
proposerIndex,
|
|
267
|
+
});
|
|
319
268
|
}
|
|
320
269
|
|
|
321
270
|
// [REJECT] The proposer signature, signed_beacon_block.signature, is valid with respect to the proposer_index pubkey.
|
|
@@ -327,7 +276,12 @@ export async function validateGossipBlock(
|
|
|
327
276
|
// shuffling, the block MAY be queued for later processing while proposers for the block's branch are calculated --
|
|
328
277
|
// in such a case do not REJECT, instead IGNORE this message.
|
|
329
278
|
if (state.getBeaconProposer(blockSlot) !== proposerIndex) {
|
|
330
|
-
throw new BlockGossipError(GossipAction.REJECT, {
|
|
279
|
+
throw new BlockGossipError(GossipAction.REJECT, {
|
|
280
|
+
code: BlockErrorCode.INCORRECT_PROPOSER,
|
|
281
|
+
slot: blockSlot,
|
|
282
|
+
root: blockRoot,
|
|
283
|
+
proposerIndex,
|
|
284
|
+
});
|
|
331
285
|
}
|
|
332
286
|
|
|
333
287
|
// Simple implementation of a pending block queue. Keeping the block here recycles the queue logic, and keeps the
|
|
@@ -372,7 +326,8 @@ export async function verifyBlockProposerSignature(
|
|
|
372
326
|
if (!(await chain.bls.verifySignatureSets([signatureSet], {verifyOnMainThread: opts.verifyOnMainThread ?? true}))) {
|
|
373
327
|
throw new BlockGossipError(GossipAction.REJECT, {
|
|
374
328
|
code: BlockErrorCode.PROPOSAL_SIGNATURE_INVALID,
|
|
375
|
-
blockSlot,
|
|
329
|
+
slot: blockSlot,
|
|
330
|
+
root: blockRoot,
|
|
376
331
|
});
|
|
377
332
|
}
|
|
378
333
|
|