@lodestar/beacon-node 1.43.0-dev.4fb05c546d → 1.43.0-dev.4fe6b362c9

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 (412) 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 +86 -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 +86 -17
  17. package/lib/api/impl/validator/index.js.map +1 -1
  18. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  19. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  20. package/lib/chain/archiveStore/interface.d.ts +4 -4
  21. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  22. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
  23. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
  24. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
  25. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +2 -2
  26. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  27. package/lib/chain/archiveStore/utils/archiveBlocks.js +110 -58
  28. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  29. package/lib/chain/blocks/blockInput/blockInput.d.ts +3 -0
  30. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  31. package/lib/chain/blocks/blockInput/blockInput.js +4 -1
  32. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  33. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  34. package/lib/chain/blocks/importBlock.js +16 -28
  35. package/lib/chain/blocks/importBlock.js.map +1 -1
  36. package/lib/chain/blocks/importExecutionPayload.d.ts +32 -14
  37. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  38. package/lib/chain/blocks/importExecutionPayload.js +100 -91
  39. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  40. package/lib/chain/blocks/index.d.ts +5 -3
  41. package/lib/chain/blocks/index.d.ts.map +1 -1
  42. package/lib/chain/blocks/index.js +58 -26
  43. package/lib/chain/blocks/index.js.map +1 -1
  44. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +12 -1
  45. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  46. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +28 -2
  47. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  48. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +17 -0
  49. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  50. package/lib/chain/blocks/payloadEnvelopeProcessor.js +2 -2
  51. package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
  52. package/lib/chain/blocks/types.d.ts +15 -20
  53. package/lib/chain/blocks/types.d.ts.map +1 -1
  54. package/lib/chain/blocks/utils/chainSegment.d.ts +21 -2
  55. package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
  56. package/lib/chain/blocks/utils/chainSegment.js +92 -12
  57. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  58. package/lib/chain/blocks/verifyBlock.d.ts +5 -3
  59. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  60. package/lib/chain/blocks/verifyBlock.js +50 -7
  61. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  62. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +0 -4
  63. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  64. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -2
  65. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  66. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts +2 -1
  67. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
  68. package/lib/chain/blocks/verifyBlocksSanityChecks.js +25 -5
  69. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  70. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +24 -0
  71. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -0
  72. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +80 -0
  73. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -0
  74. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -1
  75. package/lib/chain/blocks/verifyPayloadsDataAvailability.js +8 -3
  76. package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -1
  77. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +1 -1
  78. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -1
  79. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +2 -11
  80. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -1
  81. package/lib/chain/chain.d.ts +10 -7
  82. package/lib/chain/chain.d.ts.map +1 -1
  83. package/lib/chain/chain.js +47 -15
  84. package/lib/chain/chain.js.map +1 -1
  85. package/lib/chain/emitter.d.ts +3 -14
  86. package/lib/chain/emitter.d.ts.map +1 -1
  87. package/lib/chain/emitter.js +0 -4
  88. package/lib/chain/emitter.js.map +1 -1
  89. package/lib/chain/errors/blockError.d.ts +8 -1
  90. package/lib/chain/errors/blockError.d.ts.map +1 -1
  91. package/lib/chain/errors/blockError.js +2 -0
  92. package/lib/chain/errors/blockError.js.map +1 -1
  93. package/lib/chain/errors/executionPayloadBid.d.ts +24 -1
  94. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  95. package/lib/chain/errors/executionPayloadBid.js +4 -0
  96. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  97. package/lib/chain/errors/executionPayloadEnvelope.d.ts +5 -0
  98. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  99. package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
  100. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  101. package/lib/chain/errors/index.d.ts +1 -0
  102. package/lib/chain/errors/index.d.ts.map +1 -1
  103. package/lib/chain/errors/index.js +1 -0
  104. package/lib/chain/errors/index.js.map +1 -1
  105. package/lib/chain/errors/proposerPreferences.d.ts +40 -0
  106. package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
  107. package/lib/chain/errors/proposerPreferences.js +14 -0
  108. package/lib/chain/errors/proposerPreferences.js.map +1 -0
  109. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  110. package/lib/chain/forkChoice/index.js +5 -17
  111. package/lib/chain/forkChoice/index.js.map +1 -1
  112. package/lib/chain/initState.d.ts.map +1 -1
  113. package/lib/chain/initState.js +6 -1
  114. package/lib/chain/initState.js.map +1 -1
  115. package/lib/chain/interface.d.ts +9 -6
  116. package/lib/chain/interface.d.ts.map +1 -1
  117. package/lib/chain/interface.js.map +1 -1
  118. package/lib/chain/lightClient/index.d.ts.map +1 -1
  119. package/lib/chain/lightClient/index.js +1 -1
  120. package/lib/chain/lightClient/index.js.map +1 -1
  121. package/lib/chain/opPools/index.d.ts +1 -0
  122. package/lib/chain/opPools/index.d.ts.map +1 -1
  123. package/lib/chain/opPools/index.js +1 -0
  124. package/lib/chain/opPools/index.js.map +1 -1
  125. package/lib/chain/opPools/payloadAttestationPool.d.ts +4 -3
  126. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
  127. package/lib/chain/opPools/payloadAttestationPool.js +56 -14
  128. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
  129. package/lib/chain/opPools/proposerPreferencesPool.d.ts +29 -0
  130. package/lib/chain/opPools/proposerPreferencesPool.d.ts.map +1 -0
  131. package/lib/chain/opPools/proposerPreferencesPool.js +56 -0
  132. package/lib/chain/opPools/proposerPreferencesPool.js.map +1 -0
  133. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  134. package/lib/chain/prepareNextSlot.js +31 -13
  135. package/lib/chain/prepareNextSlot.js.map +1 -1
  136. package/lib/chain/produceBlock/produceBlockBody.d.ts +11 -1
  137. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  138. package/lib/chain/produceBlock/produceBlockBody.js +52 -14
  139. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  140. package/lib/chain/regen/interface.d.ts +1 -0
  141. package/lib/chain/regen/interface.d.ts.map +1 -1
  142. package/lib/chain/regen/interface.js +1 -0
  143. package/lib/chain/regen/interface.js.map +1 -1
  144. package/lib/chain/regen/queued.d.ts.map +1 -1
  145. package/lib/chain/regen/queued.js +1 -4
  146. package/lib/chain/regen/queued.js.map +1 -1
  147. package/lib/chain/regen/regen.d.ts.map +1 -1
  148. package/lib/chain/regen/regen.js +1 -4
  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 +24 -7
  155. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  156. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +69 -17
  157. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  158. package/lib/chain/seenCache/seenProposerPreferences.d.ts +16 -0
  159. package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
  160. package/lib/chain/seenCache/seenProposerPreferences.js +26 -0
  161. package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
  162. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  163. package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -1
  164. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  165. package/lib/chain/validation/block.d.ts.map +1 -1
  166. package/lib/chain/validation/block.js +1 -0
  167. package/lib/chain/validation/block.js.map +1 -1
  168. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  169. package/lib/chain/validation/executionPayloadBid.js +81 -18
  170. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  171. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  172. package/lib/chain/validation/executionPayloadEnvelope.js +19 -9
  173. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  174. package/lib/chain/validation/payloadAttestationMessage.d.ts +1 -1
  175. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  176. package/lib/chain/validation/payloadAttestationMessage.js +5 -3
  177. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  178. package/lib/chain/validation/proposerPreferences.d.ts +8 -0
  179. package/lib/chain/validation/proposerPreferences.d.ts.map +1 -0
  180. package/lib/chain/validation/proposerPreferences.js +91 -0
  181. package/lib/chain/validation/proposerPreferences.js.map +1 -0
  182. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
  183. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
  184. package/lib/execution/engine/http.d.ts.map +1 -1
  185. package/lib/execution/engine/http.js +21 -14
  186. package/lib/execution/engine/http.js.map +1 -1
  187. package/lib/execution/engine/interface.d.ts +1 -0
  188. package/lib/execution/engine/interface.d.ts.map +1 -1
  189. package/lib/execution/engine/mock.d.ts.map +1 -1
  190. package/lib/execution/engine/mock.js +6 -0
  191. package/lib/execution/engine/mock.js.map +1 -1
  192. package/lib/execution/engine/types.d.ts +20 -0
  193. package/lib/execution/engine/types.d.ts.map +1 -1
  194. package/lib/execution/engine/types.js +18 -0
  195. package/lib/execution/engine/types.js.map +1 -1
  196. package/lib/metrics/metrics/lodestar.d.ts +5 -0
  197. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  198. package/lib/metrics/metrics/lodestar.js +9 -0
  199. package/lib/metrics/metrics/lodestar.js.map +1 -1
  200. package/lib/network/gossip/interface.d.ts +7 -1
  201. package/lib/network/gossip/interface.d.ts.map +1 -1
  202. package/lib/network/gossip/interface.js +1 -0
  203. package/lib/network/gossip/interface.js.map +1 -1
  204. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  205. package/lib/network/gossip/scoringParameters.js +12 -1
  206. package/lib/network/gossip/scoringParameters.js.map +1 -1
  207. package/lib/network/gossip/topic.d.ts +13 -2
  208. package/lib/network/gossip/topic.d.ts.map +1 -1
  209. package/lib/network/gossip/topic.js +6 -0
  210. package/lib/network/gossip/topic.js.map +1 -1
  211. package/lib/network/interface.d.ts +3 -0
  212. package/lib/network/interface.d.ts.map +1 -1
  213. package/lib/network/network.d.ts +3 -0
  214. package/lib/network/network.d.ts.map +1 -1
  215. package/lib/network/network.js +14 -1
  216. package/lib/network/network.js.map +1 -1
  217. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  218. package/lib/network/processor/gossipHandlers.js +80 -23
  219. package/lib/network/processor/gossipHandlers.js.map +1 -1
  220. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  221. package/lib/network/processor/gossipQueues/index.js +5 -0
  222. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  223. package/lib/network/processor/index.d.ts.map +1 -1
  224. package/lib/network/processor/index.js +6 -5
  225. package/lib/network/processor/index.js.map +1 -1
  226. package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
  227. package/lib/network/reqresp/ReqRespBeaconNode.js +1 -1
  228. package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
  229. package/lib/network/reqresp/handlers/beaconBlocksByHead.d.ts +9 -0
  230. package/lib/network/reqresp/handlers/beaconBlocksByHead.d.ts.map +1 -0
  231. package/lib/network/reqresp/handlers/beaconBlocksByHead.js +61 -0
  232. package/lib/network/reqresp/handlers/beaconBlocksByHead.js.map +1 -0
  233. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  234. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +14 -6
  235. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  236. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
  237. package/lib/network/reqresp/handlers/blobSidecarsByRange.js +11 -5
  238. package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
  239. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  240. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +17 -5
  241. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  242. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
  243. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +7 -4
  244. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
  245. package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
  246. package/lib/network/reqresp/handlers/index.js +5 -0
  247. package/lib/network/reqresp/handlers/index.js.map +1 -1
  248. package/lib/network/reqresp/interface.d.ts +1 -1
  249. package/lib/network/reqresp/interface.js +1 -1
  250. package/lib/network/reqresp/protocols.d.ts +1 -0
  251. package/lib/network/reqresp/protocols.d.ts.map +1 -1
  252. package/lib/network/reqresp/protocols.js +5 -0
  253. package/lib/network/reqresp/protocols.js.map +1 -1
  254. package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
  255. package/lib/network/reqresp/rateLimit.js +4 -0
  256. package/lib/network/reqresp/rateLimit.js.map +1 -1
  257. package/lib/network/reqresp/score.d.ts.map +1 -1
  258. package/lib/network/reqresp/score.js +1 -0
  259. package/lib/network/reqresp/score.js.map +1 -1
  260. package/lib/network/reqresp/types.d.ts +3 -0
  261. package/lib/network/reqresp/types.d.ts.map +1 -1
  262. package/lib/network/reqresp/types.js +3 -0
  263. package/lib/network/reqresp/types.js.map +1 -1
  264. package/lib/node/nodejs.js +2 -2
  265. package/lib/node/nodejs.js.map +1 -1
  266. package/lib/sync/constants.d.ts +7 -1
  267. package/lib/sync/constants.d.ts.map +1 -1
  268. package/lib/sync/constants.js +7 -4
  269. package/lib/sync/constants.js.map +1 -1
  270. package/lib/sync/range/batch.d.ts +55 -8
  271. package/lib/sync/range/batch.d.ts.map +1 -1
  272. package/lib/sync/range/batch.js +291 -66
  273. package/lib/sync/range/batch.js.map +1 -1
  274. package/lib/sync/range/chain.d.ts +22 -4
  275. package/lib/sync/range/chain.d.ts.map +1 -1
  276. package/lib/sync/range/chain.js +103 -11
  277. package/lib/sync/range/chain.js.map +1 -1
  278. package/lib/sync/range/range.d.ts.map +1 -1
  279. package/lib/sync/range/range.js +71 -11
  280. package/lib/sync/range/range.js.map +1 -1
  281. package/lib/sync/range/utils/peerBalancer.d.ts +2 -1
  282. package/lib/sync/range/utils/peerBalancer.d.ts.map +1 -1
  283. package/lib/sync/range/utils/peerBalancer.js +8 -4
  284. package/lib/sync/range/utils/peerBalancer.js.map +1 -1
  285. package/lib/sync/sync.d.ts.map +1 -1
  286. package/lib/sync/sync.js +13 -0
  287. package/lib/sync/sync.js.map +1 -1
  288. package/lib/sync/types.d.ts +34 -0
  289. package/lib/sync/types.d.ts.map +1 -1
  290. package/lib/sync/types.js +34 -0
  291. package/lib/sync/types.js.map +1 -1
  292. package/lib/sync/unknownBlock.d.ts +29 -1
  293. package/lib/sync/unknownBlock.d.ts.map +1 -1
  294. package/lib/sync/unknownBlock.js +727 -61
  295. package/lib/sync/unknownBlock.js.map +1 -1
  296. package/lib/sync/utils/downloadByRange.d.ts +73 -10
  297. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  298. package/lib/sync/utils/downloadByRange.js +213 -26
  299. package/lib/sync/utils/downloadByRange.js.map +1 -1
  300. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  301. package/lib/sync/utils/downloadByRoot.js +16 -2
  302. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  303. package/lib/sync/utils/pendingBlocksTree.d.ts +0 -1
  304. package/lib/sync/utils/pendingBlocksTree.d.ts.map +1 -1
  305. package/lib/sync/utils/pendingBlocksTree.js +0 -9
  306. package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
  307. package/lib/sync/utils/rateLimit.d.ts +2 -0
  308. package/lib/sync/utils/rateLimit.d.ts.map +1 -0
  309. package/lib/sync/utils/rateLimit.js +15 -0
  310. package/lib/sync/utils/rateLimit.js.map +1 -0
  311. package/lib/util/dependentRoot.d.ts +6 -2
  312. package/lib/util/dependentRoot.d.ts.map +1 -1
  313. package/lib/util/dependentRoot.js +20 -16
  314. package/lib/util/dependentRoot.js.map +1 -1
  315. package/lib/util/sszBytes.d.ts.map +1 -1
  316. package/lib/util/sszBytes.js +20 -5
  317. package/lib/util/sszBytes.js.map +1 -1
  318. package/package.json +16 -16
  319. package/src/api/impl/beacon/blocks/index.ts +22 -9
  320. package/src/api/impl/beacon/pool/index.ts +136 -1
  321. package/src/api/impl/beacon/state/utils.ts +2 -2
  322. package/src/api/impl/debug/index.ts +0 -1
  323. package/src/api/impl/lodestar/index.ts +1 -1
  324. package/src/api/impl/validator/index.ts +101 -16
  325. package/src/chain/archiveStore/archiveStore.ts +5 -5
  326. package/src/chain/archiveStore/interface.ts +4 -4
  327. package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +4 -4
  328. package/src/chain/archiveStore/utils/archiveBlocks.ts +153 -94
  329. package/src/chain/blocks/blockInput/blockInput.ts +4 -1
  330. package/src/chain/blocks/importBlock.ts +16 -48
  331. package/src/chain/blocks/importExecutionPayload.ts +126 -110
  332. package/src/chain/blocks/index.ts +71 -23
  333. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +37 -3
  334. package/src/chain/blocks/payloadEnvelopeInput/types.ts +18 -0
  335. package/src/chain/blocks/payloadEnvelopeProcessor.ts +2 -2
  336. package/src/chain/blocks/types.ts +15 -25
  337. package/src/chain/blocks/utils/chainSegment.ts +117 -17
  338. package/src/chain/blocks/verifyBlock.ts +70 -9
  339. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +6 -4
  340. package/src/chain/blocks/verifyBlocksSanityChecks.ts +26 -7
  341. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +137 -0
  342. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +7 -4
  343. package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +9 -18
  344. package/src/chain/chain.ts +68 -26
  345. package/src/chain/emitter.ts +3 -14
  346. package/src/chain/errors/blockError.ts +4 -1
  347. package/src/chain/errors/executionPayloadBid.ts +28 -1
  348. package/src/chain/errors/executionPayloadEnvelope.ts +6 -0
  349. package/src/chain/errors/index.ts +1 -0
  350. package/src/chain/errors/proposerPreferences.ts +47 -0
  351. package/src/chain/forkChoice/index.ts +2 -22
  352. package/src/chain/initState.ts +9 -1
  353. package/src/chain/interface.ts +13 -3
  354. package/src/chain/lightClient/index.ts +6 -6
  355. package/src/chain/opPools/index.ts +1 -0
  356. package/src/chain/opPools/payloadAttestationPool.ts +63 -18
  357. package/src/chain/opPools/proposerPreferencesPool.ts +59 -0
  358. package/src/chain/prepareNextSlot.ts +36 -14
  359. package/src/chain/produceBlock/produceBlockBody.ts +63 -13
  360. package/src/chain/regen/interface.ts +1 -0
  361. package/src/chain/regen/queued.ts +2 -7
  362. package/src/chain/regen/regen.ts +2 -7
  363. package/src/chain/seenCache/index.ts +1 -0
  364. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +89 -21
  365. package/src/chain/seenCache/seenProposerPreferences.ts +32 -0
  366. package/src/chain/stateCache/persistentCheckpointsCache.ts +4 -1
  367. package/src/chain/validation/block.ts +1 -0
  368. package/src/chain/validation/executionPayloadBid.ts +85 -18
  369. package/src/chain/validation/executionPayloadEnvelope.ts +20 -10
  370. package/src/chain/validation/payloadAttestationMessage.ts +6 -4
  371. package/src/chain/validation/proposerPreferences.ts +110 -0
  372. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
  373. package/src/execution/engine/http.ts +21 -14
  374. package/src/execution/engine/interface.ts +1 -0
  375. package/src/execution/engine/mock.ts +8 -1
  376. package/src/execution/engine/types.ts +41 -0
  377. package/src/metrics/metrics/lodestar.ts +10 -0
  378. package/src/network/gossip/interface.ts +6 -0
  379. package/src/network/gossip/scoringParameters.ts +14 -1
  380. package/src/network/gossip/topic.ts +6 -0
  381. package/src/network/interface.ts +3 -0
  382. package/src/network/network.ts +35 -1
  383. package/src/network/processor/gossipHandlers.ts +99 -23
  384. package/src/network/processor/gossipQueues/index.ts +5 -0
  385. package/src/network/processor/index.ts +6 -5
  386. package/src/network/reqresp/ReqRespBeaconNode.ts +1 -0
  387. package/src/network/reqresp/handlers/beaconBlocksByHead.ts +91 -0
  388. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +14 -6
  389. package/src/network/reqresp/handlers/blobSidecarsByRange.ts +11 -5
  390. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -5
  391. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +7 -4
  392. package/src/network/reqresp/handlers/index.ts +5 -0
  393. package/src/network/reqresp/interface.ts +1 -1
  394. package/src/network/reqresp/protocols.ts +6 -0
  395. package/src/network/reqresp/rateLimit.ts +4 -0
  396. package/src/network/reqresp/score.ts +1 -0
  397. package/src/network/reqresp/types.ts +5 -0
  398. package/src/node/nodejs.ts +2 -2
  399. package/src/sync/constants.ts +8 -4
  400. package/src/sync/range/batch.ts +388 -75
  401. package/src/sync/range/chain.ts +131 -14
  402. package/src/sync/range/range.ts +86 -11
  403. package/src/sync/range/utils/peerBalancer.ts +9 -3
  404. package/src/sync/sync.ts +13 -1
  405. package/src/sync/types.ts +72 -0
  406. package/src/sync/unknownBlock.ts +915 -65
  407. package/src/sync/utils/downloadByRange.ts +386 -39
  408. package/src/sync/utils/downloadByRoot.ts +24 -2
  409. package/src/sync/utils/pendingBlocksTree.ts +0 -15
  410. package/src/sync/utils/rateLimit.ts +16 -0
  411. package/src/util/dependentRoot.ts +22 -18
  412. package/src/util/sszBytes.ts +25 -5
@@ -1,7 +1,7 @@
1
1
  import {Signature, aggregateSignatures} from "@chainsafe/blst";
2
2
  import {BitArray} from "@chainsafe/ssz";
3
3
  import {ChainForkConfig} from "@lodestar/config";
4
- import {MAX_COMMITTEES_PER_SLOT, PTC_SIZE} from "@lodestar/params";
4
+ import {MAX_COMMITTEES_PER_SLOT, MAX_PAYLOAD_ATTESTATIONS, PTC_SIZE} from "@lodestar/params";
5
5
  import {RootHex, Slot, gloas} from "@lodestar/types";
6
6
  import {MapDef, toRootHex} from "@lodestar/utils";
7
7
  import {Metrics} from "../../metrics/metrics.js";
@@ -57,7 +57,7 @@ export class PayloadAttestationPool {
57
57
  add(
58
58
  message: gloas.PayloadAttestationMessage,
59
59
  payloadAttDataRootHex: RootHex,
60
- validatorCommitteeIndex: number
60
+ validatorCommitteeIndices: number[]
61
61
  ): InsertOutcome {
62
62
  const slot = message.data.slot;
63
63
  const lowestPermissibleSlot = this.lowestPermissibleSlot;
@@ -85,23 +85,19 @@ export class PayloadAttestationPool {
85
85
  const aggregate = aggregateByDataRoot.get(payloadAttDataRootHex);
86
86
  if (aggregate) {
87
87
  // Aggregate msg into aggregate
88
- return aggregateMessageInto(message, validatorCommitteeIndex, aggregate);
88
+ return aggregateMessageInto(message, validatorCommitteeIndices, aggregate);
89
89
  }
90
90
  // Create a new aggregate with data
91
- aggregateByDataRoot.set(payloadAttDataRootHex, messageToAggregate(message, validatorCommitteeIndex));
91
+ aggregateByDataRoot.set(payloadAttDataRootHex, messageToAggregate(message, validatorCommitteeIndices));
92
92
 
93
93
  return InsertOutcome.NewData;
94
94
  }
95
95
 
96
96
  /**
97
97
  * Get payload attestations to be included in a block.
98
- * Pick the top `maxAttestation` number of attestations with the most votes
98
+ * Pick the top `MAX_PAYLOAD_ATTESTATIONS` aggregates with the most votes.
99
99
  */
100
- getPayloadAttestationsForBlock(
101
- beaconBlockRoot: BlockRootHex,
102
- slot: Slot,
103
- maxAttestation: number
104
- ): gloas.PayloadAttestation[] {
100
+ getPayloadAttestationsForBlock(beaconBlockRoot: BlockRootHex, slot: Slot): gloas.PayloadAttestation[] {
105
101
  const aggregateByDataRootByBlockRoot = this.aggregateByDataRootByBlockRootBySlot.get(slot);
106
102
 
107
103
  if (!aggregateByDataRootByBlockRoot) {
@@ -119,7 +115,32 @@ export class PayloadAttestationPool {
119
115
  return Array.from(aggregateByDataRoot.values())
120
116
  .slice()
121
117
  .sort((a, b) => b.aggregationBits.getTrueBitIndexes().length - a.aggregationBits.getTrueBitIndexes().length)
122
- .slice(0, maxAttestation)
118
+ .slice(0, MAX_PAYLOAD_ATTESTATIONS)
119
+ .map(fastToPayloadAttestation);
120
+ }
121
+
122
+ getAll(slot?: Slot): gloas.PayloadAttestation[] {
123
+ const aggregates: AggregateFast[] = [];
124
+
125
+ const addAggregates = (aggregateByDataRootByBlockRoot: Map<BlockRootHex, Map<DataRootHex, AggregateFast>>) => {
126
+ for (const aggregateByDataRoot of aggregateByDataRootByBlockRoot.values()) {
127
+ aggregates.push(...aggregateByDataRoot.values());
128
+ }
129
+ };
130
+
131
+ if (slot !== undefined) {
132
+ const aggregateByDataRootByBlockRoot = this.aggregateByDataRootByBlockRootBySlot.get(slot);
133
+ if (aggregateByDataRootByBlockRoot) {
134
+ addAggregates(aggregateByDataRootByBlockRoot);
135
+ }
136
+ } else {
137
+ for (const aggregateByDataRootByBlockRoot of this.aggregateByDataRootByBlockRootBySlot.values()) {
138
+ addAggregates(aggregateByDataRootByBlockRoot);
139
+ }
140
+ }
141
+
142
+ return aggregates
143
+ .sort((a, b) => b.aggregationBits.getTrueBitIndexes().length - a.aggregationBits.getTrueBitIndexes().length)
123
144
  .map(fastToPayloadAttestation);
124
145
  }
125
146
 
@@ -129,25 +150,49 @@ export class PayloadAttestationPool {
129
150
  }
130
151
  }
131
152
 
132
- function messageToAggregate(message: gloas.PayloadAttestationMessage, validatorCommitteeIndex: number): AggregateFast {
153
+ function messageToAggregate(
154
+ message: gloas.PayloadAttestationMessage,
155
+ validatorCommitteeIndices: number[]
156
+ ): AggregateFast {
157
+ const aggregationBits = BitArray.fromBitLen(PTC_SIZE);
158
+ for (const index of validatorCommitteeIndices) {
159
+ aggregationBits.set(index, true);
160
+ }
161
+ const sig = signatureFromBytesNoCheck(message.signature);
162
+ // The validator signed once but occupies `validatorCommitteeIndices.length` PTC positions.
163
+ // Verification aggregates the pubkey once per set bit, so the signature must be aggregated
164
+ // the same number of times for the BLS check to balance — same pattern as sync committee.
165
+ const signature =
166
+ validatorCommitteeIndices.length === 1
167
+ ? sig
168
+ : aggregateSignatures(new Array(validatorCommitteeIndices.length).fill(sig));
133
169
  return {
134
- aggregationBits: BitArray.fromSingleBit(PTC_SIZE, validatorCommitteeIndex),
170
+ aggregationBits,
135
171
  data: message.data,
136
- signature: signatureFromBytesNoCheck(message.signature),
172
+ signature,
137
173
  };
138
174
  }
139
175
 
140
176
  function aggregateMessageInto(
141
177
  message: gloas.PayloadAttestationMessage,
142
- validatorCommitteeIndex: number,
178
+ validatorCommitteeIndices: number[],
143
179
  aggregate: AggregateFast
144
180
  ): InsertOutcome {
145
- if (aggregate.aggregationBits.get(validatorCommitteeIndex) === true) {
181
+ // Gossip dedup via `seenPayloadAttesters` is keyed by (epoch, validatorIndex), so the same
182
+ // validator's message is never processed twice — all of its bits are set together or none.
183
+ // Checking the first index is sufficient.
184
+ if (aggregate.aggregationBits.get(validatorCommitteeIndices[0]) === true) {
146
185
  return InsertOutcome.AlreadyKnown;
147
186
  }
148
187
 
149
- aggregate.aggregationBits.set(validatorCommitteeIndex, true);
150
- aggregate.signature = aggregateSignatures([aggregate.signature, signatureFromBytesNoCheck(message.signature)]);
188
+ for (const index of validatorCommitteeIndices) {
189
+ aggregate.aggregationBits.set(index, true);
190
+ }
191
+ const sig = signatureFromBytesNoCheck(message.signature);
192
+ aggregate.signature = aggregateSignatures([
193
+ aggregate.signature,
194
+ ...new Array(validatorCommitteeIndices.length).fill(sig),
195
+ ]);
151
196
 
152
197
  return InsertOutcome.Aggregated;
153
198
  }
@@ -0,0 +1,59 @@
1
+ import {RootHex, Slot, gloas} from "@lodestar/types";
2
+ import {toRootHex} from "@lodestar/utils";
3
+
4
+ /**
5
+ * Pool of validated `SignedProposerPreferences` indexed by `(slot, dependent_root)`.
6
+ *
7
+ * The primary consumer is `validateExecutionPayloadBid`, which looks up the matching
8
+ * preferences via `get(bid.slot, dependent_root)` to enforce the IGNORE-existence and
9
+ * REJECT-equality rules from the gloas spec. The beacon API `/pool/proposer_preferences`
10
+ * GET endpoint reads from the same pool via `getAll`.
11
+ *
12
+ * `validator_index` is intentionally not part of the key: gossip validation enforces
13
+ * `proposers[proposalSlot % SLOTS_PER_EPOCH] === validatorIndex` against the shuffling
14
+ * implied by `dependent_root`, so once a preference has been validated `(slot, dependent_root)`
15
+ * already pins down the validator.
16
+ */
17
+ export class ProposerPreferencesPool {
18
+ private readonly bySlot = new Map<Slot, Map<RootHex, gloas.SignedProposerPreferences>>();
19
+
20
+ /** Lookup for bid validation: matches `(bid.slot, get_proposer_dependent_root(parent_state, ...))`. */
21
+ get(slot: Slot, dependentRootHex: RootHex): gloas.SignedProposerPreferences | null {
22
+ return this.bySlot.get(slot)?.get(dependentRootHex) ?? null;
23
+ }
24
+
25
+ add(signed: gloas.SignedProposerPreferences): void {
26
+ const {proposalSlot, dependentRoot} = signed.message;
27
+ const rootHex = toRootHex(dependentRoot);
28
+ let byRoot = this.bySlot.get(proposalSlot);
29
+ if (!byRoot) {
30
+ byRoot = new Map();
31
+ this.bySlot.set(proposalSlot, byRoot);
32
+ }
33
+ byRoot.set(rootHex, signed);
34
+ }
35
+
36
+ /** API read-out: flatten across branches, optionally filtered by slot. */
37
+ getAll(slot?: Slot): gloas.SignedProposerPreferences[] {
38
+ if (slot !== undefined) {
39
+ const byRoot = this.bySlot.get(slot);
40
+ return byRoot ? Array.from(byRoot.values()) : [];
41
+ }
42
+ const out: gloas.SignedProposerPreferences[] = [];
43
+ for (const byRoot of this.bySlot.values()) {
44
+ for (const v of byRoot.values()) out.push(v);
45
+ }
46
+ return out;
47
+ }
48
+
49
+ /**
50
+ * Entries are only load-bearing while `proposal_slot >= current_slot`. Once the slot has
51
+ * passed the `[IGNORE] proposal_slot > current_slot` gossip rule takes over, so drop them
52
+ * on each slot tick.
53
+ */
54
+ prune(currentSlot: Slot): void {
55
+ for (const slot of this.bySlot.keys()) {
56
+ if (slot < currentSlot) this.bySlot.delete(slot);
57
+ }
58
+ }
59
+ }
@@ -4,6 +4,7 @@ import {getSafeExecutionBlockHash} from "@lodestar/fork-choice";
4
4
  import {ForkPostBellatrix, ForkSeq, SLOTS_PER_EPOCH, isForkPostBellatrix} from "@lodestar/params";
5
5
  import {
6
6
  IBeaconStateView,
7
+ IBeaconStateViewBellatrix,
7
8
  StateHashTreeRootSource,
8
9
  computeEpochAtSlot,
9
10
  computeTimeAtSlot,
@@ -83,7 +84,7 @@ export class PrepareNextSlotScheduler {
83
84
  const headBlock = this.chain.recomputeForkChoiceHead(ForkchoiceCaller.prepareNextSlot);
84
85
  const {slot: headSlot, blockRoot: headRoot} = headBlock;
85
86
  // may be updated below if we predict a proposer-boost-reorg
86
- let updatedHeadRoot = headRoot;
87
+ let updatedHead = headBlock;
87
88
 
88
89
  // PS: previously this was comparing slots, but that gave no leway on the skipped
89
90
  // slots on epoch bounday. Making it more fluid.
@@ -148,7 +149,7 @@ export class PrepareNextSlotScheduler {
148
149
  {dontTransferCache: !isEpochTransition},
149
150
  RegenCaller.predictProposerHead
150
151
  );
151
- updatedHeadRoot = proposerHeadRoot;
152
+ updatedHead = proposerHead;
152
153
  }
153
154
 
154
155
  // Update the builder status, if enabled shoot an api call to check status
@@ -165,10 +166,22 @@ export class PrepareNextSlotScheduler {
165
166
  }
166
167
 
167
168
  let parentBlockHash: Bytes32;
169
+ // Apply parent payload once here as it's reused by EL prep and SSE emit below
170
+ let stateAfterParentPayload: IBeaconStateViewBellatrix = updatedPrepareState;
168
171
  if (isStatePostGloas(updatedPrepareState)) {
169
- parentBlockHash = this.chain.forkChoice.shouldExtendPayload(updatedHeadRoot)
170
- ? updatedPrepareState.latestExecutionPayloadBid.blockHash
171
- : updatedPrepareState.latestExecutionPayloadBid.parentBlockHash;
172
+ if (this.chain.forkChoice.shouldExtendPayload(updatedHead.blockRoot)) {
173
+ parentBlockHash = updatedPrepareState.latestExecutionPayloadBid.blockHash;
174
+ // Skip applying parent payload unless we're proposing the next slot or have to emit payload_attributes events
175
+ if (feeRecipient !== undefined || this.chain.opts.emitPayloadAttributes === true) {
176
+ const parentExecutionRequests = await this.chain.getParentExecutionRequests(
177
+ updatedHead.slot,
178
+ updatedHead.blockRoot
179
+ );
180
+ stateAfterParentPayload = updatedPrepareState.withParentPayloadApplied(parentExecutionRequests);
181
+ }
182
+ } else {
183
+ parentBlockHash = updatedPrepareState.latestExecutionPayloadBid.parentBlockHash;
184
+ }
172
185
  } else {
173
186
  parentBlockHash = updatedPrepareState.latestExecutionPayloadHeader.blockHash;
174
187
  }
@@ -189,11 +202,11 @@ export class PrepareNextSlotScheduler {
189
202
  this.chain,
190
203
  this.logger,
191
204
  fork as ForkPostBellatrix, // State is of execution type
192
- fromHex(updatedHeadRoot),
205
+ fromHex(updatedHead.blockRoot),
193
206
  parentBlockHash,
194
207
  safeBlockHash,
195
208
  finalizedBlockHash,
196
- updatedPrepareState,
209
+ stateAfterParentPayload,
197
210
  feeRecipient
198
211
  );
199
212
  this.logger.verbose("PrepareNextSlotScheduler prepared new payload", {
@@ -203,21 +216,30 @@ export class PrepareNextSlotScheduler {
203
216
  });
204
217
  }
205
218
 
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.pruneBelowParent(updatedHeadParent);
226
+ }
227
+ }
228
+
206
229
  this.computeStateHashTreeRoot(updatedPrepareState, isEpochTransition);
207
230
 
208
- // 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.
209
233
  if (
210
- this.chain.opts.emitPayloadAttributes === true &&
234
+ (feeRecipient || this.chain.opts.emitPayloadAttributes === true) &&
211
235
  this.chain.emitter.listenerCount(routes.events.EventType.payloadAttributes)
212
236
  ) {
213
237
  const data = getPayloadAttributesForSSE(fork as ForkPostBellatrix, this.chain, {
214
- prepareState: updatedPrepareState,
238
+ prepareState: stateAfterParentPayload,
215
239
  prepareSlot,
216
- parentBlockRoot: fromHex(headRoot),
240
+ parentBlockRoot: fromHex(updatedHead.blockRoot),
217
241
  parentBlockHash,
218
- // The likely consumers of this API are builders and will anyway ignore the
219
- // feeRecipient, so just pass zero hash for now till a real use case arises
220
- feeRecipient: "0x0000000000000000000000000000000000000000000000000000000000000000",
242
+ feeRecipient: feeRecipient ?? "0x0000000000000000000000000000000000000000",
221
243
  });
222
244
  this.chain.emitter.emit(routes.events.EventType.payloadAttributes, {data, version: fork});
223
245
  }
@@ -46,6 +46,7 @@ import {
46
46
  electra,
47
47
  fulu,
48
48
  gloas,
49
+ ssz,
49
50
  } from "@lodestar/types";
50
51
  import {Logger, byteArrayEquals, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
51
52
  import {ZERO_HASH_HEX} from "../../constants/index.js";
@@ -110,6 +111,7 @@ export type ProduceFullGloas = {
110
111
  executionRequests: electra.ExecutionRequests;
111
112
  blobsBundle: BlobsBundle<ForkPostGloas>;
112
113
  cells: fulu.Cell[][];
114
+ parentBlockRoot: Root;
113
115
  };
114
116
  export type ProduceFullFulu = {
115
117
  type: BlockType.Full;
@@ -213,9 +215,19 @@ export async function produceBlockBody<T extends BlockType>(
213
215
  });
214
216
 
215
217
  // Get execution payload from EL
216
- const parentBlockHash = this.forkChoice.shouldExtendPayload(toRootHex(parentBlockRoot))
217
- ? currentState.latestExecutionPayloadBid.blockHash
218
- : currentState.latestExecutionPayloadBid.parentBlockHash;
218
+ let parentBlockHash: Bytes32;
219
+ let parentExecutionRequests: electra.ExecutionRequests;
220
+ // Apply parent payload once here as it's reused by EL prep and voluntary exit filtering below
221
+ let stateAfterParentPayload: IBeaconStateViewBellatrix = currentState;
222
+ const isExtendingPayload = this.forkChoice.shouldExtendPayload(toRootHex(parentBlockRoot));
223
+ if (isExtendingPayload) {
224
+ parentBlockHash = currentState.latestExecutionPayloadBid.blockHash;
225
+ parentExecutionRequests = await this.getParentExecutionRequests(parentBlock.slot, parentBlock.blockRoot);
226
+ stateAfterParentPayload = currentState.withParentPayloadApplied(parentExecutionRequests);
227
+ } else {
228
+ parentBlockHash = currentState.latestExecutionPayloadBid.parentBlockHash;
229
+ parentExecutionRequests = ssz.electra.ExecutionRequests.defaultValue();
230
+ }
219
231
  const prepareRes = await prepareExecutionPayload(
220
232
  this,
221
233
  this.logger,
@@ -224,7 +236,7 @@ export async function produceBlockBody<T extends BlockType>(
224
236
  parentBlockHash,
225
237
  safeBlockHash,
226
238
  finalizedBlockHash ?? ZERO_HASH_HEX,
227
- currentState,
239
+ stateAfterParentPayload,
228
240
  feeRecipient
229
241
  );
230
242
 
@@ -269,6 +281,7 @@ export async function produceBlockBody<T extends BlockType>(
269
281
  value: 0,
270
282
  executionPayment: 0,
271
283
  blobKzgCommitments: blobsBundle.commitments,
284
+ executionRequestsRoot: ssz.electra.ExecutionRequests.hashTreeRoot(executionRequests),
272
285
  };
273
286
  const signedBid: gloas.SignedExecutionPayloadBid = {
274
287
  message: bid,
@@ -278,8 +291,19 @@ export async function produceBlockBody<T extends BlockType>(
278
291
  const commonBlockBody = await commonBlockBodyPromise;
279
292
  const gloasBody = Object.assign({}, commonBlockBody) as gloas.BeaconBlockBody;
280
293
  gloasBody.signedExecutionPayloadBid = signedBid;
281
- // TODO GLOAS: Get payload attestations from pool for previous slot
282
- gloasBody.payloadAttestations = [];
294
+ gloasBody.payloadAttestations = this.payloadAttestationPool.getPayloadAttestationsForBlock(
295
+ parentBlock.blockRoot,
296
+ blockSlot - 1
297
+ );
298
+ gloasBody.parentExecutionRequests = parentExecutionRequests;
299
+ // Drop voluntary exits that parent_execution_requests have invalidated (e.g. a withdrawal
300
+ // request initiating an exit on the same validator). Op pool selected against the unapplied
301
+ // state, so re-validate against the post-apply state to avoid producing an invalid block.
302
+ if (isExtendingPayload && commonBlockBody.voluntaryExits.length > 0) {
303
+ gloasBody.voluntaryExits = commonBlockBody.voluntaryExits.filter((signedVoluntaryExit) =>
304
+ stateAfterParentPayload.isValidVoluntaryExit(signedVoluntaryExit, false)
305
+ );
306
+ }
283
307
  blockBody = gloasBody as AssembledBodyType<T>;
284
308
 
285
309
  // Store execution payload data required to construct execution payload envelope later
@@ -288,6 +312,7 @@ export async function produceBlockBody<T extends BlockType>(
288
312
  gloasResult.executionRequests = executionRequests;
289
313
  gloasResult.blobsBundle = blobsBundle;
290
314
  gloasResult.cells = cells;
315
+ gloasResult.parentBlockRoot = fromHex(parentBlock.blockRoot);
291
316
 
292
317
  const fetchedTime = Date.now() / 1000 - computeTimeAtSlot(this.config, blockSlot, this.genesisTime);
293
318
  this.metrics?.blockPayload.payloadFetchedTime.observe({prepType}, fetchedTime);
@@ -615,6 +640,10 @@ export async function prepareExecutionPayload(
615
640
  parentBlockHash: Bytes32,
616
641
  safeBlockHash: RootHex,
617
642
  finalizedBlockHash: RootHex,
643
+ /**
644
+ * Post-gloas, when extending a full parent, callers must apply
645
+ * parent execution payload first (see `withParentPayloadApplied`).
646
+ */
618
647
  state: IBeaconStateViewBellatrix,
619
648
  suggestedFeeRecipient: string
620
649
  ): Promise<{prepType: PayloadPreparationType; payloadId: PayloadId}> {
@@ -712,6 +741,10 @@ export function getPayloadAttributesForSSE(
712
741
  parentBlockHash,
713
742
  feeRecipient,
714
743
  }: {
744
+ /**
745
+ * Post-gloas, when extending a full parent, callers must apply
746
+ * parent execution payload first (see `withParentPayloadApplied`).
747
+ */
715
748
  prepareState: IBeaconStateViewBellatrix;
716
749
  prepareSlot: Slot;
717
750
  parentBlockRoot: Root;
@@ -764,6 +797,10 @@ function preparePayloadAttributes(
764
797
  parentBlockHash,
765
798
  feeRecipient,
766
799
  }: {
800
+ /**
801
+ * Post-gloas, when extending a full parent, callers must apply
802
+ * parent execution payload first (see `withParentPayloadApplied`).
803
+ */
767
804
  prepareState: IBeaconStateViewBellatrix;
768
805
  prepareSlot: Slot;
769
806
  parentBlockRoot: Root;
@@ -786,13 +823,22 @@ function preparePayloadAttributes(
786
823
 
787
824
  if (isStatePostGloas(prepareState)) {
788
825
  const isExtendingPayload = byteArrayEquals(parentBlockHash, prepareState.latestExecutionPayloadBid.blockHash);
789
- // When the parent block is empty, state.payloadExpectedWithdrawals holds a batch
790
- // already deducted from CL balances but never credited on the EL (the envelope
791
- // was not delivered). The next payload must carry those same withdrawals to
792
- // restore CL/EL consistency, otherwise validators permanently lose that balance.
793
- (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals = isExtendingPayload
794
- ? prepareState.getExpectedWithdrawals().expectedWithdrawals
795
- : prepareState.payloadExpectedWithdrawals;
826
+ if (isExtendingPayload) {
827
+ // applyParentExecutionPayload sets latestBlockHash = parentBid.blockHash, so a mismatch
828
+ // here means the caller did not apply parent payload to prepareState
829
+ if (!byteArrayEquals(prepareState.latestBlockHash, prepareState.latestExecutionPayloadBid.blockHash)) {
830
+ throw new Error("Expected state with parent execution payload applied for withdrawals");
831
+ }
832
+ (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
833
+ prepareState.getExpectedWithdrawals().expectedWithdrawals;
834
+ } else {
835
+ // When the parent block is empty, state.payloadExpectedWithdrawals holds a batch
836
+ // already deducted from CL balances but never credited on the EL (the envelope
837
+ // was not delivered). The next payload must carry those same withdrawals to
838
+ // restore CL/EL consistency, otherwise validators permanently lose that balance.
839
+ (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
840
+ prepareState.payloadExpectedWithdrawals;
841
+ }
796
842
  } else {
797
843
  // withdrawals logic is now fork aware as it changes on electra fork post capella
798
844
  (payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
@@ -804,6 +850,10 @@ function preparePayloadAttributes(
804
850
  (payloadAttributes as deneb.SSEPayloadAttributes["payloadAttributes"]).parentBeaconBlockRoot = parentBlockRoot;
805
851
  }
806
852
 
853
+ if (ForkSeq[fork] >= ForkSeq.gloas) {
854
+ (payloadAttributes as gloas.SSEPayloadAttributes["payloadAttributes"]).slotNumber = prepareSlot;
855
+ }
856
+
807
857
  return payloadAttributes;
808
858
  }
809
859
 
@@ -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
  }
@@ -1,7 +1,7 @@
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";
@@ -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,
@@ -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,
@@ -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";