@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
@@ -1,6 +1,23 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
- import {ForkPostDeneb, ForkPostFulu, ForkPreFulu, isForkPostFulu} from "@lodestar/params";
3
- import {SignedBeaconBlock, Slot, deneb, fulu, phase0} from "@lodestar/types";
2
+ import {
3
+ ForkPostDeneb,
4
+ ForkPostFulu,
5
+ ForkPostGloas,
6
+ ForkPreFulu,
7
+ isForkPostFulu,
8
+ isForkPostGloas,
9
+ } from "@lodestar/params";
10
+ import {
11
+ DataColumnSidecar,
12
+ SignedBeaconBlock,
13
+ Slot,
14
+ deneb,
15
+ fulu,
16
+ gloas,
17
+ isGloasBeaconBlock,
18
+ isGloasDataColumnSidecar,
19
+ phase0,
20
+ } from "@lodestar/types";
4
21
  import {LodestarError, Logger, byteArrayEquals, fromHex, prettyPrintIndices, toRootHex} from "@lodestar/utils";
5
22
  import {
6
23
  BlockInputSource,
@@ -9,12 +26,18 @@ import {
9
26
  isBlockInputBlobs,
10
27
  isBlockInputColumns,
11
28
  } from "../../chain/blocks/blockInput/index.js";
29
+ import {PayloadEnvelopeInput} from "../../chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
30
+ import {PayloadEnvelopeInputSource} from "../../chain/blocks/payloadEnvelopeInput/types.js";
12
31
  import {SeenBlockInput} from "../../chain/seenCache/seenGossipBlockInput.js";
32
+ import {SeenPayloadEnvelopeInput} from "../../chain/seenCache/seenPayloadEnvelopeInput.js";
13
33
  import {validateBlockBlobSidecars} from "../../chain/validation/blobSidecar.js";
14
- import {validateFuluBlockDataColumnSidecars} from "../../chain/validation/dataColumnSidecar.js";
34
+ import {
35
+ validateFuluBlockDataColumnSidecars,
36
+ validateGloasBlockDataColumnSidecars,
37
+ } from "../../chain/validation/dataColumnSidecar.js";
15
38
  import {BeaconMetrics} from "../../metrics/metrics/beacon.js";
16
39
  import {INetwork} from "../../network/index.js";
17
- import {getBlobKzgCommitments} from "../../util/dataColumns.js";
40
+ import {CustodyConfig, getBlobKzgCommitments} from "../../util/dataColumns.js";
18
41
  import {PeerIdStr} from "../../util/peerId.js";
19
42
  import {WarnResult} from "../../util/wrapError.js";
20
43
 
@@ -22,12 +45,14 @@ export type DownloadByRangeRequests = {
22
45
  blocksRequest?: phase0.BeaconBlocksByRangeRequest;
23
46
  blobsRequest?: deneb.BlobSidecarsByRangeRequest;
24
47
  columnsRequest?: fulu.DataColumnSidecarsByRangeRequest;
48
+ envelopesRequest?: gloas.ExecutionPayloadEnvelopesByRangeRequest;
25
49
  };
26
50
 
27
51
  export type DownloadByRangeResponses = {
28
52
  blocks?: SignedBeaconBlock[];
29
53
  blobSidecars?: deneb.BlobSidecars;
30
- columnSidecars?: fulu.DataColumnSidecar[];
54
+ columnSidecars?: DataColumnSidecar[];
55
+ payloadEnvelopes?: gloas.SignedExecutionPayloadEnvelope[];
31
56
  };
32
57
 
33
58
  export type DownloadAndCacheByRangeProps = DownloadByRangeRequests & {
@@ -41,9 +66,17 @@ export type DownloadAndCacheByRangeProps = DownloadByRangeRequests & {
41
66
 
42
67
  export type CacheByRangeResponsesProps = {
43
68
  cache: SeenBlockInput;
69
+ seenPayloadEnvelopeInputCache: SeenPayloadEnvelopeInput;
44
70
  peerIdStr: string;
45
71
  responses: ValidatedResponses;
46
72
  batchBlocks: IBlockInput[];
73
+ /** Raw envelopes downloaded in this batch, keyed by slot (from downloadByRange return) */
74
+ downloadedPayloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null;
75
+ /** Envelopes already wrapped from previous partial downloads on this batch */
76
+ existingPayloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null;
77
+ /** Sampled/custody column indices for building PayloadEnvelopeInputs */
78
+ custodyConfig: Pick<CustodyConfig, "sampledColumns" | "custodyColumns">;
79
+ seenTimestampSec: number;
47
80
  };
48
81
 
49
82
  export type ValidatedBlock = {
@@ -58,7 +91,7 @@ export type ValidatedBlobSidecars = {
58
91
 
59
92
  export type ValidatedColumnSidecars = {
60
93
  blockRoot: Uint8Array;
61
- columnSidecars: fulu.DataColumnSidecar[];
94
+ columnSidecars: DataColumnSidecar[];
62
95
  };
63
96
 
64
97
  export type ValidatedResponses = {
@@ -72,12 +105,16 @@ export type ValidatedResponses = {
72
105
  */
73
106
  export function cacheByRangeResponses({
74
107
  cache,
108
+ seenPayloadEnvelopeInputCache,
75
109
  peerIdStr,
76
110
  responses,
77
111
  batchBlocks,
78
- }: CacheByRangeResponsesProps): IBlockInput[] {
112
+ downloadedPayloadEnvelopes,
113
+ existingPayloadEnvelopes,
114
+ custodyConfig,
115
+ seenTimestampSec,
116
+ }: CacheByRangeResponsesProps): {blocks: IBlockInput[]; payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null} {
79
117
  const source = BlockInputSource.byRange;
80
- const seenTimestampSec = Date.now() / 1000;
81
118
  const updatedBatchBlocks = new Map<Slot, IBlockInput>(batchBlocks.map((block) => [block.slot, block]));
82
119
 
83
120
  const blocks = responses.validatedBlocks ?? [];
@@ -149,16 +186,86 @@ export function cacheByRangeResponses({
149
186
  }
150
187
  }
151
188
 
189
+ // Seed seenPayloadEnvelopeInputCache for every gloas block in the batch, regardless of whether
190
+ // the peer returned its envelope. Without this, a block returned without its envelope would be
191
+ // imported with no cache entry, and later payload-by-root sync would throw
192
+ // "Missing PayloadEnvelopeInput for known block" (see issue #9306).
193
+ for (const blockInput of updatedBatchBlocks.values()) {
194
+ if (!blockInput.hasBlock() || !isForkPostGloas(blockInput.forkName)) continue;
195
+ seenPayloadEnvelopeInputCache.add({
196
+ blockRootHex: blockInput.blockRootHex,
197
+ block: blockInput.getBlock() as SignedBeaconBlock<ForkPostGloas>,
198
+ forkName: blockInput.forkName,
199
+ sampledColumns: custodyConfig.sampledColumns,
200
+ custodyColumns: custodyConfig.custodyColumns,
201
+ timeCreatedSec: seenTimestampSec,
202
+ });
203
+ }
204
+
205
+ let payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null =
206
+ existingPayloadEnvelopes !== null ? new Map(existingPayloadEnvelopes) : null;
207
+ if (downloadedPayloadEnvelopes !== null) {
208
+ payloadEnvelopes ??= new Map();
209
+ for (const [slot, envelope] of downloadedPayloadEnvelopes) {
210
+ const blockInput = updatedBatchBlocks.get(slot);
211
+ if (!blockInput?.hasBlock() || !isForkPostGloas(blockInput.forkName)) {
212
+ // No block to pair this envelope with; drop silently
213
+ continue;
214
+ }
215
+
216
+ const payloadInput = seenPayloadEnvelopeInputCache.get(blockInput.blockRootHex);
217
+ if (payloadInput === undefined) {
218
+ // Unreachable given the loop above seeded an entry for every gloas block in the batch.
219
+ continue;
220
+ }
221
+
222
+ if (!payloadInput.hasPayloadEnvelope()) {
223
+ payloadInput.addPayloadEnvelope({
224
+ envelope,
225
+ source: PayloadEnvelopeInputSource.byRange,
226
+ seenTimestampSec,
227
+ peerIdStr,
228
+ });
229
+ }
230
+
231
+ payloadEnvelopes.set(slot, payloadInput);
232
+ }
233
+ }
234
+
152
235
  for (const {blockRoot, columnSidecars} of responses.validatedColumnSidecars ?? []) {
153
- const dataSlot = columnSidecars.at(0)?.signedBlockHeader.message.slot;
154
- if (dataSlot === undefined) {
236
+ const firstColumn = columnSidecars[0];
237
+ if (!firstColumn) {
155
238
  throw new Error(
156
239
  `Coding Error: empty columnSidecars returned for blockRoot=${toRootHex(blockRoot)} from validation functions`
157
240
  );
158
241
  }
159
- const existing = updatedBatchBlocks.get(dataSlot);
242
+
160
243
  const blockRootHex = toRootHex(blockRoot);
161
244
 
245
+ if (isGloasDataColumnSidecar(firstColumn)) {
246
+ // Gloas columns are attached to the matching PayloadEnvelopeInput, NOT to IBlockInput.
247
+ // Gloas DataColumnSidecar has `slot` directly (no signedBlockHeader).
248
+ const dataSlot = firstColumn.slot;
249
+ const payloadInput = payloadEnvelopes?.get(dataSlot);
250
+ if (!payloadInput) {
251
+ // Should not happen: we built payloadInputs for all gloas blocks above
252
+ continue;
253
+ }
254
+ for (const columnSidecar of columnSidecars as gloas.DataColumnSidecar[]) {
255
+ payloadInput.addColumn({
256
+ columnSidecar,
257
+ seenTimestampSec,
258
+ peerIdStr,
259
+ source: PayloadEnvelopeInputSource.byRange,
260
+ });
261
+ }
262
+ continue;
263
+ }
264
+
265
+ const fuluColumns = columnSidecars as fulu.DataColumnSidecar[];
266
+ const dataSlot = fuluColumns[0].signedBlockHeader.message.slot;
267
+ const existing = updatedBatchBlocks.get(dataSlot);
268
+
162
269
  if (!existing) {
163
270
  throw new Error("Coding error: blockInput must exist when adding columns");
164
271
  }
@@ -172,7 +279,7 @@ export function cacheByRangeResponses({
172
279
  actual: existing.type,
173
280
  });
174
281
  }
175
- for (const columnSidecar of columnSidecars) {
282
+ for (const columnSidecar of fuluColumns) {
176
283
  // will throw if root hex does not match (meaning we are following the wrong chain)
177
284
  existing.addColumn(
178
285
  {
@@ -187,7 +294,7 @@ export function cacheByRangeResponses({
187
294
  }
188
295
  }
189
296
 
190
- return Array.from(updatedBatchBlocks.values());
297
+ return {blocks: Array.from(updatedBatchBlocks.values()), payloadEnvelopes};
191
298
  }
192
299
 
193
300
  export async function downloadByRange({
@@ -198,8 +305,14 @@ export async function downloadByRange({
198
305
  blocksRequest,
199
306
  blobsRequest,
200
307
  columnsRequest,
308
+ envelopesRequest,
201
309
  peerDasMetrics,
202
- }: DownloadAndCacheByRangeProps): Promise<WarnResult<ValidatedResponses, DownloadByRangeError>> {
310
+ }: DownloadAndCacheByRangeProps): Promise<
311
+ WarnResult<
312
+ {responses: ValidatedResponses; payloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null},
313
+ DownloadByRangeError
314
+ >
315
+ > {
203
316
  let response: DownloadByRangeResponses;
204
317
  try {
205
318
  response = await requestByRange({
@@ -208,6 +321,7 @@ export async function downloadByRange({
208
321
  blocksRequest,
209
322
  blobsRequest,
210
323
  columnsRequest,
324
+ envelopesRequest,
211
325
  });
212
326
  } catch (err) {
213
327
  throw new DownloadByRangeError({
@@ -217,17 +331,16 @@ export async function downloadByRange({
217
331
  });
218
332
  }
219
333
 
220
- const validated = await validateResponses({
334
+ return validateResponses({
221
335
  config,
222
336
  batchBlocks,
223
337
  blocksRequest,
224
338
  blobsRequest,
225
339
  columnsRequest,
340
+ envelopesRequest,
226
341
  peerDasMetrics,
227
342
  ...response,
228
343
  });
229
-
230
- return validated;
231
344
  }
232
345
 
233
346
  /**
@@ -239,13 +352,15 @@ export async function requestByRange({
239
352
  blocksRequest,
240
353
  blobsRequest,
241
354
  columnsRequest,
355
+ envelopesRequest,
242
356
  }: DownloadByRangeRequests & {
243
357
  network: INetwork;
244
358
  peerIdStr: PeerIdStr;
245
359
  }): Promise<DownloadByRangeResponses> {
246
360
  let blocks: undefined | SignedBeaconBlock[];
247
361
  let blobSidecars: undefined | deneb.BlobSidecars;
248
- let columnSidecars: undefined | fulu.DataColumnSidecar[];
362
+ let columnSidecars: undefined | DataColumnSidecar[];
363
+ const payloadEnvelopes: gloas.SignedExecutionPayloadEnvelope[] = [];
249
364
 
250
365
  const requests: Promise<unknown>[] = [];
251
366
 
@@ -253,6 +368,17 @@ export async function requestByRange({
253
368
  requests.push(
254
369
  network.sendBeaconBlocksByRange(peerIdStr, blocksRequest).then((blockResponse) => {
255
370
  blocks = blockResponse;
371
+ const firstBlock = blockResponse.at(0);
372
+ if (firstBlock && isGloasBeaconBlock(firstBlock.message)) {
373
+ return network
374
+ .sendExecutionPayloadEnvelopesByRoot(peerIdStr, [
375
+ firstBlock.message.body.signedExecutionPayloadBid.message.parentBlockRoot,
376
+ ])
377
+ .then((envelopeResponse) => {
378
+ payloadEnvelopes?.unshift(...envelopeResponse);
379
+ });
380
+ }
381
+ return undefined;
256
382
  })
257
383
  );
258
384
  }
@@ -268,7 +394,15 @@ export async function requestByRange({
268
394
  if (columnsRequest) {
269
395
  requests.push(
270
396
  network.sendDataColumnSidecarsByRange(peerIdStr, columnsRequest).then((columnResponse) => {
271
- columnSidecars = columnResponse as fulu.DataColumnSidecar[];
397
+ columnSidecars = columnResponse;
398
+ })
399
+ );
400
+ }
401
+
402
+ if (envelopesRequest) {
403
+ requests.push(
404
+ network.sendExecutionPayloadEnvelopesByRange(peerIdStr, envelopesRequest).then((envelopeResponse) => {
405
+ payloadEnvelopes?.push(...envelopeResponse);
272
406
  })
273
407
  );
274
408
  }
@@ -279,6 +413,7 @@ export async function requestByRange({
279
413
  blocks,
280
414
  blobSidecars,
281
415
  columnSidecars,
416
+ payloadEnvelopes,
282
417
  };
283
418
  }
284
419
 
@@ -291,16 +426,23 @@ export async function validateResponses({
291
426
  blocksRequest,
292
427
  blobsRequest,
293
428
  columnsRequest,
429
+ envelopesRequest,
294
430
  blocks,
295
431
  blobSidecars,
296
432
  columnSidecars,
433
+ payloadEnvelopes,
297
434
  peerDasMetrics,
298
435
  }: DownloadByRangeRequests &
299
436
  DownloadByRangeResponses & {
300
437
  config: ChainForkConfig;
301
438
  batchBlocks?: IBlockInput[];
302
439
  peerDasMetrics?: BeaconMetrics["peerDas"] | null;
303
- }): Promise<WarnResult<ValidatedResponses, DownloadByRangeError>> {
440
+ }): Promise<
441
+ WarnResult<
442
+ {responses: ValidatedResponses; payloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null},
443
+ DownloadByRangeError
444
+ >
445
+ > {
304
446
  // Blocks are always required for blob/column validation
305
447
  // If a blocksRequest is provided, blocks have just been downloaded
306
448
  // If no blocksRequest is provided, batchBlocks must have been provided from cache
@@ -326,8 +468,21 @@ export async function validateResponses({
326
468
  }
327
469
 
328
470
  const dataRequest = blobsRequest ?? columnsRequest;
471
+ if (!dataRequest && !envelopesRequest) {
472
+ return {result: {responses: validatedResponses, payloadEnvelopes: null}, warnings};
473
+ }
474
+
329
475
  if (!dataRequest) {
330
- return {result: validatedResponses, warnings};
476
+ // Only envelope validation needed
477
+ let validatedPayloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null = null;
478
+ if (envelopesRequest) {
479
+ validatedPayloadEnvelopes = validateEnvelopesByRangeResponse(
480
+ validatedResponses.validatedBlocks ?? [],
481
+ batchBlocks,
482
+ payloadEnvelopes ?? []
483
+ );
484
+ }
485
+ return {result: {responses: validatedResponses, payloadEnvelopes: validatedPayloadEnvelopes}, warnings};
331
486
  }
332
487
 
333
488
  const blocksForDataValidation = getBlocksForDataValidation(
@@ -385,7 +540,17 @@ export async function validateResponses({
385
540
  warnings = validatedColumnSidecarsResult.warnings;
386
541
  }
387
542
 
388
- return {result: validatedResponses, warnings};
543
+ // Validate envelopes if an envelopes request was made
544
+ let validatedPayloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null = null;
545
+ if (envelopesRequest) {
546
+ validatedPayloadEnvelopes = validateEnvelopesByRangeResponse(
547
+ validatedResponses.validatedBlocks ?? [],
548
+ batchBlocks,
549
+ payloadEnvelopes ?? []
550
+ );
551
+ }
552
+
553
+ return {result: {responses: validatedResponses, payloadEnvelopes: validatedPayloadEnvelopes}, warnings};
389
554
  }
390
555
 
391
556
  /**
@@ -615,19 +780,19 @@ export async function validateColumnsByRangeResponse(
615
780
  config: ChainForkConfig,
616
781
  request: fulu.DataColumnSidecarsByRangeRequest,
617
782
  blocks: ValidatedBlock[],
618
- columnSidecars: fulu.DataColumnSidecar[],
783
+ columnSidecars: DataColumnSidecar[],
619
784
  peerDasMetrics?: BeaconMetrics["peerDas"] | null
620
785
  ): Promise<WarnResult<ValidatedColumnSidecars[], DownloadByRangeError>> {
621
786
  const warnings: DownloadByRangeError[] = [];
622
787
 
623
- // TODO GLOAS: Extend by range column sync to support gloas.DataColumnSidecar and
624
- // validate against the block bid commitments instead of the fulu signed header shape
625
- const seenColumns = new Map<Slot, Map<number, fulu.DataColumnSidecar>>();
788
+ const seenColumns = new Map<Slot, Map<number, DataColumnSidecar>>();
626
789
  let currentSlot = -1;
627
790
  let currentIndex = -1;
628
791
  // Check for duplicates and order
629
792
  for (const columnSidecar of columnSidecars) {
630
- const slot = columnSidecar.signedBlockHeader.message.slot;
793
+ const slot = isGloasDataColumnSidecar(columnSidecar)
794
+ ? columnSidecar.slot
795
+ : columnSidecar.signedBlockHeader.message.slot;
631
796
  let seenSlotColumns = seenColumns.get(slot);
632
797
  if (!seenSlotColumns) {
633
798
  seenSlotColumns = new Map();
@@ -686,20 +851,20 @@ export async function validateColumnsByRangeResponse(
686
851
  const slot = block.message.slot;
687
852
  const rootHex = toRootHex(blockRoot);
688
853
  const forkName = config.getForkName(slot);
689
- const columnSidecarsMap: Map<number, fulu.DataColumnSidecar> = seenColumns.get(slot) ?? new Map();
854
+ const columnSidecarsMap: Map<number, DataColumnSidecar> = seenColumns.get(slot) ?? new Map();
690
855
  const columnSidecars = Array.from(columnSidecarsMap.values()).sort((a, b) => a.index - b.index);
691
856
 
692
857
  let blobCount: number;
693
858
  if (!isForkPostFulu(forkName)) {
694
- const dataSlot = columnSidecars.at(0)?.signedBlockHeader.message.slot;
695
859
  throw new DownloadByRangeError({
696
860
  code: DownloadByRangeErrorCode.MISMATCH_BLOCK_FORK,
697
861
  slot,
698
862
  blockFork: forkName,
699
- dataFork: dataSlot ? config.getForkName(dataSlot) : "unknown",
863
+ dataFork: "unknown",
700
864
  });
701
865
  }
702
- blobCount = getBlobKzgCommitments(forkName, block as SignedBeaconBlock<ForkPostFulu>).length;
866
+ const kzgCommitments = getBlobKzgCommitments(forkName, block as SignedBeaconBlock<ForkPostFulu>);
867
+ blobCount = kzgCommitments.length;
703
868
 
704
869
  if (columnSidecars.length === 0) {
705
870
  if (!blobCount) {
@@ -768,15 +933,25 @@ export async function validateColumnsByRangeResponse(
768
933
  );
769
934
  }
770
935
 
936
+ const validatePromise = isForkPostGloas(forkName)
937
+ ? validateGloasBlockDataColumnSidecars(
938
+ slot,
939
+ blockRoot,
940
+ kzgCommitments,
941
+ columnSidecars as gloas.DataColumnSidecar[],
942
+ peerDasMetrics
943
+ )
944
+ : validateFuluBlockDataColumnSidecars(
945
+ null, // do not pass chain here so we do not validate header signature
946
+ slot,
947
+ blockRoot,
948
+ blobCount,
949
+ columnSidecars as fulu.DataColumnSidecar[],
950
+ peerDasMetrics
951
+ );
952
+
771
953
  validationPromises.push(
772
- validateFuluBlockDataColumnSidecars(
773
- null, // do not pass chain here so we do not validate header signature
774
- slot,
775
- blockRoot,
776
- blobCount,
777
- columnSidecars,
778
- peerDasMetrics
779
- ).then(() => ({
954
+ validatePromise.then(() => ({
780
955
  blockRoot,
781
956
  columnSidecars,
782
957
  }))
@@ -882,6 +1057,9 @@ export enum DownloadByRangeErrorCode {
882
1057
  /** Cached block input type mismatches new data */
883
1058
  MISMATCH_BLOCK_FORK = "DOWNLOAD_BY_RANGE_ERROR_MISMATCH_BLOCK_FORK",
884
1059
  MISMATCH_BLOCK_INPUT_TYPE = "DOWNLOAD_BY_RANGE_ERROR_MISMATCH_BLOCK_INPUT_TYPE",
1060
+
1061
+ /** Envelope beaconBlockRoot does not match the block's root */
1062
+ INVALID_ENVELOPE_BEACON_BLOCK_ROOT = "DOWNLOAD_BY_RANGE_ERROR_INVALID_ENVELOPE_BEACON_BLOCK_ROOT",
885
1063
  }
886
1064
 
887
1065
  export type DownloadByRangeErrorType =
@@ -973,6 +1151,61 @@ export type DownloadByRangeErrorType =
973
1151
  blockRoot: string;
974
1152
  expected: DAType;
975
1153
  actual: DAType;
1154
+ }
1155
+ | {
1156
+ code: DownloadByRangeErrorCode.INVALID_ENVELOPE_BEACON_BLOCK_ROOT;
1157
+ slot: Slot;
1158
+ expected: string;
1159
+ actual: string;
976
1160
  };
977
1161
 
978
1162
  export class DownloadByRangeError extends LodestarError<DownloadByRangeErrorType> {}
1163
+
1164
+ /**
1165
+ * Validates SignedExecutionPayloadEnvelopes received for a range request.
1166
+ * For each envelope whose slot appears in the downloaded blocks, verifies that
1167
+ * envelope.message.beaconBlockRoot matches the corresponding block's root.
1168
+ * Envelopes for slots not in the batch (orphaned payloads) are silently ignored.
1169
+ */
1170
+ export function validateEnvelopesByRangeResponse(
1171
+ validatedBlocks: ValidatedBlock[],
1172
+ batchBlocks: IBlockInput[] | undefined,
1173
+ payloadEnvelopes: gloas.SignedExecutionPayloadEnvelope[]
1174
+ ): Map<Slot, gloas.SignedExecutionPayloadEnvelope> {
1175
+ // Build a map of slot -> blockRoot for all blocks in the batch
1176
+ const batchBlockRoots = new Map<Slot, Uint8Array>();
1177
+ if (batchBlocks) {
1178
+ for (const blockInput of batchBlocks) {
1179
+ batchBlockRoots.set(blockInput.slot, fromHex(blockInput.blockRootHex));
1180
+ }
1181
+ }
1182
+ for (const {block, blockRoot} of validatedBlocks) {
1183
+ batchBlockRoots.set(block.message.slot, blockRoot);
1184
+ }
1185
+
1186
+ const payloadEnvelopeMap = new Map<Slot, gloas.SignedExecutionPayloadEnvelope>();
1187
+
1188
+ for (const payloadEnvelope of payloadEnvelopes) {
1189
+ const slot = payloadEnvelope.message.payload.slotNumber;
1190
+ const batchBlockRoot = batchBlockRoots.get(slot);
1191
+
1192
+ // Envelopes for slots not in the batch are silently ignored (orphaned payloads or a parent payload)
1193
+ if (batchBlockRoot === undefined) {
1194
+ continue;
1195
+ }
1196
+
1197
+ // Verify beaconBlockRoot matches the block's root
1198
+ if (!byteArrayEquals(payloadEnvelope.message.beaconBlockRoot, batchBlockRoot)) {
1199
+ throw new DownloadByRangeError({
1200
+ code: DownloadByRangeErrorCode.INVALID_ENVELOPE_BEACON_BLOCK_ROOT,
1201
+ slot,
1202
+ expected: toRootHex(batchBlockRoot),
1203
+ actual: toRootHex(payloadEnvelope.message.beaconBlockRoot),
1204
+ });
1205
+ }
1206
+
1207
+ payloadEnvelopeMap.set(slot, payloadEnvelope);
1208
+ }
1209
+
1210
+ return payloadEnvelopeMap;
1211
+ }
@@ -1,6 +1,14 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {ChainForkConfig} from "@lodestar/config";
3
- import {ForkPostDeneb, ForkPostFulu, ForkPreFulu, isForkPostDeneb, isForkPostFulu} from "@lodestar/params";
3
+ import {
4
+ ForkPostDeneb,
5
+ ForkPostFulu,
6
+ ForkPostGloas,
7
+ ForkPreFulu,
8
+ isForkPostDeneb,
9
+ isForkPostFulu,
10
+ isForkPostGloas,
11
+ } from "@lodestar/params";
4
12
  import {BlobIndex, ColumnIndex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
5
13
  import {LodestarError, byteArrayEquals, fromHex, prettyPrintIndices, toHex, toRootHex} from "@lodestar/utils";
6
14
  import {isBlockInputBlobs, isBlockInputColumns} from "../../chain/blocks/blockInput/blockInput.js";
@@ -107,6 +115,17 @@ export async function downloadByRoot({
107
115
  });
108
116
  }
109
117
 
118
+ if (isForkPostGloas(blockInput.forkName)) {
119
+ chain.seenPayloadEnvelopeInputCache.add({
120
+ blockRootHex: rootHex,
121
+ block: blockInput.getBlock() as SignedBeaconBlock<ForkPostGloas>,
122
+ forkName: blockInput.forkName,
123
+ sampledColumns: chain.custodyConfig.sampledColumns,
124
+ custodyColumns: chain.custodyConfig.custodyColumns,
125
+ timeCreatedSec: Date.now() / 1000,
126
+ });
127
+ }
128
+
110
129
  const hasAllDataPreDownload = blockInput.hasBlockAndAllData();
111
130
 
112
131
  if (isBlockInputBlobs(blockInput) && !hasAllDataPreDownload) {
@@ -263,7 +282,10 @@ export async function fetchByRoot({
263
282
  blockRoot,
264
283
  });
265
284
  const forkName = config.getForkName(block.message.slot);
266
- if (isForkPostFulu(forkName)) {
285
+ if (isForkPostGloas(forkName)) {
286
+ // Post-gloas block sync only needs the block body. Payload columns stay on the
287
+ // payload/envelope path and are queued independently in the network processor.
288
+ } else if (isForkPostFulu(forkName)) {
267
289
  columnSidecarResult = await fetchAndValidateColumns({
268
290
  config,
269
291
  chain,
@@ -40,21 +40,6 @@ function addToDescendantBlocks(
40
40
  return descendantBlocks;
41
41
  }
42
42
 
43
- export function getDescendantBlocks(
44
- blockRootHex: RootHex,
45
- blocks: Map<RootHex, BlockInputSyncCacheItem>
46
- ): BlockInputSyncCacheItem[] {
47
- const descendantBlocks: BlockInputSyncCacheItem[] = [];
48
-
49
- for (const block of blocks.values()) {
50
- if ((isPendingBlockInput(block) ? block.blockInput.parentRootHex : undefined) === blockRootHex) {
51
- descendantBlocks.push(block);
52
- }
53
- }
54
-
55
- return descendantBlocks;
56
- }
57
-
58
43
  export type UnknownAndAncestorBlocks = {
59
44
  unknowns: BlockInputSyncCacheItem[];
60
45
  ancestors: PendingBlockInput[];
@@ -558,10 +558,11 @@ export function getBeaconBlockRootFromDataColumnSidecarSerialized(data: Uint8Arr
558
558
  * └─ ExecutionPayloadEnvelope (starts at byte 100):
559
559
  * ├─ 4 bytes: payload offset
560
560
  * ├─ 4 bytes: executionRequests offset
561
- * ├─ 8 bytes: builderIndex (offset 108-115)
562
- * ├─ 32 bytes: beaconBlockRoot (offset 116-147)
563
- * ├─ 8 bytes: slot (offset 148-155)
564
- * └─ 32 bytes: stateRoot (offset 156-187)
561
+ * ├─ 8 bytes: builderIndex (offset 108-115)
562
+ * ├─ 32 bytes: beaconBlockRoot (offset 116-147)
563
+ * ├─ 32 bytes: parentBeaconBlockRoot (offset 148-179) — new in Gloas alpha.6 (consensus-specs#5152)
564
+ * └─ variable: payload data (starts at envelope + 80)
565
+ * └─ ExecutionPayload fixed portion includes slotNumber at offset 532
565
566
  */
566
567
  const SIGNED_EXECUTION_PAYLOAD_ENVELOPE_MESSAGE_OFFSET = 4;
567
568
  const SIGNED_EXECUTION_PAYLOAD_ENVELOPE_SIGNATURE_SIZE = 96;
@@ -576,8 +577,27 @@ const BEACON_BLOCK_ROOT_OFFSET_IN_SIGNED_EXECUTION_PAYLOAD_ENVELOPE =
576
577
  EXECUTION_PAYLOAD_ENVELOPE_REQUESTS_OFFSET +
577
578
  EXECUTION_PAYLOAD_ENVELOPE_BUILDER_INDEX_SIZE; // 116
578
579
 
580
+ // Envelope fixed portion: payload_offset(4) + requests_offset(4) + builderIndex(8) + beaconBlockRoot(32) + parentBeaconBlockRoot(32) = 80
581
+ const EXECUTION_PAYLOAD_ENVELOPE_FIXED_SIZE =
582
+ EXECUTION_PAYLOAD_ENVELOPE_PAYLOAD_OFFSET +
583
+ EXECUTION_PAYLOAD_ENVELOPE_REQUESTS_OFFSET +
584
+ EXECUTION_PAYLOAD_ENVELOPE_BUILDER_INDEX_SIZE +
585
+ ROOT_SIZE +
586
+ ROOT_SIZE; // 80
587
+
588
+ // slotNumber offset within ExecutionPayload fixed portion:
589
+ // parentHash(32) + feeRecipient(20) + stateRoot(32) + receiptsRoot(32) + logsBloom(256) +
590
+ // prevRandao(32) + blockNumber(8) + gasLimit(8) + gasUsed(8) + timestamp(8) +
591
+ // extraData_offset(4) + baseFeePerGas(32) + blockHash(32) + transactions_offset(4) +
592
+ // withdrawals_offset(4) + blobGasUsed(8) + excessBlobGas(8) + blockAccessList_offset(4) = 532
593
+ const SLOT_NUMBER_OFFSET_IN_EXECUTION_PAYLOAD = 532;
594
+
595
+ // Payload data starts right after the envelope's fixed portion
596
+ const ENVELOPE_START_IN_SIGNED =
597
+ SIGNED_EXECUTION_PAYLOAD_ENVELOPE_MESSAGE_OFFSET + SIGNED_EXECUTION_PAYLOAD_ENVELOPE_SIGNATURE_SIZE; // 100
598
+
579
599
  const SLOT_OFFSET_IN_SIGNED_EXECUTION_PAYLOAD_ENVELOPE =
580
- BEACON_BLOCK_ROOT_OFFSET_IN_SIGNED_EXECUTION_PAYLOAD_ENVELOPE + ROOT_SIZE; // 148
600
+ ENVELOPE_START_IN_SIGNED + EXECUTION_PAYLOAD_ENVELOPE_FIXED_SIZE + SLOT_NUMBER_OFFSET_IN_EXECUTION_PAYLOAD; // 100 + 80 + 532 = 712
581
601
 
582
602
  export function getSlotFromExecutionPayloadEnvelopeSerialized(data: Uint8Array): Slot | null {
583
603
  if (data.length < SLOT_OFFSET_IN_SIGNED_EXECUTION_PAYLOAD_ENVELOPE + SLOT_SIZE) {