@lodestar/beacon-node 1.43.0-dev.6641fd750e → 1.43.0-dev.66d2c102e3

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 (368) hide show
  1. package/lib/api/impl/beacon/blocks/index.js +4 -6
  2. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  3. package/lib/api/impl/beacon/state/utils.d.ts +2 -2
  4. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  6. package/lib/api/impl/lodestar/attesterSlashing.d.ts +8 -0
  7. package/lib/api/impl/lodestar/attesterSlashing.d.ts.map +1 -0
  8. package/lib/api/impl/lodestar/attesterSlashing.js +29 -0
  9. package/lib/api/impl/lodestar/attesterSlashing.js.map +1 -0
  10. package/lib/api/impl/lodestar/index.d.ts.map +1 -1
  11. package/lib/api/impl/lodestar/index.js +37 -2
  12. package/lib/api/impl/lodestar/index.js.map +1 -1
  13. package/lib/api/impl/validator/index.d.ts.map +1 -1
  14. package/lib/api/impl/validator/index.js +1 -4
  15. package/lib/api/impl/validator/index.js.map +1 -1
  16. package/lib/chain/GetBlobsTracker.d.ts +1 -1
  17. package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
  18. package/lib/chain/GetBlobsTracker.js +1 -2
  19. package/lib/chain/GetBlobsTracker.js.map +1 -1
  20. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  21. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  22. package/lib/chain/archiveStore/interface.d.ts +4 -4
  23. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  24. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
  25. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
  26. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +2 -4
  27. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
  28. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +2 -2
  29. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  30. package/lib/chain/archiveStore/utils/archiveBlocks.js +110 -58
  31. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  32. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  33. package/lib/chain/blocks/importBlock.js +32 -37
  34. package/lib/chain/blocks/importBlock.js.map +1 -1
  35. package/lib/chain/blocks/importExecutionPayload.d.ts +25 -13
  36. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  37. package/lib/chain/blocks/importExecutionPayload.js +73 -84
  38. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  39. package/lib/chain/blocks/index.d.ts +5 -3
  40. package/lib/chain/blocks/index.d.ts.map +1 -1
  41. package/lib/chain/blocks/index.js +29 -11
  42. package/lib/chain/blocks/index.js.map +1 -1
  43. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +3 -0
  44. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  45. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +20 -0
  46. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  47. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +5 -0
  48. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -1
  49. package/lib/chain/blocks/payloadEnvelopeProcessor.js +7 -5
  50. package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
  51. package/lib/chain/blocks/types.d.ts +15 -21
  52. package/lib/chain/blocks/types.d.ts.map +1 -1
  53. package/lib/chain/blocks/utils/chainSegment.d.ts +23 -2
  54. package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
  55. package/lib/chain/blocks/utils/chainSegment.js +81 -12
  56. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  57. package/lib/chain/blocks/verifyBlock.d.ts +3 -2
  58. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  59. package/lib/chain/blocks/verifyBlock.js +30 -5
  60. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  61. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
  62. package/lib/chain/blocks/verifyBlocksSanityChecks.js +15 -4
  63. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  64. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +24 -0
  65. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -0
  66. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +76 -0
  67. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -0
  68. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts +14 -0
  69. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -0
  70. package/lib/chain/blocks/verifyPayloadsDataAvailability.js +25 -0
  71. package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -0
  72. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +1 -1
  73. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -1
  74. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +2 -11
  75. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -1
  76. package/lib/chain/chain.d.ts +8 -6
  77. package/lib/chain/chain.d.ts.map +1 -1
  78. package/lib/chain/chain.js +36 -43
  79. package/lib/chain/chain.js.map +1 -1
  80. package/lib/chain/emitter.d.ts +16 -4
  81. package/lib/chain/emitter.d.ts.map +1 -1
  82. package/lib/chain/emitter.js +5 -0
  83. package/lib/chain/emitter.js.map +1 -1
  84. package/lib/chain/errors/attestationError.d.ts +8 -1
  85. package/lib/chain/errors/attestationError.d.ts.map +1 -1
  86. package/lib/chain/errors/attestationError.js +4 -0
  87. package/lib/chain/errors/attestationError.js.map +1 -1
  88. package/lib/chain/errors/blockError.d.ts +8 -1
  89. package/lib/chain/errors/blockError.d.ts.map +1 -1
  90. package/lib/chain/errors/blockError.js +2 -0
  91. package/lib/chain/errors/blockError.js.map +1 -1
  92. package/lib/chain/errors/executionPayloadBid.d.ts +5 -0
  93. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  94. package/lib/chain/errors/executionPayloadBid.js +1 -0
  95. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  96. package/lib/chain/errors/executionPayloadEnvelope.d.ts +5 -0
  97. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  98. package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
  99. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  100. package/lib/chain/errors/index.d.ts +1 -0
  101. package/lib/chain/errors/index.d.ts.map +1 -1
  102. package/lib/chain/errors/index.js +1 -0
  103. package/lib/chain/errors/index.js.map +1 -1
  104. package/lib/chain/errors/proposerPreferences.d.ts +33 -0
  105. package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
  106. package/lib/chain/errors/proposerPreferences.js +13 -0
  107. package/lib/chain/errors/proposerPreferences.js.map +1 -0
  108. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  109. package/lib/chain/forkChoice/index.js +11 -15
  110. package/lib/chain/forkChoice/index.js.map +1 -1
  111. package/lib/chain/interface.d.ts +7 -5
  112. package/lib/chain/interface.d.ts.map +1 -1
  113. package/lib/chain/interface.js.map +1 -1
  114. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  115. package/lib/chain/prepareNextSlot.js +48 -22
  116. package/lib/chain/prepareNextSlot.js.map +1 -1
  117. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +3 -9
  118. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  119. package/lib/chain/produceBlock/computeNewStateRoot.js +5 -32
  120. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  121. package/lib/chain/produceBlock/produceBlockBody.d.ts +4 -8
  122. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  123. package/lib/chain/produceBlock/produceBlockBody.js +55 -24
  124. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  125. package/lib/chain/regen/errors.d.ts +1 -11
  126. package/lib/chain/regen/errors.d.ts.map +1 -1
  127. package/lib/chain/regen/errors.js +0 -2
  128. package/lib/chain/regen/errors.js.map +1 -1
  129. package/lib/chain/regen/interface.d.ts +7 -12
  130. package/lib/chain/regen/interface.d.ts.map +1 -1
  131. package/lib/chain/regen/interface.js +1 -0
  132. package/lib/chain/regen/interface.js.map +1 -1
  133. package/lib/chain/regen/queued.d.ts +6 -11
  134. package/lib/chain/regen/queued.d.ts.map +1 -1
  135. package/lib/chain/regen/queued.js +8 -40
  136. package/lib/chain/regen/queued.js.map +1 -1
  137. package/lib/chain/regen/regen.d.ts +0 -5
  138. package/lib/chain/regen/regen.d.ts.map +1 -1
  139. package/lib/chain/regen/regen.js +7 -34
  140. package/lib/chain/regen/regen.js.map +1 -1
  141. package/lib/chain/seenCache/index.d.ts +1 -0
  142. package/lib/chain/seenCache/index.d.ts.map +1 -1
  143. package/lib/chain/seenCache/index.js +1 -0
  144. package/lib/chain/seenCache/index.js.map +1 -1
  145. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +11 -4
  146. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  147. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +20 -18
  148. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  149. package/lib/chain/seenCache/seenProposerPreferences.d.ts +15 -0
  150. package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
  151. package/lib/chain/seenCache/seenProposerPreferences.js +25 -0
  152. package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
  153. package/lib/chain/stateCache/datastore/db.d.ts +5 -4
  154. package/lib/chain/stateCache/datastore/db.d.ts.map +1 -1
  155. package/lib/chain/stateCache/datastore/db.js +10 -32
  156. package/lib/chain/stateCache/datastore/db.js.map +1 -1
  157. package/lib/chain/stateCache/datastore/file.d.ts +1 -1
  158. package/lib/chain/stateCache/datastore/file.d.ts.map +1 -1
  159. package/lib/chain/stateCache/datastore/file.js +5 -5
  160. package/lib/chain/stateCache/datastore/file.js.map +1 -1
  161. package/lib/chain/stateCache/datastore/types.d.ts +1 -1
  162. package/lib/chain/stateCache/datastore/types.d.ts.map +1 -1
  163. package/lib/chain/stateCache/fifoBlockStateCache.d.ts +1 -7
  164. package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
  165. package/lib/chain/stateCache/fifoBlockStateCache.js +0 -8
  166. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  167. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +13 -30
  168. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  169. package/lib/chain/stateCache/persistentCheckpointsCache.js +120 -216
  170. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  171. package/lib/chain/stateCache/types.d.ts +8 -15
  172. package/lib/chain/stateCache/types.d.ts.map +1 -1
  173. package/lib/chain/stateCache/types.js.map +1 -1
  174. package/lib/chain/validation/aggregateAndProof.js +12 -0
  175. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  176. package/lib/chain/validation/attestation.d.ts.map +1 -1
  177. package/lib/chain/validation/attestation.js +12 -0
  178. package/lib/chain/validation/attestation.js.map +1 -1
  179. package/lib/chain/validation/block.d.ts.map +1 -1
  180. package/lib/chain/validation/block.js +1 -0
  181. package/lib/chain/validation/block.js.map +1 -1
  182. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  183. package/lib/chain/validation/executionPayloadBid.js +13 -1
  184. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  185. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  186. package/lib/chain/validation/executionPayloadEnvelope.js +21 -11
  187. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  188. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  189. package/lib/chain/validation/payloadAttestationMessage.js +4 -3
  190. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  191. package/lib/chain/validation/proposerPreferences.d.ts +8 -0
  192. package/lib/chain/validation/proposerPreferences.d.ts.map +1 -0
  193. package/lib/chain/validation/proposerPreferences.js +69 -0
  194. package/lib/chain/validation/proposerPreferences.js.map +1 -0
  195. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
  196. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
  197. package/lib/execution/engine/http.d.ts.map +1 -1
  198. package/lib/execution/engine/http.js +21 -14
  199. package/lib/execution/engine/http.js.map +1 -1
  200. package/lib/execution/engine/interface.d.ts +1 -0
  201. package/lib/execution/engine/interface.d.ts.map +1 -1
  202. package/lib/execution/engine/mock.d.ts.map +1 -1
  203. package/lib/execution/engine/mock.js +6 -0
  204. package/lib/execution/engine/mock.js.map +1 -1
  205. package/lib/execution/engine/types.d.ts +20 -0
  206. package/lib/execution/engine/types.d.ts.map +1 -1
  207. package/lib/execution/engine/types.js +18 -0
  208. package/lib/execution/engine/types.js.map +1 -1
  209. package/lib/metrics/metrics/lodestar.d.ts +1 -0
  210. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  211. package/lib/metrics/metrics/lodestar.js +4 -0
  212. package/lib/metrics/metrics/lodestar.js.map +1 -1
  213. package/lib/network/gossip/interface.d.ts +7 -1
  214. package/lib/network/gossip/interface.d.ts.map +1 -1
  215. package/lib/network/gossip/interface.js +1 -0
  216. package/lib/network/gossip/interface.js.map +1 -1
  217. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  218. package/lib/network/gossip/scoringParameters.js +12 -1
  219. package/lib/network/gossip/scoringParameters.js.map +1 -1
  220. package/lib/network/gossip/topic.d.ts +30 -748
  221. package/lib/network/gossip/topic.d.ts.map +1 -1
  222. package/lib/network/gossip/topic.js +6 -0
  223. package/lib/network/gossip/topic.js.map +1 -1
  224. package/lib/network/network.js +1 -1
  225. package/lib/network/network.js.map +1 -1
  226. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  227. package/lib/network/processor/gossipHandlers.js +32 -12
  228. package/lib/network/processor/gossipHandlers.js.map +1 -1
  229. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  230. package/lib/network/processor/gossipQueues/index.js +5 -0
  231. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  232. package/lib/network/processor/index.d.ts.map +1 -1
  233. package/lib/network/processor/index.js +1 -0
  234. package/lib/network/processor/index.js.map +1 -1
  235. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  236. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +14 -6
  237. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  238. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
  239. package/lib/network/reqresp/handlers/blobSidecarsByRange.js +11 -5
  240. package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
  241. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  242. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +17 -5
  243. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  244. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
  245. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +7 -4
  246. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
  247. package/lib/node/nodejs.d.ts.map +1 -1
  248. package/lib/node/nodejs.js +4 -2
  249. package/lib/node/nodejs.js.map +1 -1
  250. package/lib/node/notifier.js +7 -1
  251. package/lib/node/notifier.js.map +1 -1
  252. package/lib/sync/range/batch.d.ts +12 -2
  253. package/lib/sync/range/batch.d.ts.map +1 -1
  254. package/lib/sync/range/batch.js +56 -30
  255. package/lib/sync/range/batch.js.map +1 -1
  256. package/lib/sync/range/chain.d.ts +6 -2
  257. package/lib/sync/range/chain.d.ts.map +1 -1
  258. package/lib/sync/range/chain.js +4 -3
  259. package/lib/sync/range/chain.js.map +1 -1
  260. package/lib/sync/range/range.d.ts.map +1 -1
  261. package/lib/sync/range/range.js +17 -6
  262. package/lib/sync/range/range.js.map +1 -1
  263. package/lib/sync/types.d.ts +34 -0
  264. package/lib/sync/types.d.ts.map +1 -1
  265. package/lib/sync/types.js +34 -0
  266. package/lib/sync/types.js.map +1 -1
  267. package/lib/sync/unknownBlock.d.ts +24 -1
  268. package/lib/sync/unknownBlock.d.ts.map +1 -1
  269. package/lib/sync/unknownBlock.js +649 -53
  270. package/lib/sync/unknownBlock.js.map +1 -1
  271. package/lib/sync/utils/downloadByRange.d.ts +46 -10
  272. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  273. package/lib/sync/utils/downloadByRange.js +147 -24
  274. package/lib/sync/utils/downloadByRange.js.map +1 -1
  275. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  276. package/lib/sync/utils/downloadByRoot.js +6 -2
  277. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  278. package/lib/sync/utils/pendingBlocksTree.d.ts +0 -1
  279. package/lib/sync/utils/pendingBlocksTree.d.ts.map +1 -1
  280. package/lib/sync/utils/pendingBlocksTree.js +0 -9
  281. package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
  282. package/lib/util/sszBytes.d.ts.map +1 -1
  283. package/lib/util/sszBytes.js +16 -3
  284. package/lib/util/sszBytes.js.map +1 -1
  285. package/package.json +17 -16
  286. package/src/api/impl/beacon/blocks/index.ts +6 -6
  287. package/src/api/impl/beacon/state/utils.ts +2 -2
  288. package/src/api/impl/lodestar/attesterSlashing.ts +43 -0
  289. package/src/api/impl/lodestar/index.ts +49 -3
  290. package/src/api/impl/validator/index.ts +3 -6
  291. package/src/chain/GetBlobsTracker.ts +1 -2
  292. package/src/chain/archiveStore/archiveStore.ts +5 -5
  293. package/src/chain/archiveStore/interface.ts +4 -4
  294. package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +6 -8
  295. package/src/chain/archiveStore/utils/archiveBlocks.ts +153 -94
  296. package/src/chain/blocks/importBlock.ts +31 -42
  297. package/src/chain/blocks/importExecutionPayload.ts +93 -104
  298. package/src/chain/blocks/index.ts +45 -14
  299. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +27 -0
  300. package/src/chain/blocks/payloadEnvelopeProcessor.ts +7 -6
  301. package/src/chain/blocks/types.ts +15 -26
  302. package/src/chain/blocks/utils/chainSegment.ts +106 -17
  303. package/src/chain/blocks/verifyBlock.ts +35 -6
  304. package/src/chain/blocks/verifyBlocksSanityChecks.ts +16 -7
  305. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +129 -0
  306. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +38 -0
  307. package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +9 -18
  308. package/src/chain/chain.ts +51 -65
  309. package/src/chain/emitter.ts +15 -3
  310. package/src/chain/errors/attestationError.ts +6 -1
  311. package/src/chain/errors/blockError.ts +4 -1
  312. package/src/chain/errors/executionPayloadBid.ts +6 -0
  313. package/src/chain/errors/executionPayloadEnvelope.ts +6 -0
  314. package/src/chain/errors/index.ts +1 -0
  315. package/src/chain/errors/proposerPreferences.ts +39 -0
  316. package/src/chain/forkChoice/index.ts +8 -20
  317. package/src/chain/interface.ts +11 -3
  318. package/src/chain/prepareNextSlot.ts +62 -23
  319. package/src/chain/produceBlock/computeNewStateRoot.ts +6 -43
  320. package/src/chain/produceBlock/produceBlockBody.ts +73 -27
  321. package/src/chain/regen/errors.ts +1 -6
  322. package/src/chain/regen/interface.ts +7 -12
  323. package/src/chain/regen/queued.ts +12 -48
  324. package/src/chain/regen/regen.ts +8 -36
  325. package/src/chain/seenCache/index.ts +1 -0
  326. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +22 -20
  327. package/src/chain/seenCache/seenProposerPreferences.ts +29 -0
  328. package/src/chain/stateCache/datastore/db.ts +10 -33
  329. package/src/chain/stateCache/datastore/file.ts +5 -6
  330. package/src/chain/stateCache/datastore/types.ts +2 -3
  331. package/src/chain/stateCache/fifoBlockStateCache.ts +1 -10
  332. package/src/chain/stateCache/persistentCheckpointsCache.ts +139 -247
  333. package/src/chain/stateCache/types.ts +8 -14
  334. package/src/chain/validation/aggregateAndProof.ts +13 -0
  335. package/src/chain/validation/attestation.ts +13 -0
  336. package/src/chain/validation/block.ts +1 -0
  337. package/src/chain/validation/executionPayloadBid.ts +14 -0
  338. package/src/chain/validation/executionPayloadEnvelope.ts +22 -12
  339. package/src/chain/validation/payloadAttestationMessage.ts +5 -3
  340. package/src/chain/validation/proposerPreferences.ts +91 -0
  341. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
  342. package/src/execution/engine/http.ts +21 -14
  343. package/src/execution/engine/interface.ts +1 -0
  344. package/src/execution/engine/mock.ts +8 -1
  345. package/src/execution/engine/types.ts +41 -0
  346. package/src/metrics/metrics/lodestar.ts +4 -0
  347. package/src/network/gossip/interface.ts +6 -0
  348. package/src/network/gossip/scoringParameters.ts +14 -1
  349. package/src/network/gossip/topic.ts +6 -0
  350. package/src/network/network.ts +1 -1
  351. package/src/network/processor/gossipHandlers.ts +41 -16
  352. package/src/network/processor/gossipQueues/index.ts +5 -0
  353. package/src/network/processor/index.ts +1 -0
  354. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +14 -6
  355. package/src/network/reqresp/handlers/blobSidecarsByRange.ts +11 -5
  356. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -5
  357. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +7 -4
  358. package/src/node/nodejs.ts +4 -2
  359. package/src/node/notifier.ts +8 -1
  360. package/src/sync/range/batch.ts +90 -35
  361. package/src/sync/range/chain.ts +13 -5
  362. package/src/sync/range/range.ts +18 -6
  363. package/src/sync/types.ts +72 -0
  364. package/src/sync/unknownBlock.ts +810 -57
  365. package/src/sync/utils/downloadByRange.ts +256 -39
  366. package/src/sync/utils/downloadByRoot.ts +12 -2
  367. package/src/sync/utils/pendingBlocksTree.ts +0 -15
  368. package/src/util/sszBytes.ts +21 -3
@@ -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, electra} 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 updatedHead = headBlock;
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
@@ -146,7 +148,7 @@ export class PrepareNextSlotScheduler {
146
148
  {dontTransferCache: !isEpochTransition},
147
149
  RegenCaller.predictProposerHead
148
150
  );
149
- updatedHeadRoot = proposerHeadRoot;
151
+ updatedHead = proposerHead;
150
152
  }
151
153
 
152
154
  // Update the builder status, if enabled shoot an api call to check status
@@ -156,29 +158,56 @@ 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
+ }
159
166
 
167
+ let parentBlockHash: Bytes32;
168
+ let isExtendingPayload = false;
169
+ if (isStatePostGloas(updatedPrepareState)) {
170
+ isExtendingPayload = this.chain.forkChoice.shouldExtendPayload(updatedHead.blockRoot);
171
+ parentBlockHash = isExtendingPayload
172
+ ? updatedPrepareState.latestExecutionPayloadBid.blockHash
173
+ : updatedPrepareState.latestExecutionPayloadBid.parentBlockHash;
174
+ } else {
175
+ parentBlockHash = updatedPrepareState.latestExecutionPayloadHeader.blockHash;
176
+ }
177
+
178
+ // Reused by the SSE emit below to avoid a second DB lookup on cache miss
179
+ let parentExecutionRequests: electra.ExecutionRequests | undefined;
180
+
181
+ if (feeRecipient) {
160
182
  const preparationTime =
161
183
  computeTimeAtSlot(this.config, prepareSlot, this.chain.genesisTime) - Date.now() / 1000;
162
184
  this.metrics?.blockPayload.payloadAdvancePrepTime.observe(preparationTime);
163
- if (!isStatePostBellatrix(updatedPrepareState)) {
164
- throw new Error("Expected Bellatrix state for payload preparation");
165
- }
166
185
 
167
186
  const safeBlockHash = getSafeExecutionBlockHash(this.chain.forkChoice);
168
187
  const finalizedBlockHash =
169
188
  this.chain.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
189
+
190
+ if (isExtendingPayload) {
191
+ parentExecutionRequests = await this.chain.getParentExecutionRequests(
192
+ updatedHead.slot,
193
+ updatedHead.blockRoot
194
+ );
195
+ }
196
+
170
197
  // 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
198
+ // left for scheduler and this gives nice semantics to catch and log errors in the
172
199
  // try/catch wrapper here.
173
200
  await prepareExecutionPayload(
174
201
  this.chain,
175
202
  this.logger,
176
203
  fork as ForkPostBellatrix, // State is of execution type
177
- fromHex(updatedHeadRoot),
204
+ fromHex(updatedHead.blockRoot),
205
+ parentBlockHash,
178
206
  safeBlockHash,
179
207
  finalizedBlockHash,
180
208
  updatedPrepareState,
181
- feeRecipient
209
+ feeRecipient,
210
+ parentExecutionRequests
182
211
  );
183
212
  this.logger.verbose("PrepareNextSlotScheduler prepared new payload", {
184
213
  prepareSlot,
@@ -187,24 +216,38 @@ export class PrepareNextSlotScheduler {
187
216
  });
188
217
  }
189
218
 
190
- if (!isStatePostBellatrix(updatedPrepareState)) {
191
- throw new Error("Expected Bellatrix state for payload attributes");
219
+ if (ForkSeq[fork] >= ForkSeq.gloas) {
220
+ // Cutoff = slot of the parent of the block we'll actually build on (post-reorg).
221
+ // Steady state: cache holds just 2 entries — head (parent for next-slot production)
222
+ // and head.parent (proposer-boost-reorg fallback). Anything older is evicted.
223
+ const updatedHeadParent = this.chain.forkChoice.getBlockHexDefaultStatus(updatedHead.parentRoot);
224
+ if (updatedHeadParent) {
225
+ this.chain.seenPayloadEnvelopeInputCache.pruneBelow(updatedHeadParent.slot);
226
+ }
192
227
  }
193
228
 
194
229
  this.computeStateHashTreeRoot(updatedPrepareState, isEpochTransition);
195
230
 
196
- // If emitPayloadAttributes is true emit a SSE payloadAttributes event
231
+ // If emitPayloadAttributes is true emit a SSE payloadAttributes event for
232
+ // every slot. Without the flag, only emit the event if we are proposing in the next slot.
197
233
  if (
198
- this.chain.opts.emitPayloadAttributes === true &&
234
+ (feeRecipient || this.chain.opts.emitPayloadAttributes === true) &&
199
235
  this.chain.emitter.listenerCount(routes.events.EventType.payloadAttributes)
200
236
  ) {
237
+ // if we didn't fetch above (not proposing), SSE still needs it here
238
+ if (!parentExecutionRequests && isExtendingPayload) {
239
+ parentExecutionRequests = await this.chain.getParentExecutionRequests(
240
+ updatedHead.slot,
241
+ updatedHead.blockRoot
242
+ );
243
+ }
201
244
  const data = getPayloadAttributesForSSE(fork as ForkPostBellatrix, this.chain, {
202
245
  prepareState: updatedPrepareState,
203
246
  prepareSlot,
204
- parentBlockRoot: fromHex(headRoot),
205
- // The likely consumers of this API are builders and will anyway ignore the
206
- // feeRecipient, so just pass zero hash for now till a real use case arises
207
- feeRecipient: "0x0000000000000000000000000000000000000000000000000000000000000000",
247
+ parentBlockRoot: fromHex(updatedHead.blockRoot),
248
+ parentBlockHash,
249
+ feeRecipient: feeRecipient ?? "0x0000000000000000000000000000000000000000",
250
+ parentExecutionRequests,
208
251
  });
209
252
  this.chain.emitter.emit(routes.events.EventType.payloadAttributes, {data, version: fork});
210
253
  }
@@ -217,11 +260,7 @@ export class PrepareNextSlotScheduler {
217
260
  // + if next slot is a skipped slot, it'd help getting target checkpoint state faster to validate attestations
218
261
  if (isEpochTransition) {
219
262
  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);
263
+ const previousHits = this.chain.regen.updatePreComputedCheckpoint(headRoot, nextEpoch);
225
264
  if (previousHits === 0) {
226
265
  this.metrics?.precomputeNextEpochTransition.waste.inc();
227
266
  }
@@ -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
  }
@@ -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,9 +46,10 @@ 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";
52
- import {ZERO_HASH_HEX} from "../../constants/index.js";
51
+ import {Logger, byteArrayEquals, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
52
+ import {ZERO_HASH, ZERO_HASH_HEX} from "../../constants/index.js";
53
53
  import {numToQuantity} from "../../execution/engine/utils.js";
54
54
  import {
55
55
  IExecutionBuilder,
@@ -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,15 +214,30 @@ export async function produceBlockBody<T extends BlockType>(
220
214
  });
221
215
 
222
216
  // Get execution payload from EL
217
+ const isExtendingPayload = this.forkChoice.shouldExtendPayload(toRootHex(parentBlockRoot));
218
+ let parentBlockHash = isExtendingPayload
219
+ ? currentState.latestExecutionPayloadBid.blockHash
220
+ : currentState.latestExecutionPayloadBid.parentBlockHash;
221
+ // At gloas genesis the committed bid has no prior EL block to reference
222
+ // (`bid.parentBlockHash` is zero). Fall back to `bid.blockHash` (= eth1 genesis hash) so the
223
+ // FCU to the EL carries a valid head. Post-genesis bids always reference a non-zero parent.
224
+ if (isStatePostGloas(currentState) && byteArrayEquals(parentBlockHash, ZERO_HASH)) {
225
+ parentBlockHash = currentState.latestExecutionPayloadBid.blockHash;
226
+ }
227
+ const parentExecutionRequests = isExtendingPayload
228
+ ? await this.getParentExecutionRequests(parentBlock.slot, parentBlock.blockRoot)
229
+ : ssz.electra.ExecutionRequests.defaultValue();
223
230
  const prepareRes = await prepareExecutionPayload(
224
231
  this,
225
232
  this.logger,
226
233
  fork,
227
234
  parentBlockRoot,
235
+ parentBlockHash,
228
236
  safeBlockHash,
229
237
  finalizedBlockHash ?? ZERO_HASH_HEX,
230
238
  currentState,
231
- feeRecipient
239
+ feeRecipient,
240
+ parentExecutionRequests
232
241
  );
233
242
 
234
243
  const {prepType, payloadId} = prepareRes;
@@ -261,8 +270,8 @@ export async function produceBlockBody<T extends BlockType>(
261
270
 
262
271
  // Create self-build execution payload bid
263
272
  const bid: gloas.ExecutionPayloadBid = {
264
- parentBlockHash: currentState.latestBlockHash,
265
- parentBlockRoot: parentBlockRoot,
273
+ parentBlockHash,
274
+ parentBlockRoot,
266
275
  blockHash: executionPayload.blockHash,
267
276
  prevRandao: currentState.getRandaoMix(currentState.epoch),
268
277
  feeRecipient: executionPayload.feeRecipient,
@@ -272,6 +281,7 @@ export async function produceBlockBody<T extends BlockType>(
272
281
  value: 0,
273
282
  executionPayment: 0,
274
283
  blobKzgCommitments: blobsBundle.commitments,
284
+ executionRequestsRoot: ssz.electra.ExecutionRequests.hashTreeRoot(executionRequests),
275
285
  };
276
286
  const signedBid: gloas.SignedExecutionPayloadBid = {
277
287
  message: bid,
@@ -283,6 +293,7 @@ export async function produceBlockBody<T extends BlockType>(
283
293
  gloasBody.signedExecutionPayloadBid = signedBid;
284
294
  // TODO GLOAS: Get payload attestations from pool for previous slot
285
295
  gloasBody.payloadAttestations = [];
296
+ gloasBody.parentExecutionRequests = parentExecutionRequests;
286
297
  blockBody = gloasBody as AssembledBodyType<T>;
287
298
 
288
299
  // Store execution payload data required to construct execution payload envelope later
@@ -340,6 +351,7 @@ export async function produceBlockBody<T extends BlockType>(
340
351
  this.logger,
341
352
  fork,
342
353
  parentBlockRoot,
354
+ currentState.latestExecutionPayloadHeader.blockHash,
343
355
  safeBlockHash,
344
356
  finalizedBlockHash ?? ZERO_HASH_HEX,
345
357
  currentState,
@@ -448,6 +460,7 @@ export async function produceBlockBody<T extends BlockType>(
448
460
  this.logger,
449
461
  fork,
450
462
  parentBlockRoot,
463
+ currentState.latestExecutionPayloadHeader.blockHash,
451
464
  safeBlockHash,
452
465
  finalizedBlockHash ?? ZERO_HASH_HEX,
453
466
  currentState,
@@ -613,17 +626,18 @@ export async function prepareExecutionPayload(
613
626
  logger: Logger,
614
627
  fork: ForkPostBellatrix,
615
628
  parentBlockRoot: Root,
629
+ parentBlockHash: Bytes32,
616
630
  safeBlockHash: RootHex,
617
631
  finalizedBlockHash: RootHex,
618
632
  state: IBeaconStateViewBellatrix,
619
- suggestedFeeRecipient: string
633
+ suggestedFeeRecipient: string,
634
+ parentExecutionRequests?: electra.ExecutionRequests
620
635
  ): Promise<{prepType: PayloadPreparationType; payloadId: PayloadId}> {
621
- const parentHash = state.latestBlockHash;
622
636
  const timestamp = computeTimeAtSlot(chain.config, state.slot, state.genesisTime);
623
637
  const prevRandao = state.getRandaoMix(state.epoch);
624
638
 
625
639
  const payloadIdCached = chain.executionEngine.payloadIdCache.get({
626
- headBlockHash: toRootHex(parentHash),
640
+ headBlockHash: toRootHex(parentBlockHash),
627
641
  finalizedBlockHash,
628
642
  timestamp: numToQuantity(timestamp),
629
643
  prevRandao: toHex(prevRandao),
@@ -652,12 +666,14 @@ export async function prepareExecutionPayload(
652
666
  prepareState: state,
653
667
  prepareSlot: state.slot,
654
668
  parentBlockRoot,
669
+ parentBlockHash,
655
670
  feeRecipient: suggestedFeeRecipient,
671
+ parentExecutionRequests,
656
672
  });
657
673
 
658
674
  payloadId = await chain.executionEngine.notifyForkchoiceUpdate(
659
675
  fork,
660
- toRootHex(parentHash),
676
+ toRootHex(parentBlockHash),
661
677
  safeBlockHash,
662
678
  finalizedBlockHash,
663
679
  attributes
@@ -709,20 +725,33 @@ export function getPayloadAttributesForSSE(
709
725
  prepareState,
710
726
  prepareSlot,
711
727
  parentBlockRoot,
728
+ parentBlockHash,
712
729
  feeRecipient,
713
- }: {prepareState: IBeaconStateViewBellatrix; prepareSlot: Slot; parentBlockRoot: Root; feeRecipient: string}
730
+ parentExecutionRequests,
731
+ }: {
732
+ prepareState: IBeaconStateViewBellatrix;
733
+ prepareSlot: Slot;
734
+ parentBlockRoot: Root;
735
+ parentBlockHash: Bytes32;
736
+ feeRecipient: string;
737
+ parentExecutionRequests?: electra.ExecutionRequests;
738
+ }
714
739
  ): SSEPayloadAttributes {
715
- const parentHash = prepareState.latestBlockHash;
716
740
  const payloadAttributes = preparePayloadAttributes(fork, chain, {
717
741
  prepareState,
718
742
  prepareSlot,
719
743
  parentBlockRoot,
744
+ parentBlockHash,
720
745
  feeRecipient,
746
+ parentExecutionRequests,
721
747
  });
722
748
 
723
749
  let parentBlockNumber: number;
724
750
  if (isForkPostGloas(fork)) {
725
- const parentBlock = chain.forkChoice.getBlockHexAndBlockHash(toRootHex(parentBlockRoot), toRootHex(parentHash));
751
+ const parentBlock = chain.forkChoice.getBlockHexAndBlockHash(
752
+ toRootHex(parentBlockRoot),
753
+ toRootHex(parentBlockHash)
754
+ );
726
755
  if (parentBlock?.executionPayloadBlockHash == null) {
727
756
  throw Error(`Parent block not found in fork choice root=${toRootHex(parentBlockRoot)}`);
728
757
  }
@@ -736,7 +765,7 @@ export function getPayloadAttributesForSSE(
736
765
  proposalSlot: prepareSlot,
737
766
  parentBlockNumber,
738
767
  parentBlockRoot,
739
- parentBlockHash: parentHash,
768
+ parentBlockHash,
740
769
  payloadAttributes,
741
770
  };
742
771
  return ssePayloadAttributes;
@@ -751,12 +780,16 @@ function preparePayloadAttributes(
751
780
  prepareState,
752
781
  prepareSlot,
753
782
  parentBlockRoot,
783
+ parentBlockHash,
754
784
  feeRecipient,
785
+ parentExecutionRequests,
755
786
  }: {
756
787
  prepareState: IBeaconStateViewBellatrix;
757
788
  prepareSlot: Slot;
758
789
  parentBlockRoot: Root;
790
+ parentBlockHash: Bytes32;
759
791
  feeRecipient: string;
792
+ parentExecutionRequests?: electra.ExecutionRequests;
760
793
  }
761
794
  ): SSEPayloadAttributes["payloadAttributes"] {
762
795
  const timestamp = computeTimeAtSlot(chain.config, prepareSlot, prepareState.genesisTime);
@@ -772,13 +805,22 @@ function preparePayloadAttributes(
772
805
  throw new Error("Expected Capella state for withdrawals");
773
806
  }
774
807
 
775
- if (isStatePostGloas(prepareState) && !isParentBlockFull(prepareState)) {
776
- // When the parent block is empty, state.payloadExpectedWithdrawals holds a batch
777
- // already deducted from CL balances but never credited on the EL (the envelope
778
- // was not delivered). The next payload must carry those same withdrawals to
779
- // restore CL/EL consistency, otherwise validators permanently lose that balance.
780
- (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
781
- prepareState.payloadExpectedWithdrawals;
808
+ if (isStatePostGloas(prepareState)) {
809
+ const isExtendingPayload = byteArrayEquals(parentBlockHash, prepareState.latestExecutionPayloadBid.blockHash);
810
+ if (isExtendingPayload) {
811
+ if (parentExecutionRequests === undefined) {
812
+ throw new Error("parentExecutionRequests required when extending full parent");
813
+ }
814
+ (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
815
+ prepareState.getExpectedWithdrawalsForFullParent(parentExecutionRequests);
816
+ } else {
817
+ // When the parent block is empty, state.payloadExpectedWithdrawals holds a batch
818
+ // already deducted from CL balances but never credited on the EL (the envelope
819
+ // was not delivered). The next payload must carry those same withdrawals to
820
+ // restore CL/EL consistency, otherwise validators permanently lose that balance.
821
+ (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
822
+ prepareState.payloadExpectedWithdrawals;
823
+ }
782
824
  } else {
783
825
  // withdrawals logic is now fork aware as it changes on electra fork post capella
784
826
  (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
@@ -790,6 +832,10 @@ function preparePayloadAttributes(
790
832
  (payloadAttributes as deneb.SSEPayloadAttributes["payloadAttributes"]).parentBeaconBlockRoot = parentBlockRoot;
791
833
  }
792
834
 
835
+ if (ForkSeq[fork] >= ForkSeq.gloas) {
836
+ (payloadAttributes as gloas.SSEPayloadAttributes["payloadAttributes"]).slotNumber = prepareSlot;
837
+ }
838
+
793
839
  return payloadAttributes;
794
840
  }
795
841
 
@@ -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",
@@ -21,6 +21,7 @@ export enum RegenCaller {
21
21
  validateGossipAttestation = "validateGossipAttestation",
22
22
  validateGossipVoluntaryExit = "validateGossipVoluntaryExit",
23
23
  validateGossipExecutionPayloadBid = "validateGossipExecutionPayloadBid",
24
+ validateGossipProposerPreferences = "validateGossipProposerPreferences",
24
25
  onForkChoiceFinalized = "onForkChoiceFinalized",
25
26
  restApi = "restApi",
26
27
  }
@@ -40,21 +41,15 @@ export interface IStateRegenerator extends IStateRegeneratorInternal {
40
41
  dumpCacheSummary(): routes.lodestar.StateCacheItem[];
41
42
  getStateSync(stateRoot: RootHex): IBeaconStateView | null;
42
43
  getPreStateSync(block: BeaconBlock): IBeaconStateView | null;
43
- getCheckpointStateOrBytes(cp: CheckpointHexPayload): Promise<IBeaconStateView | Uint8Array | null>;
44
- getCheckpointStateSync(cp: CheckpointHexPayload): IBeaconStateView | null;
44
+ getCheckpointStateOrBytes(cp: CheckpointHex): Promise<IBeaconStateView | Uint8Array | null>;
45
+ getCheckpointStateSync(cp: CheckpointHex): IBeaconStateView | null;
45
46
  getClosestHeadState(head: ProtoBlock): IBeaconStateView | null;
46
47
  pruneOnCheckpoint(finalizedEpoch: Epoch, justifiedEpoch: Epoch, headStateRoot: RootHex): void;
47
48
  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;
49
+ processState(blockRootHex: RootHex, postState: IBeaconStateView): void;
50
+ addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView): void;
55
51
  updateHeadState(newHead: ProtoBlock, maybeHeadState: IBeaconStateView): void;
56
- updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch, payloadPresent: boolean): number | null;
57
- upgradeForGloas(epoch: Epoch): void;
52
+ updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null;
58
53
  }
59
54
 
60
55
  /**