@lodestar/beacon-node 1.42.0-dev.04e52d162f → 1.42.0-dev.1e596a7422

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 (294) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +24 -12
  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 +4 -0
  6. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  7. package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
  8. package/lib/api/impl/beacon/state/index.js +13 -10
  9. package/lib/api/impl/beacon/state/index.js.map +1 -1
  10. package/lib/api/impl/debug/index.js.map +1 -1
  11. package/lib/api/impl/lodestar/index.d.ts.map +1 -1
  12. package/lib/api/impl/lodestar/index.js +4 -0
  13. package/lib/api/impl/lodestar/index.js.map +1 -1
  14. package/lib/api/impl/validator/index.d.ts.map +1 -1
  15. package/lib/api/impl/validator/index.js +9 -3
  16. package/lib/api/impl/validator/index.js.map +1 -1
  17. package/lib/chain/ColumnReconstructionTracker.d.ts +2 -1
  18. package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
  19. package/lib/chain/ColumnReconstructionTracker.js +5 -5
  20. package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
  21. package/lib/chain/GetBlobsTracker.d.ts +2 -1
  22. package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
  23. package/lib/chain/GetBlobsTracker.js +14 -12
  24. package/lib/chain/GetBlobsTracker.js.map +1 -1
  25. package/lib/chain/blocks/blockInput/blockInput.d.ts +5 -5
  26. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  27. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  28. package/lib/chain/blocks/blockInput/types.d.ts +4 -4
  29. package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
  30. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  31. package/lib/chain/blocks/importBlock.js +19 -5
  32. package/lib/chain/blocks/importBlock.js.map +1 -1
  33. package/lib/chain/blocks/importExecutionPayload.d.ts +10 -8
  34. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  35. package/lib/chain/blocks/importExecutionPayload.js +67 -39
  36. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  37. package/lib/chain/blocks/index.js +1 -1
  38. package/lib/chain/blocks/index.js.map +1 -1
  39. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +14 -6
  40. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  41. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +33 -2
  42. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  43. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +2 -1
  44. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  45. package/lib/chain/blocks/types.d.ts +3 -3
  46. package/lib/chain/blocks/types.d.ts.map +1 -1
  47. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  48. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +3 -2
  49. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  50. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  51. package/lib/chain/blocks/verifyBlocksSignatures.js +4 -2
  52. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  53. package/lib/chain/chain.d.ts +3 -2
  54. package/lib/chain/chain.d.ts.map +1 -1
  55. package/lib/chain/chain.js +68 -28
  56. package/lib/chain/chain.js.map +1 -1
  57. package/lib/chain/emitter.d.ts +29 -7
  58. package/lib/chain/emitter.d.ts.map +1 -1
  59. package/lib/chain/emitter.js +12 -3
  60. package/lib/chain/emitter.js.map +1 -1
  61. package/lib/chain/errors/blockError.d.ts +11 -1
  62. package/lib/chain/errors/blockError.d.ts.map +1 -1
  63. package/lib/chain/errors/blockError.js +4 -0
  64. package/lib/chain/errors/blockError.js.map +1 -1
  65. package/lib/chain/errors/dataColumnSidecarError.d.ts +31 -1
  66. package/lib/chain/errors/dataColumnSidecarError.d.ts.map +1 -1
  67. package/lib/chain/errors/dataColumnSidecarError.js +7 -0
  68. package/lib/chain/errors/dataColumnSidecarError.js.map +1 -1
  69. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  70. package/lib/chain/forkChoice/index.js +10 -8
  71. package/lib/chain/forkChoice/index.js.map +1 -1
  72. package/lib/chain/interface.d.ts +4 -2
  73. package/lib/chain/interface.d.ts.map +1 -1
  74. package/lib/chain/lightClient/index.d.ts +2 -2
  75. package/lib/chain/lightClient/index.d.ts.map +1 -1
  76. package/lib/chain/lightClient/index.js +7 -0
  77. package/lib/chain/lightClient/index.js.map +1 -1
  78. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  79. package/lib/chain/opPools/aggregatedAttestationPool.js +5 -2
  80. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  81. package/lib/chain/opPools/executionPayloadBidPool.d.ts +2 -2
  82. package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -1
  83. package/lib/chain/opPools/executionPayloadBidPool.js +2 -2
  84. package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -1
  85. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  86. package/lib/chain/prepareNextSlot.js +7 -1
  87. package/lib/chain/prepareNextSlot.js.map +1 -1
  88. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +3 -3
  89. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  90. package/lib/chain/produceBlock/computeNewStateRoot.js +8 -8
  91. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  92. package/lib/chain/produceBlock/produceBlockBody.d.ts +5 -5
  93. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  94. package/lib/chain/produceBlock/produceBlockBody.js +23 -4
  95. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  96. package/lib/chain/seenCache/seenGossipBlockInput.d.ts +1 -1
  97. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  98. package/lib/chain/seenCache/seenGossipBlockInput.js +2 -2
  99. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  100. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +1 -1
  101. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  102. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +2 -2
  103. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  104. package/lib/chain/validation/block.d.ts.map +1 -1
  105. package/lib/chain/validation/block.js +27 -5
  106. package/lib/chain/validation/block.js.map +1 -1
  107. package/lib/chain/validation/dataColumnSidecar.d.ts +11 -4
  108. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  109. package/lib/chain/validation/dataColumnSidecar.js +184 -5
  110. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  111. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  112. package/lib/chain/validation/executionPayloadBid.js +7 -4
  113. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  114. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  115. package/lib/chain/validation/executionPayloadEnvelope.js +6 -1
  116. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  117. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  118. package/lib/chain/validation/payloadAttestationMessage.js +4 -1
  119. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  120. package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
  121. package/lib/chain/validation/syncCommittee.js +4 -0
  122. package/lib/chain/validation/syncCommittee.js.map +1 -1
  123. package/lib/chain/validation/syncCommitteeContributionAndProof.js +4 -1
  124. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  125. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  126. package/lib/chain/validatorMonitor.js +3 -3
  127. package/lib/chain/validatorMonitor.js.map +1 -1
  128. package/lib/db/buckets.d.ts +2 -2
  129. package/lib/db/buckets.d.ts.map +1 -1
  130. package/lib/db/buckets.js +2 -2
  131. package/lib/db/buckets.js.map +1 -1
  132. package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
  133. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  134. package/lib/db/repositories/dataColumnSidecar.d.ts.map +1 -1
  135. package/lib/db/repositories/dataColumnSidecar.js +4 -2
  136. package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
  137. package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
  138. package/lib/db/repositories/dataColumnSidecarArchive.js +4 -2
  139. package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
  140. package/lib/metrics/metrics/lodestar.d.ts +20 -0
  141. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  142. package/lib/metrics/metrics/lodestar.js +33 -0
  143. package/lib/metrics/metrics/lodestar.js.map +1 -1
  144. package/lib/network/interface.d.ts +3 -2
  145. package/lib/network/interface.d.ts.map +1 -1
  146. package/lib/network/libp2p/index.d.ts.map +1 -1
  147. package/lib/network/libp2p/index.js +19 -13
  148. package/lib/network/libp2p/index.js.map +1 -1
  149. package/lib/network/network.d.ts +3 -2
  150. package/lib/network/network.d.ts.map +1 -1
  151. package/lib/network/network.js +3 -0
  152. package/lib/network/network.js.map +1 -1
  153. package/lib/network/options.d.ts.map +1 -1
  154. package/lib/network/options.js +7 -2
  155. package/lib/network/options.js.map +1 -1
  156. package/lib/network/processor/extractSlotRootFns.d.ts +1 -1
  157. package/lib/network/processor/extractSlotRootFns.d.ts.map +1 -1
  158. package/lib/network/processor/extractSlotRootFns.js +25 -5
  159. package/lib/network/processor/extractSlotRootFns.js.map +1 -1
  160. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  161. package/lib/network/processor/gossipHandlers.js +260 -73
  162. package/lib/network/processor/gossipHandlers.js.map +1 -1
  163. package/lib/network/processor/index.d.ts +11 -1
  164. package/lib/network/processor/index.d.ts.map +1 -1
  165. package/lib/network/processor/index.js +234 -22
  166. package/lib/network/processor/index.js.map +1 -1
  167. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  168. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +2 -1
  169. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  170. package/lib/network/reqresp/handlers/beaconBlocksByRoot.d.ts.map +1 -1
  171. package/lib/network/reqresp/handlers/beaconBlocksByRoot.js +2 -0
  172. package/lib/network/reqresp/handlers/beaconBlocksByRoot.js.map +1 -1
  173. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts +2 -2
  174. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
  175. package/lib/network/reqresp/handlers/blobSidecarsByRange.js +7 -3
  176. package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
  177. package/lib/network/reqresp/handlers/blobSidecarsByRoot.d.ts.map +1 -1
  178. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js +6 -0
  179. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js.map +1 -1
  180. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts +2 -2
  181. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  182. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +7 -3
  183. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  184. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
  185. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +2 -1
  186. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
  187. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -1
  188. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +3 -8
  189. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
  190. package/lib/network/reqresp/types.d.ts +3 -3
  191. package/lib/network/reqresp/types.d.ts.map +1 -1
  192. package/lib/network/reqresp/types.js +9 -3
  193. package/lib/network/reqresp/types.js.map +1 -1
  194. package/lib/node/nodejs.d.ts.map +1 -1
  195. package/lib/node/nodejs.js +4 -1
  196. package/lib/node/nodejs.js.map +1 -1
  197. package/lib/node/notifier.d.ts.map +1 -1
  198. package/lib/node/notifier.js +2 -2
  199. package/lib/node/notifier.js.map +1 -1
  200. package/lib/sync/unknownBlock.js +2 -2
  201. package/lib/sync/unknownBlock.js.map +1 -1
  202. package/lib/sync/utils/downloadByRange.d.ts +3 -3
  203. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  204. package/lib/sync/utils/downloadByRange.js +4 -2
  205. package/lib/sync/utils/downloadByRange.js.map +1 -1
  206. package/lib/sync/utils/downloadByRoot.d.ts +3 -3
  207. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  208. package/lib/sync/utils/downloadByRoot.js +10 -5
  209. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  210. package/lib/util/blobs.d.ts +3 -3
  211. package/lib/util/blobs.d.ts.map +1 -1
  212. package/lib/util/blobs.js +21 -10
  213. package/lib/util/blobs.js.map +1 -1
  214. package/lib/util/dataColumns.d.ts +18 -11
  215. package/lib/util/dataColumns.d.ts.map +1 -1
  216. package/lib/util/dataColumns.js +51 -17
  217. package/lib/util/dataColumns.js.map +1 -1
  218. package/lib/util/execution.d.ts +6 -2
  219. package/lib/util/execution.d.ts.map +1 -1
  220. package/lib/util/execution.js +49 -25
  221. package/lib/util/execution.js.map +1 -1
  222. package/lib/util/sszBytes.d.ts +25 -1
  223. package/lib/util/sszBytes.d.ts.map +1 -1
  224. package/lib/util/sszBytes.js +189 -2
  225. package/lib/util/sszBytes.js.map +1 -1
  226. package/package.json +15 -15
  227. package/src/api/impl/beacon/blocks/index.ts +32 -15
  228. package/src/api/impl/beacon/pool/index.ts +4 -0
  229. package/src/api/impl/beacon/state/index.ts +15 -15
  230. package/src/api/impl/debug/index.ts +2 -2
  231. package/src/api/impl/lodestar/index.ts +4 -0
  232. package/src/api/impl/validator/index.ts +9 -2
  233. package/src/chain/ColumnReconstructionTracker.ts +6 -5
  234. package/src/chain/GetBlobsTracker.ts +14 -12
  235. package/src/chain/blocks/blockInput/blockInput.ts +8 -8
  236. package/src/chain/blocks/blockInput/types.ts +4 -4
  237. package/src/chain/blocks/importBlock.ts +29 -8
  238. package/src/chain/blocks/importExecutionPayload.ts +72 -42
  239. package/src/chain/blocks/index.ts +1 -1
  240. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +53 -12
  241. package/src/chain/blocks/payloadEnvelopeInput/types.ts +2 -1
  242. package/src/chain/blocks/types.ts +3 -3
  243. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +2 -1
  244. package/src/chain/blocks/verifyBlocksSignatures.ts +9 -2
  245. package/src/chain/chain.ts +77 -32
  246. package/src/chain/emitter.ts +25 -7
  247. package/src/chain/errors/blockError.ts +7 -1
  248. package/src/chain/errors/dataColumnSidecarError.ts +32 -1
  249. package/src/chain/forkChoice/index.ts +11 -8
  250. package/src/chain/interface.ts +4 -2
  251. package/src/chain/lightClient/index.ts +15 -3
  252. package/src/chain/opPools/aggregatedAttestationPool.ts +6 -1
  253. package/src/chain/opPools/executionPayloadBidPool.ts +3 -3
  254. package/src/chain/prepareNextSlot.ts +8 -0
  255. package/src/chain/produceBlock/computeNewStateRoot.ts +11 -10
  256. package/src/chain/produceBlock/produceBlockBody.ts +40 -10
  257. package/src/chain/seenCache/seenGossipBlockInput.ts +2 -2
  258. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +2 -2
  259. package/src/chain/validation/block.ts +30 -7
  260. package/src/chain/validation/dataColumnSidecar.ts +230 -7
  261. package/src/chain/validation/executionPayloadBid.ts +7 -3
  262. package/src/chain/validation/executionPayloadEnvelope.ts +10 -1
  263. package/src/chain/validation/payloadAttestationMessage.ts +4 -0
  264. package/src/chain/validation/syncCommittee.ts +5 -1
  265. package/src/chain/validation/syncCommitteeContributionAndProof.ts +5 -1
  266. package/src/chain/validatorMonitor.ts +3 -2
  267. package/src/db/buckets.ts +2 -2
  268. package/src/db/repositories/dataColumnSidecar.ts +4 -2
  269. package/src/db/repositories/dataColumnSidecarArchive.ts +4 -2
  270. package/src/metrics/metrics/lodestar.ts +34 -0
  271. package/src/network/interface.ts +3 -2
  272. package/src/network/libp2p/index.ts +21 -15
  273. package/src/network/network.ts +7 -4
  274. package/src/network/options.ts +7 -2
  275. package/src/network/processor/extractSlotRootFns.ts +32 -6
  276. package/src/network/processor/gossipHandlers.ts +325 -86
  277. package/src/network/processor/index.ts +304 -22
  278. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +3 -1
  279. package/src/network/reqresp/handlers/beaconBlocksByRoot.ts +3 -0
  280. package/src/network/reqresp/handlers/blobSidecarsByRange.ts +15 -3
  281. package/src/network/reqresp/handlers/blobSidecarsByRoot.ts +11 -0
  282. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +19 -3
  283. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +3 -1
  284. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +3 -12
  285. package/src/network/reqresp/types.ts +13 -5
  286. package/src/node/nodejs.ts +5 -2
  287. package/src/node/notifier.ts +7 -2
  288. package/src/sync/unknownBlock.ts +3 -3
  289. package/src/sync/utils/downloadByRange.ts +9 -7
  290. package/src/sync/utils/downloadByRoot.ts +16 -12
  291. package/src/util/blobs.ts +35 -15
  292. package/src/util/dataColumns.ts +69 -25
  293. package/src/util/execution.ts +49 -30
  294. package/src/util/sszBytes.ts +245 -3
@@ -1,7 +1,7 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {ExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
3
- import {ForkName, SLOTS_PER_EPOCH} from "@lodestar/params";
4
- import {getExecutionPayloadEnvelopeSignatureSet} from "@lodestar/state-transition";
3
+ import {SLOTS_PER_EPOCH} from "@lodestar/params";
4
+ import {getExecutionPayloadEnvelopeSignatureSet, isStatePostGloas} from "@lodestar/state-transition";
5
5
  import {byteArrayEquals, fromHex, toRootHex} from "@lodestar/utils";
6
6
  import {ExecutionPayloadStatus} from "../../execution/index.js";
7
7
  import {isQueueErrorAborted} from "../../util/queue/index.js";
@@ -69,14 +69,16 @@ function toForkChoiceExecutionStatus(status: ExecutionPayloadStatus): PayloadExe
69
69
  * Import an execution payload envelope after all data is available.
70
70
  *
71
71
  * This function:
72
- * 1. Gets the ProtoBlock from fork choice
73
- * 2. Applies write-queue backpressure (waitForSpace) early, before verification
74
- * 3. Regenerates the block state
75
- * 4. Runs EL verification (notifyNewPayload) in parallel with signature verification and processExecutionPayloadEnvelope
76
- * 5. Persists verified payload envelope to hot DB
77
- * 6. Updates fork choice
78
- * 7. Caches the post-execution payload state
79
- * 8. Records metrics for column sources
72
+ * 1. Emits `execution_payload_available` if payload is for current slot
73
+ * 2. Gets the ProtoBlock from fork choice
74
+ * 3. Applies write-queue backpressure (waitForSpace) early, before verification
75
+ * 4. Regenerates the block state
76
+ * 5. Runs EL verification (notifyNewPayload) in parallel with signature verification and processExecutionPayloadEnvelope
77
+ * 6. Persists verified payload envelope to hot DB
78
+ * 7. Updates fork choice
79
+ * 8. Caches the post-execution payload state
80
+ * 9. Records metrics for column sources
81
+ * 10. Emits `execution_payload` for recent enough payloads after successful import
80
82
  *
81
83
  */
82
84
  export async function importExecutionPayload(
@@ -84,10 +86,24 @@ export async function importExecutionPayload(
84
86
  payloadInput: PayloadEnvelopeInput,
85
87
  opts: ImportPayloadOpts = {}
86
88
  ): Promise<void> {
87
- const envelope = payloadInput.getPayloadEnvelope();
89
+ const signedEnvelope = payloadInput.getPayloadEnvelope();
90
+ const envelope = signedEnvelope.message;
88
91
  const blockRootHex = payloadInput.blockRootHex;
92
+ const blockHashHex = payloadInput.getBlockHashHex();
93
+ const fork = this.config.getForkName(envelope.slot);
89
94
 
90
- // 1. Get ProtoBlock for parent root lookup
95
+ // 1. Emit `execution_payload_available` event at the start of import. At this point the payload input
96
+ // is already complete, so the payload and required data are available for payload attestation.
97
+ // This event is only about availability, not validity of the execution payload, hence we can emit
98
+ // it before getting a response from the execution client on whether the payload is valid or not.
99
+ if (this.clock.currentSlot - envelope.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
100
+ this.emitter.emit(routes.events.EventType.executionPayloadAvailable, {
101
+ slot: envelope.slot,
102
+ blockRoot: blockRootHex,
103
+ });
104
+ }
105
+
106
+ // 2. Get ProtoBlock for parent root lookup
91
107
  const protoBlock = this.forkChoice.getBlockHexDefaultStatus(blockRootHex);
92
108
  if (!protoBlock) {
93
109
  throw new PayloadError({
@@ -96,11 +112,11 @@ export async function importExecutionPayload(
96
112
  });
97
113
  }
98
114
 
99
- // 2. Apply backpressure from the write queue early, before doing verification work.
115
+ // 3. Apply backpressure from the write queue early, before doing verification work.
100
116
  // The actual DB write is deferred until after verification succeeds.
101
117
  await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();
102
118
 
103
- // 3. Get pre-state for processExecutionPayloadEnvelope
119
+ // 4. Get pre-state for processExecutionPayloadEnvelope
104
120
  // We need the block state (post-block, pre-payload) to process the envelope
105
121
  const blockState = await this.regen.getBlockSlotState(
106
122
  protoBlock,
@@ -108,17 +124,23 @@ export async function importExecutionPayload(
108
124
  {dontTransferCache: true},
109
125
  RegenCaller.processBlock
110
126
  );
127
+ if (!isStatePostGloas(blockState)) {
128
+ throw new PayloadError({
129
+ code: PayloadErrorCode.STATE_TRANSITION_ERROR,
130
+ message: `Expected gloas+ block state for payload import, got fork=${blockState.forkName}`,
131
+ });
132
+ }
111
133
 
112
- // 4. Run verification steps in parallel
134
+ // 5. Run verification steps in parallel
113
135
  // Note: No data availability check needed here - importExecutionPayload is only
114
136
  // called when payloadInput.isComplete() is true, so all data is already available.
115
137
  const [execResult, signatureValid, postPayloadResult] = await Promise.all([
116
138
  this.executionEngine.notifyNewPayload(
117
- ForkName.gloas,
118
- envelope.message.payload,
139
+ fork,
140
+ envelope.payload,
119
141
  payloadInput.getVersionedHashes(),
120
142
  fromHex(protoBlock.parentRoot),
121
- envelope.message.executionRequests
143
+ envelope.executionRequests
122
144
  ),
123
145
 
124
146
  opts.validSignature === true
@@ -128,7 +150,7 @@ export async function importExecutionPayload(
128
150
  this.config,
129
151
  this.pubkeyCache,
130
152
  blockState,
131
- envelope,
153
+ signedEnvelope,
132
154
  payloadInput.proposerIndex
133
155
  );
134
156
  return this.bls.verifySignatureSets([signatureSet]);
@@ -139,7 +161,7 @@ export async function importExecutionPayload(
139
161
  (async () => {
140
162
  try {
141
163
  return {
142
- postPayloadState: blockState.processExecutionPayloadEnvelope(envelope, {
164
+ postPayloadState: blockState.processExecutionPayloadEnvelope(signedEnvelope, {
143
165
  verifySignature: false,
144
166
  verifyStateRoot: false,
145
167
  }),
@@ -156,12 +178,12 @@ export async function importExecutionPayload(
156
178
  })(),
157
179
  ]);
158
180
 
159
- // 4b. Check signature verification result
181
+ // 5a. Check signature verification result
160
182
  if (!signatureValid) {
161
183
  throw new PayloadError({code: PayloadErrorCode.INVALID_SIGNATURE});
162
184
  }
163
185
 
164
- // 5. Handle EL response
186
+ // 5b. Handle EL response
165
187
  switch (execResult.status) {
166
188
  case ExecutionPayloadStatus.VALID:
167
189
  break;
@@ -187,61 +209,69 @@ export async function importExecutionPayload(
187
209
  });
188
210
  }
189
211
 
190
- // 5b. Verify envelope state root matches post-state
212
+ // 5c. Verify envelope state root matches post-state
191
213
  const postPayloadState = postPayloadResult.postPayloadState;
192
214
  const postPayloadStateRoot = postPayloadState.hashTreeRoot();
193
- if (!byteArrayEquals(envelope.message.stateRoot, postPayloadStateRoot)) {
215
+ if (!byteArrayEquals(envelope.stateRoot, postPayloadStateRoot)) {
194
216
  throw new PayloadError({
195
217
  code: PayloadErrorCode.STATE_TRANSITION_ERROR,
196
- message: `Envelope state root mismatch expected=${toRootHex(envelope.message.stateRoot)} actual=${toRootHex(postPayloadStateRoot)}`,
218
+ message: `Envelope state root mismatch expected=${toRootHex(envelope.stateRoot)} actual=${toRootHex(postPayloadStateRoot)}`,
197
219
  });
198
220
  }
199
221
 
200
- // 5c. Persist payload envelope to hot DB (performed asynchronously to avoid blocking)
222
+ // 6. Persist payload envelope to hot DB (performed asynchronously to avoid blocking)
201
223
  this.unfinalizedPayloadEnvelopeWrites.push(payloadInput).catch((e) => {
202
224
  if (!isQueueErrorAborted(e)) {
203
225
  this.logger.error(
204
226
  "Error pushing payload envelope to unfinalized write queue",
205
- {slot: payloadInput.slot, root: blockRootHex},
227
+ {slot: envelope.slot, blockRoot: blockRootHex},
206
228
  e as Error
207
229
  );
208
230
  }
209
231
  });
210
232
 
211
- // 6. Update fork choice
233
+ // 7. Update fork choice
212
234
  this.forkChoice.onExecutionPayload(
213
235
  blockRootHex,
214
- payloadInput.getBlockHashHex(),
215
- envelope.message.payload.blockNumber,
236
+ blockHashHex,
237
+ envelope.payload.blockNumber,
216
238
  toRootHex(postPayloadStateRoot),
217
239
  toForkChoiceExecutionStatus(execResult.status)
218
240
  );
219
241
 
220
- // 7. Cache payload state
242
+ // 8. Cache payload state
221
243
  this.regen.processPayloadState(postPayloadState);
222
244
  if (postPayloadState.slot % SLOTS_PER_EPOCH === 0) {
223
245
  const {checkpoint} = postPayloadState.computeAnchorCheckpoint();
224
246
  this.regen.addCheckpointState(checkpoint, postPayloadState, true);
225
247
  }
226
248
 
227
- // 8. Record metrics for payload envelope and column sources
249
+ // 9. Record metrics for payload envelope and column sources
228
250
  this.metrics?.importPayload.bySource.inc({source: payloadInput.getPayloadEnvelopeSource().source});
229
251
  for (const {source} of payloadInput.getSampledColumnsWithSource()) {
230
252
  this.metrics?.importPayload.columnsBySource.inc({source});
231
253
  }
232
254
 
233
- this.logger.verbose("Execution payload imported", {
234
- slot: payloadInput.slot,
235
- root: blockRootHex,
236
- blockHash: payloadInput.getBlockHashHex(),
237
- });
255
+ const stateRootHex = toRootHex(envelope.stateRoot);
238
256
 
239
- // 9. Emit event after payload is fully verified and imported to fork choice, only for recent enough payloads
240
- const currentSlot = this.clock.currentSlot;
241
- if (currentSlot - payloadInput.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
242
- this.emitter.emit(routes.events.EventType.executionPayloadAvailable, {
243
- slot: payloadInput.slot,
257
+ // 10. Emit event after payload is fully verified and imported to fork choice, only for recent enough payloads
258
+ if (this.clock.currentSlot - envelope.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
259
+ this.emitter.emit(routes.events.EventType.executionPayload, {
260
+ slot: envelope.slot,
261
+ builderIndex: envelope.builderIndex,
262
+ blockHash: blockHashHex,
244
263
  blockRoot: blockRootHex,
264
+ stateRoot: stateRootHex,
265
+ // TODO GLOAS: revisit once we support optimistic import
266
+ executionOptimistic: false,
245
267
  });
246
268
  }
269
+
270
+ this.logger.verbose("Execution payload imported", {
271
+ slot: envelope.slot,
272
+ builderIndex: envelope.builderIndex,
273
+ blockRoot: blockRootHex,
274
+ blockHash: blockHashHex,
275
+ stateRoot: stateRootHex,
276
+ });
247
277
  }
@@ -89,7 +89,7 @@ export async function processBlocks(
89
89
  (block, i): FullyVerifiedBlock => ({
90
90
  blockInput: block,
91
91
  postBlockState: postStates[i],
92
- postEnvelopeState: null,
92
+ postPayloadState: null,
93
93
  parentBlockSlot: parentSlots[i],
94
94
  executionStatus: executionStatuses[i],
95
95
  // start supporting optimistic syncing/processing
@@ -1,8 +1,9 @@
1
- import {NUMBER_OF_COLUMNS} from "@lodestar/params";
2
- import {ColumnIndex, DataColumnSidecars, RootHex, Slot, ValidatorIndex, deneb, gloas} from "@lodestar/types";
1
+ import {ForkName, NUMBER_OF_COLUMNS} from "@lodestar/params";
2
+ import {ColumnIndex, RootHex, Slot, ValidatorIndex, deneb, gloas} from "@lodestar/types";
3
3
  import {toRootHex, withTimeout} from "@lodestar/utils";
4
4
  import {VersionedHashes} from "../../../execution/index.js";
5
5
  import {kzgCommitmentToVersionedHash} from "../../../util/blobs.js";
6
+ import {MissingColumnMeta} from "../blockInput/types.js";
6
7
  import {AddPayloadEnvelopeProps, ColumnWithSource, CreateFromBlockProps, SourceMeta} from "./types.js";
7
8
 
8
9
  export type PayloadEnvelopeInputState =
@@ -59,6 +60,7 @@ function createPromise<T>(): PromiseParts<T> {
59
60
  export class PayloadEnvelopeInput {
60
61
  readonly blockRootHex: RootHex;
61
62
  readonly slot: Slot;
63
+ readonly forkName: ForkName;
62
64
  readonly proposerIndex: ValidatorIndex;
63
65
  readonly bid: gloas.ExecutionPayloadBid;
64
66
  readonly versionedHashes: VersionedHashes;
@@ -71,13 +73,14 @@ export class PayloadEnvelopeInput {
71
73
  private timeCreatedSec: number;
72
74
 
73
75
  private readonly payloadEnvelopeDataPromise: PromiseParts<gloas.SignedExecutionPayloadEnvelope>;
74
- private readonly columnsDataPromise: PromiseParts<DataColumnSidecars>;
76
+ private readonly columnsDataPromise: PromiseParts<gloas.DataColumnSidecar[]>;
75
77
 
76
78
  state: PayloadEnvelopeInputState;
77
79
 
78
80
  private constructor(props: {
79
81
  blockRootHex: RootHex;
80
82
  slot: Slot;
83
+ forkName: ForkName;
81
84
  proposerIndex: ValidatorIndex;
82
85
  bid: gloas.ExecutionPayloadBid;
83
86
  sampledColumns: ColumnIndex[];
@@ -86,6 +89,7 @@ export class PayloadEnvelopeInput {
86
89
  }) {
87
90
  this.blockRootHex = props.blockRootHex;
88
91
  this.slot = props.slot;
92
+ this.forkName = props.forkName;
89
93
  this.proposerIndex = props.proposerIndex;
90
94
  this.bid = props.bid;
91
95
  this.versionedHashes = props.bid.blobKzgCommitments.map(kzgCommitmentToVersionedHash);
@@ -112,6 +116,7 @@ export class PayloadEnvelopeInput {
112
116
  return new PayloadEnvelopeInput({
113
117
  blockRootHex: props.blockRootHex,
114
118
  slot: props.block.message.slot,
119
+ forkName: props.forkName,
115
120
  proposerIndex: props.block.message.proposerIndex,
116
121
  bid,
117
122
  sampledColumns: props.sampledColumns,
@@ -173,8 +178,12 @@ export class PayloadEnvelopeInput {
173
178
  }
174
179
  }
175
180
 
176
- addColumn(columnWithSource: ColumnWithSource): void {
181
+ addColumn(columnWithSource: ColumnWithSource): boolean {
177
182
  const {columnSidecar, seenTimestampSec} = columnWithSource;
183
+ if (this.columnsCache.has(columnSidecar.index)) {
184
+ return false;
185
+ }
186
+
178
187
  this.columnsCache.set(columnSidecar.index, columnWithSource);
179
188
 
180
189
  const sampledColumns = this.getSampledColumns();
@@ -191,7 +200,7 @@ export class PayloadEnvelopeInput {
191
200
  sampledColumns.length === this.sampledColumns.length;
192
201
 
193
202
  if (!hasAllData) {
194
- return;
203
+ return true;
195
204
  }
196
205
 
197
206
  if (hasComputedAllData) {
@@ -217,6 +226,20 @@ export class PayloadEnvelopeInput {
217
226
  hasComputedAllData: hasComputedAllData || this.state.hasComputedAllData,
218
227
  };
219
228
  }
229
+
230
+ return true;
231
+ }
232
+
233
+ hasColumn(index: ColumnIndex): boolean {
234
+ return this.columnsCache.has(index);
235
+ }
236
+
237
+ getColumn(index: ColumnIndex): gloas.DataColumnSidecar | undefined {
238
+ return this.columnsCache.get(index)?.columnSidecar;
239
+ }
240
+
241
+ getAllColumns(): gloas.DataColumnSidecar[] {
242
+ return [...this.columnsCache.values()].map(({columnSidecar}) => columnSidecar);
220
243
  }
221
244
 
222
245
  getVersionedHashes(): VersionedHashes {
@@ -237,8 +260,8 @@ export class PayloadEnvelopeInput {
237
260
  return this.state.payloadEnvelopeSource;
238
261
  }
239
262
 
240
- getSampledColumns(): gloas.DataColumnSidecars {
241
- const columns: gloas.DataColumnSidecars = [];
263
+ getSampledColumns(): gloas.DataColumnSidecar[] {
264
+ const columns: gloas.DataColumnSidecar[] = [];
242
265
  for (const index of this.sampledColumns) {
243
266
  const column = this.columnsCache.get(index);
244
267
  if (column) {
@@ -259,8 +282,8 @@ export class PayloadEnvelopeInput {
259
282
  return columns;
260
283
  }
261
284
 
262
- getCustodyColumns(): gloas.DataColumnSidecars {
263
- const columns: gloas.DataColumnSidecars = [];
285
+ getCustodyColumns(): gloas.DataColumnSidecar[] {
286
+ const columns: gloas.DataColumnSidecar[] = [];
264
287
  for (const index of this.custodyColumns) {
265
288
  const column = this.columnsCache.get(index);
266
289
  if (column) {
@@ -270,11 +293,29 @@ export class PayloadEnvelopeInput {
270
293
  return columns;
271
294
  }
272
295
 
296
+ hasAllData(): boolean {
297
+ return this.state.hasAllData;
298
+ }
299
+
300
+ getMissingSampledColumnMeta(): MissingColumnMeta {
301
+ if (this.state.hasAllData) {
302
+ return {missing: [], versionedHashes: this.versionedHashes};
303
+ }
304
+
305
+ const missing: ColumnIndex[] = [];
306
+ for (const index of this.sampledColumns) {
307
+ if (!this.columnsCache.has(index)) {
308
+ missing.push(index);
309
+ }
310
+ }
311
+ return {missing, versionedHashes: this.versionedHashes};
312
+ }
313
+
273
314
  hasComputedAllData(): boolean {
274
315
  return this.state.hasComputedAllData;
275
316
  }
276
317
 
277
- waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<DataColumnSidecars> {
318
+ waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<gloas.DataColumnSidecar[]> {
278
319
  if (this.state.hasComputedAllData) {
279
320
  return Promise.resolve(this.getSampledColumns());
280
321
  }
@@ -319,7 +360,7 @@ export class PayloadEnvelopeInput {
319
360
  hasAllData: boolean;
320
361
  hasComputedAllData: boolean;
321
362
  isComplete: boolean;
322
- columnsCount: number;
363
+ receivedColumns: number;
323
364
  sampledColumnsCount: number;
324
365
  } {
325
366
  return {
@@ -329,7 +370,7 @@ export class PayloadEnvelopeInput {
329
370
  hasAllData: this.state.hasAllData,
330
371
  hasComputedAllData: this.state.hasComputedAllData,
331
372
  isComplete: this.isComplete(),
332
- columnsCount: this.columnsCache.size,
373
+ receivedColumns: this.columnsCache.size,
333
374
  sampledColumnsCount: this.sampledColumns.length,
334
375
  };
335
376
  }
@@ -1,4 +1,4 @@
1
- import {ForkPostGloas} from "@lodestar/params";
1
+ import {ForkName, ForkPostGloas} from "@lodestar/params";
2
2
  import {ColumnIndex, RootHex, SignedBeaconBlock, gloas} from "@lodestar/types";
3
3
 
4
4
  export enum PayloadEnvelopeInputSource {
@@ -23,6 +23,7 @@ export type ColumnWithSource = SourceMeta & {
23
23
  export type CreateFromBlockProps = {
24
24
  blockRootHex: RootHex;
25
25
  block: SignedBeaconBlock<ForkPostGloas>;
26
+ forkName: ForkName;
26
27
  sampledColumns: ColumnIndex[];
27
28
  custodyColumns: ColumnIndex[];
28
29
  timeCreatedSec: number;
@@ -103,7 +103,7 @@ type FullyVerifiedBlockBase = {
103
103
  /**
104
104
  * A wrapper around a `SignedBeaconBlock` that indicates that this block is fully verified and ready to import.
105
105
  *
106
- * Discriminated union on `postEnvelopeState`:
106
+ * Discriminated union on `postPayloadState`:
107
107
  * - `null` → block has no pre-verified envelope; `executionStatus` is any `BlockExecutionStatus`
108
108
  * - non-null → envelope was pre-verified during state transition; `executionStatus` is narrowed to
109
109
  * `Valid | Syncing` (matching what `forkChoice.onExecutionPayload` expects)
@@ -111,12 +111,12 @@ type FullyVerifiedBlockBase = {
111
111
  export type FullyVerifiedBlock = FullyVerifiedBlockBase &
112
112
  (
113
113
  | {
114
- postEnvelopeState: null;
114
+ postPayloadState: null;
115
115
  /** If the execution payload couldn't be verified because of EL syncing status, used in optimistic sync or for merge block */
116
116
  executionStatus: BlockExecutionStatus;
117
117
  }
118
118
  | {
119
- postEnvelopeState: IBeaconStateView;
119
+ postPayloadState: IBeaconStateView;
120
120
  executionStatus: PayloadExecutionStatus;
121
121
  }
122
122
  );
@@ -8,7 +8,7 @@ import {
8
8
  ProtoBlock,
9
9
  } from "@lodestar/fork-choice";
10
10
  import {ForkSeq} from "@lodestar/params";
11
- import {IBeaconStateView, isExecutionBlockBodyType} from "@lodestar/state-transition";
11
+ import {IBeaconStateView, isExecutionBlockBodyType, isStatePostBellatrix} from "@lodestar/state-transition";
12
12
  import {bellatrix, electra} from "@lodestar/types";
13
13
  import {ErrorAborted, Logger, toRootHex} from "@lodestar/utils";
14
14
  import {ExecutionPayloadStatus, IExecutionEngine} from "../../execution/engine/interface.js";
@@ -152,6 +152,7 @@ export async function verifyBlockExecutionPayload(
152
152
 
153
153
  /** Not null if execution is enabled */
154
154
  const executionPayloadEnabled =
155
+ isStatePostBellatrix(preState0) &&
155
156
  preState0.isExecutionStateType &&
156
157
  isExecutionBlockBodyType(block.message.body) &&
157
158
  preState0.isExecutionEnabled(block.message)
@@ -1,5 +1,10 @@
1
1
  import {BeaconConfig} from "@lodestar/config";
2
- import {IBeaconStateView, getBlockSignatureSets} from "@lodestar/state-transition";
2
+ import {
3
+ IBeaconStateView,
4
+ SyncCommitteeCacheEmpty,
5
+ getBlockSignatureSets,
6
+ isStatePostAltair,
7
+ } from "@lodestar/state-transition";
3
8
  import {IndexedAttestation, SignedBeaconBlock} from "@lodestar/types";
4
9
  import {Logger} from "@lodestar/utils";
5
10
  import {Metrics} from "../../metrics/metrics.js";
@@ -27,7 +32,9 @@ export async function verifyBlocksSignatures(
27
32
  ): Promise<{verifySignaturesTime: number}> {
28
33
  const isValidPromises: Promise<boolean>[] = [];
29
34
  const recvToValLatency = Date.now() / 1000 - (opts.seenTimestampSec ?? Date.now() / 1000);
30
- const currentSyncCommitteeIndexed = preState0.currentSyncCommitteeIndexed;
35
+ const currentSyncCommitteeIndexed = isStatePostAltair(preState0)
36
+ ? preState0.currentSyncCommitteeIndexed
37
+ : new SyncCommitteeCacheEmpty();
31
38
 
32
39
  // Verifies signatures after running state transition, so all SyncCommittee signed roots are known at this point.
33
40
  // We must ensure block.slot <= state.slot before running getAllBlockSignatureSets().
@@ -15,9 +15,9 @@ import {
15
15
  BUILDER_INDEX_SELF_BUILD,
16
16
  EFFECTIVE_BALANCE_INCREMENT,
17
17
  type ForkPostFulu,
18
+ type ForkPostGloas,
18
19
  GENESIS_SLOT,
19
20
  SLOTS_PER_EPOCH,
20
- isForkPostElectra,
21
21
  isForkPostGloas,
22
22
  } from "@lodestar/params";
23
23
  import {
@@ -29,12 +29,15 @@ import {
29
29
  computeEpochAtSlot,
30
30
  computeStartSlotAtEpoch,
31
31
  getEffectiveBalancesFromStateBytes,
32
+ isStatePostAltair,
33
+ isStatePostElectra,
34
+ isStatePostGloas,
32
35
  } from "@lodestar/state-transition";
33
36
  import {
34
37
  BeaconBlock,
35
38
  BlindedBeaconBlock,
36
39
  BlindedBeaconBlockBody,
37
- DataColumnSidecars,
40
+ DataColumnSidecar,
38
41
  Epoch,
39
42
  Root,
40
43
  RootHex,
@@ -97,7 +100,7 @@ import {
97
100
  } from "./opPools/index.js";
98
101
  import {IChainOptions} from "./options.js";
99
102
  import {PrepareNextSlotScheduler} from "./prepareNextSlot.js";
100
- import {computeEnvelopeStateRoot, computeNewStateRoot} from "./produceBlock/computeNewStateRoot.js";
103
+ import {computeNewStateRoot, computePayloadEnvelopeStateRoot} from "./produceBlock/computeNewStateRoot.js";
101
104
  import {AssembledBlockType, BlockType, ProduceFullGloas, ProduceResult} from "./produceBlock/index.js";
102
105
  import {BlockAttributes, produceBlockBody, produceCommonBlockBody} from "./produceBlock/produceBlockBody.js";
103
106
  import {QueuedStateRegenerator, RegenCaller} from "./regen/index.js";
@@ -504,7 +507,11 @@ export class BeaconChain implements IBeaconChain {
504
507
  }
505
508
 
506
509
  seenBlock(blockRoot: RootHex): boolean {
507
- return this.seenBlockInputCache.has(blockRoot) || this.forkChoice.hasBlockHex(blockRoot);
510
+ return this.seenBlockInputCache.hasBlock(blockRoot) || this.forkChoice.hasBlockHexUnsafe(blockRoot);
511
+ }
512
+
513
+ seenPayloadEnvelope(blockRoot: RootHex): boolean {
514
+ return this.seenPayloadEnvelopeInputCache.hasPayload(blockRoot) || this.forkChoice.hasPayloadHexUnsafe(blockRoot);
508
515
  }
509
516
 
510
517
  regenCanAcceptWork(): boolean {
@@ -873,20 +880,32 @@ export class BeaconChain implements IBeaconChain {
873
880
  );
874
881
  }
875
882
 
876
- async getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<DataColumnSidecars> {
877
- const blockInput = this.seenBlockInputCache.get(blockRootHex);
878
- if (blockInput) {
879
- if (!isBlockInputColumns(blockInput)) {
880
- throw new Error(`Expected block input to have columns: slot=${blockSlot} root=${blockRootHex}`);
883
+ async getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<DataColumnSidecar[]> {
884
+ const fork = this.config.getForkName(blockSlot);
885
+
886
+ if (isForkPostGloas(fork)) {
887
+ // After gloas, columns are tracked in PayloadEnvelopeInput
888
+ const payloadInput = this.seenPayloadEnvelopeInputCache.get(blockRootHex);
889
+ if (payloadInput) {
890
+ return payloadInput.getAllColumns();
891
+ }
892
+ } else {
893
+ // Before gloas, columns are tracked in BlockInput
894
+ const blockInput = this.seenBlockInputCache.get(blockRootHex);
895
+ if (blockInput) {
896
+ if (!isBlockInputColumns(blockInput)) {
897
+ throw new Error(`Expected block input to have columns: slot=${blockSlot} root=${blockRootHex}`);
898
+ }
899
+ return blockInput.getAllColumns();
881
900
  }
882
- return blockInput.getAllColumns();
883
901
  }
902
+
884
903
  const sidecarsUnfinalized = await this.db.dataColumnSidecar.values(fromHex(blockRootHex));
885
904
  if (sidecarsUnfinalized.length > 0) {
886
- return sidecarsUnfinalized as DataColumnSidecars;
905
+ return sidecarsUnfinalized;
887
906
  }
888
907
  const sidecarsFinalized = await this.db.dataColumnSidecarArchive.values(blockSlot);
889
- return sidecarsFinalized as DataColumnSidecars;
908
+ return sidecarsFinalized;
890
909
  }
891
910
 
892
911
  async getSerializedDataColumnSidecars(
@@ -894,23 +913,45 @@ export class BeaconChain implements IBeaconChain {
894
913
  blockRootHex: string,
895
914
  indices: number[]
896
915
  ): Promise<(Uint8Array | undefined)[]> {
897
- const blockInput = this.seenBlockInputCache.get(blockRootHex);
898
- if (blockInput) {
899
- if (!isBlockInputColumns(blockInput)) {
900
- throw new Error(`Expected block input to have columns: slot=${blockSlot} root=${blockRootHex}`);
916
+ const fork = this.config.getForkName(blockSlot);
917
+
918
+ if (isForkPostGloas(fork)) {
919
+ // After gloas, columns are tracked in PayloadEnvelopeInput
920
+ const payloadInput = this.seenPayloadEnvelopeInputCache.get(blockRootHex);
921
+ if (payloadInput) {
922
+ return indices.map((index) => {
923
+ const sidecar = payloadInput.getColumn(index);
924
+ if (!sidecar) {
925
+ return undefined;
926
+ }
927
+ const serialized = this.serializedCache.get(sidecar);
928
+ if (serialized) {
929
+ return serialized;
930
+ }
931
+ return sszTypesFor(fork as ForkPostGloas).DataColumnSidecar.serialize(sidecar);
932
+ });
901
933
  }
902
- return indices.map((index) => {
903
- const sidecar = blockInput.getColumn(index);
904
- if (!sidecar) {
905
- return undefined;
906
- }
907
- const serialized = this.serializedCache.get(sidecar);
908
- if (serialized) {
909
- return serialized;
934
+ } else {
935
+ // Before gloas, columns are tracked in BlockInput
936
+ const blockInput = this.seenBlockInputCache.get(blockRootHex);
937
+ if (blockInput) {
938
+ if (!isBlockInputColumns(blockInput)) {
939
+ throw new Error(`Expected block input to have columns: slot=${blockSlot} root=${blockRootHex}`);
910
940
  }
911
- return sszTypesFor(blockInput.forkName as ForkPostFulu).DataColumnSidecar.serialize(sidecar);
912
- });
941
+ return indices.map((index) => {
942
+ const sidecar = blockInput.getColumn(index);
943
+ if (!sidecar) {
944
+ return undefined;
945
+ }
946
+ const serialized = this.serializedCache.get(sidecar);
947
+ if (serialized) {
948
+ return serialized;
949
+ }
950
+ return sszTypesFor(blockInput.forkName as ForkPostFulu).DataColumnSidecar.serialize(sidecar);
951
+ });
952
+ }
913
953
  }
954
+
914
955
  const sidecarsUnfinalized = await this.db.dataColumnSidecar.getManyBinary(fromHex(blockRootHex), indices);
915
956
  if (sidecarsUnfinalized.some((sidecar) => sidecar != null)) {
916
957
  return sidecarsUnfinalized;
@@ -1013,7 +1054,7 @@ export class BeaconChain implements IBeaconChain {
1013
1054
  body,
1014
1055
  } as AssembledBlockType<T>;
1015
1056
 
1016
- const {newStateRoot, proposerReward, postState} = computeNewStateRoot(this.metrics, state, block);
1057
+ const {newStateRoot, proposerReward, postBlockState} = computeNewStateRoot(this.metrics, state, block);
1017
1058
  block.stateRoot = newStateRoot;
1018
1059
  const blockRoot =
1019
1060
  produceResult.type === BlockType.Full
@@ -1037,8 +1078,11 @@ export class BeaconChain implements IBeaconChain {
1037
1078
  slot,
1038
1079
  stateRoot: ZERO_HASH,
1039
1080
  };
1040
- const envelopeStateRoot = computeEnvelopeStateRoot(this.metrics, postState, envelope);
1041
- gloasResult.envelopeStateRoot = envelopeStateRoot;
1081
+ if (!isStatePostGloas(postBlockState)) {
1082
+ throw Error(`Expected gloas+ post-state for execution payload envelope, got fork=${postBlockState.forkName}`);
1083
+ }
1084
+ const payloadEnvelopeStateRoot = computePayloadEnvelopeStateRoot(this.metrics, postBlockState, envelope);
1085
+ gloasResult.payloadEnvelopeStateRoot = payloadEnvelopeStateRoot;
1042
1086
  }
1043
1087
 
1044
1088
  // Track the produced block for consensus broadcast validations, later validation, etc.
@@ -1365,9 +1409,7 @@ export class BeaconChain implements IBeaconChain {
1365
1409
  metrics.chain.blacklistedBlocks.set(this.blacklistedBlocks.size);
1366
1410
 
1367
1411
  const headState = this.getHeadState();
1368
- const fork = this.config.getForkName(headState.slot);
1369
-
1370
- if (isForkPostElectra(fork)) {
1412
+ if (isStatePostElectra(headState)) {
1371
1413
  metrics.pendingDeposits.set(headState.pendingDepositsCount);
1372
1414
  metrics.pendingPartialWithdrawals.set(headState.pendingPartialWithdrawalsCount);
1373
1415
  metrics.pendingConsolidations.set(headState.pendingConsolidationsCount);
@@ -1614,6 +1656,9 @@ export class BeaconChain implements IBeaconChain {
1614
1656
  }
1615
1657
 
1616
1658
  preState = preState.processSlots(block.slot); // Dial preState's slot to block.slot
1659
+ if (!isStatePostAltair(preState)) {
1660
+ throw new Error("Sync committee rewards are not supported before Altair");
1661
+ }
1617
1662
 
1618
1663
  return preState.computeSyncCommitteeRewards(block, validatorIds ?? []);
1619
1664
  }