@lodestar/beacon-node 1.43.0-dev.4fb05c546d → 1.43.0-dev.549a5b8115
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.js +7 -9
- 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 +45 -2
- package/lib/api/impl/beacon/pool/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/lodestar/index.js +1 -1
- 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 +66 -5
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- 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.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +2 -2
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +110 -58
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +3 -2
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +28 -14
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +86 -86
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.d.ts +5 -3
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +31 -11
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +4 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeProcessor.js +2 -2
- package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
- package/lib/chain/blocks/types.d.ts +14 -20
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.d.ts +23 -2
- package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.js +81 -12
- package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts +5 -3
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +51 -7
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js +15 -4
- package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +24 -0
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -0
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +76 -0
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -1
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js +8 -3
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +2 -11
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -1
- package/lib/chain/chain.d.ts +8 -6
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +21 -6
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +3 -3
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/errors/blockError.d.ts +8 -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/executionPayloadBid.d.ts +5 -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 +5 -0
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/errors/index.d.ts +1 -0
- package/lib/chain/errors/index.d.ts.map +1 -1
- package/lib/chain/errors/index.js +1 -0
- package/lib/chain/errors/index.js.map +1 -1
- package/lib/chain/errors/proposerPreferences.d.ts +33 -0
- package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
- package/lib/chain/errors/proposerPreferences.js +13 -0
- package/lib/chain/errors/proposerPreferences.js.map +1 -0
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +5 -17
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +7 -5
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.d.ts +3 -2
- package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.js +26 -4
- package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +30 -10
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -2
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +40 -15
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +1 -0
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +1 -0
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/seenCache/index.d.ts +1 -0
- package/lib/chain/seenCache/index.d.ts.map +1 -1
- package/lib/chain/seenCache/index.js +1 -0
- package/lib/chain/seenCache/index.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +19 -6
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +28 -20
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/seenCache/seenProposerPreferences.d.ts +15 -0
- package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
- package/lib/chain/seenCache/seenProposerPreferences.js +25 -0
- package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +1 -0
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +13 -1
- 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 +19 -9
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/proposerPreferences.d.ts +8 -0
- package/lib/chain/validation/proposerPreferences.d.ts.map +1 -0
- package/lib/chain/validation/proposerPreferences.js +69 -0
- package/lib/chain/validation/proposerPreferences.js.map +1 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +21 -14
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +1 -0
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/mock.d.ts.map +1 -1
- package/lib/execution/engine/mock.js +6 -0
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/execution/engine/types.d.ts +20 -0
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js +18 -0
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +1 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +4 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/interface.d.ts +7 -1
- package/lib/network/gossip/interface.d.ts.map +1 -1
- package/lib/network/gossip/interface.js +1 -0
- package/lib/network/gossip/interface.js.map +1 -1
- package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
- package/lib/network/gossip/scoringParameters.js +12 -1
- package/lib/network/gossip/scoringParameters.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +11 -2
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +6 -0
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/interface.d.ts +1 -0
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/network.d.ts +1 -0
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +6 -1
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +17 -12
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
- package/lib/network/processor/gossipQueues/index.js +5 -0
- package/lib/network/processor/gossipQueues/index.js.map +1 -1
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +1 -0
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js +14 -6
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js +11 -5
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +17 -5
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +7 -4
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
- package/lib/node/notifier.js +7 -1
- package/lib/node/notifier.js.map +1 -1
- package/lib/sync/range/batch.d.ts +12 -2
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +56 -30
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +6 -2
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +4 -3
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/range/range.d.ts.map +1 -1
- package/lib/sync/range/range.js +17 -6
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/types.d.ts +34 -0
- package/lib/sync/types.d.ts.map +1 -1
- package/lib/sync/types.js +34 -0
- package/lib/sync/types.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +24 -1
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +649 -53
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts +46 -10
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +147 -24
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRoot.js +6 -2
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/lib/sync/utils/pendingBlocksTree.d.ts +0 -1
- package/lib/sync/utils/pendingBlocksTree.d.ts.map +1 -1
- package/lib/sync/utils/pendingBlocksTree.js +0 -9
- package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +16 -3
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +16 -15
- package/src/api/impl/beacon/blocks/index.ts +9 -9
- package/src/api/impl/beacon/pool/index.ts +83 -1
- package/src/api/impl/beacon/state/utils.ts +2 -2
- package/src/api/impl/lodestar/index.ts +1 -1
- package/src/api/impl/validator/index.ts +80 -4
- package/src/chain/archiveStore/archiveStore.ts +5 -5
- package/src/chain/archiveStore/interface.ts +4 -4
- package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +4 -4
- package/src/chain/archiveStore/utils/archiveBlocks.ts +153 -94
- package/src/chain/blocks/importBlock.ts +3 -2
- package/src/chain/blocks/importExecutionPayload.ts +107 -101
- package/src/chain/blocks/index.ts +54 -15
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +5 -1
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +1 -0
- package/src/chain/blocks/payloadEnvelopeProcessor.ts +2 -2
- package/src/chain/blocks/types.ts +14 -25
- package/src/chain/blocks/utils/chainSegment.ts +106 -17
- package/src/chain/blocks/verifyBlock.ts +68 -9
- package/src/chain/blocks/verifyBlocksSanityChecks.ts +16 -7
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +129 -0
- package/src/chain/blocks/verifyPayloadsDataAvailability.ts +7 -4
- package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +9 -18
- package/src/chain/chain.ts +38 -19
- package/src/chain/emitter.ts +3 -3
- package/src/chain/errors/blockError.ts +4 -1
- package/src/chain/errors/executionPayloadBid.ts +6 -0
- package/src/chain/errors/executionPayloadEnvelope.ts +6 -0
- package/src/chain/errors/index.ts +1 -0
- package/src/chain/errors/proposerPreferences.ts +39 -0
- package/src/chain/forkChoice/index.ts +2 -22
- package/src/chain/interface.ts +11 -3
- package/src/chain/opPools/payloadAttestationPool.ts +29 -8
- package/src/chain/prepareNextSlot.ts +42 -12
- package/src/chain/produceBlock/produceBlockBody.ts +47 -13
- package/src/chain/regen/interface.ts +1 -0
- package/src/chain/seenCache/index.ts +1 -0
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +35 -23
- package/src/chain/seenCache/seenProposerPreferences.ts +29 -0
- package/src/chain/stateCache/persistentCheckpointsCache.ts +4 -1
- package/src/chain/validation/block.ts +1 -0
- package/src/chain/validation/executionPayloadBid.ts +14 -0
- package/src/chain/validation/executionPayloadEnvelope.ts +20 -10
- package/src/chain/validation/proposerPreferences.ts +91 -0
- package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
- package/src/execution/engine/http.ts +21 -14
- package/src/execution/engine/interface.ts +1 -0
- package/src/execution/engine/mock.ts +8 -1
- package/src/execution/engine/types.ts +41 -0
- package/src/metrics/metrics/lodestar.ts +4 -0
- package/src/network/gossip/interface.ts +6 -0
- package/src/network/gossip/scoringParameters.ts +14 -1
- package/src/network/gossip/topic.ts +6 -0
- package/src/network/interface.ts +1 -0
- package/src/network/network.ts +12 -1
- package/src/network/processor/gossipHandlers.ts +26 -13
- package/src/network/processor/gossipQueues/index.ts +5 -0
- package/src/network/processor/index.ts +1 -0
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +14 -6
- package/src/network/reqresp/handlers/blobSidecarsByRange.ts +11 -5
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -5
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +7 -4
- package/src/node/notifier.ts +8 -1
- package/src/sync/range/batch.ts +90 -35
- package/src/sync/range/chain.ts +13 -5
- package/src/sync/range/range.ts +18 -6
- package/src/sync/types.ts +72 -0
- package/src/sync/unknownBlock.ts +810 -57
- package/src/sync/utils/downloadByRange.ts +256 -39
- package/src/sync/utils/downloadByRoot.ts +12 -2
- package/src/sync/utils/pendingBlocksTree.ts +0 -15
- package/src/util/sszBytes.ts +21 -3
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
|
-
import {ExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import {ExecutionStatus, PayloadExecutionStatus, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
|
|
3
|
+
import {DataAvailabilityStatus, isStatePostGloas} from "@lodestar/state-transition";
|
|
4
|
+
import {fromHex, isErrorAborted} from "@lodestar/utils";
|
|
5
|
+
import {ZERO_HASH_HEX} from "../../constants/index.js";
|
|
6
6
|
import {ExecutionPayloadStatus} from "../../execution/index.js";
|
|
7
7
|
import {isQueueErrorAborted} from "../../util/queue/index.js";
|
|
8
8
|
import {BeaconChain} from "../chain.js";
|
|
9
9
|
import {RegenCaller} from "../regen/interface.js";
|
|
10
10
|
import {PayloadEnvelopeInput} from "../seenCache/seenPayloadEnvelopeInput.js";
|
|
11
11
|
import {ImportPayloadOpts} from "./types.js";
|
|
12
|
+
import {
|
|
13
|
+
verifyExecutionPayloadEnvelope,
|
|
14
|
+
verifyExecutionPayloadEnvelopeSignature,
|
|
15
|
+
} from "./verifyExecutionPayloadEnvelope.js";
|
|
12
16
|
import {verifyPayloadsDataAvailability} from "./verifyPayloadsDataAvailability.js";
|
|
13
17
|
|
|
14
18
|
const EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS = 64;
|
|
@@ -17,7 +21,7 @@ export enum PayloadErrorCode {
|
|
|
17
21
|
EXECUTION_ENGINE_INVALID = "PAYLOAD_ERROR_EXECUTION_ENGINE_INVALID",
|
|
18
22
|
EXECUTION_ENGINE_ERROR = "PAYLOAD_ERROR_EXECUTION_ENGINE_ERROR",
|
|
19
23
|
BLOCK_NOT_IN_FORK_CHOICE = "PAYLOAD_ERROR_BLOCK_NOT_IN_FORK_CHOICE",
|
|
20
|
-
|
|
24
|
+
ENVELOPE_VERIFICATION_ERROR = "PAYLOAD_ERROR_ENVELOPE_VERIFICATION_ERROR",
|
|
21
25
|
INVALID_SIGNATURE = "PAYLOAD_ERROR_INVALID_SIGNATURE",
|
|
22
26
|
}
|
|
23
27
|
|
|
@@ -37,7 +41,7 @@ export type PayloadErrorType =
|
|
|
37
41
|
blockRootHex: string;
|
|
38
42
|
}
|
|
39
43
|
| {
|
|
40
|
-
code: PayloadErrorCode.
|
|
44
|
+
code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR;
|
|
41
45
|
message: string;
|
|
42
46
|
}
|
|
43
47
|
| {
|
|
@@ -69,38 +73,43 @@ function toForkChoiceExecutionStatus(status: ExecutionPayloadStatus): PayloadExe
|
|
|
69
73
|
/**
|
|
70
74
|
* Import an execution payload envelope after all data is available.
|
|
71
75
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* 2. Gets the ProtoBlock from fork choice
|
|
75
|
-
* 3. Applies write-queue backpressure (waitForSpace) early, before verification
|
|
76
|
-
* 4. Regenerates the block state
|
|
77
|
-
* 5. Runs EL verification (notifyNewPayload) in parallel with signature verification and processExecutionPayloadEnvelope
|
|
78
|
-
* 6. Persists verified payload envelope to hot DB
|
|
79
|
-
* 7. Updates fork choice
|
|
80
|
-
* 8. Caches the post-execution payload state
|
|
81
|
-
* 9. Records metrics for column sources
|
|
82
|
-
* 10. Emits `execution_payload` for recent enough payloads after successful import
|
|
76
|
+
* The envelope is only verified here, no state mutation. State effects from the payload
|
|
77
|
+
* are applied on the next block via processParentExecutionPayload.
|
|
83
78
|
*
|
|
79
|
+
* The DA wait must have run upstream (range sync awaits DA in `verifyBlocksInEpoch` for the
|
|
80
|
+
* whole segment; gossip / API path uses the `processExecutionPayload` wrapper below).
|
|
81
|
+
*
|
|
82
|
+
* Steps:
|
|
83
|
+
* 1. Emit `execution_payload_available` event for payload attestation
|
|
84
|
+
* 2. Get the ProtoBlock from fork choice
|
|
85
|
+
* 3. Regenerate state for envelope verification
|
|
86
|
+
* 4. Verify envelope (fields against state, signature, and EL in parallel where possible)
|
|
87
|
+
* 5. Persist verified payload envelope to hot DB (waits for write-queue space for backpressure)
|
|
88
|
+
* 6. Update fork choice (transitions the block's PENDING variant to FULL)
|
|
89
|
+
* 7. Queue notifyForkchoiceUpdate to engine api
|
|
90
|
+
* 8. Record metrics for payload envelope and column sources
|
|
91
|
+
* 9. Emit `execution_payload` event
|
|
84
92
|
*/
|
|
85
93
|
export async function importExecutionPayload(
|
|
86
94
|
this: BeaconChain,
|
|
87
95
|
payloadInput: PayloadEnvelopeInput,
|
|
88
|
-
|
|
96
|
+
dataAvailabilityStatus: DataAvailabilityStatus,
|
|
89
97
|
opts: ImportPayloadOpts = {}
|
|
90
98
|
): Promise<void> {
|
|
91
99
|
const signedEnvelope = payloadInput.getPayloadEnvelope();
|
|
92
100
|
const envelope = signedEnvelope.message;
|
|
101
|
+
const slot = envelope.payload.slotNumber;
|
|
93
102
|
const blockRootHex = payloadInput.blockRootHex;
|
|
94
103
|
const blockHashHex = payloadInput.getBlockHashHex();
|
|
95
|
-
const fork = this.config.getForkName(
|
|
104
|
+
const fork = this.config.getForkName(slot);
|
|
96
105
|
|
|
97
|
-
// 1. Emit `execution_payload_available` event at the start of import. At this point the
|
|
98
|
-
// is already complete, so the payload and required data are available for
|
|
99
|
-
// This event
|
|
100
|
-
// it before getting a response from the
|
|
101
|
-
if (this.clock.currentSlot -
|
|
106
|
+
// 1. Emit `execution_payload_available` event at the start of import. At this point the
|
|
107
|
+
// payload input is already complete, so the payload and required data are available for
|
|
108
|
+
// payload attestation. This event only signals availability (not validity), so we can emit
|
|
109
|
+
// it before getting a response from the EL on whether the payload is valid or not.
|
|
110
|
+
if (this.clock.currentSlot - slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
|
|
102
111
|
this.emitter.emit(routes.events.EventType.executionPayloadAvailable, {
|
|
103
|
-
slot
|
|
112
|
+
slot,
|
|
104
113
|
blockRoot: blockRootHex,
|
|
105
114
|
});
|
|
106
115
|
}
|
|
@@ -114,16 +123,7 @@ export async function importExecutionPayload(
|
|
|
114
123
|
});
|
|
115
124
|
}
|
|
116
125
|
|
|
117
|
-
// 3.
|
|
118
|
-
// The helper is shared with future gloas sync services; take the single-item batch form here.
|
|
119
|
-
await verifyPayloadsDataAvailability([payloadInput], signal);
|
|
120
|
-
|
|
121
|
-
// 4. Apply backpressure from the write queue, before doing verification work.
|
|
122
|
-
// The actual DB write is deferred until after verification succeeds.
|
|
123
|
-
await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();
|
|
124
|
-
|
|
125
|
-
// 5. Get pre-state for processExecutionPayloadEnvelope
|
|
126
|
-
// We need the block state (post-block, pre-payload) to process the envelope
|
|
126
|
+
// 3. Regenerate state for envelope verification
|
|
127
127
|
const blockState = await this.regen.getBlockSlotState(
|
|
128
128
|
protoBlock,
|
|
129
129
|
protoBlock.slot,
|
|
@@ -132,13 +132,30 @@ export async function importExecutionPayload(
|
|
|
132
132
|
);
|
|
133
133
|
if (!isStatePostGloas(blockState)) {
|
|
134
134
|
throw new PayloadError({
|
|
135
|
-
code: PayloadErrorCode.
|
|
136
|
-
message: `Expected gloas+
|
|
135
|
+
code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR,
|
|
136
|
+
message: `Expected gloas+ state for payload import, got fork=${blockState.forkName}`,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// 4. Verify envelope fields against state first to fail fast before the EL + BLS work.
|
|
141
|
+
// When validSignature is true, gossip/API has already verified both the signature and the
|
|
142
|
+
// executionRequestsRoot, so we skip those checks here.
|
|
143
|
+
try {
|
|
144
|
+
verifyExecutionPayloadEnvelope(this.config, blockState, envelope, {
|
|
145
|
+
verifyExecutionRequestsRoot: !opts.validSignature,
|
|
137
146
|
});
|
|
147
|
+
} catch (e) {
|
|
148
|
+
throw new PayloadError(
|
|
149
|
+
{
|
|
150
|
+
code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR,
|
|
151
|
+
message: (e as Error).message,
|
|
152
|
+
},
|
|
153
|
+
`Envelope verification error: ${(e as Error).message}`
|
|
154
|
+
);
|
|
138
155
|
}
|
|
139
156
|
|
|
140
|
-
//
|
|
141
|
-
const [execResult, signatureValid
|
|
157
|
+
// 4a. Run EL and signature verification in parallel
|
|
158
|
+
const [execResult, signatureValid] = await Promise.all([
|
|
142
159
|
this.executionEngine.notifyNewPayload(
|
|
143
160
|
fork,
|
|
144
161
|
envelope.payload,
|
|
@@ -149,45 +166,22 @@ export async function importExecutionPayload(
|
|
|
149
166
|
|
|
150
167
|
opts.validSignature === true
|
|
151
168
|
? Promise.resolve(true)
|
|
152
|
-
: (
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return this.bls.verifySignatureSets([signatureSet]);
|
|
161
|
-
})(),
|
|
162
|
-
|
|
163
|
-
// Signature verified separately above.
|
|
164
|
-
// State root check is done separately below with better error typing (matching block pipeline pattern).
|
|
165
|
-
(async () => {
|
|
166
|
-
try {
|
|
167
|
-
return {
|
|
168
|
-
postPayloadState: blockState.processExecutionPayloadEnvelope(signedEnvelope, {
|
|
169
|
-
verifySignature: false,
|
|
170
|
-
verifyStateRoot: false,
|
|
171
|
-
}),
|
|
172
|
-
};
|
|
173
|
-
} catch (e) {
|
|
174
|
-
throw new PayloadError(
|
|
175
|
-
{
|
|
176
|
-
code: PayloadErrorCode.STATE_TRANSITION_ERROR,
|
|
177
|
-
message: (e as Error).message,
|
|
178
|
-
},
|
|
179
|
-
`State transition error: ${(e as Error).message}`
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
})(),
|
|
169
|
+
: verifyExecutionPayloadEnvelopeSignature(
|
|
170
|
+
this.config,
|
|
171
|
+
blockState,
|
|
172
|
+
this.pubkeyCache,
|
|
173
|
+
signedEnvelope,
|
|
174
|
+
payloadInput.proposerIndex,
|
|
175
|
+
this.bls
|
|
176
|
+
),
|
|
183
177
|
]);
|
|
184
178
|
|
|
185
|
-
//
|
|
179
|
+
// 4b. Check signature verification result
|
|
186
180
|
if (!signatureValid) {
|
|
187
181
|
throw new PayloadError({code: PayloadErrorCode.INVALID_SIGNATURE});
|
|
188
182
|
}
|
|
189
183
|
|
|
190
|
-
//
|
|
184
|
+
// 4c. Handle EL response
|
|
191
185
|
switch (execResult.status) {
|
|
192
186
|
case ExecutionPayloadStatus.VALID:
|
|
193
187
|
break;
|
|
@@ -213,69 +207,81 @@ export async function importExecutionPayload(
|
|
|
213
207
|
});
|
|
214
208
|
}
|
|
215
209
|
|
|
216
|
-
//
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (!byteArrayEquals(envelope.stateRoot, postPayloadStateRoot)) {
|
|
220
|
-
throw new PayloadError({
|
|
221
|
-
code: PayloadErrorCode.STATE_TRANSITION_ERROR,
|
|
222
|
-
message: `Envelope state root mismatch expected=${toRootHex(envelope.stateRoot)} actual=${toRootHex(postPayloadStateRoot)}`,
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// 6. Persist payload envelope to hot DB (performed asynchronously to avoid blocking)
|
|
210
|
+
// 5. Persist payload envelope to hot DB. Wait for write-queue space here to apply backpressure
|
|
211
|
+
// on the import pipeline during sync, then perform the write asynchronously to avoid blocking.
|
|
212
|
+
await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();
|
|
227
213
|
this.unfinalizedPayloadEnvelopeWrites.push(payloadInput).catch((e) => {
|
|
228
214
|
if (!isQueueErrorAborted(e)) {
|
|
229
215
|
this.logger.error(
|
|
230
216
|
"Error pushing payload envelope to unfinalized write queue",
|
|
231
|
-
{slot
|
|
217
|
+
{slot, blockRoot: blockRootHex},
|
|
232
218
|
e as Error
|
|
233
219
|
);
|
|
234
220
|
}
|
|
235
221
|
});
|
|
236
222
|
|
|
237
|
-
//
|
|
223
|
+
// 6. Update fork choice, transitions the block's PENDING variant to FULL
|
|
224
|
+
const execStatus = toForkChoiceExecutionStatus(execResult.status);
|
|
238
225
|
this.forkChoice.onExecutionPayload(
|
|
239
226
|
blockRootHex,
|
|
240
227
|
blockHashHex,
|
|
241
228
|
envelope.payload.blockNumber,
|
|
242
|
-
|
|
243
|
-
|
|
229
|
+
execStatus,
|
|
230
|
+
dataAvailabilityStatus
|
|
244
231
|
);
|
|
245
232
|
|
|
246
|
-
//
|
|
247
|
-
this.
|
|
248
|
-
if (
|
|
249
|
-
const
|
|
250
|
-
this.
|
|
233
|
+
// 7. Queue notifyForkchoiceUpdate to engine api
|
|
234
|
+
const head = this.forkChoice.getHead();
|
|
235
|
+
if (!this.opts.disableImportExecutionFcU && blockRootHex === head.blockRoot) {
|
|
236
|
+
const safeBlockHash = getSafeExecutionBlockHash(this.forkChoice);
|
|
237
|
+
const finalizedBlockHash = this.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
|
|
238
|
+
this.executionEngine.notifyForkchoiceUpdate(fork, blockHashHex, safeBlockHash, finalizedBlockHash).catch((e) => {
|
|
239
|
+
if (!isErrorAborted(e) && !isQueueErrorAborted(e)) {
|
|
240
|
+
this.logger.error("Error pushing notifyForkchoiceUpdate()", {blockHashHex, finalizedBlockHash}, e);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
251
243
|
}
|
|
252
244
|
|
|
253
|
-
//
|
|
245
|
+
// 8. Record metrics for payload envelope and column sources
|
|
254
246
|
this.metrics?.importPayload.bySource.inc({source: payloadInput.getPayloadEnvelopeSource().source});
|
|
255
247
|
for (const {source} of payloadInput.getSampledColumnsWithSource()) {
|
|
256
248
|
this.metrics?.importPayload.columnsBySource.inc({source});
|
|
257
249
|
}
|
|
258
250
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
// 10. Emit event after payload is fully verified and imported to fork choice, only for recent enough payloads
|
|
262
|
-
if (this.clock.currentSlot - envelope.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
|
|
251
|
+
// 9. Emit event after payload is fully verified and imported to fork choice, only for recent enough payloads
|
|
252
|
+
if (this.clock.currentSlot - slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
|
|
263
253
|
this.emitter.emit(routes.events.EventType.executionPayload, {
|
|
264
|
-
slot
|
|
254
|
+
slot,
|
|
265
255
|
builderIndex: envelope.builderIndex,
|
|
266
256
|
blockHash: blockHashHex,
|
|
267
257
|
blockRoot: blockRootHex,
|
|
268
|
-
stateRoot: stateRootHex,
|
|
269
258
|
// TODO GLOAS: revisit once we support optimistic import
|
|
270
259
|
executionOptimistic: false,
|
|
271
260
|
});
|
|
272
261
|
}
|
|
273
262
|
|
|
274
263
|
this.logger.verbose("Execution payload imported", {
|
|
275
|
-
slot
|
|
264
|
+
slot,
|
|
276
265
|
builderIndex: envelope.builderIndex,
|
|
277
266
|
blockRoot: blockRootHex,
|
|
278
267
|
blockHash: blockHashHex,
|
|
279
|
-
stateRoot: stateRootHex,
|
|
280
268
|
});
|
|
281
269
|
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Process an execution payload envelope end-to-end: wait for DA, then import.
|
|
273
|
+
*
|
|
274
|
+
* Used by the PayloadEnvelopeProcessor queue (gossip / API / unknown-payload sync) — i.e.
|
|
275
|
+
* callers that have NOT already awaited DA themselves. Range sync's inline dispatch in
|
|
276
|
+
* processBlocks skips this wrapper and calls `importExecutionPayload` directly, since
|
|
277
|
+
* `verifyBlocksInEpoch` already awaited DA for the segment.
|
|
278
|
+
*/
|
|
279
|
+
export async function processExecutionPayload(
|
|
280
|
+
this: BeaconChain,
|
|
281
|
+
payloadInput: PayloadEnvelopeInput,
|
|
282
|
+
signal: AbortSignal,
|
|
283
|
+
opts: ImportPayloadOpts = {}
|
|
284
|
+
): Promise<void> {
|
|
285
|
+
const {dataAvailabilityStatuses} = await verifyPayloadsDataAvailability([payloadInput], signal);
|
|
286
|
+
await importExecutionPayload.call(this, payloadInput, dataAvailabilityStatuses[0], opts);
|
|
287
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {SignedBeaconBlock} from "@lodestar/types";
|
|
1
|
+
import {SignedBeaconBlock, Slot} from "@lodestar/types";
|
|
2
2
|
import {isErrorAborted, toRootHex} from "@lodestar/utils";
|
|
3
3
|
import {Metrics} from "../../metrics/metrics.js";
|
|
4
4
|
import {nextEventLoop} from "../../util/eventLoop.js";
|
|
@@ -8,6 +8,8 @@ import {BlockError, BlockErrorCode, isBlockErrorAborted} from "../errors/index.j
|
|
|
8
8
|
import {BlockProcessOpts} from "../options.js";
|
|
9
9
|
import {IBlockInput} from "./blockInput/types.js";
|
|
10
10
|
import {importBlock} from "./importBlock.js";
|
|
11
|
+
import {importExecutionPayload} from "./importExecutionPayload.js";
|
|
12
|
+
import {PayloadEnvelopeInput} from "./payloadEnvelopeInput/payloadEnvelopeInput.js";
|
|
11
13
|
import {FullyVerifiedBlock, ImportBlockOpts} from "./types.js";
|
|
12
14
|
import {assertLinearChainSegment} from "./utils/chainSegment.js";
|
|
13
15
|
import {verifyBlocksInEpoch} from "./verifyBlock.js";
|
|
@@ -21,20 +23,24 @@ const QUEUE_MAX_LENGTH = 256;
|
|
|
21
23
|
* BlockProcessor processes block jobs in a queued fashion, one after the other.
|
|
22
24
|
*/
|
|
23
25
|
export class BlockProcessor {
|
|
24
|
-
readonly jobQueue: JobItemQueue<[IBlockInput[], ImportBlockOpts], void>;
|
|
26
|
+
readonly jobQueue: JobItemQueue<[IBlockInput[], Map<Slot, PayloadEnvelopeInput> | null, ImportBlockOpts], void>;
|
|
25
27
|
|
|
26
28
|
constructor(chain: BeaconChain, metrics: Metrics | null, opts: BlockProcessOpts, signal: AbortSignal) {
|
|
27
|
-
this.jobQueue = new JobItemQueue<[IBlockInput[], ImportBlockOpts], void>(
|
|
28
|
-
(job, importOpts) => {
|
|
29
|
-
return processBlocks.call(chain, job, {...opts, ...importOpts});
|
|
29
|
+
this.jobQueue = new JobItemQueue<[IBlockInput[], Map<Slot, PayloadEnvelopeInput> | null, ImportBlockOpts], void>(
|
|
30
|
+
(job, payloadEnvelopes, importOpts) => {
|
|
31
|
+
return processBlocks.call(chain, job, payloadEnvelopes, {...opts, ...importOpts});
|
|
30
32
|
},
|
|
31
33
|
{maxLength: QUEUE_MAX_LENGTH, noYieldIfOneItem: true, signal},
|
|
32
34
|
metrics?.blockProcessorQueue ?? undefined
|
|
33
35
|
);
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
async processBlocksJob(
|
|
37
|
-
|
|
38
|
+
async processBlocksJob(
|
|
39
|
+
job: IBlockInput[],
|
|
40
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
|
|
41
|
+
opts: ImportBlockOpts = {}
|
|
42
|
+
): Promise<void> {
|
|
43
|
+
await this.jobQueue.push(job, payloadEnvelopes, opts);
|
|
38
44
|
}
|
|
39
45
|
}
|
|
40
46
|
|
|
@@ -51,16 +57,13 @@ export class BlockProcessor {
|
|
|
51
57
|
export async function processBlocks(
|
|
52
58
|
this: BeaconChain,
|
|
53
59
|
blocks: IBlockInput[],
|
|
60
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
|
|
54
61
|
opts: BlockProcessOpts & ImportBlockOpts
|
|
55
62
|
): Promise<void> {
|
|
56
63
|
if (blocks.length === 0) {
|
|
57
64
|
return; // TODO: or throw?
|
|
58
65
|
}
|
|
59
66
|
|
|
60
|
-
if (blocks.length > 1) {
|
|
61
|
-
assertLinearChainSegment(this.config, blocks);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
67
|
try {
|
|
65
68
|
const {relevantBlocks, parentSlots, parentBlock} = verifyBlocksSanityChecks(this, blocks, opts);
|
|
66
69
|
|
|
@@ -70,10 +73,31 @@ export async function processBlocks(
|
|
|
70
73
|
return;
|
|
71
74
|
}
|
|
72
75
|
|
|
76
|
+
const {warnings: orphanedPayloads} = assertLinearChainSegment(
|
|
77
|
+
this.config,
|
|
78
|
+
relevantBlocks,
|
|
79
|
+
payloadEnvelopes,
|
|
80
|
+
parentBlock
|
|
81
|
+
);
|
|
82
|
+
if (orphanedPayloads != null) {
|
|
83
|
+
for (const orphaned of orphanedPayloads) {
|
|
84
|
+
this.logger.debug("Orphaned payload envelope in chain segment", {
|
|
85
|
+
slot: orphaned.slot,
|
|
86
|
+
blockRoot: orphaned.payloadEnvelopeInput.blockRootHex,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
73
91
|
// Fully verify a block to be imported immediately after. Does not produce any side-effects besides adding intermediate
|
|
74
92
|
// states in the state cache through regen.
|
|
75
|
-
const {
|
|
76
|
-
|
|
93
|
+
const {
|
|
94
|
+
postStates,
|
|
95
|
+
blockDAStatuses,
|
|
96
|
+
payloadDAStatuses,
|
|
97
|
+
proposerBalanceDeltas,
|
|
98
|
+
segmentExecStatus,
|
|
99
|
+
indexedAttestationsByBlock,
|
|
100
|
+
} = await verifyBlocksInEpoch.call(this, parentBlock, relevantBlocks, payloadEnvelopes, opts);
|
|
77
101
|
|
|
78
102
|
// If segmentExecStatus has lvhForkchoice then, the entire segment should be invalid
|
|
79
103
|
// and we need to further propagate
|
|
@@ -89,11 +113,10 @@ export async function processBlocks(
|
|
|
89
113
|
(block, i): FullyVerifiedBlock => ({
|
|
90
114
|
blockInput: block,
|
|
91
115
|
postState: postStates[i],
|
|
92
|
-
postPayloadState: null,
|
|
93
116
|
parentBlockSlot: parentSlots[i],
|
|
94
117
|
executionStatus: executionStatuses[i],
|
|
95
118
|
// start supporting optimistic syncing/processing
|
|
96
|
-
dataAvailabilityStatus:
|
|
119
|
+
dataAvailabilityStatus: blockDAStatuses[i],
|
|
97
120
|
proposerBalanceDelta: proposerBalanceDeltas[i],
|
|
98
121
|
indexedAttestations: indexedAttestationsByBlock[i],
|
|
99
122
|
// TODO: Make this param mandatory and capture in gossip
|
|
@@ -104,6 +127,22 @@ export async function processBlocks(
|
|
|
104
127
|
for (const fullyVerifiedBlock of fullyVerifiedBlocks) {
|
|
105
128
|
// TODO: Consider batching importBlock too if it takes significant time
|
|
106
129
|
await importBlock.call(this, fullyVerifiedBlock, opts);
|
|
130
|
+
|
|
131
|
+
const slot = fullyVerifiedBlock.blockInput.getBlock().message.slot;
|
|
132
|
+
const payloadInput = payloadEnvelopes?.get(slot);
|
|
133
|
+
if (payloadInput?.hasPayloadEnvelope()) {
|
|
134
|
+
if (!payloadInput.isComplete()) {
|
|
135
|
+
// we validated DA before reaching this
|
|
136
|
+
throw new Error(`Payload envelope for slot ${slot} not complete after DA verification`);
|
|
137
|
+
}
|
|
138
|
+
// we already awaited DA in verifyBlocksInEpoch for this segment
|
|
139
|
+
const payloadDA = payloadDAStatuses.get(slot);
|
|
140
|
+
if (payloadDA === undefined) {
|
|
141
|
+
throw new Error(`Missing payload DA status for slot ${slot}`);
|
|
142
|
+
}
|
|
143
|
+
await importExecutionPayload.call(this, payloadInput, payloadDA, {validSignature: false});
|
|
144
|
+
}
|
|
145
|
+
|
|
107
146
|
await nextEventLoop();
|
|
108
147
|
}
|
|
109
148
|
} catch (e) {
|
|
@@ -64,6 +64,7 @@ export class PayloadEnvelopeInput {
|
|
|
64
64
|
readonly proposerIndex: ValidatorIndex;
|
|
65
65
|
readonly bid: gloas.ExecutionPayloadBid;
|
|
66
66
|
readonly versionedHashes: VersionedHashes;
|
|
67
|
+
readonly daOutOfRange: boolean;
|
|
67
68
|
|
|
68
69
|
private columnsCache = new Map<ColumnIndex, ColumnWithSource>();
|
|
69
70
|
|
|
@@ -87,6 +88,7 @@ export class PayloadEnvelopeInput {
|
|
|
87
88
|
sampledColumns: ColumnIndex[];
|
|
88
89
|
custodyColumns: ColumnIndex[];
|
|
89
90
|
timeCreatedSec: number;
|
|
91
|
+
daOutOfRange: boolean;
|
|
90
92
|
}) {
|
|
91
93
|
this.blockRootHex = props.blockRootHex;
|
|
92
94
|
this.slot = props.slot;
|
|
@@ -97,13 +99,14 @@ export class PayloadEnvelopeInput {
|
|
|
97
99
|
this.sampledColumns = props.sampledColumns;
|
|
98
100
|
this.custodyColumns = props.custodyColumns;
|
|
99
101
|
this.timeCreatedSec = props.timeCreatedSec;
|
|
102
|
+
this.daOutOfRange = props.daOutOfRange;
|
|
100
103
|
this.payloadEnvelopeDataPromise = createPromise();
|
|
101
104
|
this.allDataPromise = createPromise();
|
|
102
105
|
this.columnsDataPromise = createPromise();
|
|
103
106
|
|
|
104
107
|
const noBlobs = props.bid.blobKzgCommitments.length === 0;
|
|
105
108
|
const noSampledColumns = props.sampledColumns.length === 0;
|
|
106
|
-
const hasAllData = noBlobs || noSampledColumns;
|
|
109
|
+
const hasAllData = props.daOutOfRange || noBlobs || noSampledColumns;
|
|
107
110
|
|
|
108
111
|
if (hasAllData) {
|
|
109
112
|
this.state = {hasPayload: false, hasAllData: true, hasComputedAllData: true};
|
|
@@ -125,6 +128,7 @@ export class PayloadEnvelopeInput {
|
|
|
125
128
|
sampledColumns: props.sampledColumns,
|
|
126
129
|
custodyColumns: props.custodyColumns,
|
|
127
130
|
timeCreatedSec: props.timeCreatedSec,
|
|
131
|
+
daOutOfRange: props.daOutOfRange,
|
|
128
132
|
});
|
|
129
133
|
}
|
|
130
134
|
|
|
@@ -2,7 +2,7 @@ import {Metrics} from "../../metrics/metrics.js";
|
|
|
2
2
|
import {JobItemQueue} from "../../util/queue/index.js";
|
|
3
3
|
import type {BeaconChain} from "../chain.js";
|
|
4
4
|
import {PayloadEnvelopeInput} from "../seenCache/seenPayloadEnvelopeInput.js";
|
|
5
|
-
import {
|
|
5
|
+
import {processExecutionPayload} from "./importExecutionPayload.js";
|
|
6
6
|
import {ImportPayloadOpts} from "./types.js";
|
|
7
7
|
|
|
8
8
|
// TODO GLOAS: Set to be equal to DEFAULT_MAX_PENDING_UNFINALIZED_PAYLOAD_ENVELOPE_WRITES for now
|
|
@@ -30,7 +30,7 @@ export class PayloadEnvelopeProcessor {
|
|
|
30
30
|
this.jobQueue = new JobItemQueue<[PayloadEnvelopeInput, ImportPayloadOpts], void>(
|
|
31
31
|
(payloadInput, opts) => {
|
|
32
32
|
this.importStatus.set(payloadInput, PayloadEnvelopeImportStatus.importing);
|
|
33
|
-
return
|
|
33
|
+
return processExecutionPayload.call(chain, payloadInput, signal, opts);
|
|
34
34
|
},
|
|
35
35
|
{maxLength: QUEUE_MAX_LENGTH, noYieldIfOneItem: true, signal},
|
|
36
36
|
metrics?.payloadEnvelopeProcessorQueue ?? undefined
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {BlockExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
|
|
2
|
+
import type {BlockExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
|
|
3
3
|
import {ForkSeq} from "@lodestar/params";
|
|
4
4
|
import {DataAvailabilityStatus, IBeaconStateView, computeEpochAtSlot} from "@lodestar/state-transition";
|
|
5
5
|
import type {IndexedAttestation, Slot, fulu} from "@lodestar/types";
|
|
@@ -43,8 +43,9 @@ export enum BlobSidecarValidation {
|
|
|
43
43
|
|
|
44
44
|
export type ImportPayloadOpts = {
|
|
45
45
|
/**
|
|
46
|
-
* Set to true
|
|
47
|
-
*
|
|
46
|
+
* Set to true when the envelope was already validated upstream (e.g., gossip/API validation):
|
|
47
|
+
* signature is trusted and execution_requests_root was already verified against the bid.
|
|
48
|
+
* When false/undefined, both are verified during import.
|
|
48
49
|
*/
|
|
49
50
|
validSignature?: boolean;
|
|
50
51
|
};
|
|
@@ -88,7 +89,14 @@ export type ImportBlockOpts = {
|
|
|
88
89
|
seenTimestampSec?: number;
|
|
89
90
|
};
|
|
90
91
|
|
|
91
|
-
|
|
92
|
+
/**
|
|
93
|
+
* A wrapper around a `SignedBeaconBlock` that indicates that this block is fully verified and ready to import.
|
|
94
|
+
*
|
|
95
|
+
* `executionStatus` reflects the outcome of execution payload verification at block-import time:
|
|
96
|
+
* - pre-gloas: Valid | Syncing | PreMerge (from EL notifyNewPayload against the in-block payload)
|
|
97
|
+
* - post-gloas: PayloadSeparated (payload arrives separately as an envelope and is imported later)
|
|
98
|
+
*/
|
|
99
|
+
export type FullyVerifiedBlock = {
|
|
92
100
|
blockInput: IBlockInput;
|
|
93
101
|
postState: IBeaconStateView;
|
|
94
102
|
parentBlockSlot: Slot;
|
|
@@ -98,25 +106,6 @@ type FullyVerifiedBlockBase = {
|
|
|
98
106
|
indexedAttestations: IndexedAttestation[];
|
|
99
107
|
/** Seen timestamp seconds */
|
|
100
108
|
seenTimestampSec: number;
|
|
109
|
+
/** If the execution payload couldn't be verified because of EL syncing status, used in optimistic sync */
|
|
110
|
+
executionStatus: BlockExecutionStatus | PayloadExecutionStatus;
|
|
101
111
|
};
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* A wrapper around a `SignedBeaconBlock` that indicates that this block is fully verified and ready to import.
|
|
105
|
-
*
|
|
106
|
-
* Discriminated union on `postPayloadState`:
|
|
107
|
-
* - `null` → block has no pre-verified envelope; `executionStatus` is any `BlockExecutionStatus`
|
|
108
|
-
* - non-null → envelope was pre-verified during state transition; `executionStatus` is narrowed to
|
|
109
|
-
* `Valid | Syncing` (matching what `forkChoice.onExecutionPayload` expects)
|
|
110
|
-
*/
|
|
111
|
-
export type FullyVerifiedBlock = FullyVerifiedBlockBase &
|
|
112
|
-
(
|
|
113
|
-
| {
|
|
114
|
-
postPayloadState: null;
|
|
115
|
-
/** If the execution payload couldn't be verified because of EL syncing status, used in optimistic sync or for merge block */
|
|
116
|
-
executionStatus: BlockExecutionStatus;
|
|
117
|
-
}
|
|
118
|
-
| {
|
|
119
|
-
postPayloadState: IBeaconStateView;
|
|
120
|
-
executionStatus: PayloadExecutionStatus;
|
|
121
|
-
}
|
|
122
|
-
);
|