@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
@@ -2,7 +2,7 @@ import {routes} from "@lodestar/api";
2
2
  import {ProtoBlock} from "@lodestar/fork-choice";
3
3
  import {IBeaconStateView} from "@lodestar/state-transition";
4
4
  import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
5
- import {CheckpointHexPayload} from "../stateCache/types.js";
5
+ import {CheckpointHex} from "../stateCache/types.js";
6
6
 
7
7
  export enum RegenCaller {
8
8
  getDuties = "getDuties",
@@ -21,6 +21,7 @@ export enum RegenCaller {
21
21
  validateGossipAttestation = "validateGossipAttestation",
22
22
  validateGossipVoluntaryExit = "validateGossipVoluntaryExit",
23
23
  validateGossipExecutionPayloadBid = "validateGossipExecutionPayloadBid",
24
+ validateGossipProposerPreferences = "validateGossipProposerPreferences",
24
25
  onForkChoiceFinalized = "onForkChoiceFinalized",
25
26
  restApi = "restApi",
26
27
  }
@@ -40,20 +41,15 @@ export interface IStateRegenerator extends IStateRegeneratorInternal {
40
41
  dumpCacheSummary(): routes.lodestar.StateCacheItem[];
41
42
  getStateSync(stateRoot: RootHex): IBeaconStateView | null;
42
43
  getPreStateSync(block: BeaconBlock): IBeaconStateView | null;
43
- getCheckpointStateOrBytes(cp: CheckpointHexPayload): Promise<IBeaconStateView | Uint8Array | null>;
44
- getCheckpointStateSync(cp: CheckpointHexPayload): IBeaconStateView | null;
44
+ getCheckpointStateOrBytes(cp: CheckpointHex): Promise<IBeaconStateView | Uint8Array | null>;
45
+ getCheckpointStateSync(cp: CheckpointHex): IBeaconStateView | null;
45
46
  getClosestHeadState(head: ProtoBlock): IBeaconStateView | null;
46
47
  pruneOnCheckpoint(finalizedEpoch: Epoch, justifiedEpoch: Epoch, headStateRoot: RootHex): void;
47
48
  pruneOnFinalized(finalizedEpoch: Epoch): void;
48
- processBlockState(blockRootHex: RootHex, postState: IBeaconStateView): void;
49
- processPayloadState(payloadState: IBeaconStateView): void;
50
- /**
51
- * payloadPresent is true if this is payload state, false if block state.
52
- * payloadPresent is always true for pre-gloas.
53
- */
54
- addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView, payloadPresent: boolean): void;
49
+ processState(blockRootHex: RootHex, postState: IBeaconStateView): void;
50
+ addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView): void;
55
51
  updateHeadState(newHead: ProtoBlock, maybeHeadState: IBeaconStateView): void;
56
- updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch, payloadPresent: boolean): number | null;
52
+ updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null;
57
53
  }
58
54
 
59
55
  /**
@@ -1,11 +1,11 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
3
3
  import {IBeaconStateView, computeEpochAtSlot} from "@lodestar/state-transition";
4
- import {BeaconBlock, Epoch, RootHex, Slot, isGloasBeaconBlock, phase0} from "@lodestar/types";
4
+ import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
5
5
  import {Logger, toRootHex} from "@lodestar/utils";
6
6
  import {Metrics} from "../../metrics/index.js";
7
7
  import {JobItemQueue} from "../../util/queue/index.js";
8
- import {BlockStateCache, CheckpointHexPayload, CheckpointStateCache} from "../stateCache/types.js";
8
+ import {BlockStateCache, CheckpointHex, CheckpointStateCache} from "../stateCache/types.js";
9
9
  import {RegenError, RegenErrorCode} from "./errors.js";
10
10
  import {
11
11
  IStateRegenerator,
@@ -88,12 +88,7 @@ export class QueuedStateRegenerator implements IStateRegenerator {
88
88
  */
89
89
  getPreStateSync(block: BeaconBlock): IBeaconStateView | null {
90
90
  const parentRoot = toRootHex(block.parentRoot);
91
- const parentBlock = isGloasBeaconBlock(block)
92
- ? this.forkChoice.getBlockHexAndBlockHash(
93
- parentRoot,
94
- toRootHex(block.body.signedExecutionPayloadBid.message.parentBlockHash)
95
- )
96
- : this.forkChoice.getBlockHexDefaultStatus(parentRoot);
91
+ const parentBlock = this.forkChoice.getBlockHexDefaultStatus(parentRoot);
97
92
  if (!parentBlock) {
98
93
  throw new RegenError({
99
94
  code: RegenErrorCode.BLOCK_NOT_IN_FORKCHOICE,
@@ -125,14 +120,14 @@ export class QueuedStateRegenerator implements IStateRegenerator {
125
120
  return null;
126
121
  }
127
122
 
128
- async getCheckpointStateOrBytes(cp: CheckpointHexPayload): Promise<IBeaconStateView | Uint8Array | null> {
123
+ async getCheckpointStateOrBytes(cp: CheckpointHex): Promise<IBeaconStateView | Uint8Array | null> {
129
124
  return this.checkpointStateCache.getStateOrBytes(cp);
130
125
  }
131
126
 
132
127
  /**
133
128
  * Get checkpoint state from cache
134
129
  */
135
- getCheckpointStateSync(cp: CheckpointHexPayload): IBeaconStateView | null {
130
+ getCheckpointStateSync(cp: CheckpointHex): IBeaconStateView | null {
136
131
  return this.checkpointStateCache.get(cp);
137
132
  }
138
133
 
@@ -153,22 +148,14 @@ export class QueuedStateRegenerator implements IStateRegenerator {
153
148
  this.blockStateCache.deleteAllBeforeEpoch(finalizedEpoch);
154
149
  }
155
150
 
156
- processBlockState(blockRootHex: RootHex, postState: IBeaconStateView): void {
151
+ processState(blockRootHex: RootHex, postState: IBeaconStateView): void {
157
152
  this.blockStateCache.add(postState);
158
153
  this.checkpointStateCache.processState(blockRootHex, postState).catch((e) => {
159
154
  this.logger.debug("Error processing block state", {blockRootHex, slot: postState.slot}, e);
160
155
  });
161
156
  }
162
157
 
163
- /**
164
- * Process payload state for caching after importing execution payload.
165
- */
166
- processPayloadState(payloadState: IBeaconStateView): void {
167
- // Add payload state to block state cache (keyed by payload state root)
168
- this.blockStateCache.add(payloadState);
169
- }
170
-
171
- addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView, _payloadPresent: boolean): void {
158
+ addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView): void {
172
159
  this.checkpointStateCache.add(cp, item);
173
160
  }
174
161
 
@@ -205,7 +192,7 @@ export class QueuedStateRegenerator implements IStateRegenerator {
205
192
  }
206
193
  }
207
194
 
208
- updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch, _payloadPresent: boolean): number | null {
195
+ updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null {
209
196
  return this.checkpointStateCache.updatePreComputedCheckpoint(rootHex, epoch);
210
197
  }
211
198
 
@@ -9,7 +9,7 @@ import {
9
9
  computeEpochAtSlot,
10
10
  computeStartSlotAtEpoch,
11
11
  } from "@lodestar/state-transition";
12
- import {BeaconBlock, RootHex, SignedBeaconBlock, Slot, isGloasBeaconBlock} from "@lodestar/types";
12
+ import {BeaconBlock, RootHex, SignedBeaconBlock, Slot} from "@lodestar/types";
13
13
  import {Logger, fromHex, toRootHex} from "@lodestar/utils";
14
14
  import {IBeaconDb} from "../../db/index.js";
15
15
  import {Metrics} from "../../metrics/index.js";
@@ -57,12 +57,7 @@ export class StateRegenerator implements IStateRegeneratorInternal {
57
57
  regenCaller: RegenCaller
58
58
  ): Promise<IBeaconStateView> {
59
59
  const parentRoot = toRootHex(block.parentRoot);
60
- const parentBlock = isGloasBeaconBlock(block)
61
- ? this.modules.forkChoice.getBlockHexAndBlockHash(
62
- parentRoot,
63
- toRootHex(block.body.signedExecutionPayloadBid.message.parentBlockHash)
64
- )
65
- : this.modules.forkChoice.getBlockHexDefaultStatus(parentRoot);
60
+ const parentBlock = this.modules.forkChoice.getBlockHexDefaultStatus(parentRoot);
66
61
  if (!parentBlock) {
67
62
  throw new RegenError({
68
63
  code: RegenErrorCode.BLOCK_NOT_IN_FORKCHOICE,
@@ -332,11 +327,6 @@ async function processSlotsByCheckpoint(
332
327
  * emitting "checkpoint" events after every epoch processed.
333
328
  *
334
329
  * Stops processing after no more full epochs can be processed.
335
- *
336
- * Output state variant:
337
- * - Post-Gloas: If slots are processed, returns block state (payloadPresent=false).
338
- * If no slots processed, returns preState as-is (preserves variant).
339
- * - Pre-Gloas: Always payloadPresent=true (no block/payload distinction).
340
330
  */
341
331
  export async function processSlotsToNearestCheckpoint(
342
332
  modules: {
@@ -380,9 +370,6 @@ export async function processSlotsToNearestCheckpoint(
380
370
  // This may becomes the "official" checkpoint state if the 1st block of epoch is skipped
381
371
  const checkpointState = postState;
382
372
  const cp = getCheckpointFromState(checkpointState);
383
- // processSlots() only does epoch transitions, never processes payloads
384
- // Pre-Gloas: payloadPresent is always true (execution payload embedded in block)
385
- // Post-Gloas: result is a block state (payloadPresent=false)
386
373
  checkpointStateCache.add(cp, checkpointState);
387
374
  // consumers should not mutate state ever
388
375
  emitter?.emit(ChainEvent.checkpoint, cp, checkpointState);
@@ -5,3 +5,4 @@ export {SeenContributionAndProof} from "./seenCommitteeContribution.js";
5
5
  export {SeenExecutionPayloadBids} from "./seenExecutionPayloadBids.js";
6
6
  export {SeenBlockInput} from "./seenGossipBlockInput.js";
7
7
  export {PayloadEnvelopeInput, SeenPayloadEnvelopeInput} from "./seenPayloadEnvelopeInput.js";
8
+ export {SeenProposerPreferences} from "./seenProposerPreferences.js";
@@ -1,9 +1,12 @@
1
- import {CheckpointWithHex} from "@lodestar/fork-choice";
1
+ import {ChainForkConfig} from "@lodestar/config";
2
+ import {CheckpointWithHex, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
2
3
  import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
3
4
  import {RootHex} from "@lodestar/types";
4
5
  import {Logger} from "@lodestar/utils";
5
6
  import {Metrics} from "../../metrics/metrics.js";
7
+ import {IClock} from "../../util/clock.js";
6
8
  import {SerializedCache} from "../../util/serializedCache.js";
9
+ import {isDaOutOfRange} from "../blocks/blockInput/index.js";
7
10
  import {CreateFromBlockProps, PayloadEnvelopeInput} from "../blocks/payloadEnvelopeInput/index.js";
8
11
  import {ChainEvent, ChainEventEmitter} from "../emitter.js";
9
12
 
@@ -11,6 +14,9 @@ export type {PayloadEnvelopeInputState} from "../blocks/payloadEnvelopeInput/ind
11
14
  export {PayloadEnvelopeInput} from "../blocks/payloadEnvelopeInput/index.js";
12
15
 
13
16
  export type SeenPayloadEnvelopeInputModules = {
17
+ config: ChainForkConfig;
18
+ clock: IClock;
19
+ forkChoice: IForkChoice;
14
20
  chainEvents: ChainEventEmitter;
15
21
  signal: AbortSignal;
16
22
  serializedCache: SerializedCache;
@@ -21,10 +27,20 @@ export type SeenPayloadEnvelopeInputModules = {
21
27
  /**
22
28
  * Cache for tracking PayloadEnvelopeInput instances, keyed by beacon block root.
23
29
  *
24
- * Created during block import when a block is processed.
25
- * Pruned on finalization and after payload is written to DB.
30
+ * Created during block import when a block is processed. Two pruning paths:
31
+ * - `prepareNextSlot` calls `pruneBelow(headParentSlot)` every slot once the head we'll build
32
+ * on is known.
33
+ * - `onFinalized` calls `pruneBelow(finalizedSlot)` on every finalization for bulk cleanup.
34
+ *
35
+ * Steady state (linear chain, healthy progression): the cache holds ~2 entries — the head
36
+ * (parent for next-slot production) and its parent (proposer-boost-reorg fallback). It can
37
+ * transiently hold more during forks, range-sync bursts, or when `prepareNextSlot` skips
38
+ * ticks; subsequent ticks settle it back.
26
39
  */
27
40
  export class SeenPayloadEnvelopeInput {
41
+ private readonly config: ChainForkConfig;
42
+ private readonly clock: IClock;
43
+ private readonly forkChoice: IForkChoice;
28
44
  private readonly chainEvents: ChainEventEmitter;
29
45
  private readonly signal: AbortSignal;
30
46
  private readonly serializedCache: SerializedCache;
@@ -32,7 +48,19 @@ export class SeenPayloadEnvelopeInput {
32
48
  private readonly logger?: Logger;
33
49
  private payloadInputs = new Map<RootHex, PayloadEnvelopeInput>();
34
50
 
35
- constructor({chainEvents, signal, serializedCache, metrics, logger}: SeenPayloadEnvelopeInputModules) {
51
+ constructor({
52
+ config,
53
+ clock,
54
+ forkChoice,
55
+ chainEvents,
56
+ signal,
57
+ serializedCache,
58
+ metrics,
59
+ logger,
60
+ }: SeenPayloadEnvelopeInputModules) {
61
+ this.config = config;
62
+ this.clock = clock;
63
+ this.forkChoice = forkChoice;
36
64
  this.chainEvents = chainEvents;
37
65
  this.signal = signal;
38
66
  this.serializedCache = serializedCache;
@@ -51,14 +79,13 @@ export class SeenPayloadEnvelopeInput {
51
79
  });
52
80
  }
53
81
 
54
- this.chainEvents.on(ChainEvent.forkChoiceFinalized, this.onFinalized);
82
+ this.chainEvents.on(ChainEvent.forkChoiceFinalized, this.pruneFinalized);
55
83
  this.signal.addEventListener("abort", () => {
56
- this.chainEvents.off(ChainEvent.forkChoiceFinalized, this.onFinalized);
84
+ this.chainEvents.off(ChainEvent.forkChoiceFinalized, this.pruneFinalized);
57
85
  });
58
86
  }
59
87
 
60
- private onFinalized = (checkpoint: CheckpointWithHex): void => {
61
- // Prune all entries with slot < finalized slot
88
+ private pruneFinalized = (checkpoint: CheckpointWithHex): void => {
62
89
  const finalizedSlot = computeStartSlotAtEpoch(checkpoint.epoch);
63
90
  let deletedCount = 0;
64
91
  for (const [, input] of this.payloadInputs) {
@@ -67,16 +94,32 @@ export class SeenPayloadEnvelopeInput {
67
94
  deletedCount++;
68
95
  }
69
96
  }
70
- this.logger?.debug("SeenPayloadEnvelopeInput.onFinalized deleted cached entries", {deletedCount});
97
+
98
+ this.logger?.debug("SeenPayloadEnvelopeInput.pruneFinalized deleted entries", {
99
+ finalizedSlot,
100
+ finalizedRoot: checkpoint.rootHex,
101
+ deletedCount,
102
+ });
71
103
  };
72
104
 
73
- add(props: CreateFromBlockProps): PayloadEnvelopeInput {
74
- if (this.payloadInputs.has(props.blockRootHex)) {
75
- throw new Error(`PayloadEnvelopeInput already exists for block ${props.blockRootHex}`);
105
+ add(props: Omit<CreateFromBlockProps, "daOutOfRange">): PayloadEnvelopeInput {
106
+ const existing = this.payloadInputs.get(props.blockRootHex);
107
+ if (existing !== undefined) {
108
+ this.logger?.verbose("SeenPayloadEnvelopeInput.add reused existing entry", {
109
+ slot: existing.slot,
110
+ root: props.blockRootHex,
111
+ });
112
+ return existing;
76
113
  }
77
- const input = PayloadEnvelopeInput.createFromBlock(props);
114
+ const daOutOfRange = isDaOutOfRange(this.config, props.forkName, props.block.message.slot, this.clock.currentEpoch);
115
+ const input = PayloadEnvelopeInput.createFromBlock({...props, daOutOfRange});
78
116
  this.payloadInputs.set(props.blockRootHex, input);
79
117
  this.metrics?.seenCache.payloadEnvelopeInput.created.inc();
118
+ this.logger?.verbose("SeenPayloadEnvelopeInput.add created new entry", {
119
+ slot: input.slot,
120
+ root: props.blockRootHex,
121
+ daOutOfRange,
122
+ });
80
123
  return input;
81
124
  }
82
125
 
@@ -88,17 +131,25 @@ export class SeenPayloadEnvelopeInput {
88
131
  return this.payloadInputs.get(blockRootHex)?.hasPayloadEnvelope() ?? false;
89
132
  }
90
133
 
91
- prune(blockRootHex: RootHex): void {
92
- const payloadInput = this.payloadInputs.get(blockRootHex);
93
- if (payloadInput) {
94
- this.evictPayloadInput(payloadInput);
95
- }
96
- }
97
-
98
134
  size(): number {
99
135
  return this.payloadInputs.size;
100
136
  }
101
137
 
138
+ pruneBelowParent(parentBlock: ProtoBlock): void {
139
+ for (const block of this.forkChoice.getAllAncestorBlocks(parentBlock.blockRoot, parentBlock.payloadStatus)) {
140
+ if (block.slot < parentBlock.slot) {
141
+ const input = this.payloadInputs.get(block.blockRoot);
142
+ if (input) {
143
+ this.evictPayloadInput(input);
144
+ this.logger?.verbose("SeenPayloadEnvelopeInput.pruneBelowParent deleted", {
145
+ slot: block.slot,
146
+ root: block.blockRoot,
147
+ });
148
+ }
149
+ }
150
+ }
151
+ }
152
+
102
153
  private evictPayloadInput(payloadInput: PayloadEnvelopeInput): void {
103
154
  this.serializedCache.delete(payloadInput.getSerializedCacheKeys());
104
155
  this.payloadInputs.delete(payloadInput.blockRootHex);
@@ -0,0 +1,32 @@
1
+ import {RootHex, Slot, ValidatorIndex} from "@lodestar/types";
2
+ import {MapDef} from "@lodestar/utils";
3
+
4
+ /**
5
+ * Tracks signed proposer preferences we've already seen per (dependent_root, proposal_slot, validator_index).
6
+ */
7
+ export class SeenProposerPreferences {
8
+ private readonly validatorByDependentRootBySlot = new MapDef<Slot, Map<RootHex, ValidatorIndex>>(
9
+ () => new Map<RootHex, ValidatorIndex>()
10
+ );
11
+
12
+ isKnown(dependentRoot: RootHex, proposalSlot: Slot, validatorIndex: ValidatorIndex): boolean {
13
+ return this.validatorByDependentRootBySlot.get(proposalSlot)?.get(dependentRoot) === validatorIndex;
14
+ }
15
+
16
+ add(dependentRoot: RootHex, proposalSlot: Slot, validatorIndex: ValidatorIndex): void {
17
+ this.validatorByDependentRootBySlot.getOrDefault(proposalSlot).set(dependentRoot, validatorIndex);
18
+ }
19
+
20
+ /**
21
+ * Entries are only load-bearing while `proposal_slot > current_slot`. Once the slot has
22
+ * passed the `[IGNORE] proposal_slot > current_slot` gossip rule takes over, so drop them
23
+ * on each slot tick.
24
+ */
25
+ prune(currentSlot: Slot): void {
26
+ for (const slot of this.validatorByDependentRootBySlot.keys()) {
27
+ if (slot < currentSlot) {
28
+ this.validatorByDependentRootBySlot.delete(slot);
29
+ }
30
+ }
31
+ }
32
+ }
@@ -9,7 +9,7 @@ import {IClock} from "../../util/clock.js";
9
9
  import {serializeState} from "../serializeState.js";
10
10
  import {CPStateDatastore, DatastoreKey} from "./datastore/index.js";
11
11
  import {MapTracker} from "./mapMetrics.js";
12
- import {BlockStateCache, CacheItemType, CheckpointHex, CheckpointHexPayload, CheckpointStateCache} from "./types.js";
12
+ import {BlockStateCache, CacheItemType, CheckpointHex, CheckpointStateCache} from "./types.js";
13
13
 
14
14
  export type PersistentCheckpointStateCacheOpts = {
15
15
  /** Keep max n state epochs in memory, persist the rest to disk */
@@ -226,7 +226,10 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
226
226
  }
227
227
  sszTimer?.();
228
228
  const timer = this.metrics?.cpStateCache.stateReloadDuration.startTimer();
229
- const newCachedState = seedState.loadOtherState(stateBytes, validatorsBytes);
229
+ // preload validators and balances for faster state transition
230
+ const newCachedState = seedState.loadOtherState(stateBytes, validatorsBytes, {
231
+ preloadValidatorsAndBalances: true,
232
+ });
230
233
  // hashTreeRoot() calls the commit() inside
231
234
  // there is no modification inside the state, it's just that we want to compute and cache all roots
232
235
  const stateRoot = toRootHex(newCachedState.hashTreeRoot());
@@ -843,19 +846,6 @@ export function toCheckpointHex(checkpoint: phase0.Checkpoint): CheckpointHex {
843
846
  };
844
847
  }
845
848
 
846
- /** TODO GLOAS: remove after rolling back regen dual-state changes */
847
- export function fcCheckpointToHexPayload(checkpoint: {
848
- epoch: Epoch;
849
- rootHex: RootHex;
850
- payloadStatus?: number;
851
- }): CheckpointHexPayload {
852
- return {
853
- epoch: checkpoint.epoch,
854
- rootHex: checkpoint.rootHex,
855
- payloadPresent: true,
856
- };
857
- }
858
-
859
849
  export function toCheckpointKey(cp: CheckpointHex): string {
860
850
  return `${cp.rootHex}:${cp.epoch}`;
861
851
  }
@@ -4,9 +4,6 @@ import {Epoch, RootHex, phase0} from "@lodestar/types";
4
4
 
5
5
  export type CheckpointHex = {epoch: Epoch; rootHex: RootHex};
6
6
 
7
- /** TODO GLOAS: payloadPresent is ignored — remove after rolling back regen dual-state changes */
8
- export type CheckpointHexPayload = {epoch: Epoch; rootHex: RootHex; payloadPresent: boolean};
9
-
10
7
  /**
11
8
  * Lodestar currently keeps two state caches around.
12
9
  *
@@ -90,6 +90,19 @@ async function validateAggregateAndProof(
90
90
  });
91
91
  }
92
92
 
93
+ // [REJECT] If `aggregate.data.index == 1` (payload present for a past
94
+ // block), the execution payload for `block` passes validation.
95
+ // [IGNORE] When `aggregate.data.index == 1` (payload present for a past block),
96
+ // the corresponding execution payload for `block` has been seen (a client MAY queue
97
+ // attestations for processing once the payload is retrieved and SHOULD request the
98
+ // payload envelope via `ExecutionPayloadEnvelopesByRoot`).
99
+ if (block !== null && attData.index === 1 && !chain.seenPayloadEnvelope(toRootHex(attData.beaconBlockRoot))) {
100
+ throw new AttestationError(GossipAction.IGNORE, {
101
+ code: AttestationErrorCode.EXECUTION_PAYLOAD_NOT_SEEN,
102
+ beaconBlockRoot: toRootHex(attData.beaconBlockRoot),
103
+ });
104
+ }
105
+
93
106
  // [REJECT] len(committee_indices) == 1, where committee_indices = get_committee_indices(aggregate)
94
107
  committeeIndex = (aggregate as electra.Attestation).committeeBits.getSingleTrueBit();
95
108
  if (committeeIndex === null) {
@@ -315,6 +315,19 @@ async function validateAttestationNoSignatureCheck(
315
315
  code: AttestationErrorCode.PREMATURELY_INDICATED_PAYLOAD_PRESENT,
316
316
  });
317
317
  }
318
+
319
+ // [REJECT] If `attestation.data.index == 1` (payload present for a past
320
+ // block), the execution payload for `block` passes validation.
321
+ // [IGNORE] When `attestation.data.index == 1` (payload present for a past block),
322
+ // the corresponding execution payload for `block` has been seen (a client MAY queue
323
+ // attestations for processing once the payload is retrieved and SHOULD request the
324
+ // payload envelope via `ExecutionPayloadEnvelopesByRoot`).
325
+ if (block !== null && attData.index === 1 && !chain.seenPayloadEnvelope(toRootHex(attData.beaconBlockRoot))) {
326
+ throw new AttestationError(GossipAction.IGNORE, {
327
+ code: AttestationErrorCode.EXECUTION_PAYLOAD_NOT_SEEN,
328
+ beaconBlockRoot: toRootHex(attData.beaconBlockRoot),
329
+ });
330
+ }
318
331
  } else {
319
332
  // [REJECT] attestation.data.index == 0
320
333
  if (attData.index !== 0) {
@@ -103,6 +103,7 @@ export async function validateGossipBlock(
103
103
  if (chain.forkChoice.getBlockHexAndBlockHash(parentRoot, parentBlockHashHex) === null) {
104
104
  throw new BlockGossipError(GossipAction.IGNORE, {
105
105
  code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN,
106
+ parentRoot,
106
107
  parentBlockHash: parentBlockHashHex,
107
108
  });
108
109
  }
@@ -1,5 +1,6 @@
1
1
  import {PublicKey} from "@chainsafe/blst";
2
2
  import {
3
+ computeEpochAtSlot,
3
4
  createSingleSignatureSetFromComponents,
4
5
  getExecutionPayloadBidSigningRoot,
5
6
  isActiveBuilder,
@@ -47,9 +48,12 @@ async function validateExecutionPayloadBid(
47
48
  });
48
49
  }
49
50
 
50
- // [IGNORE] the `SignedProposerPreferences` where `preferences.proposal_slot`
51
- // is equal to `bid.slot` has been seen.
52
- // TODO GLOAS: Implement this along with proposer preference
51
+ // [IGNORE] A `SignedProposerPreferences` matching `bid.slot` and the bid's branch has been
52
+ // seen i.e. `proposal_slot == bid.slot` AND `dependent_root ==
53
+ // get_proposer_dependent_root(parent_state, compute_epoch_at_slot(bid.slot))`,
54
+ // where `parent_state` is the post-state of `bid.parent_block_root`.
55
+ // This is the message referenced as `proposer_preferences` in the following REJECT rules.
56
+ // TODO GLOAS: Implement once a ProposerPreferencesPool exists.
53
57
 
54
58
  // [REJECT] `bid.builder_index` is a valid/active builder index -- i.e.
55
59
  // `is_active_builder(state, bid.builder_index)` returns `True`.
@@ -70,11 +74,24 @@ async function validateExecutionPayloadBid(
70
74
  });
71
75
  }
72
76
 
73
- // [REJECT] `bid.fee_recipient` matches the `fee_recipient` from the proposer's
74
- // `SignedProposerPreferences` associated with `bid.slot`.
75
- // [REJECT] `bid.gas_limit` matches the `gas_limit` from the proposer's
76
- // `SignedProposerPreferences` associated with `bid.slot`.
77
- // TODO GLOAS: Implement this along with proposer preference
77
+ // [REJECT] `bid.fee_recipient == proposer_preferences.fee_recipient`.
78
+ // [REJECT] `bid.gas_limit == proposer_preferences.gas_limit`.
79
+ // Both compared against the matching `proposer_preferences` defined above (same branch
80
+ // via dependent_root, same proposal_slot).
81
+ // TODO GLOAS: Implement once a ProposerPreferencesPool exists.
82
+
83
+ // [REJECT] The length of KZG commitments is less than or equal to the limitation defined in the
84
+ // consensus layer -- i.e. validate that
85
+ // `len(bid.blob_kzg_commitments) <= get_blob_parameters(compute_epoch_at_slot(bid.slot)).max_blobs_per_block`.
86
+ const blobKzgCommitmentsLen = bid.blobKzgCommitments.length;
87
+ const maxBlobsPerBlock = chain.config.getMaxBlobsPerBlock(computeEpochAtSlot(bid.slot));
88
+ if (blobKzgCommitmentsLen > maxBlobsPerBlock) {
89
+ throw new ExecutionPayloadBidError(GossipAction.REJECT, {
90
+ code: ExecutionPayloadBidErrorCode.TOO_MANY_KZG_COMMITMENTS,
91
+ blobKzgCommitmentsLen,
92
+ commitmentLimit: maxBlobsPerBlock,
93
+ });
94
+ }
78
95
 
79
96
  // [IGNORE] this is the first signed bid seen with a valid signature from the given builder for this slot.
80
97
  if (chain.seenExecutionPayloadBids.isKnown(bid.slot, bid.builderIndex)) {
@@ -4,8 +4,8 @@ import {
4
4
  getExecutionPayloadEnvelopeSignatureSet,
5
5
  isStatePostGloas,
6
6
  } from "@lodestar/state-transition";
7
- import {gloas} from "@lodestar/types";
8
- import {toRootHex} from "@lodestar/utils";
7
+ import {gloas, ssz} from "@lodestar/types";
8
+ import {byteArrayEquals, toRootHex} from "@lodestar/utils";
9
9
  import {ExecutionPayloadEnvelopeError, ExecutionPayloadEnvelopeErrorCode, GossipAction} from "../errors/index.js";
10
10
  import {IBeaconChain} from "../index.js";
11
11
  import {RegenCaller} from "../regen/index.js";
@@ -32,7 +32,7 @@ async function validateExecutionPayloadEnvelope(
32
32
  const {payload} = envelope;
33
33
  const blockRootHex = toRootHex(envelope.beaconBlockRoot);
34
34
 
35
- // [IGNORE] The envelope's block root `envelope.block_root` has been seen (via
35
+ // [IGNORE] The envelope's block root `envelope.beacon_block_root` has been seen (via
36
36
  // gossip or non-gossip sources) (a client MAY queue payload for processing once
37
37
  // the block is retrieved).
38
38
  // TODO GLOAS: Need to review this, we should queue the envelope for later
@@ -53,7 +53,7 @@ async function validateExecutionPayloadEnvelope(
53
53
  throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
54
54
  code: ExecutionPayloadEnvelopeErrorCode.ENVELOPE_ALREADY_KNOWN,
55
55
  blockRoot: blockRootHex,
56
- slot: envelope.slot,
56
+ slot: payload.slotNumber,
57
57
  });
58
58
  }
59
59
 
@@ -65,13 +65,13 @@ async function validateExecutionPayloadEnvelope(
65
65
  });
66
66
  }
67
67
 
68
- // [IGNORE] The envelope is from a slot greater than or equal to the latest finalized slot -- i.e. validate that `envelope.slot >= compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)`
68
+ // [IGNORE] The envelope is from a slot greater than or equal to the latest finalized slot -- i.e. validate that `payload.slotNumber >= compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)`
69
69
  const finalizedCheckpoint = chain.forkChoice.getFinalizedCheckpoint();
70
70
  const finalizedSlot = computeStartSlotAtEpoch(finalizedCheckpoint.epoch);
71
- if (envelope.slot < finalizedSlot) {
71
+ if (payload.slotNumber < finalizedSlot) {
72
72
  throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
73
73
  code: ExecutionPayloadEnvelopeErrorCode.BELONG_TO_FINALIZED_BLOCK,
74
- envelopeSlot: envelope.slot,
74
+ envelopeSlot: payload.slotNumber,
75
75
  finalizedSlot,
76
76
  });
77
77
  }
@@ -80,11 +80,11 @@ async function validateExecutionPayloadEnvelope(
80
80
  // TODO GLOAS: implement this. Technically if we cannot get proto block from fork choice,
81
81
  // it is possible that the block didn't pass the validation
82
82
 
83
- // [REJECT] `block.slot` equals `envelope.slot`.
84
- if (block.slot !== envelope.slot) {
83
+ // [REJECT] `block.slot` equals `payload.slotNumber`.
84
+ if (block.slot !== payload.slotNumber) {
85
85
  throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
86
86
  code: ExecutionPayloadEnvelopeErrorCode.SLOT_MISMATCH,
87
- envelopeSlot: envelope.slot,
87
+ envelopeSlot: payload.slotNumber,
88
88
  blockSlot: block.slot,
89
89
  });
90
90
  }
@@ -107,14 +107,24 @@ async function validateExecutionPayloadEnvelope(
107
107
  });
108
108
  }
109
109
 
110
- // Get the post block state which is the pre-payload state to verify the builder's signature.
110
+ // [REJECT] `hash_tree_root(envelope.execution_requests) == bid.execution_requests_root`
111
+ const requestsRoot = ssz.electra.ExecutionRequests.hashTreeRoot(envelope.executionRequests);
112
+ if (!byteArrayEquals(requestsRoot, payloadInput.getBid().executionRequestsRoot)) {
113
+ throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
114
+ code: ExecutionPayloadEnvelopeErrorCode.EXECUTION_REQUESTS_ROOT_MISMATCH,
115
+ envelopeRequestsRoot: toRootHex(requestsRoot),
116
+ bidRequestsRoot: toRootHex(payloadInput.getBid().executionRequestsRoot),
117
+ });
118
+ }
119
+
120
+ // Get the block state to verify the builder's signature.
111
121
  const blockState = await chain.regen
112
122
  .getState(block.stateRoot, RegenCaller.validateGossipPayloadEnvelope)
113
123
  .catch(() => {
114
124
  throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
115
125
  code: ExecutionPayloadEnvelopeErrorCode.UNKNOWN_BLOCK_STATE,
116
126
  blockRoot: blockRootHex,
117
- slot: envelope.slot,
127
+ slot: payload.slotNumber,
118
128
  });
119
129
  });
120
130
  if (!isStatePostGloas(blockState)) {
@@ -18,7 +18,8 @@ export async function validateApiPayloadAttestationMessage(
18
18
  chain: IBeaconChain,
19
19
  payloadAttestationMessage: gloas.PayloadAttestationMessage
20
20
  ): Promise<PayloadAttestationValidationResult> {
21
- return validatePayloadAttestationMessage(chain, payloadAttestationMessage);
21
+ const prioritizeBls = true;
22
+ return validatePayloadAttestationMessage(chain, payloadAttestationMessage, prioritizeBls);
22
23
  }
23
24
 
24
25
  export async function validateGossipPayloadAttestationMessage(
@@ -30,7 +31,8 @@ export async function validateGossipPayloadAttestationMessage(
30
31
 
31
32
  async function validatePayloadAttestationMessage(
32
33
  chain: IBeaconChain,
33
- payloadAttestationMessage: gloas.PayloadAttestationMessage
34
+ payloadAttestationMessage: gloas.PayloadAttestationMessage,
35
+ prioritizeBls = false
34
36
  ): Promise<PayloadAttestationValidationResult> {
35
37
  const {data, validatorIndex} = payloadAttestationMessage;
36
38
  const epoch = computeEpochAtSlot(data.slot);
@@ -102,7 +104,7 @@ async function validatePayloadAttestationMessage(
102
104
  payloadAttestationMessage.signature
103
105
  );
104
106
 
105
- if (!(await chain.bls.verifySignatureSets([signatureSet]))) {
107
+ if (!(await chain.bls.verifySignatureSets([signatureSet], {batchable: true, priority: prioritizeBls}))) {
106
108
  throw new PayloadAttestationError(GossipAction.REJECT, {
107
109
  code: PayloadAttestationErrorCode.INVALID_SIGNATURE,
108
110
  });