@lodestar/beacon-node 1.41.0 → 1.42.0-dev.4118b5b440
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 +35 -16
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +2 -2
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +6 -2
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +0 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +0 -9
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/interface.d.ts +4 -4
- package/lib/chain/archiveStore/interface.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +4 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +38 -0
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/blocks/blockInput/types.d.ts +4 -3
- package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/types.js +1 -0
- package/lib/chain/blocks/blockInput/types.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +29 -9
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +48 -0
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -0
- package/lib/chain/blocks/importExecutionPayload.js +159 -0
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/index.d.ts +3 -0
- package/lib/chain/blocks/payloadEnvelopeInput/index.d.ts.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/index.js +3 -0
- package/lib/chain/blocks/payloadEnvelopeInput/index.js.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +80 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +248 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +29 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.js +11 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.js.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +15 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.js +46 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -0
- package/lib/chain/blocks/types.d.ts +7 -0
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +12 -0
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -0
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +40 -0
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -0
- package/lib/chain/chain.d.ts +10 -5
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +44 -10
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +12 -2
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.js +3 -1
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +0 -10
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +8 -5
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/opPools/utils.js +1 -1
- package/lib/chain/opPools/utils.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +6 -2
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +6 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/errors.d.ts +11 -1
- package/lib/chain/regen/errors.d.ts.map +1 -1
- package/lib/chain/regen/errors.js +2 -0
- package/lib/chain/regen/errors.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +14 -6
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +2 -0
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts +11 -6
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +40 -8
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts +5 -0
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +33 -6
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/index.d.ts +1 -1
- package/lib/chain/seenCache/index.d.ts.map +1 -1
- package/lib/chain/seenCache/index.js +1 -1
- package/lib/chain/seenCache/index.js.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 +38 -0
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -0
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +76 -0
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -0
- package/lib/chain/stateCache/datastore/db.d.ts +4 -5
- package/lib/chain/stateCache/datastore/db.d.ts.map +1 -1
- package/lib/chain/stateCache/datastore/db.js +32 -10
- package/lib/chain/stateCache/datastore/db.js.map +1 -1
- package/lib/chain/stateCache/datastore/file.d.ts +1 -1
- package/lib/chain/stateCache/datastore/file.d.ts.map +1 -1
- package/lib/chain/stateCache/datastore/file.js +5 -5
- package/lib/chain/stateCache/datastore/file.js.map +1 -1
- package/lib/chain/stateCache/datastore/types.d.ts +1 -1
- package/lib/chain/stateCache/datastore/types.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts +7 -4
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.js +8 -3
- package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +33 -14
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +217 -119
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +15 -8
- package/lib/chain/stateCache/types.d.ts.map +1 -1
- package/lib/chain/stateCache/types.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +30 -19
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/lightClientFinalityUpdate.js +1 -1
- package/lib/chain/validation/lightClientFinalityUpdate.js.map +1 -1
- package/lib/chain/validation/lightClientOptimisticUpdate.js +1 -1
- package/lib/chain/validation/lightClientOptimisticUpdate.js.map +1 -1
- package/lib/chain/validation/syncCommittee.d.ts +2 -2
- package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
- package/lib/chain/validation/syncCommittee.js +12 -11
- package/lib/chain/validation/syncCommittee.js.map +1 -1
- package/lib/chain/validation/voluntaryExit.d.ts.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +2 -2
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts +2 -1
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +4 -1
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +2 -2
- package/lib/metrics/metrics/lodestar.d.ts +40 -4
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +93 -15
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/encoding.d.ts.map +1 -1
- package/lib/network/gossip/encoding.js +15 -0
- package/lib/network/gossip/encoding.js.map +1 -1
- package/lib/network/interface.d.ts +1 -1
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/network.d.ts +1 -1
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +4 -4
- package/lib/network/network.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 +15 -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 +39 -9
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/index.d.ts +12 -7
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +99 -78
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.d.ts +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.js +1 -1
- package/lib/sync/backfill/backfill.d.ts +1 -1
- package/lib/sync/backfill/backfill.js +1 -1
- package/lib/sync/constants.d.ts +1 -1
- package/lib/sync/constants.js +1 -1
- package/lib/sync/unknownBlock.d.ts +3 -9
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +8 -41
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/util/sszBytes.d.ts +4 -1
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +69 -12
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/beacon/blocks/index.ts +36 -17
- package/src/api/impl/beacon/state/utils.ts +2 -2
- package/src/api/impl/validator/index.ts +8 -4
- package/src/chain/archiveStore/archiveStore.ts +0 -10
- package/src/chain/archiveStore/interface.ts +4 -4
- package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +8 -5
- package/src/chain/archiveStore/utils/archiveBlocks.ts +59 -1
- package/src/chain/blocks/blockInput/types.ts +4 -3
- package/src/chain/blocks/importBlock.ts +47 -8
- package/src/chain/blocks/importExecutionPayload.ts +241 -0
- package/src/chain/blocks/payloadEnvelopeInput/index.ts +2 -0
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +336 -0
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +33 -0
- package/src/chain/blocks/payloadEnvelopeProcessor.ts +61 -0
- package/src/chain/blocks/types.ts +8 -0
- package/src/chain/blocks/verifyBlocksSignatures.ts +1 -1
- package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +55 -0
- package/src/chain/chain.ts +60 -15
- package/src/chain/errors/executionPayloadEnvelope.ts +6 -2
- package/src/chain/forkChoice/index.ts +0 -10
- package/src/chain/interface.ts +8 -5
- package/src/chain/opPools/utils.ts +1 -1
- package/src/chain/prepareNextSlot.ts +6 -2
- package/src/chain/produceBlock/computeNewStateRoot.ts +6 -1
- package/src/chain/produceBlock/produceBlockBody.ts +1 -1
- package/src/chain/regen/errors.ts +6 -1
- package/src/chain/regen/interface.ts +14 -6
- package/src/chain/regen/queued.ts +48 -12
- package/src/chain/regen/regen.ts +37 -7
- package/src/chain/seenCache/index.ts +1 -1
- package/src/chain/seenCache/seenGossipBlockInput.ts +2 -2
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +106 -0
- package/src/chain/stateCache/datastore/db.ts +33 -10
- package/src/chain/stateCache/datastore/file.ts +6 -5
- package/src/chain/stateCache/datastore/types.ts +3 -2
- package/src/chain/stateCache/fifoBlockStateCache.ts +10 -4
- package/src/chain/stateCache/persistentCheckpointsCache.ts +248 -139
- package/src/chain/stateCache/types.ts +18 -8
- package/src/chain/validation/executionPayloadEnvelope.ts +38 -25
- package/src/chain/validation/lightClientFinalityUpdate.ts +1 -1
- package/src/chain/validation/lightClientOptimisticUpdate.ts +1 -1
- package/src/chain/validation/syncCommittee.ts +15 -14
- package/src/chain/validation/voluntaryExit.ts +2 -1
- package/src/chain/validatorMonitor.ts +11 -1
- package/src/execution/engine/interface.ts +2 -2
- package/src/metrics/metrics/lodestar.ts +100 -19
- package/src/network/gossip/encoding.ts +16 -0
- package/src/network/interface.ts +1 -1
- package/src/network/network.ts +4 -4
- package/src/network/processor/extractSlotRootFns.ts +19 -6
- package/src/network/processor/gossipHandlers.ts +45 -8
- package/src/network/processor/index.ts +110 -89
- package/src/network/reqresp/ReqRespBeaconNode.ts +1 -1
- package/src/sync/backfill/backfill.ts +1 -1
- package/src/sync/constants.ts +1 -1
- package/src/sync/unknownBlock.ts +10 -50
- package/src/util/sszBytes.ts +90 -10
- package/lib/chain/archiveStore/utils/archivePayloads.d.ts +0 -7
- package/lib/chain/archiveStore/utils/archivePayloads.d.ts.map +0 -1
- package/lib/chain/archiveStore/utils/archivePayloads.js +0 -10
- package/lib/chain/archiveStore/utils/archivePayloads.js.map +0 -1
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts +0 -15
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts.map +0 -1
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js +0 -28
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js.map +0 -1
- package/src/chain/archiveStore/utils/archivePayloads.ts +0 -15
- package/src/chain/seenCache/seenExecutionPayloadEnvelope.ts +0 -34
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {CheckpointWithPayloadStatus} from "@lodestar/fork-choice";
|
|
2
2
|
import {SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
3
3
|
import {computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
4
4
|
import {Epoch, RootHex, Slot} from "@lodestar/types";
|
|
@@ -9,6 +9,7 @@ import {AllocSource, BufferPool} from "../../../util/bufferPool.js";
|
|
|
9
9
|
import {getStateSlotFromBytes} from "../../../util/multifork.js";
|
|
10
10
|
import {IStateRegenerator} from "../../regen/interface.js";
|
|
11
11
|
import {serializeState} from "../../serializeState.js";
|
|
12
|
+
import {fcCheckpointToHexPayload} from "../../stateCache/persistentCheckpointsCache.js";
|
|
12
13
|
import {StateArchiveStrategy, StatesArchiveOpts} from "../interface.js";
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -40,7 +41,7 @@ export class FrequencyStateArchiveStrategy implements StateArchiveStrategy {
|
|
|
40
41
|
private readonly bufferPool?: BufferPool | null
|
|
41
42
|
) {}
|
|
42
43
|
|
|
43
|
-
async onFinalizedCheckpoint(_finalized:
|
|
44
|
+
async onFinalizedCheckpoint(_finalized: CheckpointWithPayloadStatus, _metrics?: Metrics | null): Promise<void> {}
|
|
44
45
|
async onCheckpoint(_stateRoot: RootHex, _metrics?: Metrics | null): Promise<void> {}
|
|
45
46
|
|
|
46
47
|
/**
|
|
@@ -55,7 +56,7 @@ export class FrequencyStateArchiveStrategy implements StateArchiveStrategy {
|
|
|
55
56
|
* epoch - 1024*2 epoch - 1024 epoch - 32 epoch
|
|
56
57
|
* ```
|
|
57
58
|
*/
|
|
58
|
-
async maybeArchiveState(finalized:
|
|
59
|
+
async maybeArchiveState(finalized: CheckpointWithPayloadStatus, metrics?: Metrics | null): Promise<void> {
|
|
59
60
|
let timer = metrics?.processFinalizedCheckpoint.frequencyStateArchive.startTimer();
|
|
60
61
|
const lastStoredSlot = await this.db.stateArchive.lastKey();
|
|
61
62
|
timer?.({step: FrequencyStateArchiveStep.LoadLastStoredSlot});
|
|
@@ -104,10 +105,12 @@ export class FrequencyStateArchiveStrategy implements StateArchiveStrategy {
|
|
|
104
105
|
* Archives finalized states from active bucket to archive bucket.
|
|
105
106
|
* Only the new finalized state is stored to disk
|
|
106
107
|
*/
|
|
107
|
-
async archiveState(finalized:
|
|
108
|
+
async archiveState(finalized: CheckpointWithPayloadStatus, metrics?: Metrics | null): Promise<void> {
|
|
108
109
|
// starting from Mar 2024, the finalized state could be from disk or in memory
|
|
109
110
|
let timer = metrics?.processFinalizedCheckpoint.frequencyStateArchive.startTimer();
|
|
110
|
-
|
|
111
|
+
// Convert fork-choice checkpoint to beacon-node checkpoint with payloadPresent
|
|
112
|
+
const finalizedHexPayload = fcCheckpointToHexPayload(finalized);
|
|
113
|
+
const finalizedStateOrBytes = await this.regen.getCheckpointStateOrBytes(finalizedHexPayload);
|
|
111
114
|
timer?.({step: FrequencyStateArchiveStep.GetFinalizedState});
|
|
112
115
|
|
|
113
116
|
const {rootHex} = finalized;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import {ChainForkConfig} from "@lodestar/config";
|
|
3
3
|
import {KeyValue} from "@lodestar/db";
|
|
4
|
-
import {CheckpointWithPayloadStatus, IForkChoice} from "@lodestar/fork-choice";
|
|
4
|
+
import {CheckpointWithPayloadStatus, IForkChoice, PayloadStatus, ProtoBlock} from "@lodestar/fork-choice";
|
|
5
5
|
import {ForkSeq, SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
6
6
|
import {computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
7
7
|
import {Epoch, Slot} from "@lodestar/types";
|
|
@@ -66,6 +66,7 @@ export async function archiveBlocks(
|
|
|
66
66
|
// NOTE: The finalized block will be exactly the first block of `epoch` or previous
|
|
67
67
|
const finalizedPostDeneb = finalizedCheckpoint.epoch >= config.DENEB_FORK_EPOCH;
|
|
68
68
|
const finalizedPostFulu = finalizedCheckpoint.epoch >= config.FULU_FORK_EPOCH;
|
|
69
|
+
const finalizedPostGloas = finalizedCheckpoint.epoch >= config.GLOAS_FORK_EPOCH;
|
|
69
70
|
|
|
70
71
|
const finalizedCanonicalBlockRoots: BlockRootSlot[] = finalizedCanonicalBlocks.map((block) => ({
|
|
71
72
|
slot: block.slot,
|
|
@@ -103,6 +104,16 @@ export async function archiveBlocks(
|
|
|
103
104
|
);
|
|
104
105
|
logger.verbose("Migrated dataColumnSidecars from hot DB to cold DB", {...logCtx, migratedEntries});
|
|
105
106
|
}
|
|
107
|
+
|
|
108
|
+
if (finalizedPostGloas) {
|
|
109
|
+
const migratedEntries = await migrateExecutionPayloadEnvelopesFromHotToColdDb(
|
|
110
|
+
config,
|
|
111
|
+
db,
|
|
112
|
+
logger,
|
|
113
|
+
finalizedCanonicalBlocks
|
|
114
|
+
);
|
|
115
|
+
logger.verbose("Migrated executionPayloadEnvelopes from hot DB to cold DB", {...logCtx, migratedEntries});
|
|
116
|
+
}
|
|
106
117
|
}
|
|
107
118
|
|
|
108
119
|
// deleteNonCanonicalBlocks
|
|
@@ -144,6 +155,11 @@ export async function archiveBlocks(
|
|
|
144
155
|
await db.dataColumnSidecar.deleteMany(nonCanonicalBlockRoots);
|
|
145
156
|
logger.verbose("Deleted non canonical dataColumnSidecars from hot DB", logCtx);
|
|
146
157
|
}
|
|
158
|
+
|
|
159
|
+
if (finalizedPostGloas) {
|
|
160
|
+
await db.executionPayloadEnvelope.batchDelete(nonCanonicalBlockRoots);
|
|
161
|
+
logger.verbose("Deleted non canonical executionPayloadEnvelopes from hot DB", logCtx);
|
|
162
|
+
}
|
|
147
163
|
}
|
|
148
164
|
|
|
149
165
|
// Delete expired blobs
|
|
@@ -372,6 +388,48 @@ async function migrateDataColumnSidecarsFromHotToColdDb(
|
|
|
372
388
|
return migratedWrappedDataColumns;
|
|
373
389
|
}
|
|
374
390
|
|
|
391
|
+
async function migrateExecutionPayloadEnvelopesFromHotToColdDb(
|
|
392
|
+
config: ChainForkConfig,
|
|
393
|
+
db: IBeaconDb,
|
|
394
|
+
logger: Logger,
|
|
395
|
+
canonicalBlocks: ProtoBlock[]
|
|
396
|
+
): Promise<number> {
|
|
397
|
+
let migratedEnvelopes = 0;
|
|
398
|
+
|
|
399
|
+
const payloadBlocks = canonicalBlocks.filter(
|
|
400
|
+
(block) => config.getForkSeq(block.slot) >= ForkSeq.gloas && block.payloadStatus === PayloadStatus.FULL
|
|
401
|
+
);
|
|
402
|
+
if (payloadBlocks.length === 0) return 0;
|
|
403
|
+
const blocks = payloadBlocks.map((block) => ({slot: block.slot, root: fromHex(block.blockRoot)}));
|
|
404
|
+
|
|
405
|
+
const envelopeEntries: KeyValue<Slot, Uint8Array>[] = [];
|
|
406
|
+
const migratedRoots: Uint8Array[] = [];
|
|
407
|
+
|
|
408
|
+
const envelopeBytesArray = await Promise.all(
|
|
409
|
+
blocks.map((block) => db.executionPayloadEnvelope.getBinary(block.root))
|
|
410
|
+
);
|
|
411
|
+
|
|
412
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
413
|
+
const bytes = envelopeBytesArray[i];
|
|
414
|
+
if (bytes !== null) {
|
|
415
|
+
envelopeEntries.push({key: blocks[i].slot, value: bytes});
|
|
416
|
+
migratedRoots.push(blocks[i].root);
|
|
417
|
+
} else {
|
|
418
|
+
logger.debug("Payload in forkchoice but missing in db", {slot: blocks[i].slot, root: toRootHex(blocks[i].root)});
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (envelopeEntries.length > 0) {
|
|
423
|
+
await Promise.all([
|
|
424
|
+
db.executionPayloadEnvelopeArchive.batchPutBinary(envelopeEntries),
|
|
425
|
+
db.executionPayloadEnvelope.batchDelete(migratedRoots),
|
|
426
|
+
]);
|
|
427
|
+
migratedEnvelopes = envelopeEntries.length;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
return migratedEnvelopes;
|
|
431
|
+
}
|
|
432
|
+
|
|
375
433
|
/**
|
|
376
434
|
* ```
|
|
377
435
|
* class SignedBeaconBlock(Container):
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {ForkName} from "@lodestar/params";
|
|
2
|
-
import {ColumnIndex, RootHex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
|
|
2
|
+
import {ColumnIndex, DataColumnSidecars, RootHex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
|
|
3
3
|
import {VersionedHashes} from "../../../execution/index.js";
|
|
4
4
|
|
|
5
5
|
export enum DAType {
|
|
@@ -16,6 +16,7 @@ export type DAData = null | deneb.BlobSidecars | fulu.DataColumnSidecars;
|
|
|
16
16
|
* sources so each should be labelled individually.
|
|
17
17
|
*/
|
|
18
18
|
export enum BlockInputSource {
|
|
19
|
+
network_processor = "network_processor",
|
|
19
20
|
gossip = "gossip",
|
|
20
21
|
api = "api",
|
|
21
22
|
engine = "engine",
|
|
@@ -107,9 +108,9 @@ export type MissingColumnMeta = {
|
|
|
107
108
|
export interface IDataColumnsInput {
|
|
108
109
|
readonly slot: Slot;
|
|
109
110
|
readonly blockRootHex: string;
|
|
110
|
-
getCustodyColumns():
|
|
111
|
+
getCustodyColumns(): DataColumnSidecars;
|
|
111
112
|
hasComputedAllData(): boolean;
|
|
112
|
-
waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<
|
|
113
|
+
waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<DataColumnSidecars>;
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
/**
|
|
@@ -7,8 +7,16 @@ import {
|
|
|
7
7
|
ForkChoiceErrorCode,
|
|
8
8
|
NotReorgedReason,
|
|
9
9
|
getSafeExecutionBlockHash,
|
|
10
|
+
isGloasBlock,
|
|
10
11
|
} from "@lodestar/fork-choice";
|
|
11
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
ForkPostAltair,
|
|
14
|
+
ForkPostElectra,
|
|
15
|
+
ForkPostGloas,
|
|
16
|
+
ForkSeq,
|
|
17
|
+
MAX_SEED_LOOKAHEAD,
|
|
18
|
+
SLOTS_PER_EPOCH,
|
|
19
|
+
} from "@lodestar/params";
|
|
12
20
|
import {
|
|
13
21
|
CachedBeaconStateAltair,
|
|
14
22
|
EpochCache,
|
|
@@ -20,7 +28,17 @@ import {
|
|
|
20
28
|
isStartSlotOfEpoch,
|
|
21
29
|
isStateValidatorsNodesPopulated,
|
|
22
30
|
} from "@lodestar/state-transition";
|
|
23
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
Attestation,
|
|
33
|
+
BeaconBlock,
|
|
34
|
+
SignedBeaconBlock,
|
|
35
|
+
altair,
|
|
36
|
+
capella,
|
|
37
|
+
electra,
|
|
38
|
+
isGloasBeaconBlock,
|
|
39
|
+
phase0,
|
|
40
|
+
ssz,
|
|
41
|
+
} from "@lodestar/types";
|
|
24
42
|
import {isErrorAborted, toRootHex} from "@lodestar/utils";
|
|
25
43
|
import {ZERO_HASH_HEX} from "../../constants/index.js";
|
|
26
44
|
import {callInNextEventLoop} from "../../util/eventLoop.js";
|
|
@@ -30,7 +48,7 @@ import type {BeaconChain} from "../chain.js";
|
|
|
30
48
|
import {ChainEvent, ReorgEventData} from "../emitter.js";
|
|
31
49
|
import {ForkchoiceCaller} from "../forkChoice/index.js";
|
|
32
50
|
import {REPROCESS_MIN_TIME_TO_NEXT_SLOT_SEC} from "../reprocess.js";
|
|
33
|
-
import {
|
|
51
|
+
import {toCheckpointHexPayload} from "../stateCache/persistentCheckpointsCache.js";
|
|
34
52
|
import {isBlockInputBlobs, isBlockInputColumns} from "./blockInput/blockInput.js";
|
|
35
53
|
import {AttestationImportOpt, FullyVerifiedBlock, ImportBlockOpts} from "./types.js";
|
|
36
54
|
import {getCheckpointFromState} from "./utils/checkpoint.js";
|
|
@@ -116,7 +134,28 @@ export async function importBlock(
|
|
|
116
134
|
|
|
117
135
|
// This adds the state necessary to process the next block
|
|
118
136
|
// Some block event handlers require state being in state cache so need to do this before emitting EventType.block
|
|
119
|
-
|
|
137
|
+
// Pre-Gloas: blockSummary.payloadStatus is always FULL, payloadPresent = true
|
|
138
|
+
// Post-Gloas: blockSummary.payloadStatus is always PENDING, so payloadPresent = false (block state only, no payload processing yet)
|
|
139
|
+
const payloadPresent = !isGloasBlock(blockSummary);
|
|
140
|
+
// processState manages both block state and payload state variants together for memory/disk management
|
|
141
|
+
this.regen.processBlockState(blockRootHex, postState);
|
|
142
|
+
|
|
143
|
+
// For Gloas blocks, create PayloadEnvelopeInput so it's available for later payload import
|
|
144
|
+
if (fork >= ForkSeq.gloas) {
|
|
145
|
+
this.seenPayloadEnvelopeInputCache.add({
|
|
146
|
+
blockRootHex,
|
|
147
|
+
block: block as SignedBeaconBlock<ForkPostGloas>,
|
|
148
|
+
sampledColumns: this.custodyConfig.sampledColumns,
|
|
149
|
+
custodyColumns: this.custodyConfig.custodyColumns,
|
|
150
|
+
timeCreatedSec: fullyVerifiedBlock.seenTimestampSec,
|
|
151
|
+
});
|
|
152
|
+
this.logger.debug("Created PayloadEnvelopeInput for block", {
|
|
153
|
+
slot: blockSlot,
|
|
154
|
+
root: blockRootHex,
|
|
155
|
+
source: source.source,
|
|
156
|
+
...(opts.seenTimestampSec !== undefined ? {recvToImport: Date.now() / 1000 - opts.seenTimestampSec} : {}),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
120
159
|
|
|
121
160
|
this.metrics?.importBlock.bySource.inc({source: source.source});
|
|
122
161
|
this.logger.verbose("Added block to forkchoice and state cache", {slot: blockSlot, root: blockRootHex});
|
|
@@ -456,12 +495,12 @@ export async function importBlock(
|
|
|
456
495
|
// Cache state to preserve epoch transition work
|
|
457
496
|
const checkpointState = postState;
|
|
458
497
|
const cp = getCheckpointFromState(checkpointState);
|
|
459
|
-
this.regen.addCheckpointState(cp, checkpointState);
|
|
498
|
+
this.regen.addCheckpointState(cp, checkpointState, payloadPresent);
|
|
460
499
|
// consumers should not mutate state ever
|
|
461
500
|
this.emitter.emit(ChainEvent.checkpoint, cp, checkpointState);
|
|
462
501
|
|
|
463
502
|
// Note: in-lined code from previos handler of ChainEvent.checkpoint
|
|
464
|
-
this.logger.verbose("Checkpoint processed",
|
|
503
|
+
this.logger.verbose("Checkpoint processed", toCheckpointHexPayload(cp, payloadPresent));
|
|
465
504
|
|
|
466
505
|
const activeValidatorsCount = checkpointState.epochCtx.currentShuffling.activeIndices.length;
|
|
467
506
|
this.metrics?.currentActiveValidators.set(activeValidatorsCount);
|
|
@@ -479,7 +518,7 @@ export async function importBlock(
|
|
|
479
518
|
const justifiedEpoch = justifiedCheckpoint.epoch;
|
|
480
519
|
const preJustifiedEpoch = parentBlockSummary.justifiedEpoch;
|
|
481
520
|
if (justifiedEpoch > preJustifiedEpoch) {
|
|
482
|
-
this.logger.verbose("Checkpoint justified",
|
|
521
|
+
this.logger.verbose("Checkpoint justified", toCheckpointHexPayload(justifiedCheckpoint, payloadPresent));
|
|
483
522
|
this.metrics?.previousJustifiedEpoch.set(checkpointState.previousJustifiedCheckpoint.epoch);
|
|
484
523
|
this.metrics?.currentJustifiedEpoch.set(justifiedCheckpoint.epoch);
|
|
485
524
|
}
|
|
@@ -493,7 +532,7 @@ export async function importBlock(
|
|
|
493
532
|
state: toRootHex(checkpointState.hashTreeRoot()),
|
|
494
533
|
executionOptimistic: false,
|
|
495
534
|
});
|
|
496
|
-
this.logger.verbose("Checkpoint finalized",
|
|
535
|
+
this.logger.verbose("Checkpoint finalized", toCheckpointHexPayload(finalizedCheckpoint, payloadPresent));
|
|
497
536
|
this.metrics?.finalizedEpoch.set(finalizedCheckpoint.epoch);
|
|
498
537
|
}
|
|
499
538
|
}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import {routes} from "@lodestar/api";
|
|
2
|
+
import {ForkName} from "@lodestar/params";
|
|
3
|
+
import {
|
|
4
|
+
BeaconStateView,
|
|
5
|
+
CachedBeaconStateGloas,
|
|
6
|
+
getExecutionPayloadEnvelopeSignatureSet,
|
|
7
|
+
} from "@lodestar/state-transition";
|
|
8
|
+
import {processExecutionPayloadEnvelope} from "@lodestar/state-transition/block";
|
|
9
|
+
import {byteArrayEquals, fromHex, toRootHex} from "@lodestar/utils";
|
|
10
|
+
import {ExecutionPayloadStatus} from "../../execution/index.js";
|
|
11
|
+
import {isQueueErrorAborted} from "../../util/queue/index.js";
|
|
12
|
+
import {BeaconChain} from "../chain.js";
|
|
13
|
+
import {RegenCaller} from "../regen/interface.js";
|
|
14
|
+
import {PayloadEnvelopeInput} from "../seenCache/seenPayloadEnvelopeInput.js";
|
|
15
|
+
import {ImportPayloadOpts} from "./types.js";
|
|
16
|
+
|
|
17
|
+
const EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS = 64;
|
|
18
|
+
|
|
19
|
+
export enum PayloadErrorCode {
|
|
20
|
+
EXECUTION_ENGINE_INVALID = "PAYLOAD_ERROR_EXECUTION_ENGINE_INVALID",
|
|
21
|
+
EXECUTION_ENGINE_ERROR = "PAYLOAD_ERROR_EXECUTION_ENGINE_ERROR",
|
|
22
|
+
BLOCK_NOT_IN_FORK_CHOICE = "PAYLOAD_ERROR_BLOCK_NOT_IN_FORK_CHOICE",
|
|
23
|
+
STATE_TRANSITION_ERROR = "PAYLOAD_ERROR_STATE_TRANSITION_ERROR",
|
|
24
|
+
INVALID_SIGNATURE = "PAYLOAD_ERROR_INVALID_SIGNATURE",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type PayloadErrorType =
|
|
28
|
+
| {
|
|
29
|
+
code: PayloadErrorCode.EXECUTION_ENGINE_INVALID;
|
|
30
|
+
execStatus: ExecutionPayloadStatus;
|
|
31
|
+
errorMessage: string;
|
|
32
|
+
}
|
|
33
|
+
| {
|
|
34
|
+
code: PayloadErrorCode.EXECUTION_ENGINE_ERROR;
|
|
35
|
+
execStatus: ExecutionPayloadStatus;
|
|
36
|
+
errorMessage: string;
|
|
37
|
+
}
|
|
38
|
+
| {
|
|
39
|
+
code: PayloadErrorCode.BLOCK_NOT_IN_FORK_CHOICE;
|
|
40
|
+
blockRootHex: string;
|
|
41
|
+
}
|
|
42
|
+
| {
|
|
43
|
+
code: PayloadErrorCode.STATE_TRANSITION_ERROR;
|
|
44
|
+
message: string;
|
|
45
|
+
}
|
|
46
|
+
| {
|
|
47
|
+
code: PayloadErrorCode.INVALID_SIGNATURE;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export class PayloadError extends Error {
|
|
51
|
+
type: PayloadErrorType;
|
|
52
|
+
|
|
53
|
+
constructor(type: PayloadErrorType, message?: string) {
|
|
54
|
+
super(message ?? type.code);
|
|
55
|
+
this.type = type;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Import an execution payload envelope after all data is available.
|
|
61
|
+
*
|
|
62
|
+
* This function:
|
|
63
|
+
* 1. Gets the ProtoBlock from fork choice
|
|
64
|
+
* 2. Applies write-queue backpressure (waitForSpace) early, before verification
|
|
65
|
+
* 3. Regenerates the block state
|
|
66
|
+
* 4. Runs EL verification (notifyNewPayload) in parallel with signature verification and processExecutionPayloadEnvelope
|
|
67
|
+
* 5. Persists verified payload envelope to hot DB
|
|
68
|
+
* 6. Updates fork choice
|
|
69
|
+
* 7. Caches the post-execution payload state
|
|
70
|
+
* 8. Records metrics for column sources
|
|
71
|
+
*
|
|
72
|
+
*/
|
|
73
|
+
export async function importExecutionPayload(
|
|
74
|
+
this: BeaconChain,
|
|
75
|
+
payloadInput: PayloadEnvelopeInput,
|
|
76
|
+
opts: ImportPayloadOpts = {}
|
|
77
|
+
): Promise<void> {
|
|
78
|
+
const envelope = payloadInput.getPayloadEnvelope();
|
|
79
|
+
const blockRootHex = payloadInput.blockRootHex;
|
|
80
|
+
|
|
81
|
+
// 1. Get ProtoBlock for parent root lookup
|
|
82
|
+
const protoBlock = this.forkChoice.getBlockHexDefaultStatus(blockRootHex);
|
|
83
|
+
if (!protoBlock) {
|
|
84
|
+
throw new PayloadError({
|
|
85
|
+
code: PayloadErrorCode.BLOCK_NOT_IN_FORK_CHOICE,
|
|
86
|
+
blockRootHex,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 2. Apply backpressure from the write queue early, before doing verification work.
|
|
91
|
+
// The actual DB write is deferred until after verification succeeds.
|
|
92
|
+
await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();
|
|
93
|
+
|
|
94
|
+
// 3. Get pre-state for processExecutionPayloadEnvelope
|
|
95
|
+
// We need the block state (post-block, pre-payload) to process the envelope
|
|
96
|
+
const blockState = (await this.regen.getBlockSlotState(
|
|
97
|
+
protoBlock,
|
|
98
|
+
protoBlock.slot,
|
|
99
|
+
{dontTransferCache: true},
|
|
100
|
+
RegenCaller.processBlock
|
|
101
|
+
)) as CachedBeaconStateGloas;
|
|
102
|
+
|
|
103
|
+
// 4. Run verification steps in parallel
|
|
104
|
+
// Note: No data availability check needed here - importExecutionPayload is only
|
|
105
|
+
// called when payloadInput.isComplete() is true, so all data is already available.
|
|
106
|
+
const [execResult, signatureValid, postPayloadResult] = await Promise.all([
|
|
107
|
+
this.executionEngine.notifyNewPayload(
|
|
108
|
+
ForkName.gloas,
|
|
109
|
+
envelope.message.payload,
|
|
110
|
+
payloadInput.getVersionedHashes(),
|
|
111
|
+
fromHex(protoBlock.parentRoot),
|
|
112
|
+
envelope.message.executionRequests
|
|
113
|
+
),
|
|
114
|
+
|
|
115
|
+
opts.validSignature === true
|
|
116
|
+
? Promise.resolve(true)
|
|
117
|
+
: (async () => {
|
|
118
|
+
const signatureSet = getExecutionPayloadEnvelopeSignatureSet(
|
|
119
|
+
this.config,
|
|
120
|
+
blockState.epochCtx.pubkeyCache,
|
|
121
|
+
new BeaconStateView(blockState),
|
|
122
|
+
envelope,
|
|
123
|
+
payloadInput.proposerIndex
|
|
124
|
+
);
|
|
125
|
+
return this.bls.verifySignatureSets([signatureSet]);
|
|
126
|
+
})(),
|
|
127
|
+
|
|
128
|
+
// Signature verified separately above.
|
|
129
|
+
// State root check is done separately below with better error typing (matching block pipeline pattern).
|
|
130
|
+
(async () => {
|
|
131
|
+
try {
|
|
132
|
+
return {
|
|
133
|
+
postPayloadState: processExecutionPayloadEnvelope(blockState, envelope, {
|
|
134
|
+
verifySignature: false,
|
|
135
|
+
verifyStateRoot: false,
|
|
136
|
+
}),
|
|
137
|
+
};
|
|
138
|
+
} catch (e) {
|
|
139
|
+
throw new PayloadError(
|
|
140
|
+
{
|
|
141
|
+
code: PayloadErrorCode.STATE_TRANSITION_ERROR,
|
|
142
|
+
message: (e as Error).message,
|
|
143
|
+
},
|
|
144
|
+
`State transition error: ${(e as Error).message}`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
})(),
|
|
148
|
+
]);
|
|
149
|
+
|
|
150
|
+
// 4b. Check signature verification result
|
|
151
|
+
if (!signatureValid) {
|
|
152
|
+
throw new PayloadError({code: PayloadErrorCode.INVALID_SIGNATURE});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 5. Handle EL response
|
|
156
|
+
switch (execResult.status) {
|
|
157
|
+
case ExecutionPayloadStatus.VALID:
|
|
158
|
+
break;
|
|
159
|
+
|
|
160
|
+
case ExecutionPayloadStatus.INVALID:
|
|
161
|
+
throw new PayloadError({
|
|
162
|
+
code: PayloadErrorCode.EXECUTION_ENGINE_INVALID,
|
|
163
|
+
execStatus: execResult.status,
|
|
164
|
+
errorMessage: execResult.validationError ?? "",
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
case ExecutionPayloadStatus.ACCEPTED:
|
|
168
|
+
case ExecutionPayloadStatus.SYNCING:
|
|
169
|
+
// TODO GLOAS: Handle optimistic import for payload - for now treat as error
|
|
170
|
+
throw new PayloadError({
|
|
171
|
+
code: PayloadErrorCode.EXECUTION_ENGINE_ERROR,
|
|
172
|
+
execStatus: execResult.status,
|
|
173
|
+
errorMessage: execResult.validationError ?? "EL syncing, payload not yet validated",
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
case ExecutionPayloadStatus.INVALID_BLOCK_HASH:
|
|
177
|
+
case ExecutionPayloadStatus.ELERROR:
|
|
178
|
+
case ExecutionPayloadStatus.UNAVAILABLE:
|
|
179
|
+
throw new PayloadError({
|
|
180
|
+
code: PayloadErrorCode.EXECUTION_ENGINE_ERROR,
|
|
181
|
+
execStatus: execResult.status,
|
|
182
|
+
errorMessage: execResult.validationError ?? "",
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// 5b. Verify envelope state root matches post-state
|
|
187
|
+
const postPayloadState = postPayloadResult.postPayloadState;
|
|
188
|
+
const postPayloadStateRoot = postPayloadState.hashTreeRoot();
|
|
189
|
+
if (!byteArrayEquals(envelope.message.stateRoot, postPayloadStateRoot)) {
|
|
190
|
+
throw new PayloadError({
|
|
191
|
+
code: PayloadErrorCode.STATE_TRANSITION_ERROR,
|
|
192
|
+
message: `Envelope state root mismatch expected=${toRootHex(envelope.message.stateRoot)} actual=${toRootHex(postPayloadStateRoot)}`,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// 5c. Persist payload envelope to hot DB (performed asynchronously to avoid blocking)
|
|
197
|
+
this.unfinalizedPayloadEnvelopeWrites.push(payloadInput).catch((e) => {
|
|
198
|
+
if (!isQueueErrorAborted(e)) {
|
|
199
|
+
this.logger.error(
|
|
200
|
+
"Error pushing payload envelope to unfinalized write queue",
|
|
201
|
+
{slot: payloadInput.slot, root: blockRootHex},
|
|
202
|
+
e as Error
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// 6. Update fork choice
|
|
208
|
+
this.forkChoice.onExecutionPayload(
|
|
209
|
+
blockRootHex,
|
|
210
|
+
payloadInput.getBlockHashHex(),
|
|
211
|
+
envelope.message.payload.blockNumber,
|
|
212
|
+
toRootHex(postPayloadStateRoot)
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
// 7. Cache payload state
|
|
216
|
+
// TODO GLOAS: Enable when PR #8868 merged (adds processPayloadState)
|
|
217
|
+
// this.regen.processPayloadState(postPayloadState);
|
|
218
|
+
// if epoch boundary also call
|
|
219
|
+
// this.regen.addCheckpointState(cp, checkpointState, true);
|
|
220
|
+
|
|
221
|
+
// 8. Record metrics for payload envelope and column sources
|
|
222
|
+
this.metrics?.importPayload.bySource.inc({source: payloadInput.getPayloadEnvelopeSource().source});
|
|
223
|
+
for (const {source} of payloadInput.getSampledColumnsWithSource()) {
|
|
224
|
+
this.metrics?.importPayload.columnsBySource.inc({source});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
this.logger.verbose("Execution payload imported", {
|
|
228
|
+
slot: payloadInput.slot,
|
|
229
|
+
root: blockRootHex,
|
|
230
|
+
blockHash: payloadInput.getBlockHashHex(),
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// 9. Emit event after payload is fully verified and imported to fork choice, only for recent enough payloads
|
|
234
|
+
const currentSlot = this.clock.currentSlot;
|
|
235
|
+
if (currentSlot - payloadInput.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
|
|
236
|
+
this.emitter.emit(routes.events.EventType.executionPayloadAvailable, {
|
|
237
|
+
slot: payloadInput.slot,
|
|
238
|
+
blockRoot: blockRootHex,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|