@lodestar/beacon-node 1.43.0-dev.5f9285892c → 1.43.0-dev.6b7eebbf6d

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.
Files changed (180) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +1 -4
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/state/utils.d.ts +2 -2
  5. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  6. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  7. package/lib/api/impl/validator/index.d.ts.map +1 -1
  8. package/lib/api/impl/validator/index.js +1 -4
  9. package/lib/api/impl/validator/index.js.map +1 -1
  10. package/lib/chain/GetBlobsTracker.d.ts +1 -1
  11. package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
  12. package/lib/chain/GetBlobsTracker.js +1 -2
  13. package/lib/chain/GetBlobsTracker.js.map +1 -1
  14. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  15. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  16. package/lib/chain/archiveStore/interface.d.ts +4 -4
  17. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  18. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
  19. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
  20. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +2 -4
  21. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
  22. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +2 -2
  23. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  24. package/lib/chain/archiveStore/utils/archiveBlocks.js +110 -58
  25. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  26. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  27. package/lib/chain/blocks/importBlock.js +23 -31
  28. package/lib/chain/blocks/importBlock.js.map +1 -1
  29. package/lib/chain/blocks/importExecutionPayload.d.ts +15 -14
  30. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  31. package/lib/chain/blocks/importExecutionPayload.js +63 -85
  32. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  33. package/lib/chain/blocks/index.d.ts.map +1 -1
  34. package/lib/chain/blocks/index.js +1 -2
  35. package/lib/chain/blocks/index.js.map +1 -1
  36. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +3 -0
  37. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  38. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +20 -0
  39. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  40. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +5 -0
  41. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -1
  42. package/lib/chain/blocks/payloadEnvelopeProcessor.js +6 -4
  43. package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
  44. package/lib/chain/blocks/types.d.ts +15 -21
  45. package/lib/chain/blocks/types.d.ts.map +1 -1
  46. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +24 -0
  47. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -0
  48. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +76 -0
  49. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -0
  50. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts +14 -0
  51. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -0
  52. package/lib/chain/blocks/verifyPayloadsDataAvailability.js +25 -0
  53. package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -0
  54. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +1 -1
  55. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +1 -1
  56. package/lib/chain/chain.d.ts +3 -3
  57. package/lib/chain/chain.d.ts.map +1 -1
  58. package/lib/chain/chain.js +16 -32
  59. package/lib/chain/chain.js.map +1 -1
  60. package/lib/chain/emitter.d.ts +16 -4
  61. package/lib/chain/emitter.d.ts.map +1 -1
  62. package/lib/chain/emitter.js +5 -0
  63. package/lib/chain/emitter.js.map +1 -1
  64. package/lib/chain/errors/executionPayloadEnvelope.d.ts +5 -0
  65. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  66. package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
  67. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  68. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  69. package/lib/chain/forkChoice/index.js +11 -19
  70. package/lib/chain/forkChoice/index.js.map +1 -1
  71. package/lib/chain/interface.d.ts +2 -2
  72. package/lib/chain/interface.d.ts.map +1 -1
  73. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  74. package/lib/chain/prepareNextSlot.js +22 -16
  75. package/lib/chain/prepareNextSlot.js.map +1 -1
  76. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +3 -9
  77. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  78. package/lib/chain/produceBlock/computeNewStateRoot.js +5 -32
  79. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  80. package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -8
  81. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  82. package/lib/chain/produceBlock/produceBlockBody.js +30 -19
  83. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  84. package/lib/chain/regen/errors.d.ts +1 -11
  85. package/lib/chain/regen/errors.d.ts.map +1 -1
  86. package/lib/chain/regen/errors.js +0 -2
  87. package/lib/chain/regen/errors.js.map +1 -1
  88. package/lib/chain/regen/interface.d.ts +6 -11
  89. package/lib/chain/regen/interface.d.ts.map +1 -1
  90. package/lib/chain/regen/queued.d.ts +6 -10
  91. package/lib/chain/regen/queued.d.ts.map +1 -1
  92. package/lib/chain/regen/queued.js +3 -10
  93. package/lib/chain/regen/queued.js.map +1 -1
  94. package/lib/chain/regen/regen.d.ts +0 -5
  95. package/lib/chain/regen/regen.d.ts.map +1 -1
  96. package/lib/chain/regen/regen.js +0 -8
  97. package/lib/chain/regen/regen.js.map +1 -1
  98. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -7
  99. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  100. package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -9
  101. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  102. package/lib/chain/stateCache/types.d.ts +0 -6
  103. package/lib/chain/stateCache/types.d.ts.map +1 -1
  104. package/lib/chain/stateCache/types.js.map +1 -1
  105. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  106. package/lib/chain/validation/executionPayloadEnvelope.js +20 -10
  107. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  108. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  109. package/lib/chain/validation/payloadAttestationMessage.js +4 -3
  110. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  111. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
  112. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
  113. package/lib/execution/engine/http.d.ts.map +1 -1
  114. package/lib/execution/engine/http.js +21 -14
  115. package/lib/execution/engine/http.js.map +1 -1
  116. package/lib/execution/engine/interface.d.ts +1 -0
  117. package/lib/execution/engine/interface.d.ts.map +1 -1
  118. package/lib/execution/engine/mock.d.ts.map +1 -1
  119. package/lib/execution/engine/mock.js +6 -0
  120. package/lib/execution/engine/mock.js.map +1 -1
  121. package/lib/execution/engine/types.d.ts +20 -0
  122. package/lib/execution/engine/types.d.ts.map +1 -1
  123. package/lib/execution/engine/types.js +18 -0
  124. package/lib/execution/engine/types.js.map +1 -1
  125. package/lib/network/gossip/topic.d.ts +3 -2
  126. package/lib/network/gossip/topic.d.ts.map +1 -1
  127. package/lib/network/network.js +1 -1
  128. package/lib/network/network.js.map +1 -1
  129. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  130. package/lib/network/processor/gossipHandlers.js +22 -6
  131. package/lib/network/processor/gossipHandlers.js.map +1 -1
  132. package/lib/node/nodejs.d.ts.map +1 -1
  133. package/lib/node/nodejs.js +4 -2
  134. package/lib/node/nodejs.js.map +1 -1
  135. package/lib/util/sszBytes.d.ts.map +1 -1
  136. package/lib/util/sszBytes.js +16 -3
  137. package/lib/util/sszBytes.js.map +1 -1
  138. package/package.json +16 -16
  139. package/src/api/impl/beacon/blocks/index.ts +1 -4
  140. package/src/api/impl/beacon/state/utils.ts +2 -2
  141. package/src/api/impl/validator/index.ts +3 -6
  142. package/src/chain/GetBlobsTracker.ts +1 -2
  143. package/src/chain/archiveStore/archiveStore.ts +5 -5
  144. package/src/chain/archiveStore/interface.ts +4 -4
  145. package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +6 -8
  146. package/src/chain/archiveStore/utils/archiveBlocks.ts +153 -94
  147. package/src/chain/blocks/importBlock.ts +22 -35
  148. package/src/chain/blocks/importExecutionPayload.ts +77 -103
  149. package/src/chain/blocks/index.ts +1 -2
  150. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +27 -0
  151. package/src/chain/blocks/payloadEnvelopeProcessor.ts +6 -5
  152. package/src/chain/blocks/types.ts +15 -26
  153. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +129 -0
  154. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +38 -0
  155. package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +1 -1
  156. package/src/chain/chain.ts +23 -48
  157. package/src/chain/emitter.ts +15 -3
  158. package/src/chain/errors/executionPayloadEnvelope.ts +6 -0
  159. package/src/chain/forkChoice/index.ts +8 -24
  160. package/src/chain/interface.ts +2 -2
  161. package/src/chain/prepareNextSlot.ts +25 -16
  162. package/src/chain/produceBlock/computeNewStateRoot.ts +6 -43
  163. package/src/chain/produceBlock/produceBlockBody.ts +41 -20
  164. package/src/chain/regen/errors.ts +1 -6
  165. package/src/chain/regen/interface.ts +6 -11
  166. package/src/chain/regen/queued.ts +6 -14
  167. package/src/chain/regen/regen.ts +0 -8
  168. package/src/chain/stateCache/persistentCheckpointsCache.ts +5 -15
  169. package/src/chain/stateCache/types.ts +0 -3
  170. package/src/chain/validation/executionPayloadEnvelope.ts +21 -11
  171. package/src/chain/validation/payloadAttestationMessage.ts +5 -3
  172. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
  173. package/src/execution/engine/http.ts +21 -14
  174. package/src/execution/engine/interface.ts +1 -0
  175. package/src/execution/engine/mock.ts +8 -1
  176. package/src/execution/engine/types.ts +41 -0
  177. package/src/network/network.ts +1 -1
  178. package/src/network/processor/gossipHandlers.ts +26 -10
  179. package/src/node/nodejs.ts +4 -2
  180. package/src/util/sszBytes.ts +21 -3
@@ -2,10 +2,9 @@ import path from "node:path";
2
2
  import {PrivateKey} from "@libp2p/interface";
3
3
  import {Type} from "@chainsafe/ssz";
4
4
  import {BeaconConfig} from "@lodestar/config";
5
- import {CheckpointWithPayloadStatus, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
5
+ import {CheckpointWithHex, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
6
6
  import {LoggerNode} from "@lodestar/logger/node";
7
7
  import {
8
- BUILDER_INDEX_SELF_BUILD,
9
8
  EFFECTIVE_BALANCE_INCREMENT,
10
9
  type ForkPostFulu,
11
10
  type ForkPostGloas,
@@ -24,7 +23,6 @@ import {
24
23
  getEffectiveBalancesFromStateBytes,
25
24
  isStatePostAltair,
26
25
  isStatePostElectra,
27
- isStatePostGloas,
28
26
  } from "@lodestar/state-transition";
29
27
  import {
30
28
  BeaconBlock,
@@ -93,8 +91,8 @@ import {
93
91
  } from "./opPools/index.js";
94
92
  import {IChainOptions} from "./options.js";
95
93
  import {PrepareNextSlotScheduler} from "./prepareNextSlot.js";
96
- import {computeNewStateRoot, computePayloadEnvelopeStateRoot} from "./produceBlock/computeNewStateRoot.js";
97
- import {AssembledBlockType, BlockType, ProduceFullGloas, ProduceResult} from "./produceBlock/index.js";
94
+ import {computeNewStateRoot} from "./produceBlock/computeNewStateRoot.js";
95
+ import {AssembledBlockType, BlockType, ProduceResult} from "./produceBlock/index.js";
98
96
  import {BlockAttributes, produceBlockBody, produceCommonBlockBody} from "./produceBlock/produceBlockBody.js";
99
97
  import {QueuedStateRegenerator, RegenCaller} from "./regen/index.js";
100
98
  import {ReprocessController} from "./reprocess.js";
@@ -118,7 +116,7 @@ import {DbCPStateDatastore, checkpointToDatastoreKey} from "./stateCache/datasto
118
116
  import {FileCPStateDatastore} from "./stateCache/datastore/file.js";
119
117
  import {CPStateDatastore} from "./stateCache/datastore/types.js";
120
118
  import {FIFOBlockStateCache} from "./stateCache/fifoBlockStateCache.js";
121
- import {PersistentCheckpointStateCache, fcCheckpointToHexPayload} from "./stateCache/persistentCheckpointsCache.js";
119
+ import {PersistentCheckpointStateCache} from "./stateCache/persistentCheckpointsCache.js";
122
120
  import {CheckpointStateCache} from "./stateCache/types.js";
123
121
  import {ValidatorMonitor} from "./validatorMonitor.js";
124
122
 
@@ -682,11 +680,11 @@ export class BeaconChain implements IBeaconChain {
682
680
  }
683
681
 
684
682
  getStateByCheckpoint(
685
- checkpoint: CheckpointWithPayloadStatus
683
+ checkpoint: CheckpointWithHex
686
684
  ): {state: IBeaconStateView; executionOptimistic: boolean; finalized: boolean} | null {
687
685
  // finalized or justified checkpoint states maynot be available with PersistentCheckpointStateCache, use getCheckpointStateOrBytes() api to get Uint8Array
688
- const checkpointHexPayload = fcCheckpointToHexPayload(checkpoint);
689
- const cachedStateCtx = this.regen.getCheckpointStateSync(checkpointHexPayload);
686
+ const checkpointHex = {epoch: checkpoint.epoch, rootHex: checkpoint.rootHex};
687
+ const cachedStateCtx = this.regen.getCheckpointStateSync(checkpointHex);
690
688
  if (cachedStateCtx) {
691
689
  const block = this.forkChoice.getBlockDefaultStatus(
692
690
  ssz.phase0.BeaconBlockHeader.hashTreeRoot(cachedStateCtx.latestBlockHeader)
@@ -703,10 +701,10 @@ export class BeaconChain implements IBeaconChain {
703
701
  }
704
702
 
705
703
  async getStateOrBytesByCheckpoint(
706
- checkpoint: CheckpointWithPayloadStatus
704
+ checkpoint: CheckpointWithHex
707
705
  ): Promise<{state: IBeaconStateView | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null> {
708
- const checkpointHexPayload = fcCheckpointToHexPayload(checkpoint);
709
- const cachedStateCtx = await this.regen.getCheckpointStateOrBytes(checkpointHexPayload);
706
+ const checkpointHex = {epoch: checkpoint.epoch, rootHex: checkpoint.rootHex};
707
+ const cachedStateCtx = await this.regen.getCheckpointStateOrBytes(checkpointHex);
710
708
  if (cachedStateCtx) {
711
709
  const block = this.forkChoice.getBlockDefaultStatus(checkpoint.root);
712
710
  const finalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
@@ -1062,7 +1060,7 @@ export class BeaconChain implements IBeaconChain {
1062
1060
  body,
1063
1061
  } as AssembledBlockType<T>;
1064
1062
 
1065
- const {newStateRoot, proposerReward, postBlockState} = computeNewStateRoot(this.metrics, state, block);
1063
+ const {newStateRoot, proposerReward} = computeNewStateRoot(this.metrics, state, block);
1066
1064
  block.stateRoot = newStateRoot;
1067
1065
  const blockRoot =
1068
1066
  produceResult.type === BlockType.Full
@@ -1071,26 +1069,9 @@ export class BeaconChain implements IBeaconChain {
1071
1069
  const blockRootHex = toRootHex(blockRoot);
1072
1070
 
1073
1071
  const fork = this.config.getForkName(slot);
1074
- if (isForkPostGloas(fork)) {
1075
- // TODO GLOAS: we should retire BlockType post-gloas, may need a new enum for self vs non-self built
1076
- if (produceResult.type !== BlockType.Full) {
1077
- throw Error(`Unexpected block type=${produceResult.type} for post-gloas fork=${fork}`);
1078
- }
1079
-
1080
- const gloasResult = produceResult as ProduceFullGloas;
1081
- const envelope: gloas.ExecutionPayloadEnvelope = {
1082
- payload: gloasResult.executionPayload,
1083
- executionRequests: gloasResult.executionRequests,
1084
- builderIndex: BUILDER_INDEX_SELF_BUILD,
1085
- beaconBlockRoot: blockRoot,
1086
- slot,
1087
- stateRoot: ZERO_HASH,
1088
- };
1089
- if (!isStatePostGloas(postBlockState)) {
1090
- throw Error(`Expected gloas+ post-state for execution payload envelope, got fork=${postBlockState.forkName}`);
1091
- }
1092
- const payloadEnvelopeStateRoot = computePayloadEnvelopeStateRoot(this.metrics, postBlockState, envelope);
1093
- gloasResult.payloadEnvelopeStateRoot = payloadEnvelopeStateRoot;
1072
+ // TODO GLOAS: we should retire BlockType post-gloas, may need a new enum for self vs non-self built
1073
+ if (isForkPostGloas(fork) && produceResult.type !== BlockType.Full) {
1074
+ throw Error(`Unexpected block type=${produceResult.type} for post-gloas fork=${fork}`);
1094
1075
  }
1095
1076
 
1096
1077
  // Track the produced block for consensus broadcast validations, later validation, etc.
@@ -1296,7 +1277,7 @@ export class BeaconChain implements IBeaconChain {
1296
1277
  * @param blockState state that declares justified checkpoint `checkpoint`
1297
1278
  */
1298
1279
  private justifiedBalancesGetter(
1299
- checkpoint: CheckpointWithPayloadStatus,
1280
+ checkpoint: CheckpointWithHex,
1300
1281
  blockState: IBeaconStateView
1301
1282
  ): EffectiveBalanceIncrements {
1302
1283
  this.metrics?.balancesCache.requests.inc();
@@ -1335,11 +1316,11 @@ export class BeaconChain implements IBeaconChain {
1335
1316
  * @param blockState state that declares justified checkpoint `checkpoint`
1336
1317
  */
1337
1318
  private closestJustifiedBalancesStateToCheckpoint(
1338
- checkpoint: CheckpointWithPayloadStatus,
1319
+ checkpoint: CheckpointWithHex,
1339
1320
  blockState: IBeaconStateView
1340
1321
  ): {state: IBeaconStateView; stateId: string; shouldWarn: boolean} {
1341
- const checkpointHexPayload = fcCheckpointToHexPayload(checkpoint);
1342
- const state = this.regen.getCheckpointStateSync(checkpointHexPayload);
1322
+ const checkpointHex = {epoch: checkpoint.epoch, rootHex: checkpoint.rootHex};
1323
+ const state = this.regen.getCheckpointStateSync(checkpointHex);
1343
1324
  if (state) {
1344
1325
  return {state, stateId: "checkpoint_state", shouldWarn: false};
1345
1326
  }
@@ -1350,10 +1331,7 @@ export class BeaconChain implements IBeaconChain {
1350
1331
  }
1351
1332
 
1352
1333
  // Find a state in the same branch of checkpoint at same epoch. Balances should exactly the same
1353
- for (const descendantBlock of this.forkChoice.forwardIterateDescendants(
1354
- checkpoint.rootHex,
1355
- checkpoint.payloadStatus
1356
- )) {
1334
+ for (const descendantBlock of this.forkChoice.forwardIterateDescendantsDefaultStatus(checkpoint.rootHex)) {
1357
1335
  if (computeEpochAtSlot(descendantBlock.slot) === checkpoint.epoch) {
1358
1336
  const descendantBlockState = this.regen.getStateSync(descendantBlock.stateRoot);
1359
1337
  if (descendantBlockState) {
@@ -1369,10 +1347,7 @@ export class BeaconChain implements IBeaconChain {
1369
1347
 
1370
1348
  // Find a state in the same branch of checkpoint at a latter epoch. Balances are not the same, but should be close
1371
1349
  // Note: must call .forwardIterateDescendants() again since nodes are not sorted
1372
- for (const descendantBlock of this.forkChoice.forwardIterateDescendants(
1373
- checkpoint.rootHex,
1374
- checkpoint.payloadStatus
1375
- )) {
1350
+ for (const descendantBlock of this.forkChoice.forwardIterateDescendantsDefaultStatus(checkpoint.rootHex)) {
1376
1351
  if (computeEpochAtSlot(descendantBlock.slot) > checkpoint.epoch) {
1377
1352
  const descendantBlockState = this.regen.getStateSync(descendantBlock.stateRoot);
1378
1353
  if (descendantBlockState) {
@@ -1476,7 +1451,7 @@ export class BeaconChain implements IBeaconChain {
1476
1451
  this.seenContributionAndProof.prune(head.slot);
1477
1452
  }
1478
1453
 
1479
- private onForkChoiceJustified(this: BeaconChain, cp: CheckpointWithPayloadStatus): void {
1454
+ private onForkChoiceJustified(this: BeaconChain, cp: CheckpointWithHex): void {
1480
1455
  this.logger.verbose("Fork choice justified", {epoch: cp.epoch, root: cp.rootHex});
1481
1456
  }
1482
1457
 
@@ -1487,7 +1462,7 @@ export class BeaconChain implements IBeaconChain {
1487
1462
  });
1488
1463
  }
1489
1464
 
1490
- private async onForkChoiceFinalized(this: BeaconChain, cp: CheckpointWithPayloadStatus): Promise<void> {
1465
+ private async onForkChoiceFinalized(this: BeaconChain, cp: CheckpointWithHex): Promise<void> {
1491
1466
  this.logger.verbose("Fork choice finalized", {epoch: cp.epoch, root: cp.rootHex});
1492
1467
  const finalizedSlot = computeStartSlotAtEpoch(cp.epoch);
1493
1468
  this.seenBlockProposers.prune(finalizedSlot);
@@ -1528,7 +1503,7 @@ export class BeaconChain implements IBeaconChain {
1528
1503
  }
1529
1504
  }
1530
1505
 
1531
- private async updateValidatorsCustodyRequirement(finalizedCheckpoint: CheckpointWithPayloadStatus): Promise<void> {
1506
+ private async updateValidatorsCustodyRequirement(finalizedCheckpoint: CheckpointWithHex): Promise<void> {
1532
1507
  if (this.custodyConfig.targetCustodyGroupCount === this.config.NUMBER_OF_CUSTODY_GROUPS) {
1533
1508
  // Custody requirements can only be increased, we can disable dynamic custody updates
1534
1509
  // if the node already maintains custody of all custody groups in case it is configured
@@ -1,12 +1,13 @@
1
1
  import {EventEmitter} from "node:events";
2
2
  import {StrictEventEmitter} from "strict-event-emitter-types";
3
3
  import {routes} from "@lodestar/api";
4
- import {CheckpointWithPayloadStatus} from "@lodestar/fork-choice";
4
+ import {CheckpointWithHex} from "@lodestar/fork-choice";
5
5
  import {IBeaconStateView} from "@lodestar/state-transition";
6
6
  import {DataColumnSidecar, RootHex, deneb, phase0} from "@lodestar/types";
7
7
  import {SignedExecutionPayloadEnvelope} from "@lodestar/types/gloas";
8
8
  import {PeerIdStr} from "../util/peerId.js";
9
9
  import {BlockInputSource, IBlockInput} from "./blocks/blockInput/types.js";
10
+ import {PayloadEnvelopeInput} from "./blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
10
11
 
11
12
  /**
12
13
  * Important chain events that occur during normal chain operation.
@@ -76,6 +77,11 @@ export enum ChainEvent {
76
77
  * cut-off window passes for waiting on gossip
77
78
  */
78
79
  incompleteBlockInput = "incompleteBlockInput",
80
+ /**
81
+ * Post-gloas: trigger BlockInputSync for payload envelopes whose envelope and/or sampled columns are partially
82
+ * received via gossip but are not complete by time the cut-off window passes for waiting on gossip
83
+ */
84
+ incompletePayloadEnvelope = "incompletePayloadEnvelope",
79
85
  }
80
86
 
81
87
  export type HeadEventData = routes.events.EventData[routes.events.EventType.head];
@@ -93,14 +99,19 @@ export type ChainEventData = {
93
99
  };
94
100
  [ChainEvent.unknownBlockRoot]: {rootHex: RootHex; peer?: PeerIdStr; source: BlockInputSource};
95
101
  [ChainEvent.incompleteBlockInput]: {blockInput: IBlockInput; peer: PeerIdStr; source: BlockInputSource};
102
+ [ChainEvent.incompletePayloadEnvelope]: {
103
+ payloadInput: PayloadEnvelopeInput;
104
+ peer: PeerIdStr;
105
+ source: BlockInputSource;
106
+ };
96
107
  [ChainEvent.unknownEnvelopeBlockRoot]: {rootHex: RootHex; peer?: PeerIdStr; source: BlockInputSource};
97
108
  };
98
109
 
99
110
  export type IChainEvents = ApiEvents & {
100
111
  [ChainEvent.checkpoint]: (checkpoint: phase0.Checkpoint, state: IBeaconStateView) => void;
101
112
 
102
- [ChainEvent.forkChoiceJustified]: (checkpoint: CheckpointWithPayloadStatus) => void;
103
- [ChainEvent.forkChoiceFinalized]: (checkpoint: CheckpointWithPayloadStatus) => void;
113
+ [ChainEvent.forkChoiceJustified]: (checkpoint: CheckpointWithHex) => void;
114
+ [ChainEvent.forkChoiceFinalized]: (checkpoint: CheckpointWithHex) => void;
104
115
 
105
116
  [ChainEvent.updateTargetCustodyGroupCount]: (targetGroupCount: number) => void;
106
117
 
@@ -116,6 +127,7 @@ export type IChainEvents = ApiEvents & {
116
127
  [ChainEvent.envelopeUnknownBlock]: (data: ChainEventData[ChainEvent.envelopeUnknownBlock]) => void;
117
128
  [ChainEvent.unknownBlockRoot]: (data: ChainEventData[ChainEvent.unknownBlockRoot]) => void;
118
129
  [ChainEvent.incompleteBlockInput]: (data: ChainEventData[ChainEvent.incompleteBlockInput]) => void;
130
+ [ChainEvent.incompletePayloadEnvelope]: (data: ChainEventData[ChainEvent.incompletePayloadEnvelope]) => void;
119
131
  [ChainEvent.unknownEnvelopeBlockRoot]: (data: ChainEventData[ChainEvent.unknownEnvelopeBlockRoot]) => void;
120
132
  };
121
133
 
@@ -11,6 +11,7 @@ export enum ExecutionPayloadEnvelopeErrorCode {
11
11
  SLOT_MISMATCH = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_SLOT_MISMATCH",
12
12
  BUILDER_INDEX_MISMATCH = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_BUILDER_INDEX_MISMATCH",
13
13
  BLOCK_HASH_MISMATCH = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_BLOCK_HASH_MISMATCH",
14
+ EXECUTION_REQUESTS_ROOT_MISMATCH = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_EXECUTION_REQUESTS_ROOT_MISMATCH",
14
15
  INVALID_SIGNATURE = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_INVALID_SIGNATURE",
15
16
  PAYLOAD_ENVELOPE_INPUT_MISSING = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_PAYLOAD_ENVELOPE_INPUT_MISSING",
16
17
  }
@@ -36,6 +37,11 @@ export type ExecutionPayloadEnvelopeErrorType =
36
37
  envelopeBlockHash: RootHex;
37
38
  bidBlockHash: RootHex | null;
38
39
  }
40
+ | {
41
+ code: ExecutionPayloadEnvelopeErrorCode.EXECUTION_REQUESTS_ROOT_MISMATCH;
42
+ envelopeRequestsRoot: RootHex;
43
+ bidRequestsRoot: RootHex;
44
+ }
39
45
  | {code: ExecutionPayloadEnvelopeErrorCode.INVALID_SIGNATURE}
40
46
  | {code: ExecutionPayloadEnvelopeErrorCode.PAYLOAD_ENVELOPE_INPUT_MISSING; blockRoot: RootHex};
41
47
 
@@ -8,7 +8,6 @@ import {
8
8
  ProtoArray,
9
9
  ProtoBlock,
10
10
  ForkChoiceOpts as RawForkChoiceOpts,
11
- getCheckpointPayloadStatus,
12
11
  } from "@lodestar/fork-choice";
13
12
  import {ZERO_HASH_HEX} from "@lodestar/params";
14
13
  import {
@@ -104,16 +103,6 @@ export function initializeForkChoiceFromFinalizedState(
104
103
 
105
104
  const isForkPostGloas = computeEpochAtSlot(state.slot) >= config.GLOAS_FORK_EPOCH;
106
105
 
107
- // Determine justified checkpoint payload status
108
- const justifiedPayloadStatus = isForkPostGloas
109
- ? PayloadStatus.PENDING
110
- : getCheckpointPayloadStatus(config, state, justifiedCheckpoint.epoch);
111
-
112
- // Determine finalized checkpoint payload status
113
- const finalizedPayloadStatus = isForkPostGloas
114
- ? PayloadStatus.PENDING
115
- : getCheckpointPayloadStatus(config, state, finalizedCheckpoint.epoch);
116
-
117
106
  return new forkchoiceConstructor(
118
107
  config,
119
108
 
@@ -123,8 +112,6 @@ export function initializeForkChoiceFromFinalizedState(
123
112
  finalizedCheckpoint,
124
113
  justifiedBalances,
125
114
  justifiedBalancesGetter,
126
- justifiedPayloadStatus,
127
- finalizedPayloadStatus,
128
115
  {
129
116
  onJustified: (cp) => emitter.emit(ChainEvent.forkChoiceJustified, cp),
130
117
  onFinalized: (cp) => emitter.emit(ChainEvent.forkChoiceFinalized, cp),
@@ -150,7 +137,9 @@ export function initializeForkChoiceFromFinalizedState(
150
137
 
151
138
  ...(isStatePostBellatrix(state) && state.isExecutionStateType && state.isMergeTransitionComplete
152
139
  ? {
153
- executionPayloadBlockHash: toRootHex(state.latestBlockHash),
140
+ executionPayloadBlockHash: isStatePostGloas(state)
141
+ ? toRootHex(state.latestBlockHash)
142
+ : toRootHex(state.latestExecutionPayloadHeader.blockHash),
154
143
  // TODO GLOAS: executionPayloadNumber is not tracked in BeaconState post-gloas (EIP-7732 removed
155
144
  // latestExecutionPayloadHeader). Using 0 as unavailable fallback until a solution is found.
156
145
  executionPayloadNumber: isStatePostGloas(state) ? 0 : state.payloadBlockNumber,
@@ -159,7 +148,7 @@ export function initializeForkChoiceFromFinalizedState(
159
148
  : {executionPayloadBlockHash: null, executionStatus: ExecutionStatus.PreMerge}),
160
149
 
161
150
  dataAvailabilityStatus: DataAvailabilityStatus.PreData,
162
- payloadStatus: isForkPostGloas ? PayloadStatus.PENDING : PayloadStatus.FULL, // TODO GLOAS: Post-gloas how do we know if the checkpoint payload is FULL or EMPTY?
151
+ payloadStatus: isForkPostGloas ? PayloadStatus.PENDING : PayloadStatus.FULL,
163
152
  parentBlockHash: isStatePostGloas(state) ? toRootHex(state.latestBlockHash) : null,
164
153
  },
165
154
  currentSlot
@@ -206,19 +195,12 @@ export function initializeForkChoiceFromUnfinalizedState(
206
195
 
207
196
  const isForkPostGloas = computeEpochAtSlot(unfinalizedState.slot) >= config.GLOAS_FORK_EPOCH;
208
197
 
209
- // For unfinalized state, use getCheckpointPayloadStatus to determine the correct status.
210
- // It checks state.execution_payload_availability to determine EMPTY vs FULL.
211
- const justifiedPayloadStatus = getCheckpointPayloadStatus(config, unfinalizedState, justifiedCheckpoint.epoch);
212
- const finalizedPayloadStatus = getCheckpointPayloadStatus(config, unfinalizedState, finalizedCheckpoint.epoch);
213
-
214
198
  const store = new ForkChoiceStore(
215
199
  currentSlot,
216
200
  justifiedCheckpoint,
217
201
  finalizedCheckpoint,
218
202
  justifiedBalances,
219
203
  justifiedBalancesGetter,
220
- justifiedPayloadStatus,
221
- finalizedPayloadStatus,
222
204
  {
223
205
  onJustified: (cp) => emitter.emit(ChainEvent.forkChoiceJustified, cp),
224
206
  onFinalized: (cp) => emitter.emit(ChainEvent.forkChoiceFinalized, cp),
@@ -247,7 +229,9 @@ export function initializeForkChoiceFromUnfinalizedState(
247
229
  unfinalizedState.isExecutionStateType &&
248
230
  unfinalizedState.isMergeTransitionComplete
249
231
  ? {
250
- executionPayloadBlockHash: toRootHex(unfinalizedState.latestBlockHash),
232
+ executionPayloadBlockHash: isStatePostGloas(unfinalizedState)
233
+ ? toRootHex(unfinalizedState.latestBlockHash)
234
+ : toRootHex(unfinalizedState.latestExecutionPayloadHeader.blockHash),
251
235
  // TODO GLOAS: executionPayloadNumber is not tracked in BeaconState post-gloas (EIP-7732 removed
252
236
  // latestExecutionPayloadHeader). Using 0 as unavailable fallback until a solution is found.
253
237
  executionPayloadNumber: isStatePostGloas(unfinalizedState) ? 0 : unfinalizedState.payloadBlockNumber,
@@ -256,7 +240,7 @@ export function initializeForkChoiceFromUnfinalizedState(
256
240
  : {executionPayloadBlockHash: null, executionStatus: ExecutionStatus.PreMerge}),
257
241
 
258
242
  dataAvailabilityStatus: DataAvailabilityStatus.PreData,
259
- payloadStatus: isForkPostGloas ? PayloadStatus.PENDING : PayloadStatus.FULL, // TODO GLOAS: Post-gloas how do we know if the checkpoint payload is FULL or EMPTY?
243
+ payloadStatus: isForkPostGloas ? PayloadStatus.PENDING : PayloadStatus.FULL,
260
244
  parentBlockHash: isStatePostGloas(unfinalizedState) ? toRootHex(unfinalizedState.latestBlockHash) : null,
261
245
  };
262
246
 
@@ -1,6 +1,6 @@
1
1
  import {Type} from "@chainsafe/ssz";
2
2
  import {BeaconConfig} from "@lodestar/config";
3
- import {CheckpointWithHex, CheckpointWithPayloadStatus, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
3
+ import {CheckpointWithHex, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
4
4
  import {EpochShuffling, IBeaconStateView, PubkeyCache} from "@lodestar/state-transition";
5
5
  import {
6
6
  BeaconBlock,
@@ -195,7 +195,7 @@ export interface IBeaconChain {
195
195
  ): {state: IBeaconStateView; executionOptimistic: boolean; finalized: boolean} | null;
196
196
  /** Return state bytes by checkpoint */
197
197
  getStateOrBytesByCheckpoint(
198
- checkpoint: CheckpointWithPayloadStatus
198
+ checkpoint: CheckpointWithHex
199
199
  ): Promise<{state: IBeaconStateView | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null>;
200
200
 
201
201
  /**
@@ -1,6 +1,6 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {ChainForkConfig} from "@lodestar/config";
3
- import {PayloadStatus, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
3
+ import {getSafeExecutionBlockHash} from "@lodestar/fork-choice";
4
4
  import {ForkPostBellatrix, ForkSeq, SLOTS_PER_EPOCH, isForkPostBellatrix} from "@lodestar/params";
5
5
  import {
6
6
  IBeaconStateView,
@@ -8,8 +8,9 @@ import {
8
8
  computeEpochAtSlot,
9
9
  computeTimeAtSlot,
10
10
  isStatePostBellatrix,
11
+ isStatePostGloas,
11
12
  } from "@lodestar/state-transition";
12
- import {Slot} from "@lodestar/types";
13
+ import {Bytes32, Slot} from "@lodestar/types";
13
14
  import {Logger, fromHex, isErrorAborted, sleep} from "@lodestar/utils";
14
15
  import {GENESIS_SLOT, ZERO_HASH_HEX} from "../constants/constants.js";
15
16
  import {BuilderStatus} from "../execution/builder/http.js";
@@ -81,6 +82,8 @@ export class PrepareNextSlotScheduler {
81
82
  // calling updateHead() here before we produce a block to reduce reorg possibility
82
83
  const headBlock = this.chain.recomputeForkChoiceHead(ForkchoiceCaller.prepareNextSlot);
83
84
  const {slot: headSlot, blockRoot: headRoot} = headBlock;
85
+ // may be updated below if we predict a proposer-boost-reorg
86
+ let updatedHeadRoot = headRoot;
84
87
 
85
88
  // PS: previously this was comparing slots, but that gave no leway on the skipped
86
89
  // slots on epoch bounday. Making it more fluid.
@@ -123,7 +126,6 @@ export class PrepareNextSlotScheduler {
123
126
  const proposerIndex = prepareState.getBeaconProposer(prepareSlot);
124
127
  const feeRecipient = this.chain.beaconProposerCache.get(proposerIndex);
125
128
  let updatedPrepareState = prepareState;
126
- let updatedHeadRoot = headRoot;
127
129
 
128
130
  if (feeRecipient) {
129
131
  // If we are proposing next slot, we need to predict if we can proposer-boost-reorg or not
@@ -156,25 +158,39 @@ export class PrepareNextSlotScheduler {
156
158
  this.logger.error("Builder disabled as the check status api failed", {prepareSlot}, e as Error);
157
159
  });
158
160
  }
161
+ }
162
+
163
+ if (!isStatePostBellatrix(updatedPrepareState)) {
164
+ throw new Error("Expected Bellatrix state for payload attributes");
165
+ }
166
+
167
+ let parentBlockHash: Bytes32;
168
+ if (isStatePostGloas(updatedPrepareState)) {
169
+ parentBlockHash = this.chain.forkChoice.shouldExtendPayload(updatedHeadRoot)
170
+ ? updatedPrepareState.latestExecutionPayloadBid.blockHash
171
+ : updatedPrepareState.latestExecutionPayloadBid.parentBlockHash;
172
+ } else {
173
+ parentBlockHash = updatedPrepareState.latestExecutionPayloadHeader.blockHash;
174
+ }
159
175
 
176
+ if (feeRecipient) {
160
177
  const preparationTime =
161
178
  computeTimeAtSlot(this.config, prepareSlot, this.chain.genesisTime) - Date.now() / 1000;
162
179
  this.metrics?.blockPayload.payloadAdvancePrepTime.observe(preparationTime);
163
- if (!isStatePostBellatrix(updatedPrepareState)) {
164
- throw new Error("Expected Bellatrix state for payload preparation");
165
- }
166
180
 
167
181
  const safeBlockHash = getSafeExecutionBlockHash(this.chain.forkChoice);
168
182
  const finalizedBlockHash =
169
183
  this.chain.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
184
+
170
185
  // awaiting here instead of throwing an async call because there is no other task
171
- // left for scheduler and this gives nice sematics to catch and log errors in the
186
+ // left for scheduler and this gives nice semantics to catch and log errors in the
172
187
  // try/catch wrapper here.
173
188
  await prepareExecutionPayload(
174
189
  this.chain,
175
190
  this.logger,
176
191
  fork as ForkPostBellatrix, // State is of execution type
177
192
  fromHex(updatedHeadRoot),
193
+ parentBlockHash,
178
194
  safeBlockHash,
179
195
  finalizedBlockHash,
180
196
  updatedPrepareState,
@@ -187,10 +203,6 @@ export class PrepareNextSlotScheduler {
187
203
  });
188
204
  }
189
205
 
190
- if (!isStatePostBellatrix(updatedPrepareState)) {
191
- throw new Error("Expected Bellatrix state for payload attributes");
192
- }
193
-
194
206
  this.computeStateHashTreeRoot(updatedPrepareState, isEpochTransition);
195
207
 
196
208
  // If emitPayloadAttributes is true emit a SSE payloadAttributes event
@@ -202,6 +214,7 @@ export class PrepareNextSlotScheduler {
202
214
  prepareState: updatedPrepareState,
203
215
  prepareSlot,
204
216
  parentBlockRoot: fromHex(headRoot),
217
+ parentBlockHash,
205
218
  // The likely consumers of this API are builders and will anyway ignore the
206
219
  // feeRecipient, so just pass zero hash for now till a real use case arises
207
220
  feeRecipient: "0x0000000000000000000000000000000000000000000000000000000000000000",
@@ -217,11 +230,7 @@ export class PrepareNextSlotScheduler {
217
230
  // + if next slot is a skipped slot, it'd help getting target checkpoint state faster to validate attestations
218
231
  if (isEpochTransition) {
219
232
  this.metrics?.precomputeNextEpochTransition.count.inc({result: "success"}, 1);
220
- // Determine payloadPresent from head block's payload status
221
- // Pre-Gloas: payloadStatus is always FULL → payloadPresent = true
222
- // Post-Gloas: FULL → true, EMPTY → false, PENDING → false (conservative, treat as block state)
223
- const payloadPresent = headBlock.payloadStatus === PayloadStatus.FULL;
224
- const previousHits = this.chain.regen.updatePreComputedCheckpoint(headRoot, nextEpoch, payloadPresent);
233
+ const previousHits = this.chain.regen.updatePreComputedCheckpoint(headRoot, nextEpoch);
225
234
  if (previousHits === 0) {
226
235
  this.metrics?.precomputeNextEpochTransition.waste.inc();
227
236
  }
@@ -1,12 +1,10 @@
1
1
  import {
2
2
  DataAvailabilityStatus,
3
3
  ExecutionPayloadStatus,
4
- G2_POINT_AT_INFINITY,
5
4
  IBeaconStateView,
6
- IBeaconStateViewGloas,
7
5
  StateHashTreeRootSource,
8
6
  } from "@lodestar/state-transition";
9
- import {BeaconBlock, BlindedBeaconBlock, Gwei, Root, gloas} from "@lodestar/types";
7
+ import {BeaconBlock, BlindedBeaconBlock, Gwei, Root} from "@lodestar/types";
10
8
  import {ZERO_HASH} from "../../constants/index.js";
11
9
  import {Metrics} from "../../metrics/index.js";
12
10
 
@@ -19,11 +17,11 @@ export function computeNewStateRoot(
19
17
  metrics: Metrics | null,
20
18
  state: IBeaconStateView,
21
19
  block: BeaconBlock | BlindedBeaconBlock
22
- ): {newStateRoot: Root; proposerReward: Gwei; postBlockState: IBeaconStateView} {
20
+ ): {newStateRoot: Root; proposerReward: Gwei; postState: IBeaconStateView} {
23
21
  // Set signature to zero to re-use stateTransition() function which requires the SignedBeaconBlock type
24
22
  const blockEmptySig = {message: block, signature: ZERO_HASH};
25
23
 
26
- const postBlockState = state.stateTransition(
24
+ const postState = state.stateTransition(
27
25
  blockEmptySig,
28
26
  {
29
27
  // ExecutionPayloadStatus.valid: Assume payload valid, it has been produced by a trusted EL
@@ -42,49 +40,14 @@ export function computeNewStateRoot(
42
40
  {metrics}
43
41
  );
44
42
 
45
- const {attestations, syncAggregate, slashing} = postBlockState.proposerRewards;
43
+ const {attestations, syncAggregate, slashing} = postState.proposerRewards;
46
44
  const proposerReward = BigInt(attestations + syncAggregate + slashing);
47
45
 
48
46
  const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({
49
47
  source: StateHashTreeRootSource.computeNewStateRoot,
50
48
  });
51
- const newStateRoot = postBlockState.hashTreeRoot();
49
+ const newStateRoot = postState.hashTreeRoot();
52
50
  hashTreeRootTimer?.();
53
51
 
54
- return {newStateRoot, proposerReward, postBlockState};
55
- }
56
-
57
- /**
58
- * Compute the state root after processing an execution payload envelope.
59
- * Similar to `computeNewStateRoot` but for payload envelope processing.
60
- *
61
- */
62
- export function computePayloadEnvelopeStateRoot(
63
- metrics: Metrics | null,
64
- postBlockState: IBeaconStateViewGloas,
65
- envelope: gloas.ExecutionPayloadEnvelope
66
- ): Root {
67
- const signedEnvelope: gloas.SignedExecutionPayloadEnvelope = {
68
- message: envelope,
69
- signature: G2_POINT_AT_INFINITY,
70
- };
71
-
72
- const processEnvelopeTimer = metrics?.blockPayload.executionPayloadEnvelopeProcessingTime.startTimer();
73
- const postPayloadState = postBlockState.processExecutionPayloadEnvelope(signedEnvelope, {
74
- // Signature is zero-ed (G2_POINT_AT_INFINITY), skip verification
75
- verifySignature: false,
76
- // State root is being computed here, the envelope doesn't have it yet
77
- verifyStateRoot: false,
78
- // Preserve cache in source state, since the resulting state is not added to the state cache
79
- dontTransferCache: true,
80
- });
81
- processEnvelopeTimer?.();
82
-
83
- const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({
84
- source: StateHashTreeRootSource.computePayloadEnvelopeStateRoot,
85
- });
86
- const stateRoot = postPayloadState.hashTreeRoot();
87
- hashTreeRootTimer?.();
88
-
89
- return stateRoot;
52
+ return {newStateRoot, proposerReward, postState};
90
53
  }