@lodestar/beacon-node 1.43.0-dev.2870b59b6a → 1.43.0-dev.2fba242f5d

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 (357) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +17 -9
  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 +45 -2
  6. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  7. package/lib/api/impl/beacon/state/utils.d.ts +2 -2
  8. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  9. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  10. package/lib/api/impl/debug/index.d.ts.map +1 -1
  11. package/lib/api/impl/debug/index.js +0 -1
  12. package/lib/api/impl/debug/index.js.map +1 -1
  13. package/lib/api/impl/lodestar/index.js +1 -1
  14. package/lib/api/impl/lodestar/index.js.map +1 -1
  15. package/lib/api/impl/validator/index.d.ts.map +1 -1
  16. package/lib/api/impl/validator/index.js +67 -5
  17. package/lib/api/impl/validator/index.js.map +1 -1
  18. package/lib/chain/GetBlobsTracker.d.ts +1 -1
  19. package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
  20. package/lib/chain/GetBlobsTracker.js +1 -2
  21. package/lib/chain/GetBlobsTracker.js.map +1 -1
  22. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  23. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  24. package/lib/chain/archiveStore/interface.d.ts +4 -4
  25. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  26. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
  27. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
  28. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +2 -4
  29. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
  30. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +2 -2
  31. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  32. package/lib/chain/archiveStore/utils/archiveBlocks.js +110 -58
  33. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  34. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  35. package/lib/chain/blocks/importBlock.js +45 -49
  36. package/lib/chain/blocks/importBlock.js.map +1 -1
  37. package/lib/chain/blocks/importExecutionPayload.d.ts +28 -14
  38. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  39. package/lib/chain/blocks/importExecutionPayload.js +88 -88
  40. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  41. package/lib/chain/blocks/index.d.ts +5 -3
  42. package/lib/chain/blocks/index.d.ts.map +1 -1
  43. package/lib/chain/blocks/index.js +59 -26
  44. package/lib/chain/blocks/index.js.map +1 -1
  45. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +4 -0
  46. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  47. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +25 -1
  48. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  49. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +1 -0
  50. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  51. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +5 -0
  52. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -1
  53. package/lib/chain/blocks/payloadEnvelopeProcessor.js +7 -5
  54. package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
  55. package/lib/chain/blocks/types.d.ts +16 -21
  56. package/lib/chain/blocks/types.d.ts.map +1 -1
  57. package/lib/chain/blocks/utils/chainSegment.d.ts +23 -2
  58. package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
  59. package/lib/chain/blocks/utils/chainSegment.js +89 -12
  60. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  61. package/lib/chain/blocks/verifyBlock.d.ts +5 -3
  62. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  63. package/lib/chain/blocks/verifyBlock.js +50 -7
  64. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  65. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +0 -4
  66. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  67. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -2
  68. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  69. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts +2 -1
  70. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
  71. package/lib/chain/blocks/verifyBlocksSanityChecks.js +25 -5
  72. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  73. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +24 -0
  74. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -0
  75. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +76 -0
  76. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -0
  77. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts +14 -0
  78. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -0
  79. package/lib/chain/blocks/verifyPayloadsDataAvailability.js +30 -0
  80. package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -0
  81. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +1 -1
  82. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -1
  83. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +2 -11
  84. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -1
  85. package/lib/chain/chain.d.ts +8 -6
  86. package/lib/chain/chain.d.ts.map +1 -1
  87. package/lib/chain/chain.js +35 -36
  88. package/lib/chain/chain.js.map +1 -1
  89. package/lib/chain/emitter.d.ts +16 -15
  90. package/lib/chain/emitter.d.ts.map +1 -1
  91. package/lib/chain/emitter.js +5 -4
  92. package/lib/chain/emitter.js.map +1 -1
  93. package/lib/chain/errors/blockError.d.ts +8 -1
  94. package/lib/chain/errors/blockError.d.ts.map +1 -1
  95. package/lib/chain/errors/blockError.js +2 -0
  96. package/lib/chain/errors/blockError.js.map +1 -1
  97. package/lib/chain/errors/executionPayloadBid.d.ts +5 -0
  98. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  99. package/lib/chain/errors/executionPayloadBid.js +1 -0
  100. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  101. package/lib/chain/errors/executionPayloadEnvelope.d.ts +5 -0
  102. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  103. package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
  104. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  105. package/lib/chain/errors/index.d.ts +1 -0
  106. package/lib/chain/errors/index.d.ts.map +1 -1
  107. package/lib/chain/errors/index.js +1 -0
  108. package/lib/chain/errors/index.js.map +1 -1
  109. package/lib/chain/errors/proposerPreferences.d.ts +33 -0
  110. package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
  111. package/lib/chain/errors/proposerPreferences.js +13 -0
  112. package/lib/chain/errors/proposerPreferences.js.map +1 -0
  113. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  114. package/lib/chain/forkChoice/index.js +11 -15
  115. package/lib/chain/forkChoice/index.js.map +1 -1
  116. package/lib/chain/interface.d.ts +7 -5
  117. package/lib/chain/interface.d.ts.map +1 -1
  118. package/lib/chain/interface.js.map +1 -1
  119. package/lib/chain/opPools/payloadAttestationPool.d.ts +3 -2
  120. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
  121. package/lib/chain/opPools/payloadAttestationPool.js +26 -4
  122. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
  123. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  124. package/lib/chain/prepareNextSlot.js +47 -23
  125. package/lib/chain/prepareNextSlot.js.map +1 -1
  126. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +3 -9
  127. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  128. package/lib/chain/produceBlock/computeNewStateRoot.js +5 -32
  129. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  130. package/lib/chain/produceBlock/produceBlockBody.d.ts +12 -8
  131. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  132. package/lib/chain/produceBlock/produceBlockBody.js +67 -25
  133. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  134. package/lib/chain/regen/errors.d.ts +1 -11
  135. package/lib/chain/regen/errors.d.ts.map +1 -1
  136. package/lib/chain/regen/errors.js +0 -2
  137. package/lib/chain/regen/errors.js.map +1 -1
  138. package/lib/chain/regen/interface.d.ts +7 -11
  139. package/lib/chain/regen/interface.d.ts.map +1 -1
  140. package/lib/chain/regen/interface.js +1 -0
  141. package/lib/chain/regen/interface.js.map +1 -1
  142. package/lib/chain/regen/queued.d.ts +6 -10
  143. package/lib/chain/regen/queued.d.ts.map +1 -1
  144. package/lib/chain/regen/queued.js +4 -14
  145. package/lib/chain/regen/queued.js.map +1 -1
  146. package/lib/chain/regen/regen.d.ts +0 -5
  147. package/lib/chain/regen/regen.d.ts.map +1 -1
  148. package/lib/chain/regen/regen.js +1 -12
  149. package/lib/chain/regen/regen.js.map +1 -1
  150. package/lib/chain/seenCache/index.d.ts +1 -0
  151. package/lib/chain/seenCache/index.d.ts.map +1 -1
  152. package/lib/chain/seenCache/index.js +1 -0
  153. package/lib/chain/seenCache/index.js.map +1 -1
  154. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +19 -6
  155. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  156. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +40 -22
  157. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  158. package/lib/chain/seenCache/seenProposerPreferences.d.ts +15 -0
  159. package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
  160. package/lib/chain/seenCache/seenProposerPreferences.js +25 -0
  161. package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
  162. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -7
  163. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  164. package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -9
  165. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  166. package/lib/chain/stateCache/types.d.ts +0 -6
  167. package/lib/chain/stateCache/types.d.ts.map +1 -1
  168. package/lib/chain/stateCache/types.js.map +1 -1
  169. package/lib/chain/validation/block.d.ts.map +1 -1
  170. package/lib/chain/validation/block.js +1 -0
  171. package/lib/chain/validation/block.js.map +1 -1
  172. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  173. package/lib/chain/validation/executionPayloadBid.js +13 -1
  174. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  175. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  176. package/lib/chain/validation/executionPayloadEnvelope.js +20 -10
  177. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  178. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  179. package/lib/chain/validation/payloadAttestationMessage.js +4 -3
  180. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  181. package/lib/chain/validation/proposerPreferences.d.ts +8 -0
  182. package/lib/chain/validation/proposerPreferences.d.ts.map +1 -0
  183. package/lib/chain/validation/proposerPreferences.js +69 -0
  184. package/lib/chain/validation/proposerPreferences.js.map +1 -0
  185. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
  186. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
  187. package/lib/execution/engine/http.d.ts.map +1 -1
  188. package/lib/execution/engine/http.js +21 -14
  189. package/lib/execution/engine/http.js.map +1 -1
  190. package/lib/execution/engine/interface.d.ts +1 -0
  191. package/lib/execution/engine/interface.d.ts.map +1 -1
  192. package/lib/execution/engine/mock.d.ts.map +1 -1
  193. package/lib/execution/engine/mock.js +6 -0
  194. package/lib/execution/engine/mock.js.map +1 -1
  195. package/lib/execution/engine/types.d.ts +20 -0
  196. package/lib/execution/engine/types.d.ts.map +1 -1
  197. package/lib/execution/engine/types.js +18 -0
  198. package/lib/execution/engine/types.js.map +1 -1
  199. package/lib/metrics/metrics/lodestar.d.ts +1 -0
  200. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  201. package/lib/metrics/metrics/lodestar.js +4 -0
  202. package/lib/metrics/metrics/lodestar.js.map +1 -1
  203. package/lib/network/gossip/interface.d.ts +7 -1
  204. package/lib/network/gossip/interface.d.ts.map +1 -1
  205. package/lib/network/gossip/interface.js +1 -0
  206. package/lib/network/gossip/interface.js.map +1 -1
  207. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  208. package/lib/network/gossip/scoringParameters.js +12 -1
  209. package/lib/network/gossip/scoringParameters.js.map +1 -1
  210. package/lib/network/gossip/topic.d.ts +11 -2
  211. package/lib/network/gossip/topic.d.ts.map +1 -1
  212. package/lib/network/gossip/topic.js +6 -0
  213. package/lib/network/gossip/topic.js.map +1 -1
  214. package/lib/network/interface.d.ts +1 -0
  215. package/lib/network/interface.d.ts.map +1 -1
  216. package/lib/network/network.d.ts +1 -0
  217. package/lib/network/network.d.ts.map +1 -1
  218. package/lib/network/network.js +6 -1
  219. package/lib/network/network.js.map +1 -1
  220. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  221. package/lib/network/processor/gossipHandlers.js +46 -22
  222. package/lib/network/processor/gossipHandlers.js.map +1 -1
  223. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  224. package/lib/network/processor/gossipQueues/index.js +5 -0
  225. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  226. package/lib/network/processor/index.d.ts.map +1 -1
  227. package/lib/network/processor/index.js +6 -5
  228. package/lib/network/processor/index.js.map +1 -1
  229. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  230. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +14 -6
  231. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  232. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
  233. package/lib/network/reqresp/handlers/blobSidecarsByRange.js +11 -5
  234. package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
  235. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  236. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +17 -5
  237. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  238. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
  239. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +7 -4
  240. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
  241. package/lib/node/nodejs.d.ts.map +1 -1
  242. package/lib/node/nodejs.js +6 -4
  243. package/lib/node/nodejs.js.map +1 -1
  244. package/lib/sync/range/batch.d.ts +23 -2
  245. package/lib/sync/range/batch.d.ts.map +1 -1
  246. package/lib/sync/range/batch.js +84 -33
  247. package/lib/sync/range/batch.js.map +1 -1
  248. package/lib/sync/range/chain.d.ts +6 -2
  249. package/lib/sync/range/chain.d.ts.map +1 -1
  250. package/lib/sync/range/chain.js +26 -7
  251. package/lib/sync/range/chain.js.map +1 -1
  252. package/lib/sync/range/range.d.ts.map +1 -1
  253. package/lib/sync/range/range.js +17 -6
  254. package/lib/sync/range/range.js.map +1 -1
  255. package/lib/sync/types.d.ts +34 -0
  256. package/lib/sync/types.d.ts.map +1 -1
  257. package/lib/sync/types.js +34 -0
  258. package/lib/sync/types.js.map +1 -1
  259. package/lib/sync/unknownBlock.d.ts +22 -1
  260. package/lib/sync/unknownBlock.d.ts.map +1 -1
  261. package/lib/sync/unknownBlock.js +602 -53
  262. package/lib/sync/unknownBlock.js.map +1 -1
  263. package/lib/sync/utils/downloadByRange.d.ts +46 -10
  264. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  265. package/lib/sync/utils/downloadByRange.js +164 -24
  266. package/lib/sync/utils/downloadByRange.js.map +1 -1
  267. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  268. package/lib/sync/utils/downloadByRoot.js +16 -2
  269. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  270. package/lib/sync/utils/pendingBlocksTree.d.ts +0 -1
  271. package/lib/sync/utils/pendingBlocksTree.d.ts.map +1 -1
  272. package/lib/sync/utils/pendingBlocksTree.js +0 -9
  273. package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
  274. package/lib/util/sszBytes.d.ts.map +1 -1
  275. package/lib/util/sszBytes.js +16 -3
  276. package/lib/util/sszBytes.js.map +1 -1
  277. package/package.json +17 -16
  278. package/src/api/impl/beacon/blocks/index.ts +22 -9
  279. package/src/api/impl/beacon/pool/index.ts +83 -1
  280. package/src/api/impl/beacon/state/utils.ts +2 -2
  281. package/src/api/impl/debug/index.ts +0 -1
  282. package/src/api/impl/lodestar/index.ts +1 -1
  283. package/src/api/impl/validator/index.ts +83 -6
  284. package/src/chain/GetBlobsTracker.ts +1 -2
  285. package/src/chain/archiveStore/archiveStore.ts +5 -5
  286. package/src/chain/archiveStore/interface.ts +4 -4
  287. package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +6 -8
  288. package/src/chain/archiveStore/utils/archiveBlocks.ts +153 -94
  289. package/src/chain/blocks/importBlock.ts +46 -73
  290. package/src/chain/blocks/importExecutionPayload.ts +109 -101
  291. package/src/chain/blocks/index.ts +74 -24
  292. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +33 -1
  293. package/src/chain/blocks/payloadEnvelopeInput/types.ts +1 -0
  294. package/src/chain/blocks/payloadEnvelopeProcessor.ts +7 -6
  295. package/src/chain/blocks/types.ts +16 -26
  296. package/src/chain/blocks/utils/chainSegment.ts +114 -17
  297. package/src/chain/blocks/verifyBlock.ts +70 -9
  298. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +6 -4
  299. package/src/chain/blocks/verifyBlocksSanityChecks.ts +26 -7
  300. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +129 -0
  301. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +41 -0
  302. package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +9 -18
  303. package/src/chain/chain.ts +51 -51
  304. package/src/chain/emitter.ts +15 -14
  305. package/src/chain/errors/blockError.ts +4 -1
  306. package/src/chain/errors/executionPayloadBid.ts +6 -0
  307. package/src/chain/errors/executionPayloadEnvelope.ts +6 -0
  308. package/src/chain/errors/index.ts +1 -0
  309. package/src/chain/errors/proposerPreferences.ts +39 -0
  310. package/src/chain/forkChoice/index.ts +8 -20
  311. package/src/chain/interface.ts +11 -3
  312. package/src/chain/opPools/payloadAttestationPool.ts +29 -8
  313. package/src/chain/prepareNextSlot.ts +55 -24
  314. package/src/chain/produceBlock/computeNewStateRoot.ts +6 -43
  315. package/src/chain/produceBlock/produceBlockBody.ts +89 -27
  316. package/src/chain/regen/errors.ts +1 -6
  317. package/src/chain/regen/interface.ts +7 -11
  318. package/src/chain/regen/queued.ts +8 -21
  319. package/src/chain/regen/regen.ts +2 -15
  320. package/src/chain/seenCache/index.ts +1 -0
  321. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +47 -25
  322. package/src/chain/seenCache/seenProposerPreferences.ts +29 -0
  323. package/src/chain/stateCache/persistentCheckpointsCache.ts +5 -15
  324. package/src/chain/stateCache/types.ts +0 -3
  325. package/src/chain/validation/block.ts +1 -0
  326. package/src/chain/validation/executionPayloadBid.ts +14 -0
  327. package/src/chain/validation/executionPayloadEnvelope.ts +21 -11
  328. package/src/chain/validation/payloadAttestationMessage.ts +5 -3
  329. package/src/chain/validation/proposerPreferences.ts +91 -0
  330. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
  331. package/src/execution/engine/http.ts +21 -14
  332. package/src/execution/engine/interface.ts +1 -0
  333. package/src/execution/engine/mock.ts +8 -1
  334. package/src/execution/engine/types.ts +41 -0
  335. package/src/metrics/metrics/lodestar.ts +4 -0
  336. package/src/network/gossip/interface.ts +6 -0
  337. package/src/network/gossip/scoringParameters.ts +14 -1
  338. package/src/network/gossip/topic.ts +6 -0
  339. package/src/network/interface.ts +1 -0
  340. package/src/network/network.ts +12 -1
  341. package/src/network/processor/gossipHandlers.ts +61 -27
  342. package/src/network/processor/gossipQueues/index.ts +5 -0
  343. package/src/network/processor/index.ts +6 -5
  344. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +14 -6
  345. package/src/network/reqresp/handlers/blobSidecarsByRange.ts +11 -5
  346. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -5
  347. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +7 -4
  348. package/src/node/nodejs.ts +6 -4
  349. package/src/sync/range/batch.ts +142 -38
  350. package/src/sync/range/chain.ts +37 -9
  351. package/src/sync/range/range.ts +18 -6
  352. package/src/sync/types.ts +72 -0
  353. package/src/sync/unknownBlock.ts +760 -57
  354. package/src/sync/utils/downloadByRange.ts +274 -39
  355. package/src/sync/utils/downloadByRoot.ts +24 -2
  356. package/src/sync/utils/pendingBlocksTree.ts +0 -15
  357. 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,14 +214,28 @@ export async function produceBlockBody<T extends BlockType>(
220
214
  });
221
215
 
222
216
  // Get execution payload from EL
217
+ let parentBlockHash: Bytes32;
218
+ let parentExecutionRequests: electra.ExecutionRequests;
219
+ // Apply parent payload once here as it's reused by EL prep and voluntary exit filtering below
220
+ let stateAfterParentPayload: IBeaconStateViewBellatrix = currentState;
221
+ const isExtendingPayload = this.forkChoice.shouldExtendPayload(toRootHex(parentBlockRoot));
222
+ if (isExtendingPayload) {
223
+ parentBlockHash = currentState.latestExecutionPayloadBid.blockHash;
224
+ parentExecutionRequests = await this.getParentExecutionRequests(parentBlock.slot, parentBlock.blockRoot);
225
+ stateAfterParentPayload = currentState.withParentPayloadApplied(parentExecutionRequests);
226
+ } else {
227
+ parentBlockHash = currentState.latestExecutionPayloadBid.parentBlockHash;
228
+ parentExecutionRequests = ssz.electra.ExecutionRequests.defaultValue();
229
+ }
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
- currentState,
238
+ stateAfterParentPayload,
231
239
  feeRecipient
232
240
  );
233
241
 
@@ -261,8 +269,8 @@ export async function produceBlockBody<T extends BlockType>(
261
269
 
262
270
  // Create self-build execution payload bid
263
271
  const bid: gloas.ExecutionPayloadBid = {
264
- parentBlockHash: currentState.latestBlockHash,
265
- parentBlockRoot: parentBlockRoot,
272
+ parentBlockHash,
273
+ parentBlockRoot,
266
274
  blockHash: executionPayload.blockHash,
267
275
  prevRandao: currentState.getRandaoMix(currentState.epoch),
268
276
  feeRecipient: executionPayload.feeRecipient,
@@ -272,6 +280,7 @@ export async function produceBlockBody<T extends BlockType>(
272
280
  value: 0,
273
281
  executionPayment: 0,
274
282
  blobKzgCommitments: blobsBundle.commitments,
283
+ executionRequestsRoot: ssz.electra.ExecutionRequests.hashTreeRoot(executionRequests),
275
284
  };
276
285
  const signedBid: gloas.SignedExecutionPayloadBid = {
277
286
  message: bid,
@@ -281,8 +290,19 @@ export async function produceBlockBody<T extends BlockType>(
281
290
  const commonBlockBody = await commonBlockBodyPromise;
282
291
  const gloasBody = Object.assign({}, commonBlockBody) as gloas.BeaconBlockBody;
283
292
  gloasBody.signedExecutionPayloadBid = signedBid;
284
- // TODO GLOAS: Get payload attestations from pool for previous slot
285
- gloasBody.payloadAttestations = [];
293
+ gloasBody.payloadAttestations = this.payloadAttestationPool.getPayloadAttestationsForBlock(
294
+ parentBlock.blockRoot,
295
+ blockSlot - 1
296
+ );
297
+ gloasBody.parentExecutionRequests = parentExecutionRequests;
298
+ // Drop voluntary exits that parent_execution_requests have invalidated (e.g. a withdrawal
299
+ // request initiating an exit on the same validator). Op pool selected against the unapplied
300
+ // state, so re-validate against the post-apply state to avoid producing an invalid block.
301
+ if (isExtendingPayload && commonBlockBody.voluntaryExits.length > 0) {
302
+ gloasBody.voluntaryExits = commonBlockBody.voluntaryExits.filter((signedVoluntaryExit) =>
303
+ stateAfterParentPayload.isValidVoluntaryExit(signedVoluntaryExit, false)
304
+ );
305
+ }
286
306
  blockBody = gloasBody as AssembledBodyType<T>;
287
307
 
288
308
  // Store execution payload data required to construct execution payload envelope later
@@ -340,6 +360,7 @@ export async function produceBlockBody<T extends BlockType>(
340
360
  this.logger,
341
361
  fork,
342
362
  parentBlockRoot,
363
+ currentState.latestExecutionPayloadHeader.blockHash,
343
364
  safeBlockHash,
344
365
  finalizedBlockHash ?? ZERO_HASH_HEX,
345
366
  currentState,
@@ -448,6 +469,7 @@ export async function produceBlockBody<T extends BlockType>(
448
469
  this.logger,
449
470
  fork,
450
471
  parentBlockRoot,
472
+ currentState.latestExecutionPayloadHeader.blockHash,
451
473
  safeBlockHash,
452
474
  finalizedBlockHash ?? ZERO_HASH_HEX,
453
475
  currentState,
@@ -613,17 +635,21 @@ export async function prepareExecutionPayload(
613
635
  logger: Logger,
614
636
  fork: ForkPostBellatrix,
615
637
  parentBlockRoot: Root,
638
+ parentBlockHash: Bytes32,
616
639
  safeBlockHash: RootHex,
617
640
  finalizedBlockHash: RootHex,
641
+ /**
642
+ * Post-gloas, when extending a full parent, callers must apply
643
+ * parent execution payload first (see `withParentPayloadApplied`).
644
+ */
618
645
  state: IBeaconStateViewBellatrix,
619
646
  suggestedFeeRecipient: string
620
647
  ): Promise<{prepType: PayloadPreparationType; payloadId: PayloadId}> {
621
- const parentHash = state.latestBlockHash;
622
648
  const timestamp = computeTimeAtSlot(chain.config, state.slot, state.genesisTime);
623
649
  const prevRandao = state.getRandaoMix(state.epoch);
624
650
 
625
651
  const payloadIdCached = chain.executionEngine.payloadIdCache.get({
626
- headBlockHash: toRootHex(parentHash),
652
+ headBlockHash: toRootHex(parentBlockHash),
627
653
  finalizedBlockHash,
628
654
  timestamp: numToQuantity(timestamp),
629
655
  prevRandao: toHex(prevRandao),
@@ -652,12 +678,13 @@ export async function prepareExecutionPayload(
652
678
  prepareState: state,
653
679
  prepareSlot: state.slot,
654
680
  parentBlockRoot,
681
+ parentBlockHash,
655
682
  feeRecipient: suggestedFeeRecipient,
656
683
  });
657
684
 
658
685
  payloadId = await chain.executionEngine.notifyForkchoiceUpdate(
659
686
  fork,
660
- toRootHex(parentHash),
687
+ toRootHex(parentBlockHash),
661
688
  safeBlockHash,
662
689
  finalizedBlockHash,
663
690
  attributes
@@ -709,20 +736,34 @@ export function getPayloadAttributesForSSE(
709
736
  prepareState,
710
737
  prepareSlot,
711
738
  parentBlockRoot,
739
+ parentBlockHash,
712
740
  feeRecipient,
713
- }: {prepareState: IBeaconStateViewBellatrix; prepareSlot: Slot; parentBlockRoot: Root; feeRecipient: string}
741
+ }: {
742
+ /**
743
+ * Post-gloas, when extending a full parent, callers must apply
744
+ * parent execution payload first (see `withParentPayloadApplied`).
745
+ */
746
+ prepareState: IBeaconStateViewBellatrix;
747
+ prepareSlot: Slot;
748
+ parentBlockRoot: Root;
749
+ parentBlockHash: Bytes32;
750
+ feeRecipient: string;
751
+ }
714
752
  ): SSEPayloadAttributes {
715
- const parentHash = prepareState.latestBlockHash;
716
753
  const payloadAttributes = preparePayloadAttributes(fork, chain, {
717
754
  prepareState,
718
755
  prepareSlot,
719
756
  parentBlockRoot,
757
+ parentBlockHash,
720
758
  feeRecipient,
721
759
  });
722
760
 
723
761
  let parentBlockNumber: number;
724
762
  if (isForkPostGloas(fork)) {
725
- const parentBlock = chain.forkChoice.getBlockHexAndBlockHash(toRootHex(parentBlockRoot), toRootHex(parentHash));
763
+ const parentBlock = chain.forkChoice.getBlockHexAndBlockHash(
764
+ toRootHex(parentBlockRoot),
765
+ toRootHex(parentBlockHash)
766
+ );
726
767
  if (parentBlock?.executionPayloadBlockHash == null) {
727
768
  throw Error(`Parent block not found in fork choice root=${toRootHex(parentBlockRoot)}`);
728
769
  }
@@ -736,7 +777,7 @@ export function getPayloadAttributesForSSE(
736
777
  proposalSlot: prepareSlot,
737
778
  parentBlockNumber,
738
779
  parentBlockRoot,
739
- parentBlockHash: parentHash,
780
+ parentBlockHash,
740
781
  payloadAttributes,
741
782
  };
742
783
  return ssePayloadAttributes;
@@ -751,11 +792,17 @@ function preparePayloadAttributes(
751
792
  prepareState,
752
793
  prepareSlot,
753
794
  parentBlockRoot,
795
+ parentBlockHash,
754
796
  feeRecipient,
755
797
  }: {
798
+ /**
799
+ * Post-gloas, when extending a full parent, callers must apply
800
+ * parent execution payload first (see `withParentPayloadApplied`).
801
+ */
756
802
  prepareState: IBeaconStateViewBellatrix;
757
803
  prepareSlot: Slot;
758
804
  parentBlockRoot: Root;
805
+ parentBlockHash: Bytes32;
759
806
  feeRecipient: string;
760
807
  }
761
808
  ): SSEPayloadAttributes["payloadAttributes"] {
@@ -772,13 +819,24 @@ function preparePayloadAttributes(
772
819
  throw new Error("Expected Capella state for withdrawals");
773
820
  }
774
821
 
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;
822
+ if (isStatePostGloas(prepareState)) {
823
+ const isExtendingPayload = byteArrayEquals(parentBlockHash, prepareState.latestExecutionPayloadBid.blockHash);
824
+ if (isExtendingPayload) {
825
+ // applyParentExecutionPayload sets latestBlockHash = parentBid.blockHash, so a mismatch
826
+ // here means the caller did not apply parent payload to prepareState
827
+ if (!byteArrayEquals(prepareState.latestBlockHash, prepareState.latestExecutionPayloadBid.blockHash)) {
828
+ throw new Error("Expected state with parent execution payload applied for withdrawals");
829
+ }
830
+ (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
831
+ prepareState.getExpectedWithdrawals().expectedWithdrawals;
832
+ } else {
833
+ // When the parent block is empty, state.payloadExpectedWithdrawals holds a batch
834
+ // already deducted from CL balances but never credited on the EL (the envelope
835
+ // was not delivered). The next payload must carry those same withdrawals to
836
+ // restore CL/EL consistency, otherwise validators permanently lose that balance.
837
+ (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
838
+ prepareState.payloadExpectedWithdrawals;
839
+ }
782
840
  } else {
783
841
  // withdrawals logic is now fork aware as it changes on electra fork post capella
784
842
  (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
@@ -790,6 +848,10 @@ function preparePayloadAttributes(
790
848
  (payloadAttributes as deneb.SSEPayloadAttributes["payloadAttributes"]).parentBeaconBlockRoot = parentBlockRoot;
791
849
  }
792
850
 
851
+ if (ForkSeq[fork] >= ForkSeq.gloas) {
852
+ (payloadAttributes as gloas.SSEPayloadAttributes["payloadAttributes"]).slotNumber = prepareSlot;
853
+ }
854
+
793
855
  return payloadAttributes;
794
856
  }
795
857
 
@@ -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,20 +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;
52
+ updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null;
57
53
  }
58
54
 
59
55
  /**
@@ -1,11 +1,11 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
3
3
  import {IBeaconStateView, computeEpochAtSlot} from "@lodestar/state-transition";
4
- import {BeaconBlock, Epoch, RootHex, Slot, isGloasBeaconBlock, phase0} from "@lodestar/types";
4
+ import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
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,
@@ -88,12 +88,7 @@ export class QueuedStateRegenerator implements IStateRegenerator {
88
88
  */
89
89
  getPreStateSync(block: BeaconBlock): IBeaconStateView | null {
90
90
  const parentRoot = toRootHex(block.parentRoot);
91
- const parentBlock = isGloasBeaconBlock(block)
92
- ? this.forkChoice.getBlockHexAndBlockHash(
93
- parentRoot,
94
- toRootHex(block.body.signedExecutionPayloadBid.message.parentBlockHash)
95
- )
96
- : this.forkChoice.getBlockHexDefaultStatus(parentRoot);
91
+ const parentBlock = this.forkChoice.getBlockHexDefaultStatus(parentRoot);
97
92
  if (!parentBlock) {
98
93
  throw new RegenError({
99
94
  code: RegenErrorCode.BLOCK_NOT_IN_FORKCHOICE,
@@ -125,14 +120,14 @@ export class QueuedStateRegenerator implements IStateRegenerator {
125
120
  return null;
126
121
  }
127
122
 
128
- async getCheckpointStateOrBytes(cp: CheckpointHexPayload): Promise<IBeaconStateView | Uint8Array | null> {
123
+ async getCheckpointStateOrBytes(cp: CheckpointHex): Promise<IBeaconStateView | Uint8Array | null> {
129
124
  return this.checkpointStateCache.getStateOrBytes(cp);
130
125
  }
131
126
 
132
127
  /**
133
128
  * Get checkpoint state from cache
134
129
  */
135
- getCheckpointStateSync(cp: CheckpointHexPayload): IBeaconStateView | null {
130
+ getCheckpointStateSync(cp: CheckpointHex): IBeaconStateView | null {
136
131
  return this.checkpointStateCache.get(cp);
137
132
  }
138
133
 
@@ -153,22 +148,14 @@ export class QueuedStateRegenerator implements IStateRegenerator {
153
148
  this.blockStateCache.deleteAllBeforeEpoch(finalizedEpoch);
154
149
  }
155
150
 
156
- processBlockState(blockRootHex: RootHex, postState: IBeaconStateView): void {
151
+ processState(blockRootHex: RootHex, postState: IBeaconStateView): void {
157
152
  this.blockStateCache.add(postState);
158
153
  this.checkpointStateCache.processState(blockRootHex, postState).catch((e) => {
159
154
  this.logger.debug("Error processing block state", {blockRootHex, slot: postState.slot}, e);
160
155
  });
161
156
  }
162
157
 
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 {
158
+ addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView): void {
172
159
  this.checkpointStateCache.add(cp, item);
173
160
  }
174
161
 
@@ -205,7 +192,7 @@ export class QueuedStateRegenerator implements IStateRegenerator {
205
192
  }
206
193
  }
207
194
 
208
- updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch, _payloadPresent: boolean): number | null {
195
+ updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null {
209
196
  return this.checkpointStateCache.updatePreComputedCheckpoint(rootHex, epoch);
210
197
  }
211
198
 
@@ -9,7 +9,7 @@ import {
9
9
  computeEpochAtSlot,
10
10
  computeStartSlotAtEpoch,
11
11
  } from "@lodestar/state-transition";
12
- import {BeaconBlock, RootHex, SignedBeaconBlock, Slot, isGloasBeaconBlock} from "@lodestar/types";
12
+ import {BeaconBlock, RootHex, SignedBeaconBlock, Slot} from "@lodestar/types";
13
13
  import {Logger, fromHex, toRootHex} from "@lodestar/utils";
14
14
  import {IBeaconDb} from "../../db/index.js";
15
15
  import {Metrics} from "../../metrics/index.js";
@@ -57,12 +57,7 @@ export class StateRegenerator implements IStateRegeneratorInternal {
57
57
  regenCaller: RegenCaller
58
58
  ): Promise<IBeaconStateView> {
59
59
  const parentRoot = toRootHex(block.parentRoot);
60
- const parentBlock = isGloasBeaconBlock(block)
61
- ? this.modules.forkChoice.getBlockHexAndBlockHash(
62
- parentRoot,
63
- toRootHex(block.body.signedExecutionPayloadBid.message.parentBlockHash)
64
- )
65
- : this.modules.forkChoice.getBlockHexDefaultStatus(parentRoot);
60
+ const parentBlock = this.modules.forkChoice.getBlockHexDefaultStatus(parentRoot);
66
61
  if (!parentBlock) {
67
62
  throw new RegenError({
68
63
  code: RegenErrorCode.BLOCK_NOT_IN_FORKCHOICE,
@@ -332,11 +327,6 @@ async function processSlotsByCheckpoint(
332
327
  * emitting "checkpoint" events after every epoch processed.
333
328
  *
334
329
  * 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
330
  */
341
331
  export async function processSlotsToNearestCheckpoint(
342
332
  modules: {
@@ -380,9 +370,6 @@ export async function processSlotsToNearestCheckpoint(
380
370
  // This may becomes the "official" checkpoint state if the 1st block of epoch is skipped
381
371
  const checkpointState = postState;
382
372
  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
373
  checkpointStateCache.add(cp, checkpointState);
387
374
  // consumers should not mutate state ever
388
375
  emitter?.emit(ChainEvent.checkpoint, cp, checkpointState);
@@ -5,3 +5,4 @@ export {SeenContributionAndProof} from "./seenCommitteeContribution.js";
5
5
  export {SeenExecutionPayloadBids} from "./seenExecutionPayloadBids.js";
6
6
  export {SeenBlockInput} from "./seenGossipBlockInput.js";
7
7
  export {PayloadEnvelopeInput, SeenPayloadEnvelopeInput} from "./seenPayloadEnvelopeInput.js";
8
+ export {SeenProposerPreferences} from "./seenProposerPreferences.js";
@@ -1,9 +1,12 @@
1
+ import {ChainForkConfig} from "@lodestar/config";
1
2
  import {CheckpointWithHex} from "@lodestar/fork-choice";
2
3
  import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
3
- import {RootHex} from "@lodestar/types";
4
+ import {RootHex, Slot} from "@lodestar/types";
4
5
  import {Logger} from "@lodestar/utils";
5
6
  import {Metrics} from "../../metrics/metrics.js";
7
+ import {IClock} from "../../util/clock.js";
6
8
  import {SerializedCache} from "../../util/serializedCache.js";
9
+ import {isDaOutOfRange} from "../blocks/blockInput/index.js";
7
10
  import {CreateFromBlockProps, PayloadEnvelopeInput} from "../blocks/payloadEnvelopeInput/index.js";
8
11
  import {ChainEvent, ChainEventEmitter} from "../emitter.js";
9
12
 
@@ -11,6 +14,8 @@ export type {PayloadEnvelopeInputState} from "../blocks/payloadEnvelopeInput/ind
11
14
  export {PayloadEnvelopeInput} from "../blocks/payloadEnvelopeInput/index.js";
12
15
 
13
16
  export type SeenPayloadEnvelopeInputModules = {
17
+ config: ChainForkConfig;
18
+ clock: IClock;
14
19
  chainEvents: ChainEventEmitter;
15
20
  signal: AbortSignal;
16
21
  serializedCache: SerializedCache;
@@ -21,10 +26,19 @@ export type SeenPayloadEnvelopeInputModules = {
21
26
  /**
22
27
  * Cache for tracking PayloadEnvelopeInput instances, keyed by beacon block root.
23
28
  *
24
- * Created during block import when a block is processed.
25
- * Pruned on finalization and after payload is written to DB.
29
+ * Created during block import when a block is processed. Two pruning paths:
30
+ * - `prepareNextSlot` calls `pruneBelow(headParentSlot)` every slot once the head we'll build
31
+ * on is known.
32
+ * - `onFinalized` calls `pruneBelow(finalizedSlot)` on every finalization for bulk cleanup.
33
+ *
34
+ * Steady state (linear chain, healthy progression): the cache holds ~2 entries — the head
35
+ * (parent for next-slot production) and its parent (proposer-boost-reorg fallback). It can
36
+ * transiently hold more during forks, range-sync bursts, or when `prepareNextSlot` skips
37
+ * ticks; subsequent ticks settle it back.
26
38
  */
27
39
  export class SeenPayloadEnvelopeInput {
40
+ private readonly config: ChainForkConfig;
41
+ private readonly clock: IClock;
28
42
  private readonly chainEvents: ChainEventEmitter;
29
43
  private readonly signal: AbortSignal;
30
44
  private readonly serializedCache: SerializedCache;
@@ -32,7 +46,9 @@ export class SeenPayloadEnvelopeInput {
32
46
  private readonly logger?: Logger;
33
47
  private payloadInputs = new Map<RootHex, PayloadEnvelopeInput>();
34
48
 
35
- constructor({chainEvents, signal, serializedCache, metrics, logger}: SeenPayloadEnvelopeInputModules) {
49
+ constructor({config, clock, chainEvents, signal, serializedCache, metrics, logger}: SeenPayloadEnvelopeInputModules) {
50
+ this.config = config;
51
+ this.clock = clock;
36
52
  this.chainEvents = chainEvents;
37
53
  this.signal = signal;
38
54
  this.serializedCache = serializedCache;
@@ -58,25 +74,27 @@ export class SeenPayloadEnvelopeInput {
58
74
  }
59
75
 
60
76
  private onFinalized = (checkpoint: CheckpointWithHex): void => {
61
- // Prune all entries with slot < finalized slot
62
- const finalizedSlot = computeStartSlotAtEpoch(checkpoint.epoch);
63
- let deletedCount = 0;
64
- for (const [, input] of this.payloadInputs) {
65
- if (input.slot < finalizedSlot) {
66
- this.evictPayloadInput(input);
67
- deletedCount++;
68
- }
69
- }
70
- this.logger?.debug("SeenPayloadEnvelopeInput.onFinalized deleted cached entries", {deletedCount});
77
+ this.pruneBelow(computeStartSlotAtEpoch(checkpoint.epoch));
71
78
  };
72
79
 
73
- add(props: CreateFromBlockProps): PayloadEnvelopeInput {
74
- if (this.payloadInputs.has(props.blockRootHex)) {
75
- throw new Error(`PayloadEnvelopeInput already exists for block ${props.blockRootHex}`);
80
+ add(props: Omit<CreateFromBlockProps, "daOutOfRange">): PayloadEnvelopeInput {
81
+ const existing = this.payloadInputs.get(props.blockRootHex);
82
+ if (existing !== undefined) {
83
+ this.logger?.verbose("SeenPayloadEnvelopeInput.add reused existing entry", {
84
+ slot: existing.slot,
85
+ root: props.blockRootHex,
86
+ });
87
+ return existing;
76
88
  }
77
- const input = PayloadEnvelopeInput.createFromBlock(props);
89
+ const daOutOfRange = isDaOutOfRange(this.config, props.forkName, props.block.message.slot, this.clock.currentEpoch);
90
+ const input = PayloadEnvelopeInput.createFromBlock({...props, daOutOfRange});
78
91
  this.payloadInputs.set(props.blockRootHex, input);
79
92
  this.metrics?.seenCache.payloadEnvelopeInput.created.inc();
93
+ this.logger?.verbose("SeenPayloadEnvelopeInput.add created new entry", {
94
+ slot: input.slot,
95
+ root: props.blockRootHex,
96
+ daOutOfRange,
97
+ });
80
98
  return input;
81
99
  }
82
100
 
@@ -88,17 +106,21 @@ export class SeenPayloadEnvelopeInput {
88
106
  return this.payloadInputs.get(blockRootHex)?.hasPayloadEnvelope() ?? false;
89
107
  }
90
108
 
91
- prune(blockRootHex: RootHex): void {
92
- const payloadInput = this.payloadInputs.get(blockRootHex);
93
- if (payloadInput) {
94
- this.evictPayloadInput(payloadInput);
95
- }
96
- }
97
-
98
109
  size(): number {
99
110
  return this.payloadInputs.size;
100
111
  }
101
112
 
113
+ pruneBelow(slot: Slot): void {
114
+ let deletedCount = 0;
115
+ for (const [, input] of this.payloadInputs) {
116
+ if (input.slot < slot) {
117
+ this.evictPayloadInput(input);
118
+ deletedCount++;
119
+ }
120
+ }
121
+ this.logger?.debug("SeenPayloadEnvelopeInput.pruneBelow deleted entries", {slot, deletedCount});
122
+ }
123
+
102
124
  private evictPayloadInput(payloadInput: PayloadEnvelopeInput): void {
103
125
  this.serializedCache.delete(payloadInput.getSerializedCacheKeys());
104
126
  this.payloadInputs.delete(payloadInput.blockRootHex);
@@ -0,0 +1,29 @@
1
+ import {Slot, ValidatorIndex} from "@lodestar/types";
2
+ import {MapDef} from "@lodestar/utils";
3
+
4
+ /**
5
+ * Tracks signed proposer preferences we've already seen per (proposal_slot, validator_index).
6
+ */
7
+ export class SeenProposerPreferences {
8
+ private readonly validatorIndexesBySlot = new MapDef<Slot, Set<ValidatorIndex>>(() => new Set<ValidatorIndex>());
9
+
10
+ isKnown(proposalSlot: Slot, validatorIndex: ValidatorIndex): boolean {
11
+ return this.validatorIndexesBySlot.get(proposalSlot)?.has(validatorIndex) === true;
12
+ }
13
+
14
+ add(proposalSlot: Slot, validatorIndex: ValidatorIndex): void {
15
+ this.validatorIndexesBySlot.getOrDefault(proposalSlot).add(validatorIndex);
16
+ }
17
+
18
+ /**
19
+ * Entries are only load-bearing while `proposal_slot > state.slot`. Once the slot has passed the
20
+ * `[IGNORE] proposal_slot > state.slot` gossip rule takes over, so drop them on each slot tick.
21
+ */
22
+ prune(currentSlot: Slot): void {
23
+ for (const slot of this.validatorIndexesBySlot.keys()) {
24
+ if (slot < currentSlot) {
25
+ this.validatorIndexesBySlot.delete(slot);
26
+ }
27
+ }
28
+ }
29
+ }
@@ -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
  *