@lodestar/beacon-node 1.42.0-dev.7df0e2c8fa → 1.42.0-dev.8300b502a6
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 +24 -12
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +4 -0
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/index.js +13 -10
- package/lib/api/impl/beacon/state/index.js.map +1 -1
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.d.ts.map +1 -1
- package/lib/api/impl/lodestar/index.js +4 -0
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +9 -3
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.d.ts +2 -1
- package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
- package/lib/chain/ColumnReconstructionTracker.js +5 -5
- package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
- package/lib/chain/GetBlobsTracker.d.ts +2 -1
- package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
- package/lib/chain/GetBlobsTracker.js +14 -12
- package/lib/chain/GetBlobsTracker.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +1 -0
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +3 -3
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js +6 -4
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts +2 -2
- 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/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 +1 -4
- package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
- package/lib/chain/archiveStore/interface.d.ts +1 -0
- package/lib/chain/archiveStore/interface.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts +5 -5
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
- package/lib/chain/blocks/blockInput/types.d.ts +4 -4
- package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +34 -20
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +10 -8
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +86 -49
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +2 -1
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +14 -6
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +33 -2
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +2 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/types.d.ts +20 -14
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +2 -2
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +4 -3
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js +4 -2
- package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
- package/lib/chain/chain.d.ts +3 -2
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +68 -28
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +29 -7
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/emitter.js +12 -3
- package/lib/chain/emitter.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +6 -1
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +2 -0
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/dataColumnSidecarError.d.ts +31 -1
- package/lib/chain/errors/dataColumnSidecarError.d.ts.map +1 -1
- package/lib/chain/errors/dataColumnSidecarError.js +7 -0
- package/lib/chain/errors/dataColumnSidecarError.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +10 -8
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +4 -2
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/lightClient/index.d.ts +2 -2
- package/lib/chain/lightClient/index.d.ts.map +1 -1
- package/lib/chain/lightClient/index.js +7 -0
- package/lib/chain/lightClient/index.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +5 -2
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/opPools/executionPayloadBidPool.d.ts +2 -2
- package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -1
- package/lib/chain/opPools/executionPayloadBidPool.js +2 -2
- package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -1
- package/lib/chain/options.d.ts +1 -0
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js +1 -0
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +7 -1
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts +3 -3
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +8 -8
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +5 -5
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +23 -4
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.d.ts +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js +2 -2
- package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +2 -2
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +14 -5
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.d.ts +11 -4
- package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js +184 -5
- 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 +7 -4
- 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 +6 -1
- 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 +4 -1
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
- package/lib/chain/validation/syncCommittee.js +4 -0
- package/lib/chain/validation/syncCommittee.js.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.js +4 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +3 -3
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/db/buckets.d.ts +2 -2
- package/lib/db/buckets.d.ts.map +1 -1
- package/lib/db/buckets.js +2 -2
- package/lib/db/buckets.js.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
- package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecar.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecar.js +4 -2
- package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
- package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecarArchive.js +4 -2
- package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +20 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +33 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/interface.d.ts +3 -2
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/libp2p/index.d.ts.map +1 -1
- package/lib/network/libp2p/index.js +19 -13
- package/lib/network/libp2p/index.js.map +1 -1
- package/lib/network/network.d.ts +3 -2
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +3 -0
- package/lib/network/network.js.map +1 -1
- package/lib/network/options.d.ts.map +1 -1
- package/lib/network/options.js +7 -2
- package/lib/network/options.js.map +1 -1
- package/lib/network/processor/extractSlotRootFns.d.ts +1 -1
- package/lib/network/processor/extractSlotRootFns.d.ts.map +1 -1
- package/lib/network/processor/extractSlotRootFns.js +25 -5
- package/lib/network/processor/extractSlotRootFns.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +260 -73
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/index.d.ts +11 -1
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +234 -22
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/types.d.ts +3 -3
- package/lib/network/reqresp/types.d.ts.map +1 -1
- package/lib/network/reqresp/types.js +9 -3
- package/lib/network/reqresp/types.js.map +1 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +4 -1
- package/lib/node/nodejs.js.map +1 -1
- package/lib/node/notifier.d.ts.map +1 -1
- package/lib/node/notifier.js +2 -2
- package/lib/node/notifier.js.map +1 -1
- package/lib/sync/unknownBlock.js +2 -2
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts +3 -3
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +4 -2
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts +3 -3
- package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRoot.js +10 -5
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/lib/util/blobs.d.ts +3 -3
- package/lib/util/blobs.d.ts.map +1 -1
- package/lib/util/blobs.js +21 -10
- package/lib/util/blobs.js.map +1 -1
- package/lib/util/dataColumns.d.ts +18 -11
- package/lib/util/dataColumns.d.ts.map +1 -1
- package/lib/util/dataColumns.js +51 -17
- package/lib/util/dataColumns.js.map +1 -1
- package/lib/util/execution.d.ts +6 -2
- package/lib/util/execution.d.ts.map +1 -1
- package/lib/util/execution.js +49 -25
- package/lib/util/execution.js.map +1 -1
- package/lib/util/sszBytes.d.ts +25 -1
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +189 -2
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/beacon/blocks/index.ts +32 -15
- package/src/api/impl/beacon/pool/index.ts +4 -0
- package/src/api/impl/beacon/state/index.ts +15 -15
- package/src/api/impl/debug/index.ts +2 -2
- package/src/api/impl/lodestar/index.ts +4 -0
- package/src/api/impl/validator/index.ts +9 -2
- package/src/chain/ColumnReconstructionTracker.ts +6 -5
- package/src/chain/GetBlobsTracker.ts +14 -12
- package/src/chain/archiveStore/archiveStore.ts +1 -0
- package/src/chain/archiveStore/historicalState/getHistoricalState.ts +6 -5
- package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +2 -1
- package/src/chain/archiveStore/historicalState/types.ts +2 -0
- package/src/chain/archiveStore/historicalState/worker.ts +1 -5
- package/src/chain/archiveStore/interface.ts +1 -0
- package/src/chain/blocks/blockInput/blockInput.ts +8 -8
- package/src/chain/blocks/blockInput/types.ts +4 -4
- package/src/chain/blocks/importBlock.ts +45 -23
- package/src/chain/blocks/importExecutionPayload.ts +94 -53
- package/src/chain/blocks/index.ts +2 -1
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +53 -12
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +2 -1
- package/src/chain/blocks/types.ts +25 -14
- package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +6 -5
- package/src/chain/blocks/verifyBlocksSignatures.ts +9 -2
- package/src/chain/chain.ts +77 -32
- package/src/chain/emitter.ts +25 -7
- package/src/chain/errors/blockError.ts +4 -1
- package/src/chain/errors/dataColumnSidecarError.ts +32 -1
- package/src/chain/forkChoice/index.ts +11 -8
- package/src/chain/interface.ts +4 -2
- package/src/chain/lightClient/index.ts +15 -3
- package/src/chain/opPools/aggregatedAttestationPool.ts +6 -1
- package/src/chain/opPools/executionPayloadBidPool.ts +3 -3
- package/src/chain/options.ts +2 -0
- package/src/chain/prepareNextSlot.ts +8 -0
- package/src/chain/produceBlock/computeNewStateRoot.ts +11 -10
- package/src/chain/produceBlock/produceBlockBody.ts +40 -10
- package/src/chain/seenCache/seenGossipBlockInput.ts +2 -2
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +2 -2
- package/src/chain/validation/block.ts +15 -7
- package/src/chain/validation/dataColumnSidecar.ts +230 -7
- package/src/chain/validation/executionPayloadBid.ts +7 -3
- package/src/chain/validation/executionPayloadEnvelope.ts +10 -1
- package/src/chain/validation/payloadAttestationMessage.ts +4 -0
- package/src/chain/validation/syncCommittee.ts +5 -1
- package/src/chain/validation/syncCommitteeContributionAndProof.ts +5 -1
- package/src/chain/validatorMonitor.ts +3 -2
- package/src/db/buckets.ts +2 -2
- package/src/db/repositories/dataColumnSidecar.ts +4 -2
- package/src/db/repositories/dataColumnSidecarArchive.ts +4 -2
- package/src/metrics/metrics/lodestar.ts +34 -0
- package/src/network/interface.ts +3 -2
- package/src/network/libp2p/index.ts +21 -15
- package/src/network/network.ts +7 -4
- package/src/network/options.ts +7 -2
- package/src/network/processor/extractSlotRootFns.ts +32 -6
- package/src/network/processor/gossipHandlers.ts +325 -86
- package/src/network/processor/index.ts +304 -22
- package/src/network/reqresp/types.ts +13 -5
- package/src/node/nodejs.ts +5 -2
- package/src/node/notifier.ts +7 -2
- package/src/sync/unknownBlock.ts +3 -3
- package/src/sync/utils/downloadByRange.ts +9 -7
- package/src/sync/utils/downloadByRoot.ts +16 -12
- package/src/util/blobs.ts +35 -15
- package/src/util/dataColumns.ts +69 -25
- package/src/util/execution.ts +49 -30
- package/src/util/sszBytes.ts +245 -3
|
@@ -7,6 +7,7 @@ export type HistoricalStateRegenInitModules = {
|
|
|
7
7
|
opts: {
|
|
8
8
|
genesisTime: number;
|
|
9
9
|
dbLocation: string;
|
|
10
|
+
nativeStateView: boolean;
|
|
10
11
|
};
|
|
11
12
|
config: BeaconConfig;
|
|
12
13
|
logger: LoggerNode;
|
|
@@ -26,6 +27,7 @@ export type HistoricalStateWorkerData = {
|
|
|
26
27
|
dbLocation: string;
|
|
27
28
|
metricsEnabled: boolean;
|
|
28
29
|
loggerOpts: LoggerNodeOpts;
|
|
30
|
+
nativeStateView: boolean;
|
|
29
31
|
};
|
|
30
32
|
|
|
31
33
|
export type HistoricalStateWorkerApi = {
|
|
@@ -3,7 +3,6 @@ import {Transfer, expose} from "@chainsafe/threads/worker";
|
|
|
3
3
|
import {chainConfigFromJson, createBeaconConfig} from "@lodestar/config";
|
|
4
4
|
import {LevelDbController} from "@lodestar/db/controller/level";
|
|
5
5
|
import {getNodeLogger} from "@lodestar/logger/node";
|
|
6
|
-
import {createPubkeyCache} from "@lodestar/state-transition";
|
|
7
6
|
import {BeaconDb} from "../../../db/index.js";
|
|
8
7
|
import {RegistryMetricCreator, collectNodeJSMetrics} from "../../../metrics/index.js";
|
|
9
8
|
import {JobFnQueue} from "../../../util/queue/fnQueue.js";
|
|
@@ -52,9 +51,6 @@ const queue = new JobFnQueue(
|
|
|
52
51
|
queueMetrics
|
|
53
52
|
);
|
|
54
53
|
|
|
55
|
-
// Reuse a single pubkey cache across all historical state regen calls in this worker
|
|
56
|
-
const pubkeyCache = createPubkeyCache();
|
|
57
|
-
|
|
58
54
|
const api: HistoricalStateWorkerApi = {
|
|
59
55
|
async close() {
|
|
60
56
|
abortController.abort();
|
|
@@ -66,7 +62,7 @@ const api: HistoricalStateWorkerApi = {
|
|
|
66
62
|
historicalStateRegenMetrics?.regenRequestCount.inc();
|
|
67
63
|
|
|
68
64
|
const stateBytes = await queue.push<Uint8Array>(() =>
|
|
69
|
-
getHistoricalState(slot, config, db,
|
|
65
|
+
getHistoricalState(slot, config, db, workerData.nativeStateView, historicalStateRegenMetrics)
|
|
70
66
|
);
|
|
71
67
|
const result = Transfer(stateBytes, [stateBytes.buffer]) as unknown as Uint8Array;
|
|
72
68
|
|
|
@@ -617,7 +617,7 @@ type BlockInputColumnsState =
|
|
|
617
617
|
* - The block is not yet seen and all required sampled columns are seen
|
|
618
618
|
* - The block is not yet seen and all required sampled columns are not yet seen
|
|
619
619
|
*/
|
|
620
|
-
export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.
|
|
620
|
+
export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.DataColumnSidecar[]> {
|
|
621
621
|
type = DAType.Columns as const;
|
|
622
622
|
|
|
623
623
|
state: BlockInputColumnsState;
|
|
@@ -630,7 +630,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
630
630
|
*
|
|
631
631
|
* This is different from `dataPromise` which resolves when all data is available or could become available (e.g. through reconstruction)
|
|
632
632
|
*/
|
|
633
|
-
protected computedDataPromise = createPromise<fulu.
|
|
633
|
+
protected computedDataPromise = createPromise<fulu.DataColumnSidecar[]>();
|
|
634
634
|
|
|
635
635
|
private constructor(
|
|
636
636
|
init: BlockInputInit,
|
|
@@ -854,8 +854,8 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
854
854
|
return this.state.versionedHashes;
|
|
855
855
|
}
|
|
856
856
|
|
|
857
|
-
getCustodyColumns(): fulu.
|
|
858
|
-
const columns: fulu.
|
|
857
|
+
getCustodyColumns(): fulu.DataColumnSidecar[] {
|
|
858
|
+
const columns: fulu.DataColumnSidecar[] = [];
|
|
859
859
|
for (const index of this.custodyColumns) {
|
|
860
860
|
const column = this.columnsCache.get(index);
|
|
861
861
|
if (column) {
|
|
@@ -876,8 +876,8 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
876
876
|
return columns;
|
|
877
877
|
}
|
|
878
878
|
|
|
879
|
-
getSampledColumns(): fulu.
|
|
880
|
-
const columns: fulu.
|
|
879
|
+
getSampledColumns(): fulu.DataColumnSidecar[] {
|
|
880
|
+
const columns: fulu.DataColumnSidecar[] = [];
|
|
881
881
|
for (const index of this.sampledColumns) {
|
|
882
882
|
const column = this.columnsCache.get(index);
|
|
883
883
|
if (column) {
|
|
@@ -891,7 +891,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
891
891
|
return [...this.columnsCache.values()];
|
|
892
892
|
}
|
|
893
893
|
|
|
894
|
-
getAllColumns(): fulu.
|
|
894
|
+
getAllColumns(): fulu.DataColumnSidecar[] {
|
|
895
895
|
return this.getAllColumnsWithSource().map(({columnSidecar}) => columnSidecar);
|
|
896
896
|
}
|
|
897
897
|
|
|
@@ -919,7 +919,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
|
|
|
919
919
|
return this.state.hasComputedAllData;
|
|
920
920
|
}
|
|
921
921
|
|
|
922
|
-
waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<fulu.
|
|
922
|
+
waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<fulu.DataColumnSidecar[]> {
|
|
923
923
|
if (!this.state.hasComputedAllData) {
|
|
924
924
|
return withTimeout(() => this.computedDataPromise.promise, timeout, signal);
|
|
925
925
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {ForkName} from "@lodestar/params";
|
|
2
|
-
import {ColumnIndex,
|
|
2
|
+
import {ColumnIndex, DataColumnSidecar, RootHex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
|
|
3
3
|
import {VersionedHashes} from "../../../execution/index.js";
|
|
4
4
|
|
|
5
5
|
export enum DAType {
|
|
@@ -9,7 +9,7 @@ export enum DAType {
|
|
|
9
9
|
NoData = "no-data",
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export type DAData = null | deneb.BlobSidecars | fulu.
|
|
12
|
+
export type DAData = null | deneb.BlobSidecars | fulu.DataColumnSidecar[];
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Represents were input originated. Blocks and Data can come from different
|
|
@@ -108,9 +108,9 @@ export type MissingColumnMeta = {
|
|
|
108
108
|
export interface IDataColumnsInput {
|
|
109
109
|
readonly slot: Slot;
|
|
110
110
|
readonly blockRootHex: string;
|
|
111
|
-
getCustodyColumns():
|
|
111
|
+
getCustodyColumns(): DataColumnSidecar[];
|
|
112
112
|
hasComputedAllData(): boolean;
|
|
113
|
-
waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<
|
|
113
|
+
waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<DataColumnSidecar[]>;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
/**
|
|
@@ -3,6 +3,7 @@ import {routes} from "@lodestar/api";
|
|
|
3
3
|
import {
|
|
4
4
|
AncestorStatus,
|
|
5
5
|
EpochDifference,
|
|
6
|
+
ExecutionStatus,
|
|
6
7
|
ForkChoiceError,
|
|
7
8
|
ForkChoiceErrorCode,
|
|
8
9
|
NotReorgedReason,
|
|
@@ -24,6 +25,8 @@ import {
|
|
|
24
25
|
computeStartSlotAtEpoch,
|
|
25
26
|
computeTimeAtSlot,
|
|
26
27
|
isStartSlotOfEpoch,
|
|
28
|
+
isStatePostAltair,
|
|
29
|
+
isStatePostBellatrix,
|
|
27
30
|
} from "@lodestar/state-transition";
|
|
28
31
|
import {
|
|
29
32
|
Attestation,
|
|
@@ -84,7 +87,7 @@ export async function importBlock(
|
|
|
84
87
|
fullyVerifiedBlock: FullyVerifiedBlock,
|
|
85
88
|
opts: ImportBlockOpts
|
|
86
89
|
): Promise<void> {
|
|
87
|
-
const {blockInput,
|
|
90
|
+
const {blockInput, postBlockState, parentBlockSlot, executionStatus, dataAvailabilityStatus, indexedAttestations} =
|
|
88
91
|
fullyVerifiedBlock;
|
|
89
92
|
const block = blockInput.getBlock();
|
|
90
93
|
const source = blockInput.getBlockSource();
|
|
@@ -96,7 +99,7 @@ export async function importBlock(
|
|
|
96
99
|
const blockEpoch = computeEpochAtSlot(blockSlot);
|
|
97
100
|
const prevFinalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
|
|
98
101
|
const blockDelaySec =
|
|
99
|
-
fullyVerifiedBlock.seenTimestampSec - computeTimeAtSlot(this.config, blockSlot,
|
|
102
|
+
fullyVerifiedBlock.seenTimestampSec - computeTimeAtSlot(this.config, blockSlot, postBlockState.genesisTime);
|
|
100
103
|
const recvToValLatency = Date.now() / 1000 - (opts.seenTimestampSec ?? Date.now() / 1000);
|
|
101
104
|
const fork = this.config.getForkSeq(blockSlot);
|
|
102
105
|
|
|
@@ -119,13 +122,13 @@ export async function importBlock(
|
|
|
119
122
|
// 2. Import block to fork choice
|
|
120
123
|
|
|
121
124
|
// Should compute checkpoint balances before forkchoice.onBlock
|
|
122
|
-
this.checkpointBalancesCache.processState(blockRootHex,
|
|
125
|
+
this.checkpointBalancesCache.processState(blockRootHex, postBlockState);
|
|
123
126
|
const blockSummary = this.forkChoice.onBlock(
|
|
124
127
|
block.message,
|
|
125
|
-
|
|
128
|
+
postBlockState,
|
|
126
129
|
blockDelaySec,
|
|
127
130
|
currentSlot,
|
|
128
|
-
executionStatus,
|
|
131
|
+
fork >= ForkSeq.gloas ? ExecutionStatus.PayloadSeparated : executionStatus,
|
|
129
132
|
dataAvailabilityStatus
|
|
130
133
|
);
|
|
131
134
|
|
|
@@ -135,13 +138,14 @@ export async function importBlock(
|
|
|
135
138
|
// Post-Gloas: blockSummary.payloadStatus is always PENDING, so payloadPresent = false (block state only, no payload processing yet)
|
|
136
139
|
const payloadPresent = !isGloasBlock(blockSummary);
|
|
137
140
|
// processState manages both block state and payload state variants together for memory/disk management
|
|
138
|
-
this.regen.processBlockState(blockRootHex,
|
|
141
|
+
this.regen.processBlockState(blockRootHex, postBlockState);
|
|
139
142
|
|
|
140
143
|
// For Gloas blocks, create PayloadEnvelopeInput so it's available for later payload import
|
|
141
144
|
if (fork >= ForkSeq.gloas) {
|
|
142
|
-
this.seenPayloadEnvelopeInputCache.add({
|
|
145
|
+
const payloadInput = this.seenPayloadEnvelopeInputCache.add({
|
|
143
146
|
blockRootHex,
|
|
144
147
|
block: block as SignedBeaconBlock<ForkPostGloas>,
|
|
148
|
+
forkName: blockInput.forkName,
|
|
145
149
|
sampledColumns: this.custodyConfig.sampledColumns,
|
|
146
150
|
custodyColumns: this.custodyConfig.custodyColumns,
|
|
147
151
|
timeCreatedSec: fullyVerifiedBlock.seenTimestampSec,
|
|
@@ -152,6 +156,22 @@ export async function importBlock(
|
|
|
152
156
|
source: source.source,
|
|
153
157
|
...(opts.seenTimestampSec !== undefined ? {recvToImport: Date.now() / 1000 - opts.seenTimestampSec} : {}),
|
|
154
158
|
});
|
|
159
|
+
|
|
160
|
+
// Immediately attempt fetch of data columns from execution engine as the bid contains kzg commitments
|
|
161
|
+
// which is all the information we need so there is no reason to delay until execution payload arrives
|
|
162
|
+
// TODO GLOAS: If we want EL retries after this initial attempt, add an explicit retry policy here
|
|
163
|
+
// (for example later in the slot). Do not couple retries to incoming gossip columns.
|
|
164
|
+
this.getBlobsTracker.triggerGetBlobs(payloadInput, () => {
|
|
165
|
+
// TODO GLOAS: come up with a better mechanism to trigger processExecutionPayload after data becomes available,
|
|
166
|
+
// similar to how pre-gloas uses waitForBlockAndAllData with a cutoff timeout and incompleteBlockInput event
|
|
167
|
+
this.processExecutionPayload(payloadInput, {validSignature: true}).catch((e) => {
|
|
168
|
+
this.logger.debug(
|
|
169
|
+
"Error processing execution payload after getBlobs",
|
|
170
|
+
{slot: blockSlot, root: blockRootHex},
|
|
171
|
+
e as Error
|
|
172
|
+
);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
155
175
|
}
|
|
156
176
|
|
|
157
177
|
this.metrics?.importBlock.bySource.inc({source: source.source});
|
|
@@ -171,7 +191,7 @@ export async function importBlock(
|
|
|
171
191
|
(opts.importAttestations !== AttestationImportOpt.Skip && blockEpoch >= currentEpoch - FORK_CHOICE_ATT_EPOCH_LIMIT)
|
|
172
192
|
) {
|
|
173
193
|
const attestations = block.message.body.attestations;
|
|
174
|
-
const rootCache = new RootCache(
|
|
194
|
+
const rootCache = new RootCache(postBlockState);
|
|
175
195
|
const invalidAttestationErrorsByCode = new Map<string, {error: Error; count: number}>();
|
|
176
196
|
|
|
177
197
|
const addAttestation = fork >= ForkSeq.electra ? addAttestationPostElectra : addAttestationPreElectra;
|
|
@@ -185,7 +205,7 @@ export async function importBlock(
|
|
|
185
205
|
const attDataRoot = toRootHex(ssz.phase0.AttestationData.hashTreeRoot(indexedAttestation.data));
|
|
186
206
|
addAttestation.call(
|
|
187
207
|
this,
|
|
188
|
-
|
|
208
|
+
postBlockState,
|
|
189
209
|
target,
|
|
190
210
|
attDataRoot,
|
|
191
211
|
attestation as Attestation<ForkPostElectra>,
|
|
@@ -300,7 +320,7 @@ export async function importBlock(
|
|
|
300
320
|
|
|
301
321
|
if (newHead.blockRoot !== oldHead.blockRoot) {
|
|
302
322
|
// Set head state as strong reference
|
|
303
|
-
this.regen.updateHeadState(newHead,
|
|
323
|
+
this.regen.updateHeadState(newHead, postBlockState);
|
|
304
324
|
|
|
305
325
|
try {
|
|
306
326
|
this.emitter.emit(routes.events.EventType.head, {
|
|
@@ -370,11 +390,13 @@ export async function importBlock(
|
|
|
370
390
|
// we want to import block asap so do this in the next event loop
|
|
371
391
|
callInNextEventLoop(() => {
|
|
372
392
|
try {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
393
|
+
if (isStatePostAltair(postBlockState)) {
|
|
394
|
+
this.lightClientServer?.onImportBlockHead(
|
|
395
|
+
block.message as BeaconBlock<ForkPostAltair>,
|
|
396
|
+
postBlockState,
|
|
397
|
+
parentBlockSlot
|
|
398
|
+
);
|
|
399
|
+
}
|
|
378
400
|
} catch (e) {
|
|
379
401
|
this.logger.verbose("Error lightClientServer.onImportBlock", {slot: blockSlot}, e as Error);
|
|
380
402
|
}
|
|
@@ -393,11 +415,11 @@ export async function importBlock(
|
|
|
393
415
|
// and the block is weak and can potentially be reorged out.
|
|
394
416
|
let shouldOverrideFcu = false;
|
|
395
417
|
|
|
396
|
-
if (blockSlot >= currentSlot &&
|
|
418
|
+
if (blockSlot >= currentSlot && isStatePostBellatrix(postBlockState) && postBlockState.isExecutionStateType) {
|
|
397
419
|
let notOverrideFcuReason = NotReorgedReason.Unknown;
|
|
398
420
|
const proposalSlot = blockSlot + 1;
|
|
399
421
|
try {
|
|
400
|
-
const proposerIndex =
|
|
422
|
+
const proposerIndex = postBlockState.getBeaconProposer(proposalSlot);
|
|
401
423
|
const feeRecipient = this.beaconProposerCache.get(proposerIndex);
|
|
402
424
|
|
|
403
425
|
if (feeRecipient) {
|
|
@@ -477,20 +499,20 @@ export async function importBlock(
|
|
|
477
499
|
}
|
|
478
500
|
}
|
|
479
501
|
|
|
480
|
-
if (!
|
|
481
|
-
this.logger.verbose("After importBlock caching postState without SSZ cache", {slot:
|
|
502
|
+
if (!postBlockState.isStateValidatorsNodesPopulated()) {
|
|
503
|
+
this.logger.verbose("After importBlock caching postState without SSZ cache", {slot: postBlockState.slot});
|
|
482
504
|
}
|
|
483
505
|
|
|
484
506
|
// Cache shufflings when crossing an epoch boundary
|
|
485
507
|
const parentEpoch = computeEpochAtSlot(parentBlockSlot);
|
|
486
508
|
if (parentEpoch < blockEpoch) {
|
|
487
|
-
this.shufflingCache.processState(
|
|
509
|
+
this.shufflingCache.processState(postBlockState);
|
|
488
510
|
this.logger.verbose("Processed shuffling for next epoch", {parentEpoch, blockEpoch, slot: blockSlot});
|
|
489
511
|
}
|
|
490
512
|
|
|
491
513
|
if (blockSlot % SLOTS_PER_EPOCH === 0) {
|
|
492
514
|
// Cache state to preserve epoch transition work
|
|
493
|
-
const checkpointState =
|
|
515
|
+
const checkpointState = postBlockState;
|
|
494
516
|
const cp = getCheckpointFromState(checkpointState);
|
|
495
517
|
this.regen.addCheckpointState(cp, checkpointState, payloadPresent);
|
|
496
518
|
// consumers should not mutate state ever
|
|
@@ -580,11 +602,11 @@ export async function importBlock(
|
|
|
580
602
|
this.metrics?.parentBlockDistance.observe(blockSlot - parentBlockSlot);
|
|
581
603
|
this.metrics?.proposerBalanceDeltaAny.observe(fullyVerifiedBlock.proposerBalanceDelta);
|
|
582
604
|
this.validatorMonitor?.registerImportedBlock(block.message, fullyVerifiedBlock);
|
|
583
|
-
if (
|
|
605
|
+
if (isStatePostAltair(fullyVerifiedBlock.postBlockState)) {
|
|
584
606
|
this.validatorMonitor?.registerSyncAggregateInBlock(
|
|
585
607
|
blockEpoch,
|
|
586
608
|
(block as altair.SignedBeaconBlock).message.body.syncAggregate,
|
|
587
|
-
fullyVerifiedBlock.
|
|
609
|
+
fullyVerifiedBlock.postBlockState.currentSyncCommitteeIndexed.validatorIndices
|
|
588
610
|
);
|
|
589
611
|
}
|
|
590
612
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import {ExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
|
|
3
|
+
import {SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
4
|
+
import {getExecutionPayloadEnvelopeSignatureSet, isStatePostGloas} from "@lodestar/state-transition";
|
|
4
5
|
import {byteArrayEquals, fromHex, toRootHex} from "@lodestar/utils";
|
|
5
6
|
import {ExecutionPayloadStatus} from "../../execution/index.js";
|
|
6
7
|
import {isQueueErrorAborted} from "../../util/queue/index.js";
|
|
@@ -51,18 +52,33 @@ export class PayloadError extends Error {
|
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
function toForkChoiceExecutionStatus(status: ExecutionPayloadStatus): PayloadExecutionStatus {
|
|
56
|
+
switch (status) {
|
|
57
|
+
case ExecutionPayloadStatus.VALID:
|
|
58
|
+
return ExecutionStatus.Valid;
|
|
59
|
+
// TODO GLOAS: Handle optimistic import for payload
|
|
60
|
+
case ExecutionPayloadStatus.SYNCING:
|
|
61
|
+
case ExecutionPayloadStatus.ACCEPTED:
|
|
62
|
+
return ExecutionStatus.Syncing;
|
|
63
|
+
default:
|
|
64
|
+
throw new Error(`Unexpected execution payload status for fork choice: ${status}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
54
68
|
/**
|
|
55
69
|
* Import an execution payload envelope after all data is available.
|
|
56
70
|
*
|
|
57
71
|
* This function:
|
|
58
|
-
* 1.
|
|
59
|
-
* 2.
|
|
60
|
-
* 3.
|
|
61
|
-
* 4.
|
|
62
|
-
* 5.
|
|
63
|
-
* 6.
|
|
64
|
-
* 7.
|
|
65
|
-
* 8.
|
|
72
|
+
* 1. Emits `execution_payload_available` if payload is for current slot
|
|
73
|
+
* 2. Gets the ProtoBlock from fork choice
|
|
74
|
+
* 3. Applies write-queue backpressure (waitForSpace) early, before verification
|
|
75
|
+
* 4. Regenerates the block state
|
|
76
|
+
* 5. Runs EL verification (notifyNewPayload) in parallel with signature verification and processExecutionPayloadEnvelope
|
|
77
|
+
* 6. Persists verified payload envelope to hot DB
|
|
78
|
+
* 7. Updates fork choice
|
|
79
|
+
* 8. Caches the post-execution payload state
|
|
80
|
+
* 9. Records metrics for column sources
|
|
81
|
+
* 10. Emits `execution_payload` for recent enough payloads after successful import
|
|
66
82
|
*
|
|
67
83
|
*/
|
|
68
84
|
export async function importExecutionPayload(
|
|
@@ -70,10 +86,24 @@ export async function importExecutionPayload(
|
|
|
70
86
|
payloadInput: PayloadEnvelopeInput,
|
|
71
87
|
opts: ImportPayloadOpts = {}
|
|
72
88
|
): Promise<void> {
|
|
73
|
-
const
|
|
89
|
+
const signedEnvelope = payloadInput.getPayloadEnvelope();
|
|
90
|
+
const envelope = signedEnvelope.message;
|
|
74
91
|
const blockRootHex = payloadInput.blockRootHex;
|
|
92
|
+
const blockHashHex = payloadInput.getBlockHashHex();
|
|
93
|
+
const fork = this.config.getForkName(envelope.slot);
|
|
94
|
+
|
|
95
|
+
// 1. Emit `execution_payload_available` event at the start of import. At this point the payload input
|
|
96
|
+
// is already complete, so the payload and required data are available for payload attestation.
|
|
97
|
+
// This event is only about availability, not validity of the execution payload, hence we can emit
|
|
98
|
+
// it before getting a response from the execution client on whether the payload is valid or not.
|
|
99
|
+
if (this.clock.currentSlot - envelope.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
|
|
100
|
+
this.emitter.emit(routes.events.EventType.executionPayloadAvailable, {
|
|
101
|
+
slot: envelope.slot,
|
|
102
|
+
blockRoot: blockRootHex,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
75
105
|
|
|
76
|
-
//
|
|
106
|
+
// 2. Get ProtoBlock for parent root lookup
|
|
77
107
|
const protoBlock = this.forkChoice.getBlockHexDefaultStatus(blockRootHex);
|
|
78
108
|
if (!protoBlock) {
|
|
79
109
|
throw new PayloadError({
|
|
@@ -82,11 +112,11 @@ export async function importExecutionPayload(
|
|
|
82
112
|
});
|
|
83
113
|
}
|
|
84
114
|
|
|
85
|
-
//
|
|
115
|
+
// 3. Apply backpressure from the write queue early, before doing verification work.
|
|
86
116
|
// The actual DB write is deferred until after verification succeeds.
|
|
87
117
|
await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();
|
|
88
118
|
|
|
89
|
-
//
|
|
119
|
+
// 4. Get pre-state for processExecutionPayloadEnvelope
|
|
90
120
|
// We need the block state (post-block, pre-payload) to process the envelope
|
|
91
121
|
const blockState = await this.regen.getBlockSlotState(
|
|
92
122
|
protoBlock,
|
|
@@ -94,17 +124,23 @@ export async function importExecutionPayload(
|
|
|
94
124
|
{dontTransferCache: true},
|
|
95
125
|
RegenCaller.processBlock
|
|
96
126
|
);
|
|
127
|
+
if (!isStatePostGloas(blockState)) {
|
|
128
|
+
throw new PayloadError({
|
|
129
|
+
code: PayloadErrorCode.STATE_TRANSITION_ERROR,
|
|
130
|
+
message: `Expected gloas+ block state for payload import, got fork=${blockState.forkName}`,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
97
133
|
|
|
98
|
-
//
|
|
134
|
+
// 5. Run verification steps in parallel
|
|
99
135
|
// Note: No data availability check needed here - importExecutionPayload is only
|
|
100
136
|
// called when payloadInput.isComplete() is true, so all data is already available.
|
|
101
137
|
const [execResult, signatureValid, postPayloadResult] = await Promise.all([
|
|
102
138
|
this.executionEngine.notifyNewPayload(
|
|
103
|
-
|
|
104
|
-
envelope.
|
|
139
|
+
fork,
|
|
140
|
+
envelope.payload,
|
|
105
141
|
payloadInput.getVersionedHashes(),
|
|
106
142
|
fromHex(protoBlock.parentRoot),
|
|
107
|
-
envelope.
|
|
143
|
+
envelope.executionRequests
|
|
108
144
|
),
|
|
109
145
|
|
|
110
146
|
opts.validSignature === true
|
|
@@ -114,7 +150,7 @@ export async function importExecutionPayload(
|
|
|
114
150
|
this.config,
|
|
115
151
|
this.pubkeyCache,
|
|
116
152
|
blockState,
|
|
117
|
-
|
|
153
|
+
signedEnvelope,
|
|
118
154
|
payloadInput.proposerIndex
|
|
119
155
|
);
|
|
120
156
|
return this.bls.verifySignatureSets([signatureSet]);
|
|
@@ -125,7 +161,7 @@ export async function importExecutionPayload(
|
|
|
125
161
|
(async () => {
|
|
126
162
|
try {
|
|
127
163
|
return {
|
|
128
|
-
postPayloadState: blockState.processExecutionPayloadEnvelope(
|
|
164
|
+
postPayloadState: blockState.processExecutionPayloadEnvelope(signedEnvelope, {
|
|
129
165
|
verifySignature: false,
|
|
130
166
|
verifyStateRoot: false,
|
|
131
167
|
}),
|
|
@@ -142,12 +178,12 @@ export async function importExecutionPayload(
|
|
|
142
178
|
})(),
|
|
143
179
|
]);
|
|
144
180
|
|
|
145
|
-
//
|
|
181
|
+
// 5a. Check signature verification result
|
|
146
182
|
if (!signatureValid) {
|
|
147
183
|
throw new PayloadError({code: PayloadErrorCode.INVALID_SIGNATURE});
|
|
148
184
|
}
|
|
149
185
|
|
|
150
|
-
//
|
|
186
|
+
// 5b. Handle EL response
|
|
151
187
|
switch (execResult.status) {
|
|
152
188
|
case ExecutionPayloadStatus.VALID:
|
|
153
189
|
break;
|
|
@@ -161,12 +197,7 @@ export async function importExecutionPayload(
|
|
|
161
197
|
|
|
162
198
|
case ExecutionPayloadStatus.ACCEPTED:
|
|
163
199
|
case ExecutionPayloadStatus.SYNCING:
|
|
164
|
-
|
|
165
|
-
throw new PayloadError({
|
|
166
|
-
code: PayloadErrorCode.EXECUTION_ENGINE_ERROR,
|
|
167
|
-
execStatus: execResult.status,
|
|
168
|
-
errorMessage: execResult.validationError ?? "EL syncing, payload not yet validated",
|
|
169
|
-
});
|
|
200
|
+
break;
|
|
170
201
|
|
|
171
202
|
case ExecutionPayloadStatus.INVALID_BLOCK_HASH:
|
|
172
203
|
case ExecutionPayloadStatus.ELERROR:
|
|
@@ -178,59 +209,69 @@ export async function importExecutionPayload(
|
|
|
178
209
|
});
|
|
179
210
|
}
|
|
180
211
|
|
|
181
|
-
//
|
|
212
|
+
// 5c. Verify envelope state root matches post-state
|
|
182
213
|
const postPayloadState = postPayloadResult.postPayloadState;
|
|
183
214
|
const postPayloadStateRoot = postPayloadState.hashTreeRoot();
|
|
184
|
-
if (!byteArrayEquals(envelope.
|
|
215
|
+
if (!byteArrayEquals(envelope.stateRoot, postPayloadStateRoot)) {
|
|
185
216
|
throw new PayloadError({
|
|
186
217
|
code: PayloadErrorCode.STATE_TRANSITION_ERROR,
|
|
187
|
-
message: `Envelope state root mismatch expected=${toRootHex(envelope.
|
|
218
|
+
message: `Envelope state root mismatch expected=${toRootHex(envelope.stateRoot)} actual=${toRootHex(postPayloadStateRoot)}`,
|
|
188
219
|
});
|
|
189
220
|
}
|
|
190
221
|
|
|
191
|
-
//
|
|
222
|
+
// 6. Persist payload envelope to hot DB (performed asynchronously to avoid blocking)
|
|
192
223
|
this.unfinalizedPayloadEnvelopeWrites.push(payloadInput).catch((e) => {
|
|
193
224
|
if (!isQueueErrorAborted(e)) {
|
|
194
225
|
this.logger.error(
|
|
195
226
|
"Error pushing payload envelope to unfinalized write queue",
|
|
196
|
-
{slot:
|
|
227
|
+
{slot: envelope.slot, blockRoot: blockRootHex},
|
|
197
228
|
e as Error
|
|
198
229
|
);
|
|
199
230
|
}
|
|
200
231
|
});
|
|
201
232
|
|
|
202
|
-
//
|
|
233
|
+
// 7. Update fork choice
|
|
203
234
|
this.forkChoice.onExecutionPayload(
|
|
204
235
|
blockRootHex,
|
|
205
|
-
|
|
206
|
-
envelope.
|
|
207
|
-
toRootHex(postPayloadStateRoot)
|
|
236
|
+
blockHashHex,
|
|
237
|
+
envelope.payload.blockNumber,
|
|
238
|
+
toRootHex(postPayloadStateRoot),
|
|
239
|
+
toForkChoiceExecutionStatus(execResult.status)
|
|
208
240
|
);
|
|
209
241
|
|
|
210
|
-
//
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
242
|
+
// 8. Cache payload state
|
|
243
|
+
this.regen.processPayloadState(postPayloadState);
|
|
244
|
+
if (postPayloadState.slot % SLOTS_PER_EPOCH === 0) {
|
|
245
|
+
const {checkpoint} = postPayloadState.computeAnchorCheckpoint();
|
|
246
|
+
this.regen.addCheckpointState(checkpoint, postPayloadState, true);
|
|
247
|
+
}
|
|
215
248
|
|
|
216
|
-
//
|
|
249
|
+
// 9. Record metrics for payload envelope and column sources
|
|
217
250
|
this.metrics?.importPayload.bySource.inc({source: payloadInput.getPayloadEnvelopeSource().source});
|
|
218
251
|
for (const {source} of payloadInput.getSampledColumnsWithSource()) {
|
|
219
252
|
this.metrics?.importPayload.columnsBySource.inc({source});
|
|
220
253
|
}
|
|
221
254
|
|
|
222
|
-
|
|
223
|
-
slot: payloadInput.slot,
|
|
224
|
-
root: blockRootHex,
|
|
225
|
-
blockHash: payloadInput.getBlockHashHex(),
|
|
226
|
-
});
|
|
255
|
+
const stateRootHex = toRootHex(envelope.stateRoot);
|
|
227
256
|
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
257
|
+
// 10. Emit event after payload is fully verified and imported to fork choice, only for recent enough payloads
|
|
258
|
+
if (this.clock.currentSlot - envelope.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
|
|
259
|
+
this.emitter.emit(routes.events.EventType.executionPayload, {
|
|
260
|
+
slot: envelope.slot,
|
|
261
|
+
builderIndex: envelope.builderIndex,
|
|
262
|
+
blockHash: blockHashHex,
|
|
233
263
|
blockRoot: blockRootHex,
|
|
264
|
+
stateRoot: stateRootHex,
|
|
265
|
+
// TODO GLOAS: revisit once we support optimistic import
|
|
266
|
+
executionOptimistic: false,
|
|
234
267
|
});
|
|
235
268
|
}
|
|
269
|
+
|
|
270
|
+
this.logger.verbose("Execution payload imported", {
|
|
271
|
+
slot: envelope.slot,
|
|
272
|
+
builderIndex: envelope.builderIndex,
|
|
273
|
+
blockRoot: blockRootHex,
|
|
274
|
+
blockHash: blockHashHex,
|
|
275
|
+
stateRoot: stateRootHex,
|
|
276
|
+
});
|
|
236
277
|
}
|
|
@@ -88,7 +88,8 @@ export async function processBlocks(
|
|
|
88
88
|
const fullyVerifiedBlocks = relevantBlocks.map(
|
|
89
89
|
(block, i): FullyVerifiedBlock => ({
|
|
90
90
|
blockInput: block,
|
|
91
|
-
|
|
91
|
+
postBlockState: postStates[i],
|
|
92
|
+
postPayloadState: null,
|
|
92
93
|
parentBlockSlot: parentSlots[i],
|
|
93
94
|
executionStatus: executionStatuses[i],
|
|
94
95
|
// start supporting optimistic syncing/processing
|