@lodestar/beacon-node 1.44.0-dev.54f7b9df03 → 1.44.0-dev.551b8b0a3d

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 (203) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +36 -33
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/pool/index.js +1 -26
  6. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  7. package/lib/api/impl/config/constants.d.ts +5 -0
  8. package/lib/api/impl/config/constants.d.ts.map +1 -1
  9. package/lib/api/impl/config/constants.js +6 -1
  10. package/lib/api/impl/config/constants.js.map +1 -1
  11. package/lib/api/impl/debug/index.d.ts.map +1 -1
  12. package/lib/api/impl/debug/index.js +69 -12
  13. package/lib/api/impl/debug/index.js.map +1 -1
  14. package/lib/api/impl/lodestar/index.d.ts.map +1 -1
  15. package/lib/api/impl/lodestar/index.js +28 -0
  16. package/lib/api/impl/lodestar/index.js.map +1 -1
  17. package/lib/api/impl/validator/index.d.ts.map +1 -1
  18. package/lib/api/impl/validator/index.js +41 -36
  19. package/lib/api/impl/validator/index.js.map +1 -1
  20. package/lib/chain/archiveStore/archiveStore.d.ts +0 -1
  21. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  22. package/lib/chain/archiveStore/archiveStore.js +0 -4
  23. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  24. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  25. package/lib/chain/blocks/importBlock.js +4 -3
  26. package/lib/chain/blocks/importBlock.js.map +1 -1
  27. package/lib/chain/blocks/importExecutionPayload.js +1 -1
  28. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  29. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
  30. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +3 -3
  31. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
  32. package/lib/chain/chain.d.ts +2 -2
  33. package/lib/chain/chain.d.ts.map +1 -1
  34. package/lib/chain/chain.js +9 -2
  35. package/lib/chain/chain.js.map +1 -1
  36. package/lib/chain/emitter.d.ts +2 -1
  37. package/lib/chain/emitter.d.ts.map +1 -1
  38. package/lib/chain/emitter.js.map +1 -1
  39. package/lib/chain/errors/blockError.d.ts +0 -7
  40. package/lib/chain/errors/blockError.d.ts.map +1 -1
  41. package/lib/chain/errors/blockError.js +0 -3
  42. package/lib/chain/errors/blockError.js.map +1 -1
  43. package/lib/chain/errors/executionPayloadBid.d.ts +17 -0
  44. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  45. package/lib/chain/errors/executionPayloadBid.js +3 -0
  46. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  47. package/lib/chain/errors/payloadAttestation.d.ts +6 -0
  48. package/lib/chain/errors/payloadAttestation.d.ts.map +1 -1
  49. package/lib/chain/errors/payloadAttestation.js +1 -0
  50. package/lib/chain/errors/payloadAttestation.js.map +1 -1
  51. package/lib/chain/forkChoice/index.d.ts +4 -4
  52. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  53. package/lib/chain/forkChoice/index.js +10 -7
  54. package/lib/chain/forkChoice/index.js.map +1 -1
  55. package/lib/chain/interface.d.ts +2 -2
  56. package/lib/chain/interface.d.ts.map +1 -1
  57. package/lib/chain/interface.js.map +1 -1
  58. package/lib/chain/options.d.ts.map +1 -1
  59. package/lib/chain/options.js +1 -0
  60. package/lib/chain/options.js.map +1 -1
  61. package/lib/chain/prepareNextSlot.js +1 -1
  62. package/lib/chain/prepareNextSlot.js.map +1 -1
  63. package/lib/chain/produceBlock/produceBlockBody.d.ts +2 -2
  64. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  65. package/lib/chain/produceBlock/produceBlockBody.js +7 -7
  66. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  67. package/lib/chain/regen/interface.d.ts +2 -1
  68. package/lib/chain/regen/interface.d.ts.map +1 -1
  69. package/lib/chain/regen/interface.js +2 -0
  70. package/lib/chain/regen/interface.js.map +1 -1
  71. package/lib/chain/regen/queued.d.ts +0 -1
  72. package/lib/chain/regen/queued.d.ts.map +1 -1
  73. package/lib/chain/regen/queued.js +0 -4
  74. package/lib/chain/regen/queued.js.map +1 -1
  75. package/lib/chain/stateCache/fifoBlockStateCache.d.ts +0 -5
  76. package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
  77. package/lib/chain/stateCache/fifoBlockStateCache.js +0 -5
  78. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  79. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -4
  80. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  81. package/lib/chain/stateCache/persistentCheckpointsCache.js +5 -2
  82. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  83. package/lib/chain/stateCache/types.d.ts +0 -2
  84. package/lib/chain/stateCache/types.d.ts.map +1 -1
  85. package/lib/chain/stateCache/types.js.map +1 -1
  86. package/lib/chain/validation/block.d.ts +5 -1
  87. package/lib/chain/validation/block.d.ts.map +1 -1
  88. package/lib/chain/validation/block.js +4 -14
  89. package/lib/chain/validation/block.js.map +1 -1
  90. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  91. package/lib/chain/validation/executionPayloadBid.js +55 -6
  92. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  93. package/lib/chain/validation/executionPayloadEnvelope.js +1 -3
  94. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  95. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  96. package/lib/chain/validation/payloadAttestationMessage.js +24 -4
  97. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  98. package/lib/execution/engine/http.js +1 -1
  99. package/lib/execution/engine/http.js.map +1 -1
  100. package/lib/execution/engine/interface.d.ts +2 -2
  101. package/lib/execution/engine/interface.d.ts.map +1 -1
  102. package/lib/execution/engine/interface.js +6 -2
  103. package/lib/execution/engine/interface.js.map +1 -1
  104. package/lib/execution/engine/mock.d.ts.map +1 -1
  105. package/lib/execution/engine/mock.js +3 -5
  106. package/lib/execution/engine/mock.js.map +1 -1
  107. package/lib/execution/engine/types.d.ts +15 -7
  108. package/lib/execution/engine/types.d.ts.map +1 -1
  109. package/lib/execution/engine/types.js +47 -9
  110. package/lib/execution/engine/types.js.map +1 -1
  111. package/lib/metrics/metrics/lodestar.d.ts +4 -0
  112. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  113. package/lib/metrics/metrics/lodestar.js +10 -0
  114. package/lib/metrics/metrics/lodestar.js.map +1 -1
  115. package/lib/network/gossip/topic.d.ts +11 -1
  116. package/lib/network/gossip/topic.d.ts.map +1 -1
  117. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  118. package/lib/network/processor/gossipHandlers.js +10 -3
  119. package/lib/network/processor/gossipHandlers.js.map +1 -1
  120. package/lib/network/processor/index.d.ts +2 -2
  121. package/lib/network/processor/index.d.ts.map +1 -1
  122. package/lib/network/processor/index.js +25 -23
  123. package/lib/network/processor/index.js.map +1 -1
  124. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  125. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +9 -5
  126. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  127. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  128. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +13 -3
  129. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  130. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +1 -1
  131. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
  132. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts +2 -1
  133. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
  134. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +16 -6
  135. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
  136. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts +2 -1
  137. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -1
  138. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +15 -1
  139. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
  140. package/lib/network/reqresp/handlers/index.js +4 -4
  141. package/lib/network/reqresp/handlers/index.js.map +1 -1
  142. package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts.map +1 -1
  143. package/lib/network/reqresp/utils/dataColumnResponseValidation.js +23 -5
  144. package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
  145. package/lib/sync/types.d.ts +9 -1
  146. package/lib/sync/types.d.ts.map +1 -1
  147. package/lib/sync/types.js +9 -2
  148. package/lib/sync/types.js.map +1 -1
  149. package/lib/sync/unknownBlock.d.ts.map +1 -1
  150. package/lib/sync/unknownBlock.js +64 -30
  151. package/lib/sync/unknownBlock.js.map +1 -1
  152. package/lib/util/dataColumns.d.ts.map +1 -1
  153. package/lib/util/dataColumns.js +16 -11
  154. package/lib/util/dataColumns.js.map +1 -1
  155. package/lib/util/sszBytes.js +1 -1
  156. package/package.json +15 -17
  157. package/src/api/impl/beacon/blocks/index.ts +40 -42
  158. package/src/api/impl/beacon/pool/index.ts +2 -41
  159. package/src/api/impl/config/constants.ts +10 -0
  160. package/src/api/impl/debug/index.ts +73 -12
  161. package/src/api/impl/lodestar/index.ts +30 -0
  162. package/src/api/impl/validator/index.ts +52 -53
  163. package/src/chain/archiveStore/archiveStore.ts +0 -5
  164. package/src/chain/blocks/importBlock.ts +8 -5
  165. package/src/chain/blocks/importExecutionPayload.ts +1 -1
  166. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +3 -5
  167. package/src/chain/chain.ts +12 -4
  168. package/src/chain/emitter.ts +3 -2
  169. package/src/chain/errors/blockError.ts +0 -4
  170. package/src/chain/errors/executionPayloadBid.ts +16 -0
  171. package/src/chain/errors/payloadAttestation.ts +2 -0
  172. package/src/chain/forkChoice/index.ts +13 -0
  173. package/src/chain/interface.ts +1 -2
  174. package/src/chain/options.ts +1 -0
  175. package/src/chain/prepareNextSlot.ts +1 -1
  176. package/src/chain/produceBlock/produceBlockBody.ts +10 -10
  177. package/src/chain/regen/interface.ts +2 -1
  178. package/src/chain/regen/queued.ts +0 -5
  179. package/src/chain/stateCache/fifoBlockStateCache.ts +0 -6
  180. package/src/chain/stateCache/persistentCheckpointsCache.ts +6 -2
  181. package/src/chain/stateCache/types.ts +0 -2
  182. package/src/chain/validation/block.ts +12 -16
  183. package/src/chain/validation/executionPayloadBid.ts +59 -6
  184. package/src/chain/validation/executionPayloadEnvelope.ts +1 -3
  185. package/src/chain/validation/payloadAttestationMessage.ts +26 -4
  186. package/src/execution/engine/http.ts +1 -1
  187. package/src/execution/engine/interface.ts +12 -2
  188. package/src/execution/engine/mock.ts +6 -5
  189. package/src/execution/engine/types.ts +75 -14
  190. package/src/metrics/metrics/lodestar.ts +11 -0
  191. package/src/network/processor/gossipHandlers.ts +10 -2
  192. package/src/network/processor/index.ts +27 -27
  193. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +12 -5
  194. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -3
  195. package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +1 -1
  196. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +22 -6
  197. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +20 -1
  198. package/src/network/reqresp/handlers/index.ts +4 -4
  199. package/src/network/reqresp/utils/dataColumnResponseValidation.ts +22 -5
  200. package/src/sync/types.ts +11 -2
  201. package/src/sync/unknownBlock.ts +70 -31
  202. package/src/util/dataColumns.ts +17 -12
  203. package/src/util/sszBytes.ts +1 -1
@@ -5,6 +5,7 @@ export enum PayloadAttestationErrorCode {
5
5
  NOT_CURRENT_SLOT = "PAYLOAD_ATTESTATION_ERROR_NOT_CURRENT_SLOT",
6
6
  PAYLOAD_ATTESTATION_ALREADY_KNOWN = "PAYLOAD_ATTESTATION_ERROR_PAYLOAD_ATTESTATION_ALREADY_KNOWN",
7
7
  UNKNOWN_BLOCK_ROOT = "PAYLOAD_ATTESTATION_ERROR_UNKNOWN_BLOCK_ROOT",
8
+ INVALID_BLOCK_SLOT = "PAYLOAD_ATTESTATION_ERROR_INVALID_BLOCK_SLOT",
8
9
  INVALID_BLOCK = "PAYLOAD_ATTESTATION_ERROR_INVALID_BLOCK",
9
10
  INVALID_ATTESTER = "PAYLOAD_ATTESTATION_ERROR_INVALID_ATTESTER",
10
11
  INVALID_SIGNATURE = "PAYLOAD_ATTESTATION_ERROR_INVALID_SIGNATURE",
@@ -18,6 +19,7 @@ export type PayloadAttestationErrorType =
18
19
  blockRoot: RootHex;
19
20
  }
20
21
  | {code: PayloadAttestationErrorCode.UNKNOWN_BLOCK_ROOT; blockRoot: RootHex}
22
+ | {code: PayloadAttestationErrorCode.INVALID_BLOCK_SLOT; blockRoot: RootHex; blockSlot: Slot; slot: Slot}
21
23
  | {code: PayloadAttestationErrorCode.INVALID_BLOCK; blockRoot: RootHex}
22
24
  | {code: PayloadAttestationErrorCode.INVALID_ATTESTER; attesterIndex: ValidatorIndex}
23
25
  | {code: PayloadAttestationErrorCode.INVALID_SIGNATURE};
@@ -1,7 +1,9 @@
1
+ import {routes} from "@lodestar/api";
1
2
  import {ChainForkConfig} from "@lodestar/config";
2
3
  import {
3
4
  ExecutionStatus,
4
5
  ForkChoice,
6
+ ForkChoiceStateGetter,
5
7
  ForkChoiceStore,
6
8
  JustifiedBalancesGetter,
7
9
  PayloadStatus,
@@ -45,6 +47,7 @@ export function initializeForkChoice(
45
47
  isFinalizedState: boolean,
46
48
  opts: ForkChoiceOpts,
47
49
  justifiedBalancesGetter: JustifiedBalancesGetter,
50
+ stateGetter: ForkChoiceStateGetter,
48
51
  metrics: Metrics | null,
49
52
  logger?: Logger
50
53
  ): ForkChoice {
@@ -56,6 +59,7 @@ export function initializeForkChoice(
56
59
  state,
57
60
  opts,
58
61
  justifiedBalancesGetter,
62
+ stateGetter,
59
63
  metrics,
60
64
  logger
61
65
  )
@@ -66,6 +70,7 @@ export function initializeForkChoice(
66
70
  state,
67
71
  opts,
68
72
  justifiedBalancesGetter,
73
+ stateGetter,
69
74
  metrics,
70
75
  logger
71
76
  );
@@ -81,6 +86,7 @@ export function initializeForkChoiceFromFinalizedState(
81
86
  state: IBeaconStateView,
82
87
  opts: ForkChoiceOpts,
83
88
  justifiedBalancesGetter: JustifiedBalancesGetter,
89
+ stateGetter: ForkChoiceStateGetter,
84
90
  metrics: Metrics | null,
85
91
  logger?: Logger
86
92
  ): ForkChoice {
@@ -112,9 +118,12 @@ export function initializeForkChoiceFromFinalizedState(
112
118
  finalizedCheckpoint,
113
119
  justifiedBalances,
114
120
  justifiedBalancesGetter,
121
+ stateGetter,
115
122
  {
116
123
  onJustified: (cp) => emitter.emit(ChainEvent.forkChoiceJustified, cp),
117
124
  onFinalized: (cp) => emitter.emit(ChainEvent.forkChoiceFinalized, cp),
125
+ onFastConfirmation: ({block, slot, currentSlot}) =>
126
+ emitter.emit(routes.events.EventType.fastConfirmation, {block, slot, currentSlot}),
118
127
  }
119
128
  ),
120
129
 
@@ -172,6 +181,7 @@ export function initializeForkChoiceFromUnfinalizedState(
172
181
  unfinalizedState: IBeaconStateView,
173
182
  opts: ForkChoiceOpts,
174
183
  justifiedBalancesGetter: JustifiedBalancesGetter,
184
+ stateGetter: ForkChoiceStateGetter,
175
185
  metrics: Metrics | null,
176
186
  logger?: Logger
177
187
  ): ForkChoice {
@@ -203,9 +213,12 @@ export function initializeForkChoiceFromUnfinalizedState(
203
213
  finalizedCheckpoint,
204
214
  justifiedBalances,
205
215
  justifiedBalancesGetter,
216
+ stateGetter,
206
217
  {
207
218
  onJustified: (cp) => emitter.emit(ChainEvent.forkChoiceJustified, cp),
208
219
  onFinalized: (cp) => emitter.emit(ChainEvent.forkChoiceFinalized, cp),
220
+ onFastConfirmation: ({block, slot, currentSlot}) =>
221
+ emitter.emit(routes.events.EventType.fastConfirmation, {block, slot, currentSlot}),
209
222
  }
210
223
  );
211
224
 
@@ -18,7 +18,6 @@ import {
18
18
  altair,
19
19
  capella,
20
20
  deneb,
21
- electra,
22
21
  gloas,
23
22
  phase0,
24
23
  rewards,
@@ -236,7 +235,7 @@ export interface IBeaconChain {
236
235
  blockSlot: Slot,
237
236
  blockRootHex: string
238
237
  ): Promise<gloas.SignedExecutionPayloadEnvelope | null>;
239
- getParentExecutionRequests(parentBlockSlot: Slot, parentBlockRootHex: RootHex): Promise<electra.ExecutionRequests>;
238
+ getParentExecutionRequests(parentBlockSlot: Slot, parentBlockRootHex: RootHex): Promise<gloas.ExecutionRequests>;
240
239
 
241
240
  produceCommonBlockBody(blockAttributes: BlockAttributes): Promise<CommonBlockBody>;
242
241
  produceBlock(blockAttributes: BlockAttributes & {commonBlockBodyPromise: Promise<CommonBlockBody>}): Promise<{
@@ -105,6 +105,7 @@ export const defaultChainOptions: IChainOptions = {
105
105
  proposerBoost: true,
106
106
  proposerBoostReorg: true,
107
107
  computeUnrealized: true,
108
+ fastConfirmation: false,
108
109
  suggestedFeeRecipient: defaultValidatorOptions.suggestedFeeRecipient,
109
110
  serveHistoricalState: false,
110
111
  assertCorrectProgressiveBalances: false,
@@ -170,7 +170,7 @@ export class PrepareNextSlotScheduler {
170
170
  let stateAfterParentPayload: IBeaconStateViewBellatrix = updatedPrepareState;
171
171
  if (isStatePostGloas(updatedPrepareState)) {
172
172
  // Spec: should_build_on_full(store, head) — see produceBlockBody.ts for context.
173
- if (this.chain.forkChoice.shouldBuildOnFull(updatedHead)) {
173
+ if (this.chain.forkChoice.shouldBuildOnFull(updatedHead, prepareSlot)) {
174
174
  parentBlockHash = updatedPrepareState.latestExecutionPayloadBid.blockHash;
175
175
  // Skip applying parent payload unless we're proposing the next slot or have to emit payload_attributes events
176
176
  if (feeRecipient !== undefined || this.chain.opts.emitPayloadAttributes === true) {
@@ -108,7 +108,7 @@ export type ProduceFullGloas = {
108
108
  type: BlockType.Full;
109
109
  fork: ForkPostGloas;
110
110
  executionPayload: ExecutionPayload<ForkPostGloas>;
111
- executionRequests: electra.ExecutionRequests;
111
+ executionRequests: gloas.ExecutionRequests;
112
112
  blobsBundle: BlobsBundle<ForkPostGloas>;
113
113
  cells: fulu.Cell[][];
114
114
  parentBlockRoot: Root;
@@ -228,7 +228,7 @@ export async function produceBlockBody<T extends BlockType>(
228
228
  );
229
229
  const parentExecutionRequests = isExtendingPayload
230
230
  ? await this.getParentExecutionRequests(parentBlock.slot, parentBlock.blockRoot)
231
- : ssz.electra.ExecutionRequests.defaultValue();
231
+ : ssz.gloas.ExecutionRequests.defaultValue();
232
232
  executionPayloadValue = BigInt(builderBid.message.value) * GWEI_TO_WEI;
233
233
 
234
234
  const commonBlockBody = await commonBlockBodyPromise;
@@ -272,20 +272,20 @@ export async function produceBlockBody<T extends BlockType>(
272
272
 
273
273
  // Get execution payload from EL
274
274
  let parentBlockHash: Bytes32;
275
- let parentExecutionRequests: electra.ExecutionRequests;
275
+ let parentExecutionRequests: gloas.ExecutionRequests;
276
276
  // Apply parent payload once here as it's reused by EL prep and voluntary exit filtering below
277
277
  let stateAfterParentPayload: IBeaconStateViewBellatrix = currentState;
278
278
  // Spec: should_build_on_full(store, head). `parentBlock` is the proposer's head
279
- // (set by chain.getProposerHead(slot)). Returns false when the PTC majority
280
- // signalled the blob data is not available, forcing a build on EMPTY (reorg).
281
- const isBuildingOnFull = this.forkChoice.shouldBuildOnFull(parentBlock);
279
+ // (set by chain.getProposerHead(slot)). Returns false when the PTC majority signalled
280
+ // the blob data is not available or the payload was not timely, forcing a build on EMPTY (reorg).
281
+ const isBuildingOnFull = this.forkChoice.shouldBuildOnFull(parentBlock, blockSlot);
282
282
  if (isBuildingOnFull) {
283
283
  parentBlockHash = currentState.latestExecutionPayloadBid.blockHash;
284
284
  parentExecutionRequests = await this.getParentExecutionRequests(parentBlock.slot, parentBlock.blockRoot);
285
285
  stateAfterParentPayload = currentState.withParentPayloadApplied(parentExecutionRequests);
286
286
  } else {
287
287
  parentBlockHash = currentState.latestExecutionPayloadBid.parentBlockHash;
288
- parentExecutionRequests = ssz.electra.ExecutionRequests.defaultValue();
288
+ parentExecutionRequests = ssz.gloas.ExecutionRequests.defaultValue();
289
289
  }
290
290
  const prepareRes = await prepareExecutionPayload(
291
291
  this,
@@ -344,13 +344,13 @@ export async function produceBlockBody<T extends BlockType>(
344
344
  blockHash: executionPayload.blockHash,
345
345
  prevRandao: currentState.getRandaoMix(currentState.epoch),
346
346
  feeRecipient: executionPayload.feeRecipient,
347
- gasLimit: BigInt(executionPayload.gasLimit),
347
+ gasLimit: executionPayload.gasLimit,
348
348
  builderIndex: BUILDER_INDEX_SELF_BUILD,
349
349
  slot: blockSlot,
350
350
  value: 0,
351
351
  executionPayment: 0,
352
352
  blobKzgCommitments: blobsBundle.commitments,
353
- executionRequestsRoot: ssz.electra.ExecutionRequests.hashTreeRoot(executionRequests),
353
+ executionRequestsRoot: ssz.gloas.ExecutionRequests.hashTreeRoot(executionRequests as gloas.ExecutionRequests),
354
354
  };
355
355
  const signedBid: gloas.SignedExecutionPayloadBid = {
356
356
  message: bid,
@@ -375,7 +375,7 @@ export async function produceBlockBody<T extends BlockType>(
375
375
  // Store execution payload data required to construct execution payload envelope later
376
376
  const gloasResult = produceResult as ProduceFullGloas;
377
377
  gloasResult.executionPayload = executionPayload as ExecutionPayload<ForkPostGloas>;
378
- gloasResult.executionRequests = executionRequests;
378
+ gloasResult.executionRequests = executionRequests as gloas.ExecutionRequests;
379
379
  gloasResult.blobsBundle = blobsBundle;
380
380
  gloasResult.cells = cells;
381
381
  gloasResult.parentBlockRoot = fromHex(parentBlock.blockRoot);
@@ -17,10 +17,12 @@ export enum RegenCaller {
17
17
  predictProposerHead = "predictProposerHead",
18
18
  produceAttestationData = "produceAttestationData",
19
19
  processBlocksInEpoch = "processBlocksInEpoch",
20
+ importExecutionPayload = "importExecutionPayload",
20
21
  validateGossipAggregateAndProof = "validateGossipAggregateAndProof",
21
22
  validateGossipAttestation = "validateGossipAttestation",
22
23
  validateGossipVoluntaryExit = "validateGossipVoluntaryExit",
23
24
  validateGossipExecutionPayloadBid = "validateGossipExecutionPayloadBid",
25
+ validateGossipPayloadAttestationMessage = "validateGossipPayloadAttestationMessage",
24
26
  validateGossipProposerPreferences = "validateGossipProposerPreferences",
25
27
  onForkChoiceFinalized = "onForkChoiceFinalized",
26
28
  restApi = "restApi",
@@ -45,7 +47,6 @@ export interface IStateRegenerator extends IStateRegeneratorInternal {
45
47
  getCheckpointStateSync(cp: CheckpointHex): IBeaconStateView | null;
46
48
  getClosestHeadState(head: ProtoBlock): IBeaconStateView | null;
47
49
  pruneOnCheckpoint(finalizedEpoch: Epoch, justifiedEpoch: Epoch, headStateRoot: RootHex): void;
48
- pruneOnFinalized(finalizedEpoch: Epoch): void;
49
50
  processState(blockRootHex: RootHex, postState: IBeaconStateView): void;
50
51
  addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView): void;
51
52
  updateHeadState(newHead: ProtoBlock, maybeHeadState: IBeaconStateView): void;
@@ -143,11 +143,6 @@ export class QueuedStateRegenerator implements IStateRegenerator {
143
143
  this.blockStateCache.prune(headStateRoot);
144
144
  }
145
145
 
146
- pruneOnFinalized(finalizedEpoch: number): void {
147
- this.checkpointStateCache.pruneFinalized(finalizedEpoch);
148
- this.blockStateCache.deleteAllBeforeEpoch(finalizedEpoch);
149
- }
150
-
151
146
  processState(blockRootHex: RootHex, postState: IBeaconStateView): void {
152
147
  this.blockStateCache.add(postState);
153
148
  this.checkpointStateCache.processState(blockRootHex, postState).catch((e) => {
@@ -167,12 +167,6 @@ export class FIFOBlockStateCache implements BlockStateCache {
167
167
  }
168
168
  }
169
169
 
170
- /**
171
- * No need for this implementation
172
- * This is only to conform to the old api
173
- */
174
- deleteAllBeforeEpoch(): void {}
175
-
176
170
  /**
177
171
  * ONLY FOR DEBUGGING PURPOSES. For lodestar debug API.
178
172
  */
@@ -414,11 +414,12 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
414
414
 
415
415
  /**
416
416
  * Prune all checkpoint states before the provided finalized epoch.
417
+ * Driven sequentially from processState() so it never interleaves with persist.
417
418
  */
418
- pruneFinalized(finalizedEpoch: Epoch): void {
419
+ private async pruneFinalized(finalizedEpoch: Epoch): Promise<void> {
419
420
  for (const epoch of this.epochIndex.keys()) {
420
421
  if (epoch < finalizedEpoch) {
421
- this.deleteAllEpochItems(epoch).catch((e) =>
422
+ await this.deleteAllEpochItems(epoch).catch((e) =>
422
423
  this.logger.debug("Error delete all epoch items", {epoch, finalizedEpoch}, e as Error)
423
424
  );
424
425
  }
@@ -476,6 +477,9 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
476
477
  * As of Mar 2024, it takes <=350ms to persist a holesky state on fast server
477
478
  */
478
479
  async processState(blockRootHex: RootHex, state: IBeaconStateView): Promise<number> {
480
+ // prune finalized in the same flow so a finalized cp state is pruned, never persisted
481
+ await this.pruneFinalized(state.finalizedCheckpoint.epoch);
482
+
479
483
  let persistCount = 0;
480
484
  // it's important to sort the epochs in ascending order, in case of big reorg we always want to keep the most recent checkpoint states
481
485
  const sortedEpochs = Array.from(this.epochIndex.keys()).sort((a, b) => a - b);
@@ -30,7 +30,6 @@ export interface BlockStateCache {
30
30
  clear(): void;
31
31
  size: number;
32
32
  prune(headStateRootHex: RootHex): void;
33
- deleteAllBeforeEpoch(finalizedEpoch: Epoch): void;
34
33
  dumpSummary(): routes.lodestar.StateCacheItem[];
35
34
  /** Expose beacon states stored in cache. Use with caution */
36
35
  getStates(): IterableIterator<IBeaconStateView>;
@@ -67,7 +66,6 @@ export interface CheckpointStateCache {
67
66
  getOrReloadLatest(rootHex: RootHex, maxEpoch: Epoch): Promise<IBeaconStateView | null>;
68
67
  updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null;
69
68
  prune(finalizedEpoch: Epoch, justifiedEpoch: Epoch): void;
70
- pruneFinalized(finalizedEpoch: Epoch): void;
71
69
  processState(blockRootHex: RootHex, state: IBeaconStateView): Promise<number>;
72
70
  clear(): void;
73
71
  dumpSummary(): routes.lodestar.StateCacheItem[];
@@ -15,12 +15,17 @@ import {BlockErrorCode, BlockGossipError, GossipAction} from "../errors/index.js
15
15
  import {IBeaconChain} from "../interface.js";
16
16
  import {RegenCaller} from "../regen/index.js";
17
17
 
18
+ export type GossipBlockValidationResult = {
19
+ /** Number of skipped slots between the block and its parent (blockSlot - parentSlot - 1) */
20
+ skippedSlots: number;
21
+ };
22
+
18
23
  export async function validateGossipBlock(
19
24
  config: ChainForkConfig,
20
25
  chain: IBeaconChain,
21
26
  signedBlock: SignedBeaconBlock,
22
27
  fork: ForkName
23
- ): Promise<void> {
28
+ ): Promise<GossipBlockValidationResult> {
24
29
  const block = signedBlock.message;
25
30
  const blockSlot = block.slot;
26
31
  const blockEpoch = computeEpochAtSlot(blockSlot);
@@ -109,21 +114,6 @@ export async function validateGossipBlock(
109
114
  }
110
115
  }
111
116
 
112
- // [IGNORE] The attestation head block is too far behind the attestation slot, causing many skip slots.
113
- // This is deemed a DoS risk because we need to get the proposerShuffling. To get the shuffling we have
114
- // to do a bunch of epoch transitions, the longer the distance between the parent and block,
115
- // the more we have to do. epochTransitions are expensive ~750ms, so we must limit how many a
116
- // single bad block can trigger
117
- // Note: Ensure this check is done before calling chain.regen.getBlockSlotStat as this is the function that does various epoch transitions.
118
- // Note: This validation check is not part of the spec.
119
- if (chain.opts.maxSkipSlots != null && parentBlock.slot + chain.opts.maxSkipSlots < blockSlot) {
120
- throw new BlockGossipError(GossipAction.IGNORE, {
121
- code: BlockErrorCode.TOO_MANY_SKIPPED_SLOTS,
122
- parentSlot: parentBlock.slot,
123
- blockSlot,
124
- });
125
- }
126
-
127
117
  // [REJECT] The block is from a higher slot than its parent.
128
118
  if (parentBlock.slot >= blockSlot) {
129
119
  throw new BlockGossipError(GossipAction.REJECT, {
@@ -133,6 +123,10 @@ export async function validateGossipBlock(
133
123
  });
134
124
  }
135
125
 
126
+ // Number of skipped slots between block and parent (non-spec). Previously this gated blocks via
127
+ // maxSkipSlots; now the caller only observes it so legitimate post-skip blocks are no longer ignored.
128
+ const skippedSlots = blockSlot - parentBlock.slot - 1;
129
+
136
130
  // [REJECT] The length of KZG commitments is less than or equal to the limitation defined in Consensus Layer -- i.e. validate that len(body.signed_beacon_block.message.blob_kzg_commitments) <= MAX_BLOBS_PER_BLOCK
137
131
  if (isForkPostDeneb(fork) && !isForkPostGloas(fork)) {
138
132
  const blobKzgCommitmentsLen = (block as deneb.BeaconBlock).body.blobKzgCommitments.length;
@@ -247,4 +241,6 @@ export async function validateGossipBlock(
247
241
  }
248
242
 
249
243
  chain.seenBlockProposers.add(blockSlot, proposerIndex);
244
+
245
+ return {skippedSlots};
250
246
  }
@@ -1,4 +1,5 @@
1
1
  import {PublicKey} from "@chainsafe/blst";
2
+ import {PAYLOAD_BUILDER_VERSION} from "@lodestar/params";
2
3
  import {
3
4
  computeEpochAtSlot,
4
5
  createSingleSignatureSetFromComponents,
@@ -35,10 +36,6 @@ async function validateExecutionPayloadBid(
35
36
  const bid = signedExecutionPayloadBid.message;
36
37
  const parentBlockRootHex = toRootHex(bid.parentBlockRoot);
37
38
  const parentBlockHashHex = toRootHex(bid.parentBlockHash);
38
- const state = await chain.getHeadStateAtCurrentEpoch(RegenCaller.validateGossipExecutionPayloadBid);
39
- if (!isStatePostGloas(state)) {
40
- throw new Error(`Expected gloas+ state for execution payload bid validation, got fork=${state.forkName}`);
41
- }
42
39
 
43
40
  // [IGNORE] `bid.slot` is the current slot or the next slot.
44
41
  const currentSlot = chain.clock.currentSlot;
@@ -61,6 +58,17 @@ async function validateExecutionPayloadBid(
61
58
  });
62
59
  }
63
60
 
61
+ // [REJECT] The bid is for a higher slot than its parent block -- i.e.
62
+ // validate that `bid.slot` is greater than the slot of the block with root
63
+ // `bid.parent_block_root`.
64
+ if (bid.slot <= parentBlock.slot) {
65
+ throw new ExecutionPayloadBidError(GossipAction.REJECT, {
66
+ code: ExecutionPayloadBidErrorCode.NOT_LATER_THAN_PARENT,
67
+ parentSlot: parentBlock.slot,
68
+ slot: bid.slot,
69
+ });
70
+ }
71
+
64
72
  // [IGNORE] A `SignedProposerPreferences` matching `bid.slot` and the bid's branch has been
65
73
  // seen — i.e. `proposal_slot == bid.slot` AND `dependent_root ==
66
74
  // get_proposer_dependent_root(parent_state, compute_epoch_at_slot(bid.slot))`.
@@ -100,9 +108,31 @@ async function validateExecutionPayloadBid(
100
108
  });
101
109
  }
102
110
 
111
+ // Use the bid's parent branch state for builder checks
112
+ const state = await chain.regen
113
+ .getBlockSlotState(parentBlock, bid.slot, {dontTransferCache: true}, RegenCaller.validateGossipExecutionPayloadBid)
114
+ .catch(() => {
115
+ throw new ExecutionPayloadBidError(GossipAction.IGNORE, {
116
+ code: ExecutionPayloadBidErrorCode.UNKNOWN_BLOCK_ROOT,
117
+ parentBlockRoot: parentBlockRootHex,
118
+ });
119
+ });
120
+
121
+ if (!isStatePostGloas(state)) {
122
+ throw new Error(`Expected gloas+ state for execution payload bid validation, got fork=${state.forkName}`);
123
+ }
124
+
103
125
  // [REJECT] `bid.builder_index` is a valid/active builder index -- i.e.
104
126
  // `is_active_builder(state, bid.builder_index)` returns `True`.
105
- const builder = state.getBuilder(bid.builderIndex);
127
+ let builder: gloas.Builder;
128
+ try {
129
+ builder = state.getBuilder(bid.builderIndex);
130
+ } catch {
131
+ throw new ExecutionPayloadBidError(GossipAction.REJECT, {
132
+ code: ExecutionPayloadBidErrorCode.BUILDER_NOT_ELIGIBLE,
133
+ builderIndex: bid.builderIndex,
134
+ });
135
+ }
106
136
  if (!isActiveBuilder(builder, state.finalizedCheckpoint.epoch)) {
107
137
  throw new ExecutionPayloadBidError(GossipAction.REJECT, {
108
138
  code: ExecutionPayloadBidErrorCode.BUILDER_NOT_ELIGIBLE,
@@ -110,6 +140,17 @@ async function validateExecutionPayloadBid(
110
140
  });
111
141
  }
112
142
 
143
+ // [REJECT] The builder version is `PAYLOAD_BUILDER_VERSION` -- i.e.
144
+ // `state.builders[bid.builder_index].version == PAYLOAD_BUILDER_VERSION`.
145
+ if (builder.version !== PAYLOAD_BUILDER_VERSION) {
146
+ throw new ExecutionPayloadBidError(GossipAction.REJECT, {
147
+ code: ExecutionPayloadBidErrorCode.INVALID_BUILDER_VERSION,
148
+ builderIndex: bid.builderIndex,
149
+ version: builder.version,
150
+ expectedVersion: PAYLOAD_BUILDER_VERSION,
151
+ });
152
+ }
153
+
113
154
  // [REJECT] `bid.execution_payment` is zero.
114
155
  if (bid.executionPayment !== 0) {
115
156
  throw new ExecutionPayloadBidError(GossipAction.REJECT, {
@@ -146,7 +187,7 @@ async function validateExecutionPayloadBid(
146
187
  // [IGNORE] `is_gas_limit_target_compatible(parent_gas_limit, bid.gas_limit, target_gas_limit)`,
147
188
  // where `parent_gas_limit` is the `gas_limit` of the parent execution payload and
148
189
  // `target_gas_limit` is `proposer_preferences.target_gas_limit`.
149
- const bidGasLimit = Number(bid.gasLimit);
190
+ const bidGasLimit = bid.gasLimit;
150
191
  const parentGasLimit = parentPayloadVariant.executionPayloadGasLimit;
151
192
  const targetGasLimit = proposerPreferences.message.targetGasLimit;
152
193
  if (!isGasLimitTargetCompatible(parentGasLimit, bidGasLimit, targetGasLimit)) {
@@ -203,6 +244,18 @@ async function validateExecutionPayloadBid(
203
244
  });
204
245
  }
205
246
 
247
+ // [REJECT] `bid.prev_randao` is the correct RANDAO mix -- i.e. validate that
248
+ // `bid.prev_randao == get_randao_mix(parent_state, get_current_epoch(parent_state))`.
249
+ const randaoMix = state.getRandaoMix(computeEpochAtSlot(state.slot));
250
+ if (!byteArrayEquals(bid.prevRandao, randaoMix)) {
251
+ throw new ExecutionPayloadBidError(GossipAction.REJECT, {
252
+ code: ExecutionPayloadBidErrorCode.INVALID_PREV_RANDAO,
253
+ builderIndex: bid.builderIndex,
254
+ bidPrevRandao: toHex(bid.prevRandao),
255
+ expectedPrevRandao: toHex(randaoMix),
256
+ });
257
+ }
258
+
206
259
  // [REJECT] `signed_execution_payload_bid.signature` is valid with respect to the `bid.builder_index`.
207
260
  const signatureSet = createSingleSignatureSetFromComponents(
208
261
  PublicKey.fromBytes(builder.pubkey),
@@ -35,8 +35,6 @@ async function validateExecutionPayloadEnvelope(
35
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
- // TODO GLOAS: Need to review this, we should queue the envelope for later
39
- // processing if the block is not yet known, otherwise we would ignore it here
40
38
  const block = chain.forkChoice.getBlockDefaultStatus(envelope.beaconBlockRoot);
41
39
  if (block === null) {
42
40
  throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
@@ -108,7 +106,7 @@ async function validateExecutionPayloadEnvelope(
108
106
  }
109
107
 
110
108
  // [REJECT] `hash_tree_root(envelope.execution_requests) == bid.execution_requests_root`
111
- const requestsRoot = ssz.electra.ExecutionRequests.hashTreeRoot(envelope.executionRequests);
109
+ const requestsRoot = ssz.gloas.ExecutionRequests.hashTreeRoot(envelope.executionRequests);
112
110
  if (!byteArrayEquals(requestsRoot, payloadInput.getBid().executionRequestsRoot)) {
113
111
  throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
114
112
  code: ExecutionPayloadEnvelopeErrorCode.EXECUTION_REQUESTS_ROOT_MISMATCH,
@@ -8,6 +8,7 @@ import {RootHex, gloas, ssz} from "@lodestar/types";
8
8
  import {toRootHex} from "@lodestar/utils";
9
9
  import {GossipAction, PayloadAttestationError, PayloadAttestationErrorCode} from "../errors/index.js";
10
10
  import {IBeaconChain} from "../index.js";
11
+ import {RegenCaller} from "../regen/index.js";
11
12
 
12
13
  export type PayloadAttestationValidationResult = {
13
14
  attDataRootHex: RootHex;
@@ -61,22 +62,43 @@ async function validatePayloadAttestationMessage(
61
62
  // [IGNORE] The message's block `data.beacon_block_root` has been seen (via
62
63
  // gossip or non-gossip sources) (a client MAY queue attestation for processing
63
64
  // once the block is retrieved. Note a client might want to request payload after).
64
- if (!chain.forkChoice.hasBlock(data.beaconBlockRoot)) {
65
+ const block = chain.forkChoice.getBlockDefaultStatus(data.beaconBlockRoot);
66
+ if (!block) {
65
67
  throw new PayloadAttestationError(GossipAction.IGNORE, {
66
68
  code: PayloadAttestationErrorCode.UNKNOWN_BLOCK_ROOT,
67
69
  blockRoot: toRootHex(data.beaconBlockRoot),
68
70
  });
69
71
  }
70
72
 
71
- const state = chain.getHeadState();
72
- if (!isStatePostGloas(state)) {
73
- throw new Error(`Expected gloas+ state for payload attestation validation, got fork=${state.forkName}`);
73
+ // [IGNORE] The block referenced by `data.beacon_block_root` is at slot `data.slot`,
74
+ // i.e. the block has `block.slot == data.slot`.
75
+ if (block.slot !== data.slot) {
76
+ throw new PayloadAttestationError(GossipAction.IGNORE, {
77
+ code: PayloadAttestationErrorCode.INVALID_BLOCK_SLOT,
78
+ blockRoot: toRootHex(data.beaconBlockRoot),
79
+ blockSlot: block.slot,
80
+ slot: data.slot,
81
+ });
74
82
  }
75
83
 
76
84
  // [REJECT] The message's block `data.beacon_block_root` passes validation.
77
85
  // TODO GLOAS: implement this. Technically if we cannot get proto block from fork choice,
78
86
  // it is possible that the block didn't pass the validation
79
87
 
88
+ // Use the referenced block's branch state for the PTC committee check
89
+ const state = await chain.regen
90
+ .getBlockSlotState(block, data.slot, {dontTransferCache: true}, RegenCaller.validateGossipPayloadAttestationMessage)
91
+ .catch(() => {
92
+ throw new PayloadAttestationError(GossipAction.IGNORE, {
93
+ code: PayloadAttestationErrorCode.UNKNOWN_BLOCK_ROOT,
94
+ blockRoot: toRootHex(data.beaconBlockRoot),
95
+ });
96
+ });
97
+
98
+ if (!isStatePostGloas(state)) {
99
+ throw new Error(`Expected gloas+ state for payload attestation validation, got fork=${state.forkName}`);
100
+ }
101
+
80
102
  // [REJECT] The message's validator index is within the payload committee in
81
103
  // `get_ptc(state, data.slot)`. The `state` is the head state corresponding to
82
104
  // processing the block up to the current slot as determined by the fork choice.
@@ -244,7 +244,7 @@ export class ExecutionEngineHttp implements IExecutionEngine {
244
244
  if (executionRequests === undefined) {
245
245
  throw Error(`executionRequests required in notifyNewPayload for fork=${fork}`);
246
246
  }
247
- const serializedExecutionRequests = serializeExecutionRequests(executionRequests);
247
+ const serializedExecutionRequests = serializeExecutionRequests(fork, executionRequests);
248
248
  engineRequest = {
249
249
  method: ForkSeq[fork] >= ForkSeq.gloas ? "engine_newPayloadV5" : "engine_newPayloadV4",
250
250
  params: [
@@ -1,5 +1,7 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {
3
+ BUILDER_DEPOSIT_REQUEST_TYPE,
4
+ BUILDER_EXIT_REQUEST_TYPE,
3
5
  CONSOLIDATION_REQUEST_TYPE,
4
6
  DEPOSIT_REQUEST_TYPE,
5
7
  ForkName,
@@ -51,10 +53,18 @@ export enum ExecutionEngineState {
51
53
  export type ExecutionRequestType =
52
54
  | typeof DEPOSIT_REQUEST_TYPE
53
55
  | typeof WITHDRAWAL_REQUEST_TYPE
54
- | typeof CONSOLIDATION_REQUEST_TYPE;
56
+ | typeof CONSOLIDATION_REQUEST_TYPE
57
+ | typeof BUILDER_DEPOSIT_REQUEST_TYPE
58
+ | typeof BUILDER_EXIT_REQUEST_TYPE;
55
59
 
56
60
  export function isExecutionRequestType(type: number): type is ExecutionRequestType {
57
- return type === DEPOSIT_REQUEST_TYPE || type === WITHDRAWAL_REQUEST_TYPE || type === CONSOLIDATION_REQUEST_TYPE;
61
+ return (
62
+ type === DEPOSIT_REQUEST_TYPE ||
63
+ type === WITHDRAWAL_REQUEST_TYPE ||
64
+ type === CONSOLIDATION_REQUEST_TYPE ||
65
+ type === BUILDER_DEPOSIT_REQUEST_TYPE ||
66
+ type === BUILDER_EXIT_REQUEST_TYPE
67
+ );
58
68
  }
59
69
 
60
70
  export type ExecutePayloadResponse =
@@ -393,11 +393,12 @@ export class ExecutionEngineMockBackend implements JsonRpcBackend {
393
393
  blobs,
394
394
  proofs,
395
395
  }),
396
- executionRequests: serializeExecutionRequests({
397
- deposits: ssz.electra.DepositRequests.defaultValue(),
398
- withdrawals: ssz.electra.WithdrawalRequests.defaultValue(),
399
- consolidations: ssz.electra.ConsolidationRequests.defaultValue(),
400
- }),
396
+ executionRequests: serializeExecutionRequests(
397
+ fork,
398
+ ForkSeq[fork] >= ForkSeq.gloas
399
+ ? ssz.gloas.ExecutionRequests.defaultValue()
400
+ : ssz.electra.ExecutionRequests.defaultValue()
401
+ ),
401
402
  });
402
403
 
403
404
  // IF the payload is deemed VALID and the build process has begun