@lodestar/beacon-node 1.42.0-rc.0 → 1.43.0-dev.05a33e512f

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 (462) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +37 -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 +49 -2
  6. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  7. package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
  8. package/lib/api/impl/beacon/state/index.js +13 -10
  9. package/lib/api/impl/beacon/state/index.js.map +1 -1
  10. package/lib/api/impl/beacon/state/utils.d.ts +2 -2
  11. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  12. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  13. package/lib/api/impl/debug/index.d.ts.map +1 -1
  14. package/lib/api/impl/debug/index.js +0 -1
  15. package/lib/api/impl/debug/index.js.map +1 -1
  16. package/lib/api/impl/lodestar/attesterSlashing.d.ts +8 -0
  17. package/lib/api/impl/lodestar/attesterSlashing.d.ts.map +1 -0
  18. package/lib/api/impl/lodestar/attesterSlashing.js +29 -0
  19. package/lib/api/impl/lodestar/attesterSlashing.js.map +1 -0
  20. package/lib/api/impl/lodestar/index.d.ts.map +1 -1
  21. package/lib/api/impl/lodestar/index.js +40 -1
  22. package/lib/api/impl/lodestar/index.js.map +1 -1
  23. package/lib/api/impl/validator/index.d.ts.map +1 -1
  24. package/lib/api/impl/validator/index.js +74 -5
  25. package/lib/api/impl/validator/index.js.map +1 -1
  26. package/lib/chain/GetBlobsTracker.d.ts +1 -1
  27. package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
  28. package/lib/chain/GetBlobsTracker.js +1 -2
  29. package/lib/chain/GetBlobsTracker.js.map +1 -1
  30. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  31. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  32. package/lib/chain/archiveStore/interface.d.ts +4 -4
  33. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  34. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
  35. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
  36. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +2 -4
  37. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
  38. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +2 -2
  39. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  40. package/lib/chain/archiveStore/utils/archiveBlocks.js +110 -58
  41. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  42. package/lib/chain/blocks/blockInput/blockInput.d.ts +3 -0
  43. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  44. package/lib/chain/blocks/blockInput/blockInput.js +4 -1
  45. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  46. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  47. package/lib/chain/blocks/importBlock.js +40 -58
  48. package/lib/chain/blocks/importBlock.js.map +1 -1
  49. package/lib/chain/blocks/importExecutionPayload.d.ts +32 -14
  50. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  51. package/lib/chain/blocks/importExecutionPayload.js +107 -87
  52. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  53. package/lib/chain/blocks/index.d.ts +5 -3
  54. package/lib/chain/blocks/index.d.ts.map +1 -1
  55. package/lib/chain/blocks/index.js +58 -26
  56. package/lib/chain/blocks/index.js.map +1 -1
  57. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +15 -1
  58. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  59. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +48 -2
  60. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  61. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +17 -0
  62. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  63. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +5 -0
  64. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -1
  65. package/lib/chain/blocks/payloadEnvelopeProcessor.js +7 -5
  66. package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
  67. package/lib/chain/blocks/types.d.ts +16 -21
  68. package/lib/chain/blocks/types.d.ts.map +1 -1
  69. package/lib/chain/blocks/utils/chainSegment.d.ts +23 -2
  70. package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
  71. package/lib/chain/blocks/utils/chainSegment.js +89 -12
  72. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  73. package/lib/chain/blocks/verifyBlock.d.ts +5 -3
  74. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  75. package/lib/chain/blocks/verifyBlock.js +50 -7
  76. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  77. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +0 -4
  78. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  79. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +8 -4
  80. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  81. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts +2 -1
  82. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
  83. package/lib/chain/blocks/verifyBlocksSanityChecks.js +25 -5
  84. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  85. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  86. package/lib/chain/blocks/verifyBlocksSignatures.js +4 -2
  87. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  88. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +24 -0
  89. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -0
  90. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +80 -0
  91. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -0
  92. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts +14 -0
  93. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -0
  94. package/lib/chain/blocks/verifyPayloadsDataAvailability.js +30 -0
  95. package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -0
  96. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +1 -1
  97. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -1
  98. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +2 -11
  99. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -1
  100. package/lib/chain/chain.d.ts +9 -6
  101. package/lib/chain/chain.d.ts.map +1 -1
  102. package/lib/chain/chain.js +73 -49
  103. package/lib/chain/chain.js.map +1 -1
  104. package/lib/chain/emitter.d.ts +16 -15
  105. package/lib/chain/emitter.d.ts.map +1 -1
  106. package/lib/chain/emitter.js +5 -4
  107. package/lib/chain/emitter.js.map +1 -1
  108. package/lib/chain/errors/attestationError.d.ts +8 -1
  109. package/lib/chain/errors/attestationError.d.ts.map +1 -1
  110. package/lib/chain/errors/attestationError.js +4 -0
  111. package/lib/chain/errors/attestationError.js.map +1 -1
  112. package/lib/chain/errors/blockError.d.ts +18 -1
  113. package/lib/chain/errors/blockError.d.ts.map +1 -1
  114. package/lib/chain/errors/blockError.js +6 -0
  115. package/lib/chain/errors/blockError.js.map +1 -1
  116. package/lib/chain/errors/executionPayloadBid.d.ts +5 -0
  117. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  118. package/lib/chain/errors/executionPayloadBid.js +1 -0
  119. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  120. package/lib/chain/errors/executionPayloadEnvelope.d.ts +5 -0
  121. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  122. package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
  123. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  124. package/lib/chain/errors/index.d.ts +1 -0
  125. package/lib/chain/errors/index.d.ts.map +1 -1
  126. package/lib/chain/errors/index.js +1 -0
  127. package/lib/chain/errors/index.js.map +1 -1
  128. package/lib/chain/errors/proposerPreferences.d.ts +40 -0
  129. package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
  130. package/lib/chain/errors/proposerPreferences.js +14 -0
  131. package/lib/chain/errors/proposerPreferences.js.map +1 -0
  132. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  133. package/lib/chain/forkChoice/index.js +21 -23
  134. package/lib/chain/forkChoice/index.js.map +1 -1
  135. package/lib/chain/initState.d.ts.map +1 -1
  136. package/lib/chain/initState.js +6 -1
  137. package/lib/chain/initState.js.map +1 -1
  138. package/lib/chain/interface.d.ts +8 -5
  139. package/lib/chain/interface.d.ts.map +1 -1
  140. package/lib/chain/interface.js.map +1 -1
  141. package/lib/chain/lightClient/index.d.ts +2 -2
  142. package/lib/chain/lightClient/index.d.ts.map +1 -1
  143. package/lib/chain/lightClient/index.js +7 -0
  144. package/lib/chain/lightClient/index.js.map +1 -1
  145. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  146. package/lib/chain/opPools/aggregatedAttestationPool.js +5 -2
  147. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  148. package/lib/chain/opPools/executionPayloadBidPool.d.ts +2 -2
  149. package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -1
  150. package/lib/chain/opPools/executionPayloadBidPool.js +2 -2
  151. package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -1
  152. package/lib/chain/opPools/payloadAttestationPool.d.ts +3 -2
  153. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
  154. package/lib/chain/opPools/payloadAttestationPool.js +26 -4
  155. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
  156. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  157. package/lib/chain/prepareNextSlot.js +48 -18
  158. package/lib/chain/prepareNextSlot.js.map +1 -1
  159. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +1 -7
  160. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  161. package/lib/chain/produceBlock/computeNewStateRoot.js +1 -28
  162. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  163. package/lib/chain/produceBlock/produceBlockBody.d.ts +15 -10
  164. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  165. package/lib/chain/produceBlock/produceBlockBody.js +83 -21
  166. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  167. package/lib/chain/regen/errors.d.ts +1 -11
  168. package/lib/chain/regen/errors.d.ts.map +1 -1
  169. package/lib/chain/regen/errors.js +0 -2
  170. package/lib/chain/regen/errors.js.map +1 -1
  171. package/lib/chain/regen/interface.d.ts +7 -12
  172. package/lib/chain/regen/interface.d.ts.map +1 -1
  173. package/lib/chain/regen/interface.js +1 -0
  174. package/lib/chain/regen/interface.js.map +1 -1
  175. package/lib/chain/regen/queued.d.ts +6 -11
  176. package/lib/chain/regen/queued.d.ts.map +1 -1
  177. package/lib/chain/regen/queued.js +9 -44
  178. package/lib/chain/regen/queued.js.map +1 -1
  179. package/lib/chain/regen/regen.d.ts +0 -5
  180. package/lib/chain/regen/regen.d.ts.map +1 -1
  181. package/lib/chain/regen/regen.js +8 -38
  182. package/lib/chain/regen/regen.js.map +1 -1
  183. package/lib/chain/seenCache/index.d.ts +1 -0
  184. package/lib/chain/seenCache/index.d.ts.map +1 -1
  185. package/lib/chain/seenCache/index.js +1 -0
  186. package/lib/chain/seenCache/index.js.map +1 -1
  187. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +24 -7
  188. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  189. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +69 -17
  190. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  191. package/lib/chain/seenCache/seenProposerPreferences.d.ts +16 -0
  192. package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
  193. package/lib/chain/seenCache/seenProposerPreferences.js +26 -0
  194. package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
  195. package/lib/chain/stateCache/datastore/db.d.ts +5 -4
  196. package/lib/chain/stateCache/datastore/db.d.ts.map +1 -1
  197. package/lib/chain/stateCache/datastore/db.js +10 -32
  198. package/lib/chain/stateCache/datastore/db.js.map +1 -1
  199. package/lib/chain/stateCache/datastore/file.d.ts +1 -1
  200. package/lib/chain/stateCache/datastore/file.d.ts.map +1 -1
  201. package/lib/chain/stateCache/datastore/file.js +5 -5
  202. package/lib/chain/stateCache/datastore/file.js.map +1 -1
  203. package/lib/chain/stateCache/datastore/types.d.ts +1 -1
  204. package/lib/chain/stateCache/datastore/types.d.ts.map +1 -1
  205. package/lib/chain/stateCache/fifoBlockStateCache.d.ts +1 -7
  206. package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
  207. package/lib/chain/stateCache/fifoBlockStateCache.js +0 -8
  208. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  209. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +13 -30
  210. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  211. package/lib/chain/stateCache/persistentCheckpointsCache.js +120 -216
  212. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  213. package/lib/chain/stateCache/types.d.ts +8 -15
  214. package/lib/chain/stateCache/types.d.ts.map +1 -1
  215. package/lib/chain/stateCache/types.js.map +1 -1
  216. package/lib/chain/validation/aggregateAndProof.js +12 -0
  217. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  218. package/lib/chain/validation/attestation.d.ts.map +1 -1
  219. package/lib/chain/validation/attestation.js +12 -0
  220. package/lib/chain/validation/attestation.js.map +1 -1
  221. package/lib/chain/validation/block.d.ts.map +1 -1
  222. package/lib/chain/validation/block.js +28 -5
  223. package/lib/chain/validation/block.js.map +1 -1
  224. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  225. package/lib/chain/validation/executionPayloadBid.js +30 -12
  226. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  227. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  228. package/lib/chain/validation/executionPayloadEnvelope.js +27 -12
  229. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  230. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  231. package/lib/chain/validation/payloadAttestationMessage.js +8 -4
  232. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  233. package/lib/chain/validation/proposerPreferences.d.ts +8 -0
  234. package/lib/chain/validation/proposerPreferences.d.ts.map +1 -0
  235. package/lib/chain/validation/proposerPreferences.js +91 -0
  236. package/lib/chain/validation/proposerPreferences.js.map +1 -0
  237. package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
  238. package/lib/chain/validation/syncCommittee.js +4 -0
  239. package/lib/chain/validation/syncCommittee.js.map +1 -1
  240. package/lib/chain/validation/syncCommitteeContributionAndProof.js +4 -1
  241. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  242. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  243. package/lib/chain/validatorMonitor.js +3 -3
  244. package/lib/chain/validatorMonitor.js.map +1 -1
  245. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
  246. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
  247. package/lib/execution/engine/http.d.ts.map +1 -1
  248. package/lib/execution/engine/http.js +21 -14
  249. package/lib/execution/engine/http.js.map +1 -1
  250. package/lib/execution/engine/interface.d.ts +1 -0
  251. package/lib/execution/engine/interface.d.ts.map +1 -1
  252. package/lib/execution/engine/mock.d.ts.map +1 -1
  253. package/lib/execution/engine/mock.js +6 -0
  254. package/lib/execution/engine/mock.js.map +1 -1
  255. package/lib/execution/engine/types.d.ts +20 -0
  256. package/lib/execution/engine/types.d.ts.map +1 -1
  257. package/lib/execution/engine/types.js +18 -0
  258. package/lib/execution/engine/types.js.map +1 -1
  259. package/lib/metrics/metrics/lodestar.d.ts +1 -0
  260. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  261. package/lib/metrics/metrics/lodestar.js +4 -0
  262. package/lib/metrics/metrics/lodestar.js.map +1 -1
  263. package/lib/network/gossip/interface.d.ts +7 -1
  264. package/lib/network/gossip/interface.d.ts.map +1 -1
  265. package/lib/network/gossip/interface.js +1 -0
  266. package/lib/network/gossip/interface.js.map +1 -1
  267. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  268. package/lib/network/gossip/scoringParameters.js +12 -1
  269. package/lib/network/gossip/scoringParameters.js.map +1 -1
  270. package/lib/network/gossip/topic.d.ts +13 -2
  271. package/lib/network/gossip/topic.d.ts.map +1 -1
  272. package/lib/network/gossip/topic.js +6 -0
  273. package/lib/network/gossip/topic.js.map +1 -1
  274. package/lib/network/interface.d.ts +1 -0
  275. package/lib/network/interface.d.ts.map +1 -1
  276. package/lib/network/network.d.ts +1 -0
  277. package/lib/network/network.d.ts.map +1 -1
  278. package/lib/network/network.js +6 -1
  279. package/lib/network/network.js.map +1 -1
  280. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  281. package/lib/network/processor/gossipHandlers.js +64 -22
  282. package/lib/network/processor/gossipHandlers.js.map +1 -1
  283. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  284. package/lib/network/processor/gossipQueues/index.js +5 -0
  285. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  286. package/lib/network/processor/index.d.ts.map +1 -1
  287. package/lib/network/processor/index.js +6 -5
  288. package/lib/network/processor/index.js.map +1 -1
  289. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  290. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +16 -7
  291. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  292. package/lib/network/reqresp/handlers/beaconBlocksByRoot.d.ts.map +1 -1
  293. package/lib/network/reqresp/handlers/beaconBlocksByRoot.js +2 -0
  294. package/lib/network/reqresp/handlers/beaconBlocksByRoot.js.map +1 -1
  295. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts +2 -2
  296. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
  297. package/lib/network/reqresp/handlers/blobSidecarsByRange.js +18 -8
  298. package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
  299. package/lib/network/reqresp/handlers/blobSidecarsByRoot.d.ts.map +1 -1
  300. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js +6 -0
  301. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js.map +1 -1
  302. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts +2 -2
  303. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  304. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +24 -8
  305. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  306. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
  307. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +9 -5
  308. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
  309. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -1
  310. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +3 -8
  311. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
  312. package/lib/node/nodejs.d.ts.map +1 -1
  313. package/lib/node/nodejs.js +7 -2
  314. package/lib/node/nodejs.js.map +1 -1
  315. package/lib/node/notifier.d.ts.map +1 -1
  316. package/lib/node/notifier.js +2 -2
  317. package/lib/node/notifier.js.map +1 -1
  318. package/lib/sync/constants.d.ts +3 -1
  319. package/lib/sync/constants.d.ts.map +1 -1
  320. package/lib/sync/constants.js +3 -4
  321. package/lib/sync/constants.js.map +1 -1
  322. package/lib/sync/range/batch.d.ts +35 -5
  323. package/lib/sync/range/batch.d.ts.map +1 -1
  324. package/lib/sync/range/batch.js +240 -59
  325. package/lib/sync/range/batch.js.map +1 -1
  326. package/lib/sync/range/chain.d.ts +19 -4
  327. package/lib/sync/range/chain.d.ts.map +1 -1
  328. package/lib/sync/range/chain.js +64 -11
  329. package/lib/sync/range/chain.js.map +1 -1
  330. package/lib/sync/range/range.d.ts.map +1 -1
  331. package/lib/sync/range/range.js +31 -9
  332. package/lib/sync/range/range.js.map +1 -1
  333. package/lib/sync/sync.d.ts.map +1 -1
  334. package/lib/sync/sync.js +13 -0
  335. package/lib/sync/sync.js.map +1 -1
  336. package/lib/sync/types.d.ts +34 -0
  337. package/lib/sync/types.d.ts.map +1 -1
  338. package/lib/sync/types.js +34 -0
  339. package/lib/sync/types.js.map +1 -1
  340. package/lib/sync/unknownBlock.d.ts +29 -1
  341. package/lib/sync/unknownBlock.d.ts.map +1 -1
  342. package/lib/sync/unknownBlock.js +738 -61
  343. package/lib/sync/unknownBlock.js.map +1 -1
  344. package/lib/sync/utils/downloadByRange.d.ts +67 -10
  345. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  346. package/lib/sync/utils/downloadByRange.js +211 -26
  347. package/lib/sync/utils/downloadByRange.js.map +1 -1
  348. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  349. package/lib/sync/utils/downloadByRoot.js +16 -2
  350. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  351. package/lib/sync/utils/pendingBlocksTree.d.ts +0 -1
  352. package/lib/sync/utils/pendingBlocksTree.d.ts.map +1 -1
  353. package/lib/sync/utils/pendingBlocksTree.js +0 -9
  354. package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
  355. package/lib/util/sszBytes.d.ts.map +1 -1
  356. package/lib/util/sszBytes.js +20 -5
  357. package/lib/util/sszBytes.js.map +1 -1
  358. package/package.json +17 -16
  359. package/src/api/impl/beacon/blocks/index.ts +51 -9
  360. package/src/api/impl/beacon/pool/index.ts +87 -1
  361. package/src/api/impl/beacon/state/index.ts +15 -15
  362. package/src/api/impl/beacon/state/utils.ts +2 -2
  363. package/src/api/impl/debug/index.ts +0 -1
  364. package/src/api/impl/lodestar/attesterSlashing.ts +43 -0
  365. package/src/api/impl/lodestar/index.ts +52 -2
  366. package/src/api/impl/validator/index.ts +91 -6
  367. package/src/chain/GetBlobsTracker.ts +1 -2
  368. package/src/chain/archiveStore/archiveStore.ts +5 -5
  369. package/src/chain/archiveStore/interface.ts +4 -4
  370. package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +6 -8
  371. package/src/chain/archiveStore/utils/archiveBlocks.ts +153 -94
  372. package/src/chain/blocks/blockInput/blockInput.ts +4 -1
  373. package/src/chain/blocks/importBlock.ts +45 -86
  374. package/src/chain/blocks/importExecutionPayload.ts +133 -103
  375. package/src/chain/blocks/index.ts +72 -24
  376. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +64 -3
  377. package/src/chain/blocks/payloadEnvelopeInput/types.ts +18 -0
  378. package/src/chain/blocks/payloadEnvelopeProcessor.ts +7 -6
  379. package/src/chain/blocks/types.ts +16 -26
  380. package/src/chain/blocks/utils/chainSegment.ts +114 -17
  381. package/src/chain/blocks/verifyBlock.ts +70 -9
  382. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +8 -5
  383. package/src/chain/blocks/verifyBlocksSanityChecks.ts +26 -7
  384. package/src/chain/blocks/verifyBlocksSignatures.ts +9 -2
  385. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +137 -0
  386. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +41 -0
  387. package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +9 -18
  388. package/src/chain/chain.ts +102 -72
  389. package/src/chain/emitter.ts +15 -14
  390. package/src/chain/errors/attestationError.ts +6 -1
  391. package/src/chain/errors/blockError.ts +10 -1
  392. package/src/chain/errors/executionPayloadBid.ts +6 -0
  393. package/src/chain/errors/executionPayloadEnvelope.ts +6 -0
  394. package/src/chain/errors/index.ts +1 -0
  395. package/src/chain/errors/proposerPreferences.ts +47 -0
  396. package/src/chain/forkChoice/index.ts +19 -28
  397. package/src/chain/initState.ts +9 -1
  398. package/src/chain/interface.ts +16 -3
  399. package/src/chain/lightClient/index.ts +15 -3
  400. package/src/chain/opPools/aggregatedAttestationPool.ts +6 -1
  401. package/src/chain/opPools/executionPayloadBidPool.ts +3 -3
  402. package/src/chain/opPools/payloadAttestationPool.ts +29 -8
  403. package/src/chain/prepareNextSlot.ts +58 -19
  404. package/src/chain/produceBlock/computeNewStateRoot.ts +1 -37
  405. package/src/chain/produceBlock/produceBlockBody.ts +120 -26
  406. package/src/chain/regen/errors.ts +1 -6
  407. package/src/chain/regen/interface.ts +7 -12
  408. package/src/chain/regen/queued.ts +14 -55
  409. package/src/chain/regen/regen.ts +10 -43
  410. package/src/chain/seenCache/index.ts +1 -0
  411. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +89 -21
  412. package/src/chain/seenCache/seenProposerPreferences.ts +32 -0
  413. package/src/chain/stateCache/datastore/db.ts +10 -33
  414. package/src/chain/stateCache/datastore/file.ts +5 -6
  415. package/src/chain/stateCache/datastore/types.ts +2 -3
  416. package/src/chain/stateCache/fifoBlockStateCache.ts +1 -10
  417. package/src/chain/stateCache/persistentCheckpointsCache.ts +139 -247
  418. package/src/chain/stateCache/types.ts +8 -14
  419. package/src/chain/validation/aggregateAndProof.ts +13 -0
  420. package/src/chain/validation/attestation.ts +13 -0
  421. package/src/chain/validation/block.ts +31 -7
  422. package/src/chain/validation/executionPayloadBid.ts +32 -11
  423. package/src/chain/validation/executionPayloadEnvelope.ts +32 -13
  424. package/src/chain/validation/payloadAttestationMessage.ts +9 -3
  425. package/src/chain/validation/proposerPreferences.ts +110 -0
  426. package/src/chain/validation/syncCommittee.ts +5 -1
  427. package/src/chain/validation/syncCommitteeContributionAndProof.ts +5 -1
  428. package/src/chain/validatorMonitor.ts +3 -2
  429. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
  430. package/src/execution/engine/http.ts +21 -14
  431. package/src/execution/engine/interface.ts +1 -0
  432. package/src/execution/engine/mock.ts +8 -1
  433. package/src/execution/engine/types.ts +41 -0
  434. package/src/metrics/metrics/lodestar.ts +4 -0
  435. package/src/network/gossip/interface.ts +6 -0
  436. package/src/network/gossip/scoringParameters.ts +14 -1
  437. package/src/network/gossip/topic.ts +6 -0
  438. package/src/network/interface.ts +1 -0
  439. package/src/network/network.ts +12 -1
  440. package/src/network/processor/gossipHandlers.ts +84 -27
  441. package/src/network/processor/gossipQueues/index.ts +5 -0
  442. package/src/network/processor/index.ts +6 -5
  443. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +17 -7
  444. package/src/network/reqresp/handlers/beaconBlocksByRoot.ts +3 -0
  445. package/src/network/reqresp/handlers/blobSidecarsByRange.ts +26 -8
  446. package/src/network/reqresp/handlers/blobSidecarsByRoot.ts +11 -0
  447. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +36 -8
  448. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +10 -5
  449. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +3 -12
  450. package/src/node/nodejs.ts +8 -3
  451. package/src/node/notifier.ts +7 -2
  452. package/src/sync/constants.ts +4 -4
  453. package/src/sync/range/batch.ts +320 -67
  454. package/src/sync/range/chain.ts +89 -14
  455. package/src/sync/range/range.ts +34 -9
  456. package/src/sync/sync.ts +13 -1
  457. package/src/sync/types.ts +72 -0
  458. package/src/sync/unknownBlock.ts +928 -65
  459. package/src/sync/utils/downloadByRange.ts +378 -39
  460. package/src/sync/utils/downloadByRoot.ts +24 -2
  461. package/src/sync/utils/pendingBlocksTree.ts +0 -15
  462. package/src/util/sszBytes.ts +25 -5
@@ -1,4 +1,4 @@
1
- import {SignedBeaconBlock} from "@lodestar/types";
1
+ import {SignedBeaconBlock, Slot} from "@lodestar/types";
2
2
  import {isErrorAborted, toRootHex} from "@lodestar/utils";
3
3
  import {Metrics} from "../../metrics/metrics.js";
4
4
  import {nextEventLoop} from "../../util/eventLoop.js";
@@ -8,6 +8,8 @@ import {BlockError, BlockErrorCode, isBlockErrorAborted} from "../errors/index.j
8
8
  import {BlockProcessOpts} from "../options.js";
9
9
  import {IBlockInput} from "./blockInput/types.js";
10
10
  import {importBlock} from "./importBlock.js";
11
+ import {importExecutionPayload} from "./importExecutionPayload.js";
12
+ import {PayloadEnvelopeInput} from "./payloadEnvelopeInput/payloadEnvelopeInput.js";
11
13
  import {FullyVerifiedBlock, ImportBlockOpts} from "./types.js";
12
14
  import {assertLinearChainSegment} from "./utils/chainSegment.js";
13
15
  import {verifyBlocksInEpoch} from "./verifyBlock.js";
@@ -21,20 +23,24 @@ const QUEUE_MAX_LENGTH = 256;
21
23
  * BlockProcessor processes block jobs in a queued fashion, one after the other.
22
24
  */
23
25
  export class BlockProcessor {
24
- readonly jobQueue: JobItemQueue<[IBlockInput[], ImportBlockOpts], void>;
26
+ readonly jobQueue: JobItemQueue<[IBlockInput[], Map<Slot, PayloadEnvelopeInput> | null, ImportBlockOpts], void>;
25
27
 
26
28
  constructor(chain: BeaconChain, metrics: Metrics | null, opts: BlockProcessOpts, signal: AbortSignal) {
27
- this.jobQueue = new JobItemQueue<[IBlockInput[], ImportBlockOpts], void>(
28
- (job, importOpts) => {
29
- return processBlocks.call(chain, job, {...opts, ...importOpts});
29
+ this.jobQueue = new JobItemQueue<[IBlockInput[], Map<Slot, PayloadEnvelopeInput> | null, ImportBlockOpts], void>(
30
+ (job, payloadEnvelopes, importOpts) => {
31
+ return processBlocks.call(chain, job, payloadEnvelopes, {...opts, ...importOpts});
30
32
  },
31
33
  {maxLength: QUEUE_MAX_LENGTH, noYieldIfOneItem: true, signal},
32
34
  metrics?.blockProcessorQueue ?? undefined
33
35
  );
34
36
  }
35
37
 
36
- async processBlocksJob(job: IBlockInput[], opts: ImportBlockOpts = {}): Promise<void> {
37
- await this.jobQueue.push(job, opts);
38
+ async processBlocksJob(
39
+ job: IBlockInput[],
40
+ payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
41
+ opts: ImportBlockOpts = {}
42
+ ): Promise<void> {
43
+ await this.jobQueue.push(job, payloadEnvelopes, opts);
38
44
  }
39
45
  }
40
46
 
@@ -51,18 +57,15 @@ export class BlockProcessor {
51
57
  export async function processBlocks(
52
58
  this: BeaconChain,
53
59
  blocks: IBlockInput[],
60
+ payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
54
61
  opts: BlockProcessOpts & ImportBlockOpts
55
62
  ): Promise<void> {
56
63
  if (blocks.length === 0) {
57
64
  return; // TODO: or throw?
58
65
  }
59
66
 
60
- if (blocks.length > 1) {
61
- assertLinearChainSegment(this.config, blocks);
62
- }
63
-
64
67
  try {
65
- const {relevantBlocks, parentSlots, parentBlock} = verifyBlocksSanityChecks(this, blocks, opts);
68
+ const {relevantBlocks, parentSlots, parentBlock} = verifyBlocksSanityChecks(this, blocks, payloadEnvelopes, opts);
66
69
 
67
70
  // No relevant blocks, skip verifyBlocksInEpoch()
68
71
  if (relevantBlocks.length === 0 || parentBlock === null) {
@@ -70,10 +73,31 @@ export async function processBlocks(
70
73
  return;
71
74
  }
72
75
 
76
+ const {warnings: orphanedPayloads} = assertLinearChainSegment(
77
+ this.config,
78
+ relevantBlocks,
79
+ payloadEnvelopes,
80
+ parentBlock
81
+ );
82
+ if (orphanedPayloads != null) {
83
+ for (const orphaned of orphanedPayloads) {
84
+ this.logger.debug("Orphaned payload envelope in chain segment", {
85
+ slot: orphaned.slot,
86
+ blockRoot: orphaned.payloadEnvelopeInput.blockRootHex,
87
+ });
88
+ }
89
+ }
90
+
73
91
  // Fully verify a block to be imported immediately after. Does not produce any side-effects besides adding intermediate
74
92
  // states in the state cache through regen.
75
- const {postStates, dataAvailabilityStatuses, proposerBalanceDeltas, segmentExecStatus, indexedAttestationsByBlock} =
76
- await verifyBlocksInEpoch.call(this, parentBlock, relevantBlocks, opts);
93
+ const {
94
+ postStates,
95
+ blockDAStatuses,
96
+ payloadDAStatuses,
97
+ proposerBalanceDeltas,
98
+ segmentExecStatus,
99
+ indexedAttestationsByBlock,
100
+ } = await verifyBlocksInEpoch.call(this, parentBlock, relevantBlocks, payloadEnvelopes, opts);
77
101
 
78
102
  // If segmentExecStatus has lvhForkchoice then, the entire segment should be invalid
79
103
  // and we need to further propagate
@@ -85,25 +109,49 @@ export async function processBlocks(
85
109
  }
86
110
 
87
111
  const {executionStatuses} = segmentExecStatus;
88
- const fullyVerifiedBlocks = relevantBlocks.map(
89
- (block, i): FullyVerifiedBlock => ({
112
+ const verifiedBlocksBySlot = new Map<Slot, FullyVerifiedBlock>();
113
+ for (let i = 0; i < relevantBlocks.length; i++) {
114
+ const block = relevantBlocks[i];
115
+ verifiedBlocksBySlot.set(block.getBlock().message.slot, {
90
116
  blockInput: block,
91
- postBlockState: postStates[i],
92
- postEnvelopeState: null,
117
+ postState: postStates[i],
93
118
  parentBlockSlot: parentSlots[i],
94
119
  executionStatus: executionStatuses[i],
95
120
  // start supporting optimistic syncing/processing
96
- dataAvailabilityStatus: dataAvailabilityStatuses[i],
121
+ dataAvailabilityStatus: blockDAStatuses[i],
97
122
  proposerBalanceDelta: proposerBalanceDeltas[i],
98
123
  indexedAttestations: indexedAttestationsByBlock[i],
99
124
  // TODO: Make this param mandatory and capture in gossip
100
125
  seenTimestampSec: opts.seenTimestampSec ?? Math.floor(Date.now() / 1000),
101
- })
102
- );
126
+ });
127
+ }
128
+
129
+ const slotSet = new Set<Slot>(blocks.map((b) => b.getBlock().message.slot));
130
+ if (payloadEnvelopes) {
131
+ for (const slot of payloadEnvelopes.keys()) slotSet.add(slot);
132
+ }
133
+ const slots = Array.from(slotSet).sort((a, b) => a - b);
134
+ for (const slot of slots) {
135
+ const fullyVerifiedBlock = verifiedBlocksBySlot.get(slot);
136
+ if (fullyVerifiedBlock !== undefined) {
137
+ // TODO: Consider batching importBlock too if it takes significant time
138
+ await importBlock.call(this, fullyVerifiedBlock, opts);
139
+ }
140
+
141
+ const payloadInput = payloadEnvelopes?.get(slot);
142
+ if (payloadInput?.hasPayloadEnvelope()) {
143
+ if (!payloadInput.isComplete()) {
144
+ // we validated DA before reaching this
145
+ throw new Error(`Payload envelope for slot ${slot} not complete after DA verification`);
146
+ }
147
+ // we already awaited DA in verifyBlocksInEpoch for this segment
148
+ const payloadDA = payloadDAStatuses.get(slot);
149
+ if (payloadDA === undefined) {
150
+ throw new Error(`Missing payload DA status for slot ${slot}`);
151
+ }
152
+ await importExecutionPayload.call(this, payloadInput, payloadDA, {validSignature: false});
153
+ }
103
154
 
104
- for (const fullyVerifiedBlock of fullyVerifiedBlocks) {
105
- // TODO: Consider batching importBlock too if it takes significant time
106
- await importBlock.call(this, fullyVerifiedBlock, opts);
107
155
  await nextEventLoop();
108
156
  }
109
157
  } catch (e) {
@@ -4,7 +4,13 @@ import {toRootHex, withTimeout} from "@lodestar/utils";
4
4
  import {VersionedHashes} from "../../../execution/index.js";
5
5
  import {kzgCommitmentToVersionedHash} from "../../../util/blobs.js";
6
6
  import {MissingColumnMeta} from "../blockInput/types.js";
7
- import {AddPayloadEnvelopeProps, ColumnWithSource, CreateFromBlockProps, SourceMeta} from "./types.js";
7
+ import {
8
+ AddPayloadEnvelopeProps,
9
+ ColumnWithSource,
10
+ CreateFromBidProps,
11
+ CreateFromBlockProps,
12
+ SourceMeta,
13
+ } from "./types.js";
8
14
 
9
15
  export type PayloadEnvelopeInputState =
10
16
  | {
@@ -64,6 +70,7 @@ export class PayloadEnvelopeInput {
64
70
  readonly proposerIndex: ValidatorIndex;
65
71
  readonly bid: gloas.ExecutionPayloadBid;
66
72
  readonly versionedHashes: VersionedHashes;
73
+ readonly daOutOfRange: boolean;
67
74
 
68
75
  private columnsCache = new Map<ColumnIndex, ColumnWithSource>();
69
76
 
@@ -73,6 +80,7 @@ export class PayloadEnvelopeInput {
73
80
  private timeCreatedSec: number;
74
81
 
75
82
  private readonly payloadEnvelopeDataPromise: PromiseParts<gloas.SignedExecutionPayloadEnvelope>;
83
+ private readonly allDataPromise: PromiseParts<gloas.DataColumnSidecar[]>;
76
84
  private readonly columnsDataPromise: PromiseParts<gloas.DataColumnSidecar[]>;
77
85
 
78
86
  state: PayloadEnvelopeInputState;
@@ -86,6 +94,7 @@ export class PayloadEnvelopeInput {
86
94
  sampledColumns: ColumnIndex[];
87
95
  custodyColumns: ColumnIndex[];
88
96
  timeCreatedSec: number;
97
+ daOutOfRange: boolean;
89
98
  }) {
90
99
  this.blockRootHex = props.blockRootHex;
91
100
  this.slot = props.slot;
@@ -96,15 +105,18 @@ export class PayloadEnvelopeInput {
96
105
  this.sampledColumns = props.sampledColumns;
97
106
  this.custodyColumns = props.custodyColumns;
98
107
  this.timeCreatedSec = props.timeCreatedSec;
108
+ this.daOutOfRange = props.daOutOfRange;
99
109
  this.payloadEnvelopeDataPromise = createPromise();
110
+ this.allDataPromise = createPromise();
100
111
  this.columnsDataPromise = createPromise();
101
112
 
102
113
  const noBlobs = props.bid.blobKzgCommitments.length === 0;
103
114
  const noSampledColumns = props.sampledColumns.length === 0;
104
- const hasAllData = noBlobs || noSampledColumns;
115
+ const hasAllData = props.daOutOfRange || noBlobs || noSampledColumns;
105
116
 
106
117
  if (hasAllData) {
107
118
  this.state = {hasPayload: false, hasAllData: true, hasComputedAllData: true};
119
+ this.allDataPromise.resolve(this.getSampledColumns());
108
120
  this.columnsDataPromise.resolve(this.getSampledColumns());
109
121
  } else {
110
122
  this.state = {hasPayload: false, hasAllData: false, hasComputedAllData: false};
@@ -122,6 +134,27 @@ export class PayloadEnvelopeInput {
122
134
  sampledColumns: props.sampledColumns,
123
135
  custodyColumns: props.custodyColumns,
124
136
  timeCreatedSec: props.timeCreatedSec,
137
+ daOutOfRange: props.daOutOfRange,
138
+ });
139
+ }
140
+
141
+ /**
142
+ * Create a `PayloadEnvelopeInput` from a state's `latestExecutionPayloadBid` (the bid
143
+ * recorded in beacon state for the latest imported block). Used when seeding the cache
144
+ * for a checkpoint anchor block — we have the bid via state but not the full
145
+ * SignedBeaconBlock body.
146
+ */
147
+ static createFromBid(props: CreateFromBidProps): PayloadEnvelopeInput {
148
+ return new PayloadEnvelopeInput({
149
+ blockRootHex: props.blockRootHex,
150
+ slot: props.slot,
151
+ forkName: props.forkName,
152
+ proposerIndex: props.proposerIndex,
153
+ bid: props.bid,
154
+ sampledColumns: props.sampledColumns,
155
+ custodyColumns: props.custodyColumns,
156
+ timeCreatedSec: props.timeCreatedSec,
157
+ daOutOfRange: props.daOutOfRange,
125
158
  });
126
159
  }
127
160
 
@@ -149,6 +182,7 @@ export class PayloadEnvelopeInput {
149
182
  throw new Error("Payload envelope beacon_block_root mismatch");
150
183
  }
151
184
 
185
+ // TODO GLOAS: track source by metrics, maybe inside the seen cache
152
186
  const source: SourceMeta = {
153
187
  source: props.source,
154
188
  seenTimestampSec: props.seenTimestampSec,
@@ -203,6 +237,12 @@ export class PayloadEnvelopeInput {
203
237
  return true;
204
238
  }
205
239
 
240
+ // Resolve allDataPromise on the first transition to hasAllData (either sampled-complete or
241
+ // reconstruction-threshold branch). Guarded so it fires exactly once.
242
+ if (!this.state.hasAllData && hasAllData) {
243
+ this.allDataPromise.resolve(sampledColumns);
244
+ }
245
+
206
246
  if (hasComputedAllData) {
207
247
  this.columnsDataPromise.resolve(sampledColumns);
208
248
  }
@@ -297,8 +337,11 @@ export class PayloadEnvelopeInput {
297
337
  return this.state.hasAllData;
298
338
  }
299
339
 
340
+ /**
341
+ * Strictly checks missing sampled columns. Does NOT short-circuit on `state.hasAllData`.
342
+ */
300
343
  getMissingSampledColumnMeta(): MissingColumnMeta {
301
- if (this.state.hasAllData) {
344
+ if (this.state.hasComputedAllData) {
302
345
  return {missing: [], versionedHashes: this.versionedHashes};
303
346
  }
304
347
 
@@ -315,6 +358,24 @@ export class PayloadEnvelopeInput {
315
358
  return this.state.hasComputedAllData;
316
359
  }
317
360
 
361
+ waitForAllData(timeout: number, signal?: AbortSignal): Promise<gloas.DataColumnSidecar[]> {
362
+ if (this.state.hasAllData) {
363
+ return Promise.resolve(this.getSampledColumns());
364
+ }
365
+ return withTimeout(() => this.allDataPromise.promise, timeout, signal);
366
+ }
367
+
368
+ async waitForEnvelopeAndAllData(timeout: number, signal?: AbortSignal): Promise<this> {
369
+ if (!this.state.hasPayload || !this.state.hasAllData) {
370
+ await withTimeout(
371
+ () => Promise.all([this.payloadEnvelopeDataPromise.promise, this.allDataPromise.promise]),
372
+ timeout,
373
+ signal
374
+ );
375
+ }
376
+ return this;
377
+ }
378
+
318
379
  waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<gloas.DataColumnSidecar[]> {
319
380
  if (this.state.hasComputedAllData) {
320
381
  return Promise.resolve(this.getSampledColumns());
@@ -27,6 +27,24 @@ export type CreateFromBlockProps = {
27
27
  sampledColumns: ColumnIndex[];
28
28
  custodyColumns: ColumnIndex[];
29
29
  timeCreatedSec: number;
30
+ daOutOfRange: boolean;
31
+ };
32
+
33
+ /**
34
+ * Used to seed an entry from a state's `latestExecutionPayloadBid` (e.g., when initializing
35
+ * the chain from a checkpoint anchor state — we have the bid via the state but not the
36
+ * full SignedBeaconBlock).
37
+ */
38
+ export type CreateFromBidProps = {
39
+ blockRootHex: RootHex;
40
+ slot: number;
41
+ forkName: ForkName;
42
+ proposerIndex: number;
43
+ bid: gloas.ExecutionPayloadBid;
44
+ sampledColumns: ColumnIndex[];
45
+ custodyColumns: ColumnIndex[];
46
+ timeCreatedSec: number;
47
+ daOutOfRange: boolean;
30
48
  };
31
49
 
32
50
  export type AddPayloadEnvelopeProps = SourceMeta & {
@@ -2,7 +2,7 @@ import {Metrics} from "../../metrics/metrics.js";
2
2
  import {JobItemQueue} from "../../util/queue/index.js";
3
3
  import type {BeaconChain} from "../chain.js";
4
4
  import {PayloadEnvelopeInput} from "../seenCache/seenPayloadEnvelopeInput.js";
5
- import {importExecutionPayload} from "./importExecutionPayload.js";
5
+ import {processExecutionPayload} from "./importExecutionPayload.js";
6
6
  import {ImportPayloadOpts} from "./types.js";
7
7
 
8
8
  // TODO GLOAS: Set to be equal to DEFAULT_MAX_PENDING_UNFINALIZED_PAYLOAD_ENVELOPE_WRITES for now
@@ -16,6 +16,11 @@ enum PayloadEnvelopeImportStatus {
16
16
 
17
17
  /**
18
18
  * PayloadEnvelopeProcessor processes payload envelope jobs in a queued fashion, one after the other.
19
+ *
20
+ * Jobs are enqueued only on envelope arrival (gossip or API). The envelope may reach us before
21
+ * the sampled data columns; importExecutionPayload awaits `verifyPayloadsDataAvailability`
22
+ * internally, so a queued job can pend for up to `PAYLOAD_DATA_AVAILABILITY_TIMEOUT` while
23
+ * waiting for columns. Duplicate triggers for the same payloadInput are deduped via `importStatus`.
19
24
  */
20
25
  export class PayloadEnvelopeProcessor {
21
26
  readonly jobQueue: JobItemQueue<[PayloadEnvelopeInput, ImportPayloadOpts], void>;
@@ -25,7 +30,7 @@ export class PayloadEnvelopeProcessor {
25
30
  this.jobQueue = new JobItemQueue<[PayloadEnvelopeInput, ImportPayloadOpts], void>(
26
31
  (payloadInput, opts) => {
27
32
  this.importStatus.set(payloadInput, PayloadEnvelopeImportStatus.importing);
28
- return importExecutionPayload.call(chain, payloadInput, opts);
33
+ return processExecutionPayload.call(chain, payloadInput, signal, opts);
29
34
  },
30
35
  {maxLength: QUEUE_MAX_LENGTH, noYieldIfOneItem: true, signal},
31
36
  metrics?.payloadEnvelopeProcessorQueue ?? undefined
@@ -33,10 +38,6 @@ export class PayloadEnvelopeProcessor {
33
38
  }
34
39
 
35
40
  async processPayloadEnvelopeJob(payloadInput: PayloadEnvelopeInput, opts: ImportPayloadOpts = {}): Promise<void> {
36
- if (!payloadInput.isComplete()) {
37
- return;
38
- }
39
-
40
41
  if (this.importStatus.get(payloadInput) !== undefined) {
41
42
  return;
42
43
  }
@@ -1,5 +1,5 @@
1
1
  import type {ChainForkConfig} from "@lodestar/config";
2
- import {BlockExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
2
+ import type {BlockExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
3
3
  import {ForkSeq} from "@lodestar/params";
4
4
  import {DataAvailabilityStatus, IBeaconStateView, computeEpochAtSlot} from "@lodestar/state-transition";
5
5
  import type {IndexedAttestation, Slot, fulu} from "@lodestar/types";
@@ -43,8 +43,9 @@ export enum BlobSidecarValidation {
43
43
 
44
44
  export type ImportPayloadOpts = {
45
45
  /**
46
- * Set to true if envelope signature was already verified (e.g., during gossip/API validation).
47
- * When false/undefined, signature will be verified during import.
46
+ * Set to true when the envelope was already validated upstream (e.g., gossip/API validation):
47
+ * signature is trusted and execution_requests_root was already verified against the bid.
48
+ * When false/undefined, both are verified during import.
48
49
  */
49
50
  validSignature?: boolean;
50
51
  };
@@ -88,9 +89,17 @@ export type ImportBlockOpts = {
88
89
  seenTimestampSec?: number;
89
90
  };
90
91
 
91
- type FullyVerifiedBlockBase = {
92
+ /**
93
+ * A wrapper around a `SignedBeaconBlock` that indicates that this block is fully verified and ready to import.
94
+ *
95
+ * `executionStatus` reflects the outcome of execution payload verification at block-import time:
96
+ * - pre-gloas: Valid | Syncing | PreMerge (from EL notifyNewPayload against the in-block payload)
97
+ * - post-gloas: inherited from parent's chain (Valid/Syncing) by importBlock; payload arrives
98
+ * separately as an envelope and creates the FULL variant later via onExecutionPayload
99
+ */
100
+ export type FullyVerifiedBlock = {
92
101
  blockInput: IBlockInput;
93
- postBlockState: IBeaconStateView;
102
+ postState: IBeaconStateView;
94
103
  parentBlockSlot: Slot;
95
104
  proposerBalanceDelta: number;
96
105
  dataAvailabilityStatus: DataAvailabilityStatus;
@@ -98,25 +107,6 @@ type FullyVerifiedBlockBase = {
98
107
  indexedAttestations: IndexedAttestation[];
99
108
  /** Seen timestamp seconds */
100
109
  seenTimestampSec: number;
110
+ /** If the execution payload couldn't be verified because of EL syncing status, used in optimistic sync */
111
+ executionStatus: BlockExecutionStatus | PayloadExecutionStatus;
101
112
  };
102
-
103
- /**
104
- * A wrapper around a `SignedBeaconBlock` that indicates that this block is fully verified and ready to import.
105
- *
106
- * Discriminated union on `postEnvelopeState`:
107
- * - `null` → block has no pre-verified envelope; `executionStatus` is any `BlockExecutionStatus`
108
- * - non-null → envelope was pre-verified during state transition; `executionStatus` is narrowed to
109
- * `Valid | Syncing` (matching what `forkChoice.onExecutionPayload` expects)
110
- */
111
- export type FullyVerifiedBlock = FullyVerifiedBlockBase &
112
- (
113
- | {
114
- postEnvelopeState: null;
115
- /** If the execution payload couldn't be verified because of EL syncing status, used in optimistic sync or for merge block */
116
- executionStatus: BlockExecutionStatus;
117
- }
118
- | {
119
- postEnvelopeState: IBeaconStateView;
120
- executionStatus: PayloadExecutionStatus;
121
- }
122
- );
@@ -1,29 +1,126 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
- import {ssz} from "@lodestar/types";
2
+ import {ProtoBlock} from "@lodestar/fork-choice";
3
+ import {Slot, isGloasBeaconBlock, ssz} from "@lodestar/types";
4
+ import {toRootHex} from "@lodestar/utils";
3
5
  import {BlockError, BlockErrorCode} from "../../errors/index.js";
4
6
  import {IBlockInput} from "../blockInput/types.js";
7
+ import {PayloadEnvelopeInput} from "../payloadEnvelopeInput/payloadEnvelopeInput.js";
8
+
9
+ export type OrphanedPayloadEnvelope = {
10
+ slot: Slot;
11
+ payloadEnvelopeInput: PayloadEnvelopeInput;
12
+ };
13
+
14
+ export type ChainSegmentResult = {warnings: OrphanedPayloadEnvelope[] | null};
5
15
 
6
16
  /**
7
- * Assert this chain segment of blocks is linear with slot numbers and hashes
17
+ * Assert this chain segment of blocks is linear with slot numbers and hashes,
18
+ * and that the provided envelopes are consistent with their respective blocks.
19
+ *
20
+ * Must be called after verifyBlocksSanityChecks so that parentBlock (from forkchoice)
21
+ * is available to seed the execution hash chain.
22
+ *
23
+ * For each block:
24
+ * - Verifies parent root + slot linearity
25
+ * - For gloas: verifies bid.parentBlockHash matches the tracked execution hash; if not, the
26
+ * previous FULL envelope is treated as orphaned (segment continues as if previous slot was EMPTY)
27
+ * - If an envelope exists for this slot: verifies it references this block's root
28
+ * - Advances the tracked execution hash (FULL if envelope present, EMPTY if not)
8
29
  */
30
+ export function assertLinearChainSegment(
31
+ config: ChainForkConfig,
32
+ blocks: IBlockInput[],
33
+ payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
34
+ parentBlock: ProtoBlock
35
+ ): ChainSegmentResult {
36
+ const warnings: OrphanedPayloadEnvelope[] = [];
9
37
 
10
- export function assertLinearChainSegment(config: ChainForkConfig, blocks: IBlockInput[]): void {
11
- for (let i = 0; i < blocks.length - 1; i++) {
38
+ // Track the expected execution payload block hash through the segment.
39
+ // Starts from the known forkchoice parent's execution hash.
40
+ // - FULL variant (envelope present for slot): advances to envelope.payload.blockHash
41
+ // - EMPTY variant (no envelope for slot): execution hash is unchanged
42
+ // null only for pre-merge parents, which cannot precede gloas blocks.
43
+ let currentExecHash: string | null = parentBlock.executionPayloadBlockHash;
44
+ // Checkpoint sync first batch: parent is the anchor PENDING whose executionPayloadBlockHash
45
+ // is the inherited parentBlockHash semantic (= grandparent's payload), not its own payload.
46
+ // If parent's own payload envelope arrives in this batch, advance currentExecHash to that
47
+ // payload's blockHash so the segment validation sees the true EL chain head.
48
+ const parentPayloadInput = payloadEnvelopes?.get(parentBlock.slot);
49
+ if (parentPayloadInput?.hasPayloadEnvelope()) {
50
+ currentExecHash = parentPayloadInput.getBlockHashHex();
51
+ }
52
+ // Track the execution hash before the last FULL advancement so we can recover
53
+ // if the next block reveals that envelope was orphaned.
54
+ let prevExecHash: string | null = currentExecHash;
55
+ // The slot whose envelope last advanced currentExecHash (for warning context).
56
+ let lastFullSlot: Slot | null = null;
57
+
58
+ for (let i = 0; i < blocks.length; i++) {
12
59
  const block = blocks[i].getBlock();
13
- const child = blocks[i + 1].getBlock();
14
- // If this block has a child in this chain segment, ensure that its parent root matches
15
- // the root of this block.
16
- if (
17
- !ssz.Root.equals(
18
- config.getForkTypes(block.message.slot).BeaconBlock.hashTreeRoot(block.message),
19
- child.message.parentRoot
20
- )
21
- ) {
22
- throw new BlockError(block, {code: BlockErrorCode.NON_LINEAR_PARENT_ROOTS});
60
+ const slot = block.message.slot;
61
+
62
+ if (i > 0) {
63
+ const prevBlock = blocks[i - 1].getBlock();
64
+ // Ensure parent root matches the previous block's root
65
+ if (
66
+ !ssz.Root.equals(
67
+ config.getForkTypes(prevBlock.message.slot).BeaconBlock.hashTreeRoot(prevBlock.message),
68
+ block.message.parentRoot
69
+ )
70
+ ) {
71
+ throw new BlockError(block, {code: BlockErrorCode.NON_LINEAR_PARENT_ROOTS});
72
+ }
73
+ // Ensure slots are strictly increasing
74
+ if (slot <= prevBlock.message.slot) {
75
+ throw new BlockError(block, {code: BlockErrorCode.NON_LINEAR_SLOTS});
76
+ }
23
77
  }
24
- // Ensure that the slots are strictly increasing throughout the chain segment.
25
- if (child.message.slot <= block.message.slot) {
26
- throw new BlockError(block, {code: BlockErrorCode.NON_LINEAR_SLOTS});
78
+
79
+ if (isGloasBeaconBlock(block.message) && currentExecHash !== null) {
80
+ // Verify the bid's parentBlockHash matches the tracked execution hash.
81
+ // This ensures the block was built on the correct FULL or EMPTY variant of its parent.
82
+ const bidParentHash = toRootHex(block.message.body.signedExecutionPayloadBid.message.parentBlockHash);
83
+ if (bidParentHash !== currentExecHash) {
84
+ // Maybe the previous slot's FULL envelope was orphaned — try falling back.
85
+ // If even prevExecHash doesn't match, the segment is non-linear.
86
+ if (bidParentHash !== prevExecHash) {
87
+ throw new BlockError(block, {
88
+ code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN,
89
+ parentRoot: toRootHex(block.message.parentRoot),
90
+ parentBlockHash: bidParentHash,
91
+ });
92
+ }
93
+ if (lastFullSlot !== null && payloadEnvelopes !== null) {
94
+ const orphanedInput = payloadEnvelopes.get(lastFullSlot);
95
+ if (orphanedInput != null) {
96
+ warnings.push({slot: lastFullSlot, payloadEnvelopeInput: orphanedInput});
97
+ }
98
+ }
99
+ currentExecHash = prevExecHash;
100
+ }
101
+
102
+ const payloadInput = payloadEnvelopes?.get(slot) ?? null;
103
+ const payloadEnvelope = payloadInput?.hasPayloadEnvelope() ? payloadInput.getPayloadEnvelope() : null;
104
+ if (payloadEnvelope !== null) {
105
+ // Verify the envelope references this block's root
106
+ const blockRoot = toRootHex(config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block.message));
107
+ const envelopeBlockRoot = toRootHex(payloadEnvelope.message.beaconBlockRoot);
108
+ if (blockRoot !== envelopeBlockRoot) {
109
+ throw new BlockError(block, {
110
+ code: BlockErrorCode.ENVELOPE_BLOCK_ROOT_MISMATCH,
111
+ envelopeBlockRoot,
112
+ blockRoot,
113
+ });
114
+ }
115
+
116
+ // FULL variant: save state before advancing, then advance
117
+ prevExecHash = currentExecHash;
118
+ lastFullSlot = slot;
119
+ currentExecHash = toRootHex(payloadEnvelope.message.payload.blockHash);
120
+ }
121
+ // EMPTY variant: currentExecHash unchanged
27
122
  }
28
123
  }
124
+
125
+ return {warnings: warnings.length > 0 ? warnings : null};
29
126
  }