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

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 (383) 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 +68 -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/blockInput/blockInput.d.ts +3 -0
  35. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  36. package/lib/chain/blocks/blockInput/blockInput.js +4 -1
  37. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  38. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  39. package/lib/chain/blocks/importBlock.js +34 -54
  40. package/lib/chain/blocks/importBlock.js.map +1 -1
  41. package/lib/chain/blocks/importExecutionPayload.d.ts +28 -14
  42. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  43. package/lib/chain/blocks/importExecutionPayload.js +89 -89
  44. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  45. package/lib/chain/blocks/index.d.ts +5 -3
  46. package/lib/chain/blocks/index.d.ts.map +1 -1
  47. package/lib/chain/blocks/index.js +59 -26
  48. package/lib/chain/blocks/index.js.map +1 -1
  49. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +7 -0
  50. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  51. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +29 -2
  52. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  53. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +1 -0
  54. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  55. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +5 -0
  56. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -1
  57. package/lib/chain/blocks/payloadEnvelopeProcessor.js +7 -5
  58. package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
  59. package/lib/chain/blocks/types.d.ts +16 -21
  60. package/lib/chain/blocks/types.d.ts.map +1 -1
  61. package/lib/chain/blocks/utils/chainSegment.d.ts +23 -2
  62. package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
  63. package/lib/chain/blocks/utils/chainSegment.js +89 -12
  64. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  65. package/lib/chain/blocks/verifyBlock.d.ts +5 -3
  66. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  67. package/lib/chain/blocks/verifyBlock.js +50 -7
  68. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  69. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +0 -4
  70. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  71. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -2
  72. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  73. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts +2 -1
  74. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
  75. package/lib/chain/blocks/verifyBlocksSanityChecks.js +25 -5
  76. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  77. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +24 -0
  78. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -0
  79. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +79 -0
  80. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -0
  81. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts +14 -0
  82. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -0
  83. package/lib/chain/blocks/verifyPayloadsDataAvailability.js +30 -0
  84. package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -0
  85. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +1 -1
  86. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -1
  87. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +2 -11
  88. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -1
  89. package/lib/chain/chain.d.ts +8 -6
  90. package/lib/chain/chain.d.ts.map +1 -1
  91. package/lib/chain/chain.js +43 -43
  92. package/lib/chain/chain.js.map +1 -1
  93. package/lib/chain/emitter.d.ts +16 -15
  94. package/lib/chain/emitter.d.ts.map +1 -1
  95. package/lib/chain/emitter.js +5 -4
  96. package/lib/chain/emitter.js.map +1 -1
  97. package/lib/chain/errors/attestationError.d.ts +8 -1
  98. package/lib/chain/errors/attestationError.d.ts.map +1 -1
  99. package/lib/chain/errors/attestationError.js +4 -0
  100. package/lib/chain/errors/attestationError.js.map +1 -1
  101. package/lib/chain/errors/blockError.d.ts +8 -1
  102. package/lib/chain/errors/blockError.d.ts.map +1 -1
  103. package/lib/chain/errors/blockError.js +2 -0
  104. package/lib/chain/errors/blockError.js.map +1 -1
  105. package/lib/chain/errors/executionPayloadBid.d.ts +5 -0
  106. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  107. package/lib/chain/errors/executionPayloadBid.js +1 -0
  108. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  109. package/lib/chain/errors/executionPayloadEnvelope.d.ts +5 -0
  110. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  111. package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
  112. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  113. package/lib/chain/errors/index.d.ts +1 -0
  114. package/lib/chain/errors/index.d.ts.map +1 -1
  115. package/lib/chain/errors/index.js +1 -0
  116. package/lib/chain/errors/index.js.map +1 -1
  117. package/lib/chain/errors/proposerPreferences.d.ts +40 -0
  118. package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
  119. package/lib/chain/errors/proposerPreferences.js +14 -0
  120. package/lib/chain/errors/proposerPreferences.js.map +1 -0
  121. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  122. package/lib/chain/forkChoice/index.js +11 -15
  123. package/lib/chain/forkChoice/index.js.map +1 -1
  124. package/lib/chain/initState.d.ts.map +1 -1
  125. package/lib/chain/initState.js +6 -1
  126. package/lib/chain/initState.js.map +1 -1
  127. package/lib/chain/interface.d.ts +7 -5
  128. package/lib/chain/interface.d.ts.map +1 -1
  129. package/lib/chain/interface.js.map +1 -1
  130. package/lib/chain/opPools/payloadAttestationPool.d.ts +3 -2
  131. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
  132. package/lib/chain/opPools/payloadAttestationPool.js +26 -4
  133. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
  134. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  135. package/lib/chain/prepareNextSlot.js +47 -23
  136. package/lib/chain/prepareNextSlot.js.map +1 -1
  137. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +3 -9
  138. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  139. package/lib/chain/produceBlock/computeNewStateRoot.js +5 -32
  140. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  141. package/lib/chain/produceBlock/produceBlockBody.d.ts +13 -8
  142. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  143. package/lib/chain/produceBlock/produceBlockBody.js +68 -25
  144. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  145. package/lib/chain/regen/errors.d.ts +1 -11
  146. package/lib/chain/regen/errors.d.ts.map +1 -1
  147. package/lib/chain/regen/errors.js +0 -2
  148. package/lib/chain/regen/errors.js.map +1 -1
  149. package/lib/chain/regen/interface.d.ts +7 -11
  150. package/lib/chain/regen/interface.d.ts.map +1 -1
  151. package/lib/chain/regen/interface.js +1 -0
  152. package/lib/chain/regen/interface.js.map +1 -1
  153. package/lib/chain/regen/queued.d.ts +6 -10
  154. package/lib/chain/regen/queued.d.ts.map +1 -1
  155. package/lib/chain/regen/queued.js +4 -14
  156. package/lib/chain/regen/queued.js.map +1 -1
  157. package/lib/chain/regen/regen.d.ts +0 -5
  158. package/lib/chain/regen/regen.d.ts.map +1 -1
  159. package/lib/chain/regen/regen.js +1 -12
  160. package/lib/chain/regen/regen.js.map +1 -1
  161. package/lib/chain/seenCache/index.d.ts +1 -0
  162. package/lib/chain/seenCache/index.d.ts.map +1 -1
  163. package/lib/chain/seenCache/index.js +1 -0
  164. package/lib/chain/seenCache/index.js.map +1 -1
  165. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +22 -6
  166. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  167. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +53 -17
  168. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  169. package/lib/chain/seenCache/seenProposerPreferences.d.ts +16 -0
  170. package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
  171. package/lib/chain/seenCache/seenProposerPreferences.js +26 -0
  172. package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
  173. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -7
  174. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  175. package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -9
  176. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  177. package/lib/chain/stateCache/types.d.ts +0 -6
  178. package/lib/chain/stateCache/types.d.ts.map +1 -1
  179. package/lib/chain/stateCache/types.js.map +1 -1
  180. package/lib/chain/validation/aggregateAndProof.js +12 -0
  181. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  182. package/lib/chain/validation/attestation.d.ts.map +1 -1
  183. package/lib/chain/validation/attestation.js +12 -0
  184. package/lib/chain/validation/attestation.js.map +1 -1
  185. package/lib/chain/validation/block.d.ts.map +1 -1
  186. package/lib/chain/validation/block.js +1 -0
  187. package/lib/chain/validation/block.js.map +1 -1
  188. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  189. package/lib/chain/validation/executionPayloadBid.js +24 -9
  190. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  191. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  192. package/lib/chain/validation/executionPayloadEnvelope.js +21 -11
  193. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  194. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  195. package/lib/chain/validation/payloadAttestationMessage.js +4 -3
  196. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  197. package/lib/chain/validation/proposerPreferences.d.ts +8 -0
  198. package/lib/chain/validation/proposerPreferences.d.ts.map +1 -0
  199. package/lib/chain/validation/proposerPreferences.js +91 -0
  200. package/lib/chain/validation/proposerPreferences.js.map +1 -0
  201. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
  202. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
  203. package/lib/execution/engine/http.d.ts.map +1 -1
  204. package/lib/execution/engine/http.js +21 -14
  205. package/lib/execution/engine/http.js.map +1 -1
  206. package/lib/execution/engine/interface.d.ts +1 -0
  207. package/lib/execution/engine/interface.d.ts.map +1 -1
  208. package/lib/execution/engine/mock.d.ts.map +1 -1
  209. package/lib/execution/engine/mock.js +6 -0
  210. package/lib/execution/engine/mock.js.map +1 -1
  211. package/lib/execution/engine/types.d.ts +20 -0
  212. package/lib/execution/engine/types.d.ts.map +1 -1
  213. package/lib/execution/engine/types.js +18 -0
  214. package/lib/execution/engine/types.js.map +1 -1
  215. package/lib/metrics/metrics/lodestar.d.ts +1 -0
  216. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  217. package/lib/metrics/metrics/lodestar.js +4 -0
  218. package/lib/metrics/metrics/lodestar.js.map +1 -1
  219. package/lib/network/gossip/interface.d.ts +7 -1
  220. package/lib/network/gossip/interface.d.ts.map +1 -1
  221. package/lib/network/gossip/interface.js +1 -0
  222. package/lib/network/gossip/interface.js.map +1 -1
  223. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  224. package/lib/network/gossip/scoringParameters.js +12 -1
  225. package/lib/network/gossip/scoringParameters.js.map +1 -1
  226. package/lib/network/gossip/topic.d.ts +13 -2
  227. package/lib/network/gossip/topic.d.ts.map +1 -1
  228. package/lib/network/gossip/topic.js +6 -0
  229. package/lib/network/gossip/topic.js.map +1 -1
  230. package/lib/network/interface.d.ts +1 -0
  231. package/lib/network/interface.d.ts.map +1 -1
  232. package/lib/network/network.d.ts +1 -0
  233. package/lib/network/network.d.ts.map +1 -1
  234. package/lib/network/network.js +6 -1
  235. package/lib/network/network.js.map +1 -1
  236. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  237. package/lib/network/processor/gossipHandlers.js +60 -22
  238. package/lib/network/processor/gossipHandlers.js.map +1 -1
  239. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  240. package/lib/network/processor/gossipQueues/index.js +5 -0
  241. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  242. package/lib/network/processor/index.d.ts.map +1 -1
  243. package/lib/network/processor/index.js +6 -5
  244. package/lib/network/processor/index.js.map +1 -1
  245. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  246. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +14 -6
  247. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  248. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
  249. package/lib/network/reqresp/handlers/blobSidecarsByRange.js +11 -5
  250. package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
  251. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  252. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +17 -5
  253. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  254. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
  255. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +7 -4
  256. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
  257. package/lib/node/nodejs.d.ts.map +1 -1
  258. package/lib/node/nodejs.js +6 -4
  259. package/lib/node/nodejs.js.map +1 -1
  260. package/lib/sync/constants.d.ts +3 -1
  261. package/lib/sync/constants.d.ts.map +1 -1
  262. package/lib/sync/constants.js +3 -4
  263. package/lib/sync/constants.js.map +1 -1
  264. package/lib/sync/range/batch.d.ts +28 -2
  265. package/lib/sync/range/batch.d.ts.map +1 -1
  266. package/lib/sync/range/batch.js +146 -44
  267. package/lib/sync/range/batch.js.map +1 -1
  268. package/lib/sync/range/chain.d.ts +12 -2
  269. package/lib/sync/range/chain.d.ts.map +1 -1
  270. package/lib/sync/range/chain.js +53 -9
  271. package/lib/sync/range/chain.js.map +1 -1
  272. package/lib/sync/range/range.d.ts.map +1 -1
  273. package/lib/sync/range/range.js +17 -6
  274. package/lib/sync/range/range.js.map +1 -1
  275. package/lib/sync/types.d.ts +34 -0
  276. package/lib/sync/types.d.ts.map +1 -1
  277. package/lib/sync/types.js +34 -0
  278. package/lib/sync/types.js.map +1 -1
  279. package/lib/sync/unknownBlock.d.ts +22 -1
  280. package/lib/sync/unknownBlock.d.ts.map +1 -1
  281. package/lib/sync/unknownBlock.js +604 -53
  282. package/lib/sync/unknownBlock.js.map +1 -1
  283. package/lib/sync/utils/downloadByRange.d.ts +46 -10
  284. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  285. package/lib/sync/utils/downloadByRange.js +162 -24
  286. package/lib/sync/utils/downloadByRange.js.map +1 -1
  287. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  288. package/lib/sync/utils/downloadByRoot.js +16 -2
  289. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  290. package/lib/sync/utils/pendingBlocksTree.d.ts +0 -1
  291. package/lib/sync/utils/pendingBlocksTree.d.ts.map +1 -1
  292. package/lib/sync/utils/pendingBlocksTree.js +0 -9
  293. package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
  294. package/lib/util/sszBytes.d.ts.map +1 -1
  295. package/lib/util/sszBytes.js +20 -5
  296. package/lib/util/sszBytes.js.map +1 -1
  297. package/package.json +17 -16
  298. package/src/api/impl/beacon/blocks/index.ts +22 -9
  299. package/src/api/impl/beacon/pool/index.ts +83 -1
  300. package/src/api/impl/beacon/state/utils.ts +2 -2
  301. package/src/api/impl/debug/index.ts +0 -1
  302. package/src/api/impl/lodestar/index.ts +1 -1
  303. package/src/api/impl/validator/index.ts +84 -6
  304. package/src/chain/GetBlobsTracker.ts +1 -2
  305. package/src/chain/archiveStore/archiveStore.ts +5 -5
  306. package/src/chain/archiveStore/interface.ts +4 -4
  307. package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +6 -8
  308. package/src/chain/archiveStore/utils/archiveBlocks.ts +153 -94
  309. package/src/chain/blocks/blockInput/blockInput.ts +4 -1
  310. package/src/chain/blocks/importBlock.ts +34 -79
  311. package/src/chain/blocks/importExecutionPayload.ts +110 -102
  312. package/src/chain/blocks/index.ts +74 -24
  313. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +37 -2
  314. package/src/chain/blocks/payloadEnvelopeInput/types.ts +1 -0
  315. package/src/chain/blocks/payloadEnvelopeProcessor.ts +7 -6
  316. package/src/chain/blocks/types.ts +16 -26
  317. package/src/chain/blocks/utils/chainSegment.ts +114 -17
  318. package/src/chain/blocks/verifyBlock.ts +70 -9
  319. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +6 -4
  320. package/src/chain/blocks/verifyBlocksSanityChecks.ts +26 -7
  321. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +134 -0
  322. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +41 -0
  323. package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +9 -18
  324. package/src/chain/chain.ts +61 -58
  325. package/src/chain/emitter.ts +15 -14
  326. package/src/chain/errors/attestationError.ts +6 -1
  327. package/src/chain/errors/blockError.ts +4 -1
  328. package/src/chain/errors/executionPayloadBid.ts +6 -0
  329. package/src/chain/errors/executionPayloadEnvelope.ts +6 -0
  330. package/src/chain/errors/index.ts +1 -0
  331. package/src/chain/errors/proposerPreferences.ts +47 -0
  332. package/src/chain/forkChoice/index.ts +8 -20
  333. package/src/chain/initState.ts +9 -1
  334. package/src/chain/interface.ts +11 -3
  335. package/src/chain/opPools/payloadAttestationPool.ts +29 -8
  336. package/src/chain/prepareNextSlot.ts +55 -24
  337. package/src/chain/produceBlock/computeNewStateRoot.ts +6 -43
  338. package/src/chain/produceBlock/produceBlockBody.ts +91 -27
  339. package/src/chain/regen/errors.ts +1 -6
  340. package/src/chain/regen/interface.ts +7 -11
  341. package/src/chain/regen/queued.ts +8 -21
  342. package/src/chain/regen/regen.ts +2 -15
  343. package/src/chain/seenCache/index.ts +1 -0
  344. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +71 -20
  345. package/src/chain/seenCache/seenProposerPreferences.ts +32 -0
  346. package/src/chain/stateCache/persistentCheckpointsCache.ts +5 -15
  347. package/src/chain/stateCache/types.ts +0 -3
  348. package/src/chain/validation/aggregateAndProof.ts +13 -0
  349. package/src/chain/validation/attestation.ts +13 -0
  350. package/src/chain/validation/block.ts +1 -0
  351. package/src/chain/validation/executionPayloadBid.ts +25 -8
  352. package/src/chain/validation/executionPayloadEnvelope.ts +22 -12
  353. package/src/chain/validation/payloadAttestationMessage.ts +5 -3
  354. package/src/chain/validation/proposerPreferences.ts +110 -0
  355. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
  356. package/src/execution/engine/http.ts +21 -14
  357. package/src/execution/engine/interface.ts +1 -0
  358. package/src/execution/engine/mock.ts +8 -1
  359. package/src/execution/engine/types.ts +41 -0
  360. package/src/metrics/metrics/lodestar.ts +4 -0
  361. package/src/network/gossip/interface.ts +6 -0
  362. package/src/network/gossip/scoringParameters.ts +14 -1
  363. package/src/network/gossip/topic.ts +6 -0
  364. package/src/network/interface.ts +1 -0
  365. package/src/network/network.ts +12 -1
  366. package/src/network/processor/gossipHandlers.ts +79 -27
  367. package/src/network/processor/gossipQueues/index.ts +5 -0
  368. package/src/network/processor/index.ts +6 -5
  369. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +14 -6
  370. package/src/network/reqresp/handlers/blobSidecarsByRange.ts +11 -5
  371. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -5
  372. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +7 -4
  373. package/src/node/nodejs.ts +6 -4
  374. package/src/sync/constants.ts +4 -4
  375. package/src/sync/range/batch.ts +204 -49
  376. package/src/sync/range/chain.ts +69 -11
  377. package/src/sync/range/range.ts +18 -6
  378. package/src/sync/types.ts +72 -0
  379. package/src/sync/unknownBlock.ts +762 -57
  380. package/src/sync/utils/downloadByRange.ts +272 -39
  381. package/src/sync/utils/downloadByRoot.ts +24 -2
  382. package/src/sync/utils/pendingBlocksTree.ts +0 -15
  383. package/src/util/sszBytes.ts +25 -5
@@ -8,16 +8,8 @@ import {
8
8
  ForkChoiceErrorCode,
9
9
  NotReorgedReason,
10
10
  getSafeExecutionBlockHash,
11
- isGloasBlock,
12
11
  } from "@lodestar/fork-choice";
13
- import {
14
- ForkPostAltair,
15
- ForkPostElectra,
16
- ForkPostGloas,
17
- ForkSeq,
18
- MAX_SEED_LOOKAHEAD,
19
- SLOTS_PER_EPOCH,
20
- } from "@lodestar/params";
12
+ import {ForkPostAltair, ForkPostElectra, ForkSeq, MAX_SEED_LOOKAHEAD, SLOTS_PER_EPOCH} from "@lodestar/params";
21
13
  import {
22
14
  IBeaconStateView,
23
15
  RootCache,
@@ -28,17 +20,7 @@ import {
28
20
  isStatePostAltair,
29
21
  isStatePostBellatrix,
30
22
  } from "@lodestar/state-transition";
31
- import {
32
- Attestation,
33
- BeaconBlock,
34
- SignedBeaconBlock,
35
- altair,
36
- capella,
37
- electra,
38
- isGloasBeaconBlock,
39
- phase0,
40
- ssz,
41
- } from "@lodestar/types";
23
+ import {Attestation, BeaconBlock, altair, capella, electra, isGloasBeaconBlock, phase0, ssz} from "@lodestar/types";
42
24
  import {isErrorAborted, toRootHex} from "@lodestar/utils";
43
25
  import {ZERO_HASH_HEX} from "../../constants/index.js";
44
26
  import {callInNextEventLoop} from "../../util/eventLoop.js";
@@ -87,8 +69,8 @@ export async function importBlock(
87
69
  fullyVerifiedBlock: FullyVerifiedBlock,
88
70
  opts: ImportBlockOpts
89
71
  ): Promise<void> {
90
- const {blockInput, postBlockState, parentBlockSlot, executionStatus, dataAvailabilityStatus, indexedAttestations} =
91
- fullyVerifiedBlock;
72
+ const {blockInput, postState, parentBlockSlot, dataAvailabilityStatus, indexedAttestations} = fullyVerifiedBlock;
73
+ let {executionStatus} = fullyVerifiedBlock;
92
74
  const block = blockInput.getBlock();
93
75
  const source = blockInput.getBlockSource();
94
76
  const {slot: blockSlot} = block.message;
@@ -99,7 +81,7 @@ export async function importBlock(
99
81
  const blockEpoch = computeEpochAtSlot(blockSlot);
100
82
  const prevFinalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
101
83
  const blockDelaySec =
102
- fullyVerifiedBlock.seenTimestampSec - computeTimeAtSlot(this.config, blockSlot, postBlockState.genesisTime);
84
+ fullyVerifiedBlock.seenTimestampSec - computeTimeAtSlot(this.config, blockSlot, postState.genesisTime);
103
85
  const recvToValLatency = Date.now() / 1000 - (opts.seenTimestampSec ?? Date.now() / 1000);
104
86
  const fork = this.config.getForkSeq(blockSlot);
105
87
 
@@ -122,57 +104,30 @@ export async function importBlock(
122
104
  // 2. Import block to fork choice
123
105
 
124
106
  // Should compute checkpoint balances before forkchoice.onBlock
125
- this.checkpointBalancesCache.processState(blockRootHex, postBlockState);
107
+ this.checkpointBalancesCache.processState(blockRootHex, postState);
108
+ if (fork >= ForkSeq.gloas) {
109
+ const parentRootHex = toRootHex(block.message.parentRoot);
110
+ const parentBlock = this.forkChoice.getBlockHexDefaultStatus(parentRootHex);
111
+ if (parentBlock === null) {
112
+ throw Error(`Parent block not found in forkChoice, parentRoot=${parentRootHex}`);
113
+ }
114
+ if (parentBlock.executionStatus === ExecutionStatus.Invalid) {
115
+ throw Error(`Parent block has invalid execution status, parentRoot=${parentRootHex}`);
116
+ }
117
+ executionStatus = parentBlock.executionStatus;
118
+ }
126
119
  const blockSummary = this.forkChoice.onBlock(
127
120
  block.message,
128
- postBlockState,
121
+ postState,
129
122
  blockDelaySec,
130
123
  currentSlot,
131
- fork >= ForkSeq.gloas ? ExecutionStatus.PayloadSeparated : executionStatus,
124
+ executionStatus,
132
125
  dataAvailabilityStatus
133
126
  );
134
127
 
135
128
  // This adds the state necessary to process the next block
136
129
  // Some block event handlers require state being in state cache so need to do this before emitting EventType.block
137
- // Pre-Gloas: blockSummary.payloadStatus is always FULL, payloadPresent = true
138
- // Post-Gloas: blockSummary.payloadStatus is always PENDING, so payloadPresent = false (block state only, no payload processing yet)
139
- const payloadPresent = !isGloasBlock(blockSummary);
140
- // processState manages both block state and payload state variants together for memory/disk management
141
- this.regen.processBlockState(blockRootHex, postBlockState);
142
-
143
- // For Gloas blocks, create PayloadEnvelopeInput so it's available for later payload import
144
- if (fork >= ForkSeq.gloas) {
145
- const payloadInput = this.seenPayloadEnvelopeInputCache.add({
146
- blockRootHex,
147
- block: block as SignedBeaconBlock<ForkPostGloas>,
148
- forkName: blockInput.forkName,
149
- sampledColumns: this.custodyConfig.sampledColumns,
150
- custodyColumns: this.custodyConfig.custodyColumns,
151
- timeCreatedSec: fullyVerifiedBlock.seenTimestampSec,
152
- });
153
- this.logger.debug("Created PayloadEnvelopeInput for block", {
154
- slot: blockSlot,
155
- root: blockRootHex,
156
- source: source.source,
157
- ...(opts.seenTimestampSec !== undefined ? {recvToImport: Date.now() / 1000 - opts.seenTimestampSec} : {}),
158
- });
159
-
160
- // Immediately attempt fetch of data columns from execution engine as the bid contains kzg commitments
161
- // which is all the information we need so there is no reason to delay until execution payload arrives
162
- // TODO GLOAS: If we want EL retries after this initial attempt, add an explicit retry policy here
163
- // (for example later in the slot). Do not couple retries to incoming gossip columns.
164
- this.getBlobsTracker.triggerGetBlobs(payloadInput, () => {
165
- // TODO GLOAS: come up with a better mechanism to trigger processExecutionPayload after data becomes available,
166
- // similar to how pre-gloas uses waitForBlockAndAllData with a cutoff timeout and incompleteBlockInput event
167
- this.processExecutionPayload(payloadInput, {validSignature: true}).catch((e) => {
168
- this.logger.debug(
169
- "Error processing execution payload after getBlobs",
170
- {slot: blockSlot, root: blockRootHex},
171
- e as Error
172
- );
173
- });
174
- });
175
- }
130
+ this.regen.processState(blockRootHex, postState);
176
131
 
177
132
  this.metrics?.importBlock.bySource.inc({source: source.source});
178
133
  this.logger.verbose("Added block to forkchoice and state cache", {slot: blockSlot, root: blockRootHex});
@@ -191,7 +146,7 @@ export async function importBlock(
191
146
  (opts.importAttestations !== AttestationImportOpt.Skip && blockEpoch >= currentEpoch - FORK_CHOICE_ATT_EPOCH_LIMIT)
192
147
  ) {
193
148
  const attestations = block.message.body.attestations;
194
- const rootCache = new RootCache(postBlockState);
149
+ const rootCache = new RootCache(postState);
195
150
  const invalidAttestationErrorsByCode = new Map<string, {error: Error; count: number}>();
196
151
 
197
152
  const addAttestation = fork >= ForkSeq.electra ? addAttestationPostElectra : addAttestationPreElectra;
@@ -205,7 +160,7 @@ export async function importBlock(
205
160
  const attDataRoot = toRootHex(ssz.phase0.AttestationData.hashTreeRoot(indexedAttestation.data));
206
161
  addAttestation.call(
207
162
  this,
208
- postBlockState,
163
+ postState,
209
164
  target,
210
165
  attDataRoot,
211
166
  attestation as Attestation<ForkPostElectra>,
@@ -320,7 +275,7 @@ export async function importBlock(
320
275
 
321
276
  if (newHead.blockRoot !== oldHead.blockRoot) {
322
277
  // Set head state as strong reference
323
- this.regen.updateHeadState(newHead, postBlockState);
278
+ this.regen.updateHeadState(newHead, postState);
324
279
 
325
280
  try {
326
281
  this.emitter.emit(routes.events.EventType.head, {
@@ -390,10 +345,10 @@ export async function importBlock(
390
345
  // we want to import block asap so do this in the next event loop
391
346
  callInNextEventLoop(() => {
392
347
  try {
393
- if (isStatePostAltair(postBlockState)) {
348
+ if (isStatePostAltair(postState)) {
394
349
  this.lightClientServer?.onImportBlockHead(
395
350
  block.message as BeaconBlock<ForkPostAltair>,
396
- postBlockState,
351
+ postState,
397
352
  parentBlockSlot
398
353
  );
399
354
  }
@@ -415,11 +370,11 @@ export async function importBlock(
415
370
  // and the block is weak and can potentially be reorged out.
416
371
  let shouldOverrideFcu = false;
417
372
 
418
- if (blockSlot >= currentSlot && isStatePostBellatrix(postBlockState) && postBlockState.isExecutionStateType) {
373
+ if (blockSlot >= currentSlot && isStatePostBellatrix(postState) && postState.isExecutionStateType) {
419
374
  let notOverrideFcuReason = NotReorgedReason.Unknown;
420
375
  const proposalSlot = blockSlot + 1;
421
376
  try {
422
- const proposerIndex = postBlockState.getBeaconProposer(proposalSlot);
377
+ const proposerIndex = postState.getBeaconProposer(proposalSlot);
423
378
  const feeRecipient = this.beaconProposerCache.get(proposerIndex);
424
379
 
425
380
  if (feeRecipient) {
@@ -499,22 +454,22 @@ export async function importBlock(
499
454
  }
500
455
  }
501
456
 
502
- if (!postBlockState.isStateValidatorsNodesPopulated()) {
503
- this.logger.verbose("After importBlock caching postState without SSZ cache", {slot: postBlockState.slot});
457
+ if (!postState.isStateValidatorsNodesPopulated()) {
458
+ this.logger.verbose("After importBlock caching postState without SSZ cache", {slot: postState.slot});
504
459
  }
505
460
 
506
461
  // Cache shufflings when crossing an epoch boundary
507
462
  const parentEpoch = computeEpochAtSlot(parentBlockSlot);
508
463
  if (parentEpoch < blockEpoch) {
509
- this.shufflingCache.processState(postBlockState);
464
+ this.shufflingCache.processState(postState);
510
465
  this.logger.verbose("Processed shuffling for next epoch", {parentEpoch, blockEpoch, slot: blockSlot});
511
466
  }
512
467
 
513
468
  if (blockSlot % SLOTS_PER_EPOCH === 0) {
514
469
  // Cache state to preserve epoch transition work
515
- const checkpointState = postBlockState;
470
+ const checkpointState = postState;
516
471
  const cp = getCheckpointFromState(checkpointState);
517
- this.regen.addCheckpointState(cp, checkpointState, payloadPresent);
472
+ this.regen.addCheckpointState(cp, checkpointState);
518
473
  // consumers should not mutate state ever
519
474
  this.emitter.emit(ChainEvent.checkpoint, cp, checkpointState);
520
475
 
@@ -602,11 +557,11 @@ export async function importBlock(
602
557
  this.metrics?.parentBlockDistance.observe(blockSlot - parentBlockSlot);
603
558
  this.metrics?.proposerBalanceDeltaAny.observe(fullyVerifiedBlock.proposerBalanceDelta);
604
559
  this.validatorMonitor?.registerImportedBlock(block.message, fullyVerifiedBlock);
605
- if (isStatePostAltair(fullyVerifiedBlock.postBlockState)) {
560
+ if (isStatePostAltair(fullyVerifiedBlock.postState)) {
606
561
  this.validatorMonitor?.registerSyncAggregateInBlock(
607
562
  blockEpoch,
608
563
  (block as altair.SignedBeaconBlock).message.body.syncAggregate,
609
- fullyVerifiedBlock.postBlockState.currentSyncCommitteeIndexed.validatorIndices
564
+ fullyVerifiedBlock.postState.currentSyncCommitteeIndexed.validatorIndices
610
565
  );
611
566
  }
612
567
 
@@ -1,14 +1,19 @@
1
1
  import {routes} from "@lodestar/api";
2
- import {ExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
3
- import {SLOTS_PER_EPOCH} from "@lodestar/params";
4
- import {getExecutionPayloadEnvelopeSignatureSet, isStatePostGloas} from "@lodestar/state-transition";
5
- import {byteArrayEquals, fromHex, toRootHex} from "@lodestar/utils";
2
+ import {ExecutionStatus, PayloadExecutionStatus, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
3
+ import {DataAvailabilityStatus, isStatePostGloas} from "@lodestar/state-transition";
4
+ import {isErrorAborted} from "@lodestar/utils";
5
+ import {ZERO_HASH_HEX} from "../../constants/index.js";
6
6
  import {ExecutionPayloadStatus} from "../../execution/index.js";
7
7
  import {isQueueErrorAborted} from "../../util/queue/index.js";
8
8
  import {BeaconChain} from "../chain.js";
9
9
  import {RegenCaller} from "../regen/interface.js";
10
10
  import {PayloadEnvelopeInput} from "../seenCache/seenPayloadEnvelopeInput.js";
11
11
  import {ImportPayloadOpts} from "./types.js";
12
+ import {
13
+ verifyExecutionPayloadEnvelope,
14
+ verifyExecutionPayloadEnvelopeSignature,
15
+ } from "./verifyExecutionPayloadEnvelope.js";
16
+ import {verifyPayloadsDataAvailability} from "./verifyPayloadsDataAvailability.js";
12
17
 
13
18
  const EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS = 64;
14
19
 
@@ -16,7 +21,7 @@ export enum PayloadErrorCode {
16
21
  EXECUTION_ENGINE_INVALID = "PAYLOAD_ERROR_EXECUTION_ENGINE_INVALID",
17
22
  EXECUTION_ENGINE_ERROR = "PAYLOAD_ERROR_EXECUTION_ENGINE_ERROR",
18
23
  BLOCK_NOT_IN_FORK_CHOICE = "PAYLOAD_ERROR_BLOCK_NOT_IN_FORK_CHOICE",
19
- STATE_TRANSITION_ERROR = "PAYLOAD_ERROR_STATE_TRANSITION_ERROR",
24
+ ENVELOPE_VERIFICATION_ERROR = "PAYLOAD_ERROR_ENVELOPE_VERIFICATION_ERROR",
20
25
  INVALID_SIGNATURE = "PAYLOAD_ERROR_INVALID_SIGNATURE",
21
26
  }
22
27
 
@@ -36,7 +41,7 @@ export type PayloadErrorType =
36
41
  blockRootHex: string;
37
42
  }
38
43
  | {
39
- code: PayloadErrorCode.STATE_TRANSITION_ERROR;
44
+ code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR;
40
45
  message: string;
41
46
  }
42
47
  | {
@@ -56,7 +61,6 @@ function toForkChoiceExecutionStatus(status: ExecutionPayloadStatus): PayloadExe
56
61
  switch (status) {
57
62
  case ExecutionPayloadStatus.VALID:
58
63
  return ExecutionStatus.Valid;
59
- // TODO GLOAS: Handle optimistic import for payload
60
64
  case ExecutionPayloadStatus.SYNCING:
61
65
  case ExecutionPayloadStatus.ACCEPTED:
62
66
  return ExecutionStatus.Syncing;
@@ -68,37 +72,43 @@ function toForkChoiceExecutionStatus(status: ExecutionPayloadStatus): PayloadExe
68
72
  /**
69
73
  * Import an execution payload envelope after all data is available.
70
74
  *
71
- * This function:
72
- * 1. Emits `execution_payload_available` if payload is for current slot
73
- * 2. Gets the ProtoBlock from fork choice
74
- * 3. Applies write-queue backpressure (waitForSpace) early, before verification
75
- * 4. Regenerates the block state
76
- * 5. Runs EL verification (notifyNewPayload) in parallel with signature verification and processExecutionPayloadEnvelope
77
- * 6. Persists verified payload envelope to hot DB
78
- * 7. Updates fork choice
79
- * 8. Caches the post-execution payload state
80
- * 9. Records metrics for column sources
81
- * 10. Emits `execution_payload` for recent enough payloads after successful import
75
+ * The envelope is only verified here, no state mutation. State effects from the payload
76
+ * are applied on the next block via processParentExecutionPayload.
82
77
  *
78
+ * The DA wait must have run upstream (range sync awaits DA in `verifyBlocksInEpoch` for the
79
+ * whole segment; gossip / API path uses the `processExecutionPayload` wrapper below).
80
+ *
81
+ * Steps:
82
+ * 1. Emit `execution_payload_available` event for payload attestation
83
+ * 2. Get the ProtoBlock from fork choice
84
+ * 3. Regenerate state for envelope verification
85
+ * 4. Verify envelope (fields against state, signature, and EL in parallel where possible)
86
+ * 5. Persist verified payload envelope to hot DB (waits for write-queue space for backpressure)
87
+ * 6. Update fork choice (transitions the block's PENDING variant to FULL)
88
+ * 7. Queue notifyForkchoiceUpdate to engine api
89
+ * 8. Record metrics for payload envelope and column sources
90
+ * 9. Emit `execution_payload` event
83
91
  */
84
92
  export async function importExecutionPayload(
85
93
  this: BeaconChain,
86
94
  payloadInput: PayloadEnvelopeInput,
95
+ dataAvailabilityStatus: DataAvailabilityStatus,
87
96
  opts: ImportPayloadOpts = {}
88
97
  ): Promise<void> {
89
98
  const signedEnvelope = payloadInput.getPayloadEnvelope();
90
99
  const envelope = signedEnvelope.message;
100
+ const slot = envelope.payload.slotNumber;
91
101
  const blockRootHex = payloadInput.blockRootHex;
92
102
  const blockHashHex = payloadInput.getBlockHashHex();
93
- const fork = this.config.getForkName(envelope.slot);
103
+ const fork = this.config.getForkName(slot);
94
104
 
95
- // 1. Emit `execution_payload_available` event at the start of import. At this point the payload input
96
- // is already complete, so the payload and required data are available for payload attestation.
97
- // This event is only about availability, not validity of the execution payload, hence we can emit
98
- // it before getting a response from the execution client on whether the payload is valid or not.
99
- if (this.clock.currentSlot - envelope.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
105
+ // 1. Emit `execution_payload_available` event at the start of import. At this point the
106
+ // payload input is already complete, so the payload and required data are available for
107
+ // payload attestation. This event only signals availability (not validity), so we can emit
108
+ // it before getting a response from the EL on whether the payload is valid or not.
109
+ if (this.clock.currentSlot - slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
100
110
  this.emitter.emit(routes.events.EventType.executionPayloadAvailable, {
101
- slot: envelope.slot,
111
+ slot,
102
112
  blockRoot: blockRootHex,
103
113
  });
104
114
  }
@@ -112,12 +122,7 @@ export async function importExecutionPayload(
112
122
  });
113
123
  }
114
124
 
115
- // 3. Apply backpressure from the write queue early, before doing verification work.
116
- // The actual DB write is deferred until after verification succeeds.
117
- await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();
118
-
119
- // 4. Get pre-state for processExecutionPayloadEnvelope
120
- // We need the block state (post-block, pre-payload) to process the envelope
125
+ // 3. Regenerate state for envelope verification
121
126
  const blockState = await this.regen.getBlockSlotState(
122
127
  protoBlock,
123
128
  protoBlock.slot,
@@ -126,64 +131,56 @@ export async function importExecutionPayload(
126
131
  );
127
132
  if (!isStatePostGloas(blockState)) {
128
133
  throw new PayloadError({
129
- code: PayloadErrorCode.STATE_TRANSITION_ERROR,
130
- message: `Expected gloas+ block state for payload import, got fork=${blockState.forkName}`,
134
+ code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR,
135
+ message: `Expected gloas+ state for payload import, got fork=${blockState.forkName}`,
131
136
  });
132
137
  }
133
138
 
134
- // 5. Run verification steps in parallel
135
- // Note: No data availability check needed here - importExecutionPayload is only
136
- // called when payloadInput.isComplete() is true, so all data is already available.
137
- const [execResult, signatureValid, postPayloadResult] = await Promise.all([
139
+ // 4. Verify envelope fields against state first to fail fast before the EL + BLS work.
140
+ // When validSignature is true, gossip/API has already verified both the signature and the
141
+ // executionRequestsRoot, so we skip those checks here.
142
+ try {
143
+ verifyExecutionPayloadEnvelope(this.config, blockState, envelope, {
144
+ verifyExecutionRequestsRoot: !opts.validSignature,
145
+ });
146
+ } catch (e) {
147
+ throw new PayloadError(
148
+ {
149
+ code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR,
150
+ message: (e as Error).message,
151
+ },
152
+ `Envelope verification error: ${(e as Error).message}`
153
+ );
154
+ }
155
+
156
+ // 4a. Run EL and signature verification in parallel
157
+ const [execResult, signatureValid] = await Promise.all([
138
158
  this.executionEngine.notifyNewPayload(
139
159
  fork,
140
160
  envelope.payload,
141
161
  payloadInput.getVersionedHashes(),
142
- fromHex(protoBlock.parentRoot),
162
+ envelope.parentBeaconBlockRoot,
143
163
  envelope.executionRequests
144
164
  ),
145
165
 
146
166
  opts.validSignature === true
147
167
  ? Promise.resolve(true)
148
- : (async () => {
149
- const signatureSet = getExecutionPayloadEnvelopeSignatureSet(
150
- this.config,
151
- this.pubkeyCache,
152
- blockState,
153
- signedEnvelope,
154
- payloadInput.proposerIndex
155
- );
156
- return this.bls.verifySignatureSets([signatureSet]);
157
- })(),
158
-
159
- // Signature verified separately above.
160
- // State root check is done separately below with better error typing (matching block pipeline pattern).
161
- (async () => {
162
- try {
163
- return {
164
- postPayloadState: blockState.processExecutionPayloadEnvelope(signedEnvelope, {
165
- verifySignature: false,
166
- verifyStateRoot: false,
167
- }),
168
- };
169
- } catch (e) {
170
- throw new PayloadError(
171
- {
172
- code: PayloadErrorCode.STATE_TRANSITION_ERROR,
173
- message: (e as Error).message,
174
- },
175
- `State transition error: ${(e as Error).message}`
176
- );
177
- }
178
- })(),
168
+ : verifyExecutionPayloadEnvelopeSignature(
169
+ this.config,
170
+ blockState,
171
+ this.pubkeyCache,
172
+ signedEnvelope,
173
+ payloadInput.proposerIndex,
174
+ this.bls
175
+ ),
179
176
  ]);
180
177
 
181
- // 5a. Check signature verification result
178
+ // 4b. Check signature verification result
182
179
  if (!signatureValid) {
183
180
  throw new PayloadError({code: PayloadErrorCode.INVALID_SIGNATURE});
184
181
  }
185
182
 
186
- // 5b. Handle EL response
183
+ // 4c. Handle EL response
187
184
  switch (execResult.status) {
188
185
  case ExecutionPayloadStatus.VALID:
189
186
  break;
@@ -209,69 +206,80 @@ export async function importExecutionPayload(
209
206
  });
210
207
  }
211
208
 
212
- // 5c. Verify envelope state root matches post-state
213
- const postPayloadState = postPayloadResult.postPayloadState;
214
- const postPayloadStateRoot = postPayloadState.hashTreeRoot();
215
- if (!byteArrayEquals(envelope.stateRoot, postPayloadStateRoot)) {
216
- throw new PayloadError({
217
- code: PayloadErrorCode.STATE_TRANSITION_ERROR,
218
- message: `Envelope state root mismatch expected=${toRootHex(envelope.stateRoot)} actual=${toRootHex(postPayloadStateRoot)}`,
219
- });
220
- }
221
-
222
- // 6. Persist payload envelope to hot DB (performed asynchronously to avoid blocking)
209
+ // 5. Persist payload envelope to hot DB. Wait for write-queue space here to apply backpressure
210
+ // on the import pipeline during sync, then perform the write asynchronously to avoid blocking.
211
+ await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();
223
212
  this.unfinalizedPayloadEnvelopeWrites.push(payloadInput).catch((e) => {
224
213
  if (!isQueueErrorAborted(e)) {
225
214
  this.logger.error(
226
215
  "Error pushing payload envelope to unfinalized write queue",
227
- {slot: envelope.slot, blockRoot: blockRootHex},
216
+ {slot, blockRoot: blockRootHex},
228
217
  e as Error
229
218
  );
230
219
  }
231
220
  });
232
221
 
233
- // 7. Update fork choice
222
+ // 6. Update fork choice, transitions the block's PENDING variant to FULL
223
+ const execStatus = toForkChoiceExecutionStatus(execResult.status);
234
224
  this.forkChoice.onExecutionPayload(
235
225
  blockRootHex,
236
226
  blockHashHex,
237
227
  envelope.payload.blockNumber,
238
- toRootHex(postPayloadStateRoot),
239
- toForkChoiceExecutionStatus(execResult.status)
228
+ execStatus,
229
+ dataAvailabilityStatus
240
230
  );
241
231
 
242
- // 8. Cache payload state
243
- this.regen.processPayloadState(postPayloadState);
244
- if (postPayloadState.slot % SLOTS_PER_EPOCH === 0) {
245
- const {checkpoint} = postPayloadState.computeAnchorCheckpoint();
246
- this.regen.addCheckpointState(checkpoint, postPayloadState, true);
232
+ // 7. Queue notifyForkchoiceUpdate to engine api
233
+ const head = this.forkChoice.getHead();
234
+ if (!this.opts.disableImportExecutionFcU && blockRootHex === head.blockRoot) {
235
+ const safeBlockHash = getSafeExecutionBlockHash(this.forkChoice);
236
+ const finalizedBlockHash = this.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
237
+ this.executionEngine.notifyForkchoiceUpdate(fork, blockHashHex, safeBlockHash, finalizedBlockHash).catch((e) => {
238
+ if (!isErrorAborted(e) && !isQueueErrorAborted(e)) {
239
+ this.logger.error("Error pushing notifyForkchoiceUpdate()", {blockHashHex, finalizedBlockHash}, e);
240
+ }
241
+ });
247
242
  }
248
243
 
249
- // 9. Record metrics for payload envelope and column sources
244
+ // 8. Record metrics for payload envelope and column sources
250
245
  this.metrics?.importPayload.bySource.inc({source: payloadInput.getPayloadEnvelopeSource().source});
251
246
  for (const {source} of payloadInput.getSampledColumnsWithSource()) {
252
247
  this.metrics?.importPayload.columnsBySource.inc({source});
253
248
  }
254
249
 
255
- const stateRootHex = toRootHex(envelope.stateRoot);
256
-
257
- // 10. Emit event after payload is fully verified and imported to fork choice, only for recent enough payloads
258
- if (this.clock.currentSlot - envelope.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
250
+ // 9. Emit event after payload is fully verified and imported to fork choice, only for recent enough payloads
251
+ if (this.clock.currentSlot - slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
259
252
  this.emitter.emit(routes.events.EventType.executionPayload, {
260
- slot: envelope.slot,
253
+ slot,
261
254
  builderIndex: envelope.builderIndex,
262
255
  blockHash: blockHashHex,
263
256
  blockRoot: blockRootHex,
264
- stateRoot: stateRootHex,
265
- // TODO GLOAS: revisit once we support optimistic import
266
- executionOptimistic: false,
257
+ executionOptimistic: execStatus === ExecutionStatus.Syncing,
267
258
  });
268
259
  }
269
260
 
270
261
  this.logger.verbose("Execution payload imported", {
271
- slot: envelope.slot,
262
+ slot,
272
263
  builderIndex: envelope.builderIndex,
273
264
  blockRoot: blockRootHex,
274
265
  blockHash: blockHashHex,
275
- stateRoot: stateRootHex,
276
266
  });
277
267
  }
268
+
269
+ /**
270
+ * Process an execution payload envelope end-to-end: wait for DA, then import.
271
+ *
272
+ * Used by the PayloadEnvelopeProcessor queue (gossip / API / unknown-payload sync) — i.e.
273
+ * callers that have NOT already awaited DA themselves. Range sync's inline dispatch in
274
+ * processBlocks skips this wrapper and calls `importExecutionPayload` directly, since
275
+ * `verifyBlocksInEpoch` already awaited DA for the segment.
276
+ */
277
+ export async function processExecutionPayload(
278
+ this: BeaconChain,
279
+ payloadInput: PayloadEnvelopeInput,
280
+ signal: AbortSignal,
281
+ opts: ImportPayloadOpts = {}
282
+ ): Promise<void> {
283
+ const {dataAvailabilityStatuses} = await verifyPayloadsDataAvailability([payloadInput], signal);
284
+ await importExecutionPayload.call(this, payloadInput, dataAvailabilityStatuses[0], opts);
285
+ }