@lodestar/beacon-node 1.43.0-dev.ade910fc78 → 1.43.0-dev.b741495bdc

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 (201) 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/attestationError.d.ts +8 -1
  65. package/lib/chain/errors/attestationError.d.ts.map +1 -1
  66. package/lib/chain/errors/attestationError.js +4 -0
  67. package/lib/chain/errors/attestationError.js.map +1 -1
  68. package/lib/chain/errors/executionPayloadBid.d.ts +5 -0
  69. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  70. package/lib/chain/errors/executionPayloadBid.js +1 -0
  71. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  72. package/lib/chain/errors/executionPayloadEnvelope.d.ts +5 -0
  73. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  74. package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
  75. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  76. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  77. package/lib/chain/forkChoice/index.js +11 -15
  78. package/lib/chain/forkChoice/index.js.map +1 -1
  79. package/lib/chain/interface.d.ts +2 -2
  80. package/lib/chain/interface.d.ts.map +1 -1
  81. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  82. package/lib/chain/prepareNextSlot.js +22 -16
  83. package/lib/chain/prepareNextSlot.js.map +1 -1
  84. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +3 -9
  85. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  86. package/lib/chain/produceBlock/computeNewStateRoot.js +5 -32
  87. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  88. package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -8
  89. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  90. package/lib/chain/produceBlock/produceBlockBody.js +30 -19
  91. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  92. package/lib/chain/regen/errors.d.ts +1 -11
  93. package/lib/chain/regen/errors.d.ts.map +1 -1
  94. package/lib/chain/regen/errors.js +0 -2
  95. package/lib/chain/regen/errors.js.map +1 -1
  96. package/lib/chain/regen/interface.d.ts +6 -11
  97. package/lib/chain/regen/interface.d.ts.map +1 -1
  98. package/lib/chain/regen/queued.d.ts +6 -10
  99. package/lib/chain/regen/queued.d.ts.map +1 -1
  100. package/lib/chain/regen/queued.js +3 -10
  101. package/lib/chain/regen/queued.js.map +1 -1
  102. package/lib/chain/regen/regen.d.ts +0 -5
  103. package/lib/chain/regen/regen.d.ts.map +1 -1
  104. package/lib/chain/regen/regen.js +0 -8
  105. package/lib/chain/regen/regen.js.map +1 -1
  106. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -7
  107. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  108. package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -9
  109. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  110. package/lib/chain/stateCache/types.d.ts +0 -6
  111. package/lib/chain/stateCache/types.d.ts.map +1 -1
  112. package/lib/chain/stateCache/types.js.map +1 -1
  113. package/lib/chain/validation/aggregateAndProof.js +12 -0
  114. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  115. package/lib/chain/validation/attestation.d.ts.map +1 -1
  116. package/lib/chain/validation/attestation.js +12 -0
  117. package/lib/chain/validation/attestation.js.map +1 -1
  118. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  119. package/lib/chain/validation/executionPayloadBid.js +13 -1
  120. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  121. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  122. package/lib/chain/validation/executionPayloadEnvelope.js +21 -11
  123. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  124. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  125. package/lib/chain/validation/payloadAttestationMessage.js +4 -3
  126. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  127. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
  128. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
  129. package/lib/execution/engine/http.d.ts.map +1 -1
  130. package/lib/execution/engine/http.js +21 -14
  131. package/lib/execution/engine/http.js.map +1 -1
  132. package/lib/execution/engine/interface.d.ts +1 -0
  133. package/lib/execution/engine/interface.d.ts.map +1 -1
  134. package/lib/execution/engine/mock.d.ts.map +1 -1
  135. package/lib/execution/engine/mock.js +6 -0
  136. package/lib/execution/engine/mock.js.map +1 -1
  137. package/lib/execution/engine/types.d.ts +20 -0
  138. package/lib/execution/engine/types.d.ts.map +1 -1
  139. package/lib/execution/engine/types.js +18 -0
  140. package/lib/execution/engine/types.js.map +1 -1
  141. package/lib/network/gossip/topic.d.ts +3 -2
  142. package/lib/network/gossip/topic.d.ts.map +1 -1
  143. package/lib/network/network.js +1 -1
  144. package/lib/network/network.js.map +1 -1
  145. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  146. package/lib/network/processor/gossipHandlers.js +22 -6
  147. package/lib/network/processor/gossipHandlers.js.map +1 -1
  148. package/lib/node/nodejs.d.ts.map +1 -1
  149. package/lib/node/nodejs.js +4 -2
  150. package/lib/node/nodejs.js.map +1 -1
  151. package/lib/util/sszBytes.d.ts.map +1 -1
  152. package/lib/util/sszBytes.js +16 -3
  153. package/lib/util/sszBytes.js.map +1 -1
  154. package/package.json +16 -16
  155. package/src/api/impl/beacon/blocks/index.ts +1 -4
  156. package/src/api/impl/beacon/state/utils.ts +2 -2
  157. package/src/api/impl/validator/index.ts +3 -6
  158. package/src/chain/GetBlobsTracker.ts +1 -2
  159. package/src/chain/archiveStore/archiveStore.ts +5 -5
  160. package/src/chain/archiveStore/interface.ts +4 -4
  161. package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +6 -8
  162. package/src/chain/archiveStore/utils/archiveBlocks.ts +153 -94
  163. package/src/chain/blocks/importBlock.ts +22 -35
  164. package/src/chain/blocks/importExecutionPayload.ts +77 -103
  165. package/src/chain/blocks/index.ts +1 -2
  166. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +27 -0
  167. package/src/chain/blocks/payloadEnvelopeProcessor.ts +6 -5
  168. package/src/chain/blocks/types.ts +15 -26
  169. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +129 -0
  170. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +38 -0
  171. package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +1 -1
  172. package/src/chain/chain.ts +23 -48
  173. package/src/chain/emitter.ts +15 -3
  174. package/src/chain/errors/attestationError.ts +6 -1
  175. package/src/chain/errors/executionPayloadBid.ts +6 -0
  176. package/src/chain/errors/executionPayloadEnvelope.ts +6 -0
  177. package/src/chain/forkChoice/index.ts +8 -20
  178. package/src/chain/interface.ts +2 -2
  179. package/src/chain/prepareNextSlot.ts +25 -16
  180. package/src/chain/produceBlock/computeNewStateRoot.ts +6 -43
  181. package/src/chain/produceBlock/produceBlockBody.ts +41 -20
  182. package/src/chain/regen/errors.ts +1 -6
  183. package/src/chain/regen/interface.ts +6 -11
  184. package/src/chain/regen/queued.ts +6 -14
  185. package/src/chain/regen/regen.ts +0 -8
  186. package/src/chain/stateCache/persistentCheckpointsCache.ts +5 -15
  187. package/src/chain/stateCache/types.ts +0 -3
  188. package/src/chain/validation/aggregateAndProof.ts +13 -0
  189. package/src/chain/validation/attestation.ts +13 -0
  190. package/src/chain/validation/executionPayloadBid.ts +14 -0
  191. package/src/chain/validation/executionPayloadEnvelope.ts +22 -12
  192. package/src/chain/validation/payloadAttestationMessage.ts +5 -3
  193. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
  194. package/src/execution/engine/http.ts +21 -14
  195. package/src/execution/engine/interface.ts +1 -0
  196. package/src/execution/engine/mock.ts +8 -1
  197. package/src/execution/engine/types.ts +41 -0
  198. package/src/network/network.ts +1 -1
  199. package/src/network/processor/gossipHandlers.ts +26 -10
  200. package/src/node/nodejs.ts +4 -2
  201. package/src/util/sszBytes.ts +21 -3
@@ -19,7 +19,6 @@ import {
19
19
  IBeaconStateView,
20
20
  type IBeaconStateViewBellatrix,
21
21
  computeTimeAtSlot,
22
- isParentBlockFull,
23
22
  isStatePostBellatrix,
24
23
  isStatePostCapella,
25
24
  isStatePostGloas,
@@ -47,8 +46,9 @@ import {
47
46
  electra,
48
47
  fulu,
49
48
  gloas,
49
+ ssz,
50
50
  } from "@lodestar/types";
51
- import {Logger, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
51
+ import {Logger, byteArrayEquals, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
52
52
  import {ZERO_HASH_HEX} from "../../constants/index.js";
53
53
  import {numToQuantity} from "../../execution/engine/utils.js";
54
54
  import {
@@ -111,12 +111,6 @@ export type ProduceFullGloas = {
111
111
  executionRequests: electra.ExecutionRequests;
112
112
  blobsBundle: BlobsBundle<ForkPostGloas>;
113
113
  cells: fulu.Cell[][];
114
- /**
115
- * Cached payload envelope state root computed during block production.
116
- * This is the state root after running `processExecutionPayloadEnvelope` on the
117
- * post-block state, and later used to construct the `ExecutionPayloadEnvelope`.
118
- */
119
- payloadEnvelopeStateRoot: Root;
120
114
  };
121
115
  export type ProduceFullFulu = {
122
116
  type: BlockType.Full;
@@ -220,11 +214,15 @@ export async function produceBlockBody<T extends BlockType>(
220
214
  });
221
215
 
222
216
  // Get execution payload from EL
217
+ const parentBlockHash = this.forkChoice.shouldExtendPayload(toRootHex(parentBlockRoot))
218
+ ? currentState.latestExecutionPayloadBid.blockHash
219
+ : currentState.latestExecutionPayloadBid.parentBlockHash;
223
220
  const prepareRes = await prepareExecutionPayload(
224
221
  this,
225
222
  this.logger,
226
223
  fork,
227
224
  parentBlockRoot,
225
+ parentBlockHash,
228
226
  safeBlockHash,
229
227
  finalizedBlockHash ?? ZERO_HASH_HEX,
230
228
  currentState,
@@ -261,8 +259,8 @@ export async function produceBlockBody<T extends BlockType>(
261
259
 
262
260
  // Create self-build execution payload bid
263
261
  const bid: gloas.ExecutionPayloadBid = {
264
- parentBlockHash: currentState.latestBlockHash,
265
- parentBlockRoot: parentBlockRoot,
262
+ parentBlockHash,
263
+ parentBlockRoot,
266
264
  blockHash: executionPayload.blockHash,
267
265
  prevRandao: currentState.getRandaoMix(currentState.epoch),
268
266
  feeRecipient: executionPayload.feeRecipient,
@@ -272,6 +270,7 @@ export async function produceBlockBody<T extends BlockType>(
272
270
  value: 0,
273
271
  executionPayment: 0,
274
272
  blobKzgCommitments: blobsBundle.commitments,
273
+ executionRequestsRoot: ssz.electra.ExecutionRequests.hashTreeRoot(executionRequests),
275
274
  };
276
275
  const signedBid: gloas.SignedExecutionPayloadBid = {
277
276
  message: bid,
@@ -283,6 +282,7 @@ export async function produceBlockBody<T extends BlockType>(
283
282
  gloasBody.signedExecutionPayloadBid = signedBid;
284
283
  // TODO GLOAS: Get payload attestations from pool for previous slot
285
284
  gloasBody.payloadAttestations = [];
285
+ // TODO GLOAS: set parentExecutionRequests in the block body
286
286
  blockBody = gloasBody as AssembledBodyType<T>;
287
287
 
288
288
  // Store execution payload data required to construct execution payload envelope later
@@ -340,6 +340,7 @@ export async function produceBlockBody<T extends BlockType>(
340
340
  this.logger,
341
341
  fork,
342
342
  parentBlockRoot,
343
+ currentState.latestExecutionPayloadHeader.blockHash,
343
344
  safeBlockHash,
344
345
  finalizedBlockHash ?? ZERO_HASH_HEX,
345
346
  currentState,
@@ -448,6 +449,7 @@ export async function produceBlockBody<T extends BlockType>(
448
449
  this.logger,
449
450
  fork,
450
451
  parentBlockRoot,
452
+ currentState.latestExecutionPayloadHeader.blockHash,
451
453
  safeBlockHash,
452
454
  finalizedBlockHash ?? ZERO_HASH_HEX,
453
455
  currentState,
@@ -613,17 +615,17 @@ export async function prepareExecutionPayload(
613
615
  logger: Logger,
614
616
  fork: ForkPostBellatrix,
615
617
  parentBlockRoot: Root,
618
+ parentBlockHash: Bytes32,
616
619
  safeBlockHash: RootHex,
617
620
  finalizedBlockHash: RootHex,
618
621
  state: IBeaconStateViewBellatrix,
619
622
  suggestedFeeRecipient: string
620
623
  ): Promise<{prepType: PayloadPreparationType; payloadId: PayloadId}> {
621
- const parentHash = state.latestBlockHash;
622
624
  const timestamp = computeTimeAtSlot(chain.config, state.slot, state.genesisTime);
623
625
  const prevRandao = state.getRandaoMix(state.epoch);
624
626
 
625
627
  const payloadIdCached = chain.executionEngine.payloadIdCache.get({
626
- headBlockHash: toRootHex(parentHash),
628
+ headBlockHash: toRootHex(parentBlockHash),
627
629
  finalizedBlockHash,
628
630
  timestamp: numToQuantity(timestamp),
629
631
  prevRandao: toHex(prevRandao),
@@ -652,12 +654,13 @@ export async function prepareExecutionPayload(
652
654
  prepareState: state,
653
655
  prepareSlot: state.slot,
654
656
  parentBlockRoot,
657
+ parentBlockHash,
655
658
  feeRecipient: suggestedFeeRecipient,
656
659
  });
657
660
 
658
661
  payloadId = await chain.executionEngine.notifyForkchoiceUpdate(
659
662
  fork,
660
- toRootHex(parentHash),
663
+ toRootHex(parentBlockHash),
661
664
  safeBlockHash,
662
665
  finalizedBlockHash,
663
666
  attributes
@@ -709,20 +712,30 @@ export function getPayloadAttributesForSSE(
709
712
  prepareState,
710
713
  prepareSlot,
711
714
  parentBlockRoot,
715
+ parentBlockHash,
712
716
  feeRecipient,
713
- }: {prepareState: IBeaconStateViewBellatrix; prepareSlot: Slot; parentBlockRoot: Root; feeRecipient: string}
717
+ }: {
718
+ prepareState: IBeaconStateViewBellatrix;
719
+ prepareSlot: Slot;
720
+ parentBlockRoot: Root;
721
+ parentBlockHash: Bytes32;
722
+ feeRecipient: string;
723
+ }
714
724
  ): SSEPayloadAttributes {
715
- const parentHash = prepareState.latestBlockHash;
716
725
  const payloadAttributes = preparePayloadAttributes(fork, chain, {
717
726
  prepareState,
718
727
  prepareSlot,
719
728
  parentBlockRoot,
729
+ parentBlockHash,
720
730
  feeRecipient,
721
731
  });
722
732
 
723
733
  let parentBlockNumber: number;
724
734
  if (isForkPostGloas(fork)) {
725
- const parentBlock = chain.forkChoice.getBlockHexAndBlockHash(toRootHex(parentBlockRoot), toRootHex(parentHash));
735
+ const parentBlock = chain.forkChoice.getBlockHexAndBlockHash(
736
+ toRootHex(parentBlockRoot),
737
+ toRootHex(parentBlockHash)
738
+ );
726
739
  if (parentBlock?.executionPayloadBlockHash == null) {
727
740
  throw Error(`Parent block not found in fork choice root=${toRootHex(parentBlockRoot)}`);
728
741
  }
@@ -736,7 +749,7 @@ export function getPayloadAttributesForSSE(
736
749
  proposalSlot: prepareSlot,
737
750
  parentBlockNumber,
738
751
  parentBlockRoot,
739
- parentBlockHash: parentHash,
752
+ parentBlockHash,
740
753
  payloadAttributes,
741
754
  };
742
755
  return ssePayloadAttributes;
@@ -751,11 +764,13 @@ function preparePayloadAttributes(
751
764
  prepareState,
752
765
  prepareSlot,
753
766
  parentBlockRoot,
767
+ parentBlockHash,
754
768
  feeRecipient,
755
769
  }: {
756
770
  prepareState: IBeaconStateViewBellatrix;
757
771
  prepareSlot: Slot;
758
772
  parentBlockRoot: Root;
773
+ parentBlockHash: Bytes32;
759
774
  feeRecipient: string;
760
775
  }
761
776
  ): SSEPayloadAttributes["payloadAttributes"] {
@@ -772,13 +787,15 @@ function preparePayloadAttributes(
772
787
  throw new Error("Expected Capella state for withdrawals");
773
788
  }
774
789
 
775
- if (isStatePostGloas(prepareState) && !isParentBlockFull(prepareState)) {
790
+ if (isStatePostGloas(prepareState)) {
791
+ const isExtendingPayload = byteArrayEquals(parentBlockHash, prepareState.latestExecutionPayloadBid.blockHash);
776
792
  // When the parent block is empty, state.payloadExpectedWithdrawals holds a batch
777
793
  // already deducted from CL balances but never credited on the EL (the envelope
778
794
  // was not delivered). The next payload must carry those same withdrawals to
779
795
  // restore CL/EL consistency, otherwise validators permanently lose that balance.
780
- (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
781
- prepareState.payloadExpectedWithdrawals;
796
+ (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals = isExtendingPayload
797
+ ? prepareState.getExpectedWithdrawals().expectedWithdrawals
798
+ : prepareState.payloadExpectedWithdrawals;
782
799
  } else {
783
800
  // withdrawals logic is now fork aware as it changes on electra fork post capella
784
801
  (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
@@ -790,6 +807,10 @@ function preparePayloadAttributes(
790
807
  (payloadAttributes as deneb.SSEPayloadAttributes["payloadAttributes"]).parentBeaconBlockRoot = parentBlockRoot;
791
808
  }
792
809
 
810
+ if (ForkSeq[fork] >= ForkSeq.gloas) {
811
+ (payloadAttributes as gloas.SSEPayloadAttributes["payloadAttributes"]).slotNumber = prepareSlot;
812
+ }
813
+
793
814
  return payloadAttributes;
794
815
  }
795
816
 
@@ -1,4 +1,3 @@
1
- import {PayloadStatus} from "@lodestar/fork-choice";
2
1
  import {Root, RootHex, Slot} from "@lodestar/types";
3
2
 
4
3
  export enum RegenErrorCode {
@@ -10,8 +9,6 @@ export enum RegenErrorCode {
10
9
  BLOCK_NOT_IN_DB = "REGEN_ERROR_BLOCK_NOT_IN_DB",
11
10
  STATE_TRANSITION_ERROR = "REGEN_ERROR_STATE_TRANSITION_ERROR",
12
11
  INVALID_STATE_ROOT = "REGEN_ERROR_INVALID_STATE_ROOT",
13
- UNEXPECTED_PAYLOAD_STATUS = "REGEN_ERROR_UNEXPECTED_PAYLOAD_STATUS",
14
- INTERNAL_ERROR = "REGEN_ERROR_INTERNAL_ERROR",
15
12
  }
16
13
 
17
14
  export type RegenErrorType =
@@ -22,9 +19,7 @@ export type RegenErrorType =
22
19
  | {code: RegenErrorCode.TOO_MANY_BLOCK_PROCESSED; stateRoot: RootHex | Root}
23
20
  | {code: RegenErrorCode.BLOCK_NOT_IN_DB; blockRoot: RootHex | Root}
24
21
  | {code: RegenErrorCode.STATE_TRANSITION_ERROR; error: Error}
25
- | {code: RegenErrorCode.INVALID_STATE_ROOT; slot: Slot; expected: RootHex; actual: RootHex}
26
- | {code: RegenErrorCode.UNEXPECTED_PAYLOAD_STATUS; blockRoot: RootHex | Root; payloadStatus: PayloadStatus}
27
- | {code: RegenErrorCode.INTERNAL_ERROR; message: string};
22
+ | {code: RegenErrorCode.INVALID_STATE_ROOT; slot: Slot; expected: RootHex; actual: RootHex};
28
23
 
29
24
  export class RegenError extends Error {
30
25
  type: RegenErrorType;
@@ -2,7 +2,7 @@ import {routes} from "@lodestar/api";
2
2
  import {ProtoBlock} from "@lodestar/fork-choice";
3
3
  import {IBeaconStateView} from "@lodestar/state-transition";
4
4
  import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
5
- import {CheckpointHexPayload} from "../stateCache/types.js";
5
+ import {CheckpointHex} from "../stateCache/types.js";
6
6
 
7
7
  export enum RegenCaller {
8
8
  getDuties = "getDuties",
@@ -40,20 +40,15 @@ export interface IStateRegenerator extends IStateRegeneratorInternal {
40
40
  dumpCacheSummary(): routes.lodestar.StateCacheItem[];
41
41
  getStateSync(stateRoot: RootHex): IBeaconStateView | null;
42
42
  getPreStateSync(block: BeaconBlock): IBeaconStateView | null;
43
- getCheckpointStateOrBytes(cp: CheckpointHexPayload): Promise<IBeaconStateView | Uint8Array | null>;
44
- getCheckpointStateSync(cp: CheckpointHexPayload): IBeaconStateView | null;
43
+ getCheckpointStateOrBytes(cp: CheckpointHex): Promise<IBeaconStateView | Uint8Array | null>;
44
+ getCheckpointStateSync(cp: CheckpointHex): IBeaconStateView | null;
45
45
  getClosestHeadState(head: ProtoBlock): IBeaconStateView | null;
46
46
  pruneOnCheckpoint(finalizedEpoch: Epoch, justifiedEpoch: Epoch, headStateRoot: RootHex): void;
47
47
  pruneOnFinalized(finalizedEpoch: Epoch): void;
48
- processBlockState(blockRootHex: RootHex, postState: IBeaconStateView): void;
49
- processPayloadState(payloadState: IBeaconStateView): void;
50
- /**
51
- * payloadPresent is true if this is payload state, false if block state.
52
- * payloadPresent is always true for pre-gloas.
53
- */
54
- addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView, payloadPresent: boolean): void;
48
+ processState(blockRootHex: RootHex, postState: IBeaconStateView): void;
49
+ addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView): void;
55
50
  updateHeadState(newHead: ProtoBlock, maybeHeadState: IBeaconStateView): void;
56
- updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch, payloadPresent: boolean): number | null;
51
+ updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null;
57
52
  }
58
53
 
59
54
  /**
@@ -5,7 +5,7 @@ import {BeaconBlock, Epoch, RootHex, Slot, isGloasBeaconBlock, phase0} from "@lo
5
5
  import {Logger, toRootHex} from "@lodestar/utils";
6
6
  import {Metrics} from "../../metrics/index.js";
7
7
  import {JobItemQueue} from "../../util/queue/index.js";
8
- import {BlockStateCache, CheckpointHexPayload, CheckpointStateCache} from "../stateCache/types.js";
8
+ import {BlockStateCache, CheckpointHex, CheckpointStateCache} from "../stateCache/types.js";
9
9
  import {RegenError, RegenErrorCode} from "./errors.js";
10
10
  import {
11
11
  IStateRegenerator,
@@ -125,14 +125,14 @@ export class QueuedStateRegenerator implements IStateRegenerator {
125
125
  return null;
126
126
  }
127
127
 
128
- async getCheckpointStateOrBytes(cp: CheckpointHexPayload): Promise<IBeaconStateView | Uint8Array | null> {
128
+ async getCheckpointStateOrBytes(cp: CheckpointHex): Promise<IBeaconStateView | Uint8Array | null> {
129
129
  return this.checkpointStateCache.getStateOrBytes(cp);
130
130
  }
131
131
 
132
132
  /**
133
133
  * Get checkpoint state from cache
134
134
  */
135
- getCheckpointStateSync(cp: CheckpointHexPayload): IBeaconStateView | null {
135
+ getCheckpointStateSync(cp: CheckpointHex): IBeaconStateView | null {
136
136
  return this.checkpointStateCache.get(cp);
137
137
  }
138
138
 
@@ -153,22 +153,14 @@ export class QueuedStateRegenerator implements IStateRegenerator {
153
153
  this.blockStateCache.deleteAllBeforeEpoch(finalizedEpoch);
154
154
  }
155
155
 
156
- processBlockState(blockRootHex: RootHex, postState: IBeaconStateView): void {
156
+ processState(blockRootHex: RootHex, postState: IBeaconStateView): void {
157
157
  this.blockStateCache.add(postState);
158
158
  this.checkpointStateCache.processState(blockRootHex, postState).catch((e) => {
159
159
  this.logger.debug("Error processing block state", {blockRootHex, slot: postState.slot}, e);
160
160
  });
161
161
  }
162
162
 
163
- /**
164
- * Process payload state for caching after importing execution payload.
165
- */
166
- processPayloadState(payloadState: IBeaconStateView): void {
167
- // Add payload state to block state cache (keyed by payload state root)
168
- this.blockStateCache.add(payloadState);
169
- }
170
-
171
- addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView, _payloadPresent: boolean): void {
163
+ addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView): void {
172
164
  this.checkpointStateCache.add(cp, item);
173
165
  }
174
166
 
@@ -205,7 +197,7 @@ export class QueuedStateRegenerator implements IStateRegenerator {
205
197
  }
206
198
  }
207
199
 
208
- updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch, _payloadPresent: boolean): number | null {
200
+ updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null {
209
201
  return this.checkpointStateCache.updatePreComputedCheckpoint(rootHex, epoch);
210
202
  }
211
203
 
@@ -332,11 +332,6 @@ async function processSlotsByCheckpoint(
332
332
  * emitting "checkpoint" events after every epoch processed.
333
333
  *
334
334
  * Stops processing after no more full epochs can be processed.
335
- *
336
- * Output state variant:
337
- * - Post-Gloas: If slots are processed, returns block state (payloadPresent=false).
338
- * If no slots processed, returns preState as-is (preserves variant).
339
- * - Pre-Gloas: Always payloadPresent=true (no block/payload distinction).
340
335
  */
341
336
  export async function processSlotsToNearestCheckpoint(
342
337
  modules: {
@@ -380,9 +375,6 @@ export async function processSlotsToNearestCheckpoint(
380
375
  // This may becomes the "official" checkpoint state if the 1st block of epoch is skipped
381
376
  const checkpointState = postState;
382
377
  const cp = getCheckpointFromState(checkpointState);
383
- // processSlots() only does epoch transitions, never processes payloads
384
- // Pre-Gloas: payloadPresent is always true (execution payload embedded in block)
385
- // Post-Gloas: result is a block state (payloadPresent=false)
386
378
  checkpointStateCache.add(cp, checkpointState);
387
379
  // consumers should not mutate state ever
388
380
  emitter?.emit(ChainEvent.checkpoint, cp, checkpointState);
@@ -9,7 +9,7 @@ import {IClock} from "../../util/clock.js";
9
9
  import {serializeState} from "../serializeState.js";
10
10
  import {CPStateDatastore, DatastoreKey} from "./datastore/index.js";
11
11
  import {MapTracker} from "./mapMetrics.js";
12
- import {BlockStateCache, CacheItemType, CheckpointHex, CheckpointHexPayload, CheckpointStateCache} from "./types.js";
12
+ import {BlockStateCache, CacheItemType, CheckpointHex, CheckpointStateCache} from "./types.js";
13
13
 
14
14
  export type PersistentCheckpointStateCacheOpts = {
15
15
  /** Keep max n state epochs in memory, persist the rest to disk */
@@ -226,7 +226,10 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
226
226
  }
227
227
  sszTimer?.();
228
228
  const timer = this.metrics?.cpStateCache.stateReloadDuration.startTimer();
229
- const newCachedState = seedState.loadOtherState(stateBytes, validatorsBytes);
229
+ // preload validators and balances for faster state transition
230
+ const newCachedState = seedState.loadOtherState(stateBytes, validatorsBytes, {
231
+ preloadValidatorsAndBalances: true,
232
+ });
230
233
  // hashTreeRoot() calls the commit() inside
231
234
  // there is no modification inside the state, it's just that we want to compute and cache all roots
232
235
  const stateRoot = toRootHex(newCachedState.hashTreeRoot());
@@ -843,19 +846,6 @@ export function toCheckpointHex(checkpoint: phase0.Checkpoint): CheckpointHex {
843
846
  };
844
847
  }
845
848
 
846
- /** TODO GLOAS: remove after rolling back regen dual-state changes */
847
- export function fcCheckpointToHexPayload(checkpoint: {
848
- epoch: Epoch;
849
- rootHex: RootHex;
850
- payloadStatus?: number;
851
- }): CheckpointHexPayload {
852
- return {
853
- epoch: checkpoint.epoch,
854
- rootHex: checkpoint.rootHex,
855
- payloadPresent: true,
856
- };
857
- }
858
-
859
849
  export function toCheckpointKey(cp: CheckpointHex): string {
860
850
  return `${cp.rootHex}:${cp.epoch}`;
861
851
  }
@@ -4,9 +4,6 @@ import {Epoch, RootHex, phase0} from "@lodestar/types";
4
4
 
5
5
  export type CheckpointHex = {epoch: Epoch; rootHex: RootHex};
6
6
 
7
- /** TODO GLOAS: payloadPresent is ignored — remove after rolling back regen dual-state changes */
8
- export type CheckpointHexPayload = {epoch: Epoch; rootHex: RootHex; payloadPresent: boolean};
9
-
10
7
  /**
11
8
  * Lodestar currently keeps two state caches around.
12
9
  *
@@ -90,6 +90,19 @@ async function validateAggregateAndProof(
90
90
  });
91
91
  }
92
92
 
93
+ // [REJECT] If `aggregate.data.index == 1` (payload present for a past
94
+ // block), the execution payload for `block` passes validation.
95
+ // [IGNORE] When `aggregate.data.index == 1` (payload present for a past block),
96
+ // the corresponding execution payload for `block` has been seen (a client MAY queue
97
+ // attestations for processing once the payload is retrieved and SHOULD request the
98
+ // payload envelope via `ExecutionPayloadEnvelopesByRoot`).
99
+ if (block !== null && attData.index === 1 && !chain.seenPayloadEnvelope(toRootHex(attData.beaconBlockRoot))) {
100
+ throw new AttestationError(GossipAction.IGNORE, {
101
+ code: AttestationErrorCode.EXECUTION_PAYLOAD_NOT_SEEN,
102
+ beaconBlockRoot: toRootHex(attData.beaconBlockRoot),
103
+ });
104
+ }
105
+
93
106
  // [REJECT] len(committee_indices) == 1, where committee_indices = get_committee_indices(aggregate)
94
107
  committeeIndex = (aggregate as electra.Attestation).committeeBits.getSingleTrueBit();
95
108
  if (committeeIndex === null) {
@@ -315,6 +315,19 @@ async function validateAttestationNoSignatureCheck(
315
315
  code: AttestationErrorCode.PREMATURELY_INDICATED_PAYLOAD_PRESENT,
316
316
  });
317
317
  }
318
+
319
+ // [REJECT] If `attestation.data.index == 1` (payload present for a past
320
+ // block), the execution payload for `block` passes validation.
321
+ // [IGNORE] When `attestation.data.index == 1` (payload present for a past block),
322
+ // the corresponding execution payload for `block` has been seen (a client MAY queue
323
+ // attestations for processing once the payload is retrieved and SHOULD request the
324
+ // payload envelope via `ExecutionPayloadEnvelopesByRoot`).
325
+ if (block !== null && attData.index === 1 && !chain.seenPayloadEnvelope(toRootHex(attData.beaconBlockRoot))) {
326
+ throw new AttestationError(GossipAction.IGNORE, {
327
+ code: AttestationErrorCode.EXECUTION_PAYLOAD_NOT_SEEN,
328
+ beaconBlockRoot: toRootHex(attData.beaconBlockRoot),
329
+ });
330
+ }
318
331
  } else {
319
332
  // [REJECT] attestation.data.index == 0
320
333
  if (attData.index !== 0) {
@@ -1,5 +1,6 @@
1
1
  import {PublicKey} from "@chainsafe/blst";
2
2
  import {
3
+ computeEpochAtSlot,
3
4
  createSingleSignatureSetFromComponents,
4
5
  getExecutionPayloadBidSigningRoot,
5
6
  isActiveBuilder,
@@ -76,6 +77,19 @@ async function validateExecutionPayloadBid(
76
77
  // `SignedProposerPreferences` associated with `bid.slot`.
77
78
  // TODO GLOAS: Implement this along with proposer preference
78
79
 
80
+ // [REJECT] The length of KZG commitments is less than or equal to the limitation defined in the
81
+ // consensus layer -- i.e. validate that
82
+ // `len(bid.blob_kzg_commitments) <= get_blob_parameters(compute_epoch_at_slot(bid.slot)).max_blobs_per_block`.
83
+ const blobKzgCommitmentsLen = bid.blobKzgCommitments.length;
84
+ const maxBlobsPerBlock = chain.config.getMaxBlobsPerBlock(computeEpochAtSlot(bid.slot));
85
+ if (blobKzgCommitmentsLen > maxBlobsPerBlock) {
86
+ throw new ExecutionPayloadBidError(GossipAction.REJECT, {
87
+ code: ExecutionPayloadBidErrorCode.TOO_MANY_KZG_COMMITMENTS,
88
+ blobKzgCommitmentsLen,
89
+ commitmentLimit: maxBlobsPerBlock,
90
+ });
91
+ }
92
+
79
93
  // [IGNORE] this is the first signed bid seen with a valid signature from the given builder for this slot.
80
94
  if (chain.seenExecutionPayloadBids.isKnown(bid.slot, bid.builderIndex)) {
81
95
  throw new ExecutionPayloadBidError(GossipAction.IGNORE, {
@@ -4,8 +4,8 @@ import {
4
4
  getExecutionPayloadEnvelopeSignatureSet,
5
5
  isStatePostGloas,
6
6
  } from "@lodestar/state-transition";
7
- import {gloas} from "@lodestar/types";
8
- import {toRootHex} from "@lodestar/utils";
7
+ import {gloas, ssz} from "@lodestar/types";
8
+ import {byteArrayEquals, toRootHex} from "@lodestar/utils";
9
9
  import {ExecutionPayloadEnvelopeError, ExecutionPayloadEnvelopeErrorCode, GossipAction} from "../errors/index.js";
10
10
  import {IBeaconChain} from "../index.js";
11
11
  import {RegenCaller} from "../regen/index.js";
@@ -32,7 +32,7 @@ async function validateExecutionPayloadEnvelope(
32
32
  const {payload} = envelope;
33
33
  const blockRootHex = toRootHex(envelope.beaconBlockRoot);
34
34
 
35
- // [IGNORE] The envelope's block root `envelope.block_root` has been seen (via
35
+ // [IGNORE] The envelope's block root `envelope.beacon_block_root` has been seen (via
36
36
  // gossip or non-gossip sources) (a client MAY queue payload for processing once
37
37
  // the block is retrieved).
38
38
  // TODO GLOAS: Need to review this, we should queue the envelope for later
@@ -53,7 +53,7 @@ async function validateExecutionPayloadEnvelope(
53
53
  throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
54
54
  code: ExecutionPayloadEnvelopeErrorCode.ENVELOPE_ALREADY_KNOWN,
55
55
  blockRoot: blockRootHex,
56
- slot: envelope.slot,
56
+ slot: payload.slotNumber,
57
57
  });
58
58
  }
59
59
 
@@ -65,13 +65,13 @@ async function validateExecutionPayloadEnvelope(
65
65
  });
66
66
  }
67
67
 
68
- // [IGNORE] The envelope is from a slot greater than or equal to the latest finalized slot -- i.e. validate that `envelope.slot >= compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)`
68
+ // [IGNORE] The envelope is from a slot greater than or equal to the latest finalized slot -- i.e. validate that `payload.slotNumber >= compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)`
69
69
  const finalizedCheckpoint = chain.forkChoice.getFinalizedCheckpoint();
70
70
  const finalizedSlot = computeStartSlotAtEpoch(finalizedCheckpoint.epoch);
71
- if (envelope.slot < finalizedSlot) {
71
+ if (payload.slotNumber < finalizedSlot) {
72
72
  throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
73
73
  code: ExecutionPayloadEnvelopeErrorCode.BELONG_TO_FINALIZED_BLOCK,
74
- envelopeSlot: envelope.slot,
74
+ envelopeSlot: payload.slotNumber,
75
75
  finalizedSlot,
76
76
  });
77
77
  }
@@ -80,11 +80,11 @@ async function validateExecutionPayloadEnvelope(
80
80
  // TODO GLOAS: implement this. Technically if we cannot get proto block from fork choice,
81
81
  // it is possible that the block didn't pass the validation
82
82
 
83
- // [REJECT] `block.slot` equals `envelope.slot`.
84
- if (block.slot !== envelope.slot) {
83
+ // [REJECT] `block.slot` equals `payload.slotNumber`.
84
+ if (block.slot !== payload.slotNumber) {
85
85
  throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
86
86
  code: ExecutionPayloadEnvelopeErrorCode.SLOT_MISMATCH,
87
- envelopeSlot: envelope.slot,
87
+ envelopeSlot: payload.slotNumber,
88
88
  blockSlot: block.slot,
89
89
  });
90
90
  }
@@ -107,14 +107,24 @@ async function validateExecutionPayloadEnvelope(
107
107
  });
108
108
  }
109
109
 
110
- // Get the post block state which is the pre-payload state to verify the builder's signature.
110
+ // [REJECT] `hash_tree_root(envelope.execution_requests) == bid.execution_requests_root`
111
+ const requestsRoot = ssz.electra.ExecutionRequests.hashTreeRoot(envelope.executionRequests);
112
+ if (!byteArrayEquals(requestsRoot, payloadInput.getBid().executionRequestsRoot)) {
113
+ throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
114
+ code: ExecutionPayloadEnvelopeErrorCode.EXECUTION_REQUESTS_ROOT_MISMATCH,
115
+ envelopeRequestsRoot: toRootHex(requestsRoot),
116
+ bidRequestsRoot: toRootHex(payloadInput.getBid().executionRequestsRoot),
117
+ });
118
+ }
119
+
120
+ // Get the block state to verify the builder's signature.
111
121
  const blockState = await chain.regen
112
122
  .getState(block.stateRoot, RegenCaller.validateGossipPayloadEnvelope)
113
123
  .catch(() => {
114
124
  throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
115
125
  code: ExecutionPayloadEnvelopeErrorCode.UNKNOWN_BLOCK_STATE,
116
126
  blockRoot: blockRootHex,
117
- slot: envelope.slot,
127
+ slot: payload.slotNumber,
118
128
  });
119
129
  });
120
130
  if (!isStatePostGloas(blockState)) {
@@ -18,7 +18,8 @@ export async function validateApiPayloadAttestationMessage(
18
18
  chain: IBeaconChain,
19
19
  payloadAttestationMessage: gloas.PayloadAttestationMessage
20
20
  ): Promise<PayloadAttestationValidationResult> {
21
- return validatePayloadAttestationMessage(chain, payloadAttestationMessage);
21
+ const prioritizeBls = true;
22
+ return validatePayloadAttestationMessage(chain, payloadAttestationMessage, prioritizeBls);
22
23
  }
23
24
 
24
25
  export async function validateGossipPayloadAttestationMessage(
@@ -30,7 +31,8 @@ export async function validateGossipPayloadAttestationMessage(
30
31
 
31
32
  async function validatePayloadAttestationMessage(
32
33
  chain: IBeaconChain,
33
- payloadAttestationMessage: gloas.PayloadAttestationMessage
34
+ payloadAttestationMessage: gloas.PayloadAttestationMessage,
35
+ prioritizeBls = false
34
36
  ): Promise<PayloadAttestationValidationResult> {
35
37
  const {data, validatorIndex} = payloadAttestationMessage;
36
38
  const epoch = computeEpochAtSlot(data.slot);
@@ -102,7 +104,7 @@ async function validatePayloadAttestationMessage(
102
104
  payloadAttestationMessage.signature
103
105
  );
104
106
 
105
- if (!(await chain.bls.verifySignatureSets([signatureSet]))) {
107
+ if (!(await chain.bls.verifySignatureSets([signatureSet], {batchable: true, priority: prioritizeBls}))) {
106
108
  throw new PayloadAttestationError(GossipAction.REJECT, {
107
109
  code: PayloadAttestationErrorCode.INVALID_SIGNATURE,
108
110
  });
@@ -19,7 +19,7 @@ export class ExecutionPayloadEnvelopeArchiveRepository extends Repository<Slot,
19
19
  * Id is the slot from the envelope
20
20
  */
21
21
  getId(value: gloas.SignedExecutionPayloadEnvelope): Slot {
22
- return value.message.slot;
22
+ return value.message.payload.slotNumber;
23
23
  }
24
24
 
25
25
  encodeKey(id: Slot): Uint8Array {
@@ -216,13 +216,15 @@ export class ExecutionEngineHttp implements IExecutionEngine {
216
216
  executionRequests?: ExecutionRequests
217
217
  ): Promise<ExecutePayloadResponse> {
218
218
  const method =
219
- ForkSeq[fork] >= ForkSeq.electra
220
- ? "engine_newPayloadV4"
221
- : ForkSeq[fork] >= ForkSeq.deneb
222
- ? "engine_newPayloadV3"
223
- : ForkSeq[fork] >= ForkSeq.capella
224
- ? "engine_newPayloadV2"
225
- : "engine_newPayloadV1";
219
+ ForkSeq[fork] >= ForkSeq.gloas
220
+ ? "engine_newPayloadV5"
221
+ : ForkSeq[fork] >= ForkSeq.electra
222
+ ? "engine_newPayloadV4"
223
+ : ForkSeq[fork] >= ForkSeq.deneb
224
+ ? "engine_newPayloadV3"
225
+ : ForkSeq[fork] >= ForkSeq.capella
226
+ ? "engine_newPayloadV2"
227
+ : "engine_newPayloadV1";
226
228
 
227
229
  const serializedExecutionPayload = serializeExecutionPayload(fork, executionPayload);
228
230
 
@@ -244,7 +246,7 @@ export class ExecutionEngineHttp implements IExecutionEngine {
244
246
  }
245
247
  const serializedExecutionRequests = serializeExecutionRequests(executionRequests);
246
248
  engineRequest = {
247
- method: "engine_newPayloadV4",
249
+ method: ForkSeq[fork] >= ForkSeq.gloas ? "engine_newPayloadV5" : "engine_newPayloadV4",
248
250
  params: [
249
251
  serializedExecutionPayload,
250
252
  serializedVersionedHashes,
@@ -348,11 +350,13 @@ export class ExecutionEngineHttp implements IExecutionEngine {
348
350
  // Once on capella, should this need to be permanently switched to v2 when payload attrs
349
351
  // not provided
350
352
  const method =
351
- ForkSeq[fork] >= ForkSeq.deneb
352
- ? "engine_forkchoiceUpdatedV3"
353
- : ForkSeq[fork] >= ForkSeq.capella
354
- ? "engine_forkchoiceUpdatedV2"
355
- : "engine_forkchoiceUpdatedV1";
353
+ ForkSeq[fork] >= ForkSeq.gloas
354
+ ? "engine_forkchoiceUpdatedV4"
355
+ : ForkSeq[fork] >= ForkSeq.deneb
356
+ ? "engine_forkchoiceUpdatedV3"
357
+ : ForkSeq[fork] >= ForkSeq.capella
358
+ ? "engine_forkchoiceUpdatedV2"
359
+ : "engine_forkchoiceUpdatedV1";
356
360
  const payloadAttributesRpc = payloadAttributes ? serializePayloadAttributes(payloadAttributes) : undefined;
357
361
  // If we are just fcUing and not asking execution for payload, retry is not required
358
362
  // and we can move on, as the next fcU will be issued soon on the new slot
@@ -438,9 +442,12 @@ export class ExecutionEngineHttp implements IExecutionEngine {
438
442
  case ForkName.electra:
439
443
  method = "engine_getPayloadV4";
440
444
  break;
441
- default:
445
+ case ForkName.fulu:
442
446
  method = "engine_getPayloadV5";
443
447
  break;
448
+ default:
449
+ method = "engine_getPayloadV6";
450
+ break;
444
451
  }
445
452
  const payloadResponse = await this.rpc.fetchWithRetries<
446
453
  EngineApiRpcReturnTypes[typeof method],