@lodestar/beacon-node 1.43.0-dev.4fb05c546d → 1.43.0-dev.549a5b8115

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 (305) hide show
  1. package/lib/api/impl/beacon/blocks/index.js +7 -9
  2. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  3. package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
  4. package/lib/api/impl/beacon/pool/index.js +45 -2
  5. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  6. package/lib/api/impl/beacon/state/utils.d.ts +2 -2
  7. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  8. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  9. package/lib/api/impl/lodestar/index.js +1 -1
  10. package/lib/api/impl/lodestar/index.js.map +1 -1
  11. package/lib/api/impl/validator/index.d.ts.map +1 -1
  12. package/lib/api/impl/validator/index.js +66 -5
  13. package/lib/api/impl/validator/index.js.map +1 -1
  14. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  15. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  16. package/lib/chain/archiveStore/interface.d.ts +4 -4
  17. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  18. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
  19. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
  20. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
  21. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +2 -2
  22. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  23. package/lib/chain/archiveStore/utils/archiveBlocks.js +110 -58
  24. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  25. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  26. package/lib/chain/blocks/importBlock.js +3 -2
  27. package/lib/chain/blocks/importBlock.js.map +1 -1
  28. package/lib/chain/blocks/importExecutionPayload.d.ts +28 -14
  29. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  30. package/lib/chain/blocks/importExecutionPayload.js +86 -86
  31. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  32. package/lib/chain/blocks/index.d.ts +5 -3
  33. package/lib/chain/blocks/index.d.ts.map +1 -1
  34. package/lib/chain/blocks/index.js +31 -11
  35. package/lib/chain/blocks/index.js.map +1 -1
  36. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +1 -0
  37. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  38. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +4 -1
  39. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  40. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +1 -0
  41. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  42. package/lib/chain/blocks/payloadEnvelopeProcessor.js +2 -2
  43. package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
  44. package/lib/chain/blocks/types.d.ts +14 -20
  45. package/lib/chain/blocks/types.d.ts.map +1 -1
  46. package/lib/chain/blocks/utils/chainSegment.d.ts +23 -2
  47. package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
  48. package/lib/chain/blocks/utils/chainSegment.js +81 -12
  49. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  50. package/lib/chain/blocks/verifyBlock.d.ts +5 -3
  51. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  52. package/lib/chain/blocks/verifyBlock.js +51 -7
  53. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  54. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
  55. package/lib/chain/blocks/verifyBlocksSanityChecks.js +15 -4
  56. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  57. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +24 -0
  58. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -0
  59. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +76 -0
  60. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -0
  61. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -1
  62. package/lib/chain/blocks/verifyPayloadsDataAvailability.js +8 -3
  63. package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -1
  64. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +1 -1
  65. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -1
  66. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +2 -11
  67. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -1
  68. package/lib/chain/chain.d.ts +8 -6
  69. package/lib/chain/chain.d.ts.map +1 -1
  70. package/lib/chain/chain.js +21 -6
  71. package/lib/chain/chain.js.map +1 -1
  72. package/lib/chain/emitter.d.ts +3 -3
  73. package/lib/chain/emitter.d.ts.map +1 -1
  74. package/lib/chain/errors/blockError.d.ts +8 -1
  75. package/lib/chain/errors/blockError.d.ts.map +1 -1
  76. package/lib/chain/errors/blockError.js +2 -0
  77. package/lib/chain/errors/blockError.js.map +1 -1
  78. package/lib/chain/errors/executionPayloadBid.d.ts +5 -0
  79. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  80. package/lib/chain/errors/executionPayloadBid.js +1 -0
  81. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  82. package/lib/chain/errors/executionPayloadEnvelope.d.ts +5 -0
  83. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  84. package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
  85. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  86. package/lib/chain/errors/index.d.ts +1 -0
  87. package/lib/chain/errors/index.d.ts.map +1 -1
  88. package/lib/chain/errors/index.js +1 -0
  89. package/lib/chain/errors/index.js.map +1 -1
  90. package/lib/chain/errors/proposerPreferences.d.ts +33 -0
  91. package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
  92. package/lib/chain/errors/proposerPreferences.js +13 -0
  93. package/lib/chain/errors/proposerPreferences.js.map +1 -0
  94. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  95. package/lib/chain/forkChoice/index.js +5 -17
  96. package/lib/chain/forkChoice/index.js.map +1 -1
  97. package/lib/chain/interface.d.ts +7 -5
  98. package/lib/chain/interface.d.ts.map +1 -1
  99. package/lib/chain/interface.js.map +1 -1
  100. package/lib/chain/opPools/payloadAttestationPool.d.ts +3 -2
  101. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
  102. package/lib/chain/opPools/payloadAttestationPool.js +26 -4
  103. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
  104. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  105. package/lib/chain/prepareNextSlot.js +30 -10
  106. package/lib/chain/prepareNextSlot.js.map +1 -1
  107. package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -2
  108. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  109. package/lib/chain/produceBlock/produceBlockBody.js +40 -15
  110. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  111. package/lib/chain/regen/interface.d.ts +1 -0
  112. package/lib/chain/regen/interface.d.ts.map +1 -1
  113. package/lib/chain/regen/interface.js +1 -0
  114. package/lib/chain/regen/interface.js.map +1 -1
  115. package/lib/chain/seenCache/index.d.ts +1 -0
  116. package/lib/chain/seenCache/index.d.ts.map +1 -1
  117. package/lib/chain/seenCache/index.js +1 -0
  118. package/lib/chain/seenCache/index.js.map +1 -1
  119. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +19 -6
  120. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  121. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +28 -20
  122. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  123. package/lib/chain/seenCache/seenProposerPreferences.d.ts +15 -0
  124. package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
  125. package/lib/chain/seenCache/seenProposerPreferences.js +25 -0
  126. package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
  127. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  128. package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -1
  129. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  130. package/lib/chain/validation/block.d.ts.map +1 -1
  131. package/lib/chain/validation/block.js +1 -0
  132. package/lib/chain/validation/block.js.map +1 -1
  133. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  134. package/lib/chain/validation/executionPayloadBid.js +13 -1
  135. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  136. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  137. package/lib/chain/validation/executionPayloadEnvelope.js +19 -9
  138. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  139. package/lib/chain/validation/proposerPreferences.d.ts +8 -0
  140. package/lib/chain/validation/proposerPreferences.d.ts.map +1 -0
  141. package/lib/chain/validation/proposerPreferences.js +69 -0
  142. package/lib/chain/validation/proposerPreferences.js.map +1 -0
  143. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
  144. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
  145. package/lib/execution/engine/http.d.ts.map +1 -1
  146. package/lib/execution/engine/http.js +21 -14
  147. package/lib/execution/engine/http.js.map +1 -1
  148. package/lib/execution/engine/interface.d.ts +1 -0
  149. package/lib/execution/engine/interface.d.ts.map +1 -1
  150. package/lib/execution/engine/mock.d.ts.map +1 -1
  151. package/lib/execution/engine/mock.js +6 -0
  152. package/lib/execution/engine/mock.js.map +1 -1
  153. package/lib/execution/engine/types.d.ts +20 -0
  154. package/lib/execution/engine/types.d.ts.map +1 -1
  155. package/lib/execution/engine/types.js +18 -0
  156. package/lib/execution/engine/types.js.map +1 -1
  157. package/lib/metrics/metrics/lodestar.d.ts +1 -0
  158. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  159. package/lib/metrics/metrics/lodestar.js +4 -0
  160. package/lib/metrics/metrics/lodestar.js.map +1 -1
  161. package/lib/network/gossip/interface.d.ts +7 -1
  162. package/lib/network/gossip/interface.d.ts.map +1 -1
  163. package/lib/network/gossip/interface.js +1 -0
  164. package/lib/network/gossip/interface.js.map +1 -1
  165. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  166. package/lib/network/gossip/scoringParameters.js +12 -1
  167. package/lib/network/gossip/scoringParameters.js.map +1 -1
  168. package/lib/network/gossip/topic.d.ts +11 -2
  169. package/lib/network/gossip/topic.d.ts.map +1 -1
  170. package/lib/network/gossip/topic.js +6 -0
  171. package/lib/network/gossip/topic.js.map +1 -1
  172. package/lib/network/interface.d.ts +1 -0
  173. package/lib/network/interface.d.ts.map +1 -1
  174. package/lib/network/network.d.ts +1 -0
  175. package/lib/network/network.d.ts.map +1 -1
  176. package/lib/network/network.js +6 -1
  177. package/lib/network/network.js.map +1 -1
  178. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  179. package/lib/network/processor/gossipHandlers.js +17 -12
  180. package/lib/network/processor/gossipHandlers.js.map +1 -1
  181. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  182. package/lib/network/processor/gossipQueues/index.js +5 -0
  183. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  184. package/lib/network/processor/index.d.ts.map +1 -1
  185. package/lib/network/processor/index.js +1 -0
  186. package/lib/network/processor/index.js.map +1 -1
  187. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  188. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +14 -6
  189. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  190. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
  191. package/lib/network/reqresp/handlers/blobSidecarsByRange.js +11 -5
  192. package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
  193. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  194. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +17 -5
  195. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  196. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
  197. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +7 -4
  198. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
  199. package/lib/node/notifier.js +7 -1
  200. package/lib/node/notifier.js.map +1 -1
  201. package/lib/sync/range/batch.d.ts +12 -2
  202. package/lib/sync/range/batch.d.ts.map +1 -1
  203. package/lib/sync/range/batch.js +56 -30
  204. package/lib/sync/range/batch.js.map +1 -1
  205. package/lib/sync/range/chain.d.ts +6 -2
  206. package/lib/sync/range/chain.d.ts.map +1 -1
  207. package/lib/sync/range/chain.js +4 -3
  208. package/lib/sync/range/chain.js.map +1 -1
  209. package/lib/sync/range/range.d.ts.map +1 -1
  210. package/lib/sync/range/range.js +17 -6
  211. package/lib/sync/range/range.js.map +1 -1
  212. package/lib/sync/types.d.ts +34 -0
  213. package/lib/sync/types.d.ts.map +1 -1
  214. package/lib/sync/types.js +34 -0
  215. package/lib/sync/types.js.map +1 -1
  216. package/lib/sync/unknownBlock.d.ts +24 -1
  217. package/lib/sync/unknownBlock.d.ts.map +1 -1
  218. package/lib/sync/unknownBlock.js +649 -53
  219. package/lib/sync/unknownBlock.js.map +1 -1
  220. package/lib/sync/utils/downloadByRange.d.ts +46 -10
  221. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  222. package/lib/sync/utils/downloadByRange.js +147 -24
  223. package/lib/sync/utils/downloadByRange.js.map +1 -1
  224. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  225. package/lib/sync/utils/downloadByRoot.js +6 -2
  226. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  227. package/lib/sync/utils/pendingBlocksTree.d.ts +0 -1
  228. package/lib/sync/utils/pendingBlocksTree.d.ts.map +1 -1
  229. package/lib/sync/utils/pendingBlocksTree.js +0 -9
  230. package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
  231. package/lib/util/sszBytes.d.ts.map +1 -1
  232. package/lib/util/sszBytes.js +16 -3
  233. package/lib/util/sszBytes.js.map +1 -1
  234. package/package.json +16 -15
  235. package/src/api/impl/beacon/blocks/index.ts +9 -9
  236. package/src/api/impl/beacon/pool/index.ts +83 -1
  237. package/src/api/impl/beacon/state/utils.ts +2 -2
  238. package/src/api/impl/lodestar/index.ts +1 -1
  239. package/src/api/impl/validator/index.ts +80 -4
  240. package/src/chain/archiveStore/archiveStore.ts +5 -5
  241. package/src/chain/archiveStore/interface.ts +4 -4
  242. package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +4 -4
  243. package/src/chain/archiveStore/utils/archiveBlocks.ts +153 -94
  244. package/src/chain/blocks/importBlock.ts +3 -2
  245. package/src/chain/blocks/importExecutionPayload.ts +107 -101
  246. package/src/chain/blocks/index.ts +54 -15
  247. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +5 -1
  248. package/src/chain/blocks/payloadEnvelopeInput/types.ts +1 -0
  249. package/src/chain/blocks/payloadEnvelopeProcessor.ts +2 -2
  250. package/src/chain/blocks/types.ts +14 -25
  251. package/src/chain/blocks/utils/chainSegment.ts +106 -17
  252. package/src/chain/blocks/verifyBlock.ts +68 -9
  253. package/src/chain/blocks/verifyBlocksSanityChecks.ts +16 -7
  254. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +129 -0
  255. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +7 -4
  256. package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +9 -18
  257. package/src/chain/chain.ts +38 -19
  258. package/src/chain/emitter.ts +3 -3
  259. package/src/chain/errors/blockError.ts +4 -1
  260. package/src/chain/errors/executionPayloadBid.ts +6 -0
  261. package/src/chain/errors/executionPayloadEnvelope.ts +6 -0
  262. package/src/chain/errors/index.ts +1 -0
  263. package/src/chain/errors/proposerPreferences.ts +39 -0
  264. package/src/chain/forkChoice/index.ts +2 -22
  265. package/src/chain/interface.ts +11 -3
  266. package/src/chain/opPools/payloadAttestationPool.ts +29 -8
  267. package/src/chain/prepareNextSlot.ts +42 -12
  268. package/src/chain/produceBlock/produceBlockBody.ts +47 -13
  269. package/src/chain/regen/interface.ts +1 -0
  270. package/src/chain/seenCache/index.ts +1 -0
  271. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +35 -23
  272. package/src/chain/seenCache/seenProposerPreferences.ts +29 -0
  273. package/src/chain/stateCache/persistentCheckpointsCache.ts +4 -1
  274. package/src/chain/validation/block.ts +1 -0
  275. package/src/chain/validation/executionPayloadBid.ts +14 -0
  276. package/src/chain/validation/executionPayloadEnvelope.ts +20 -10
  277. package/src/chain/validation/proposerPreferences.ts +91 -0
  278. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
  279. package/src/execution/engine/http.ts +21 -14
  280. package/src/execution/engine/interface.ts +1 -0
  281. package/src/execution/engine/mock.ts +8 -1
  282. package/src/execution/engine/types.ts +41 -0
  283. package/src/metrics/metrics/lodestar.ts +4 -0
  284. package/src/network/gossip/interface.ts +6 -0
  285. package/src/network/gossip/scoringParameters.ts +14 -1
  286. package/src/network/gossip/topic.ts +6 -0
  287. package/src/network/interface.ts +1 -0
  288. package/src/network/network.ts +12 -1
  289. package/src/network/processor/gossipHandlers.ts +26 -13
  290. package/src/network/processor/gossipQueues/index.ts +5 -0
  291. package/src/network/processor/index.ts +1 -0
  292. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +14 -6
  293. package/src/network/reqresp/handlers/blobSidecarsByRange.ts +11 -5
  294. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -5
  295. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +7 -4
  296. package/src/node/notifier.ts +8 -1
  297. package/src/sync/range/batch.ts +90 -35
  298. package/src/sync/range/chain.ts +13 -5
  299. package/src/sync/range/range.ts +18 -6
  300. package/src/sync/types.ts +72 -0
  301. package/src/sync/unknownBlock.ts +810 -57
  302. package/src/sync/utils/downloadByRange.ts +256 -39
  303. package/src/sync/utils/downloadByRoot.ts +12 -2
  304. package/src/sync/utils/pendingBlocksTree.ts +0 -15
  305. package/src/util/sszBytes.ts +21 -3
@@ -1,14 +1,18 @@
1
1
  import {routes} from "@lodestar/api";
2
- import {ExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
3
- import {SLOTS_PER_EPOCH} from "@lodestar/params";
4
- import {getExecutionPayloadEnvelopeSignatureSet, isStatePostGloas} from "@lodestar/state-transition";
5
- import {byteArrayEquals, fromHex, toRootHex} from "@lodestar/utils";
2
+ import {ExecutionStatus, PayloadExecutionStatus, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
3
+ import {DataAvailabilityStatus, isStatePostGloas} from "@lodestar/state-transition";
4
+ import {fromHex, isErrorAborted} from "@lodestar/utils";
5
+ import {ZERO_HASH_HEX} from "../../constants/index.js";
6
6
  import {ExecutionPayloadStatus} from "../../execution/index.js";
7
7
  import {isQueueErrorAborted} from "../../util/queue/index.js";
8
8
  import {BeaconChain} from "../chain.js";
9
9
  import {RegenCaller} from "../regen/interface.js";
10
10
  import {PayloadEnvelopeInput} from "../seenCache/seenPayloadEnvelopeInput.js";
11
11
  import {ImportPayloadOpts} from "./types.js";
12
+ import {
13
+ verifyExecutionPayloadEnvelope,
14
+ verifyExecutionPayloadEnvelopeSignature,
15
+ } from "./verifyExecutionPayloadEnvelope.js";
12
16
  import {verifyPayloadsDataAvailability} from "./verifyPayloadsDataAvailability.js";
13
17
 
14
18
  const EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS = 64;
@@ -17,7 +21,7 @@ export enum PayloadErrorCode {
17
21
  EXECUTION_ENGINE_INVALID = "PAYLOAD_ERROR_EXECUTION_ENGINE_INVALID",
18
22
  EXECUTION_ENGINE_ERROR = "PAYLOAD_ERROR_EXECUTION_ENGINE_ERROR",
19
23
  BLOCK_NOT_IN_FORK_CHOICE = "PAYLOAD_ERROR_BLOCK_NOT_IN_FORK_CHOICE",
20
- STATE_TRANSITION_ERROR = "PAYLOAD_ERROR_STATE_TRANSITION_ERROR",
24
+ ENVELOPE_VERIFICATION_ERROR = "PAYLOAD_ERROR_ENVELOPE_VERIFICATION_ERROR",
21
25
  INVALID_SIGNATURE = "PAYLOAD_ERROR_INVALID_SIGNATURE",
22
26
  }
23
27
 
@@ -37,7 +41,7 @@ export type PayloadErrorType =
37
41
  blockRootHex: string;
38
42
  }
39
43
  | {
40
- code: PayloadErrorCode.STATE_TRANSITION_ERROR;
44
+ code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR;
41
45
  message: string;
42
46
  }
43
47
  | {
@@ -69,38 +73,43 @@ function toForkChoiceExecutionStatus(status: ExecutionPayloadStatus): PayloadExe
69
73
  /**
70
74
  * Import an execution payload envelope after all data is available.
71
75
  *
72
- * This function:
73
- * 1. Emits `execution_payload_available` if payload is for current slot
74
- * 2. Gets the ProtoBlock from fork choice
75
- * 3. Applies write-queue backpressure (waitForSpace) early, before verification
76
- * 4. Regenerates the block state
77
- * 5. Runs EL verification (notifyNewPayload) in parallel with signature verification and processExecutionPayloadEnvelope
78
- * 6. Persists verified payload envelope to hot DB
79
- * 7. Updates fork choice
80
- * 8. Caches the post-execution payload state
81
- * 9. Records metrics for column sources
82
- * 10. Emits `execution_payload` for recent enough payloads after successful import
76
+ * The envelope is only verified here, no state mutation. State effects from the payload
77
+ * are applied on the next block via processParentExecutionPayload.
83
78
  *
79
+ * The DA wait must have run upstream (range sync awaits DA in `verifyBlocksInEpoch` for the
80
+ * whole segment; gossip / API path uses the `processExecutionPayload` wrapper below).
81
+ *
82
+ * Steps:
83
+ * 1. Emit `execution_payload_available` event for payload attestation
84
+ * 2. Get the ProtoBlock from fork choice
85
+ * 3. Regenerate state for envelope verification
86
+ * 4. Verify envelope (fields against state, signature, and EL in parallel where possible)
87
+ * 5. Persist verified payload envelope to hot DB (waits for write-queue space for backpressure)
88
+ * 6. Update fork choice (transitions the block's PENDING variant to FULL)
89
+ * 7. Queue notifyForkchoiceUpdate to engine api
90
+ * 8. Record metrics for payload envelope and column sources
91
+ * 9. Emit `execution_payload` event
84
92
  */
85
93
  export async function importExecutionPayload(
86
94
  this: BeaconChain,
87
95
  payloadInput: PayloadEnvelopeInput,
88
- signal: AbortSignal,
96
+ dataAvailabilityStatus: DataAvailabilityStatus,
89
97
  opts: ImportPayloadOpts = {}
90
98
  ): Promise<void> {
91
99
  const signedEnvelope = payloadInput.getPayloadEnvelope();
92
100
  const envelope = signedEnvelope.message;
101
+ const slot = envelope.payload.slotNumber;
93
102
  const blockRootHex = payloadInput.blockRootHex;
94
103
  const blockHashHex = payloadInput.getBlockHashHex();
95
- const fork = this.config.getForkName(envelope.slot);
104
+ const fork = this.config.getForkName(slot);
96
105
 
97
- // 1. Emit `execution_payload_available` event at the start of import. At this point the payload input
98
- // is already complete, so the payload and required data are available for payload attestation.
99
- // This event is only about availability, not validity of the execution payload, hence we can emit
100
- // it before getting a response from the execution client on whether the payload is valid or not.
101
- if (this.clock.currentSlot - envelope.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
106
+ // 1. Emit `execution_payload_available` event at the start of import. At this point the
107
+ // payload input is already complete, so the payload and required data are available for
108
+ // payload attestation. This event only signals availability (not validity), so we can emit
109
+ // it before getting a response from the EL on whether the payload is valid or not.
110
+ if (this.clock.currentSlot - slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
102
111
  this.emitter.emit(routes.events.EventType.executionPayloadAvailable, {
103
- slot: envelope.slot,
112
+ slot,
104
113
  blockRoot: blockRootHex,
105
114
  });
106
115
  }
@@ -114,16 +123,7 @@ export async function importExecutionPayload(
114
123
  });
115
124
  }
116
125
 
117
- // 3. Wait for data columns to be available before claiming a write-queue slot.
118
- // The helper is shared with future gloas sync services; take the single-item batch form here.
119
- await verifyPayloadsDataAvailability([payloadInput], signal);
120
-
121
- // 4. Apply backpressure from the write queue, before doing verification work.
122
- // The actual DB write is deferred until after verification succeeds.
123
- await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();
124
-
125
- // 5. Get pre-state for processExecutionPayloadEnvelope
126
- // We need the block state (post-block, pre-payload) to process the envelope
126
+ // 3. Regenerate state for envelope verification
127
127
  const blockState = await this.regen.getBlockSlotState(
128
128
  protoBlock,
129
129
  protoBlock.slot,
@@ -132,13 +132,30 @@ export async function importExecutionPayload(
132
132
  );
133
133
  if (!isStatePostGloas(blockState)) {
134
134
  throw new PayloadError({
135
- code: PayloadErrorCode.STATE_TRANSITION_ERROR,
136
- message: `Expected gloas+ block state for payload import, got fork=${blockState.forkName}`,
135
+ code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR,
136
+ message: `Expected gloas+ state for payload import, got fork=${blockState.forkName}`,
137
+ });
138
+ }
139
+
140
+ // 4. Verify envelope fields against state first to fail fast before the EL + BLS work.
141
+ // When validSignature is true, gossip/API has already verified both the signature and the
142
+ // executionRequestsRoot, so we skip those checks here.
143
+ try {
144
+ verifyExecutionPayloadEnvelope(this.config, blockState, envelope, {
145
+ verifyExecutionRequestsRoot: !opts.validSignature,
137
146
  });
147
+ } catch (e) {
148
+ throw new PayloadError(
149
+ {
150
+ code: PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR,
151
+ message: (e as Error).message,
152
+ },
153
+ `Envelope verification error: ${(e as Error).message}`
154
+ );
138
155
  }
139
156
 
140
- // 6. Run verification steps in parallel
141
- const [execResult, signatureValid, postPayloadResult] = await Promise.all([
157
+ // 4a. Run EL and signature verification in parallel
158
+ const [execResult, signatureValid] = await Promise.all([
142
159
  this.executionEngine.notifyNewPayload(
143
160
  fork,
144
161
  envelope.payload,
@@ -149,45 +166,22 @@ export async function importExecutionPayload(
149
166
 
150
167
  opts.validSignature === true
151
168
  ? Promise.resolve(true)
152
- : (async () => {
153
- const signatureSet = getExecutionPayloadEnvelopeSignatureSet(
154
- this.config,
155
- this.pubkeyCache,
156
- blockState,
157
- signedEnvelope,
158
- payloadInput.proposerIndex
159
- );
160
- return this.bls.verifySignatureSets([signatureSet]);
161
- })(),
162
-
163
- // Signature verified separately above.
164
- // State root check is done separately below with better error typing (matching block pipeline pattern).
165
- (async () => {
166
- try {
167
- return {
168
- postPayloadState: blockState.processExecutionPayloadEnvelope(signedEnvelope, {
169
- verifySignature: false,
170
- verifyStateRoot: false,
171
- }),
172
- };
173
- } catch (e) {
174
- throw new PayloadError(
175
- {
176
- code: PayloadErrorCode.STATE_TRANSITION_ERROR,
177
- message: (e as Error).message,
178
- },
179
- `State transition error: ${(e as Error).message}`
180
- );
181
- }
182
- })(),
169
+ : verifyExecutionPayloadEnvelopeSignature(
170
+ this.config,
171
+ blockState,
172
+ this.pubkeyCache,
173
+ signedEnvelope,
174
+ payloadInput.proposerIndex,
175
+ this.bls
176
+ ),
183
177
  ]);
184
178
 
185
- // 5a. Check signature verification result
179
+ // 4b. Check signature verification result
186
180
  if (!signatureValid) {
187
181
  throw new PayloadError({code: PayloadErrorCode.INVALID_SIGNATURE});
188
182
  }
189
183
 
190
- // 5b. Handle EL response
184
+ // 4c. Handle EL response
191
185
  switch (execResult.status) {
192
186
  case ExecutionPayloadStatus.VALID:
193
187
  break;
@@ -213,69 +207,81 @@ export async function importExecutionPayload(
213
207
  });
214
208
  }
215
209
 
216
- // 5c. Verify envelope state root matches post-state
217
- const postPayloadState = postPayloadResult.postPayloadState;
218
- const postPayloadStateRoot = postPayloadState.hashTreeRoot();
219
- if (!byteArrayEquals(envelope.stateRoot, postPayloadStateRoot)) {
220
- throw new PayloadError({
221
- code: PayloadErrorCode.STATE_TRANSITION_ERROR,
222
- message: `Envelope state root mismatch expected=${toRootHex(envelope.stateRoot)} actual=${toRootHex(postPayloadStateRoot)}`,
223
- });
224
- }
225
-
226
- // 6. Persist payload envelope to hot DB (performed asynchronously to avoid blocking)
210
+ // 5. Persist payload envelope to hot DB. Wait for write-queue space here to apply backpressure
211
+ // on the import pipeline during sync, then perform the write asynchronously to avoid blocking.
212
+ await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();
227
213
  this.unfinalizedPayloadEnvelopeWrites.push(payloadInput).catch((e) => {
228
214
  if (!isQueueErrorAborted(e)) {
229
215
  this.logger.error(
230
216
  "Error pushing payload envelope to unfinalized write queue",
231
- {slot: envelope.slot, blockRoot: blockRootHex},
217
+ {slot, blockRoot: blockRootHex},
232
218
  e as Error
233
219
  );
234
220
  }
235
221
  });
236
222
 
237
- // 7. Update fork choice
223
+ // 6. Update fork choice, transitions the block's PENDING variant to FULL
224
+ const execStatus = toForkChoiceExecutionStatus(execResult.status);
238
225
  this.forkChoice.onExecutionPayload(
239
226
  blockRootHex,
240
227
  blockHashHex,
241
228
  envelope.payload.blockNumber,
242
- toRootHex(postPayloadStateRoot),
243
- toForkChoiceExecutionStatus(execResult.status)
229
+ execStatus,
230
+ dataAvailabilityStatus
244
231
  );
245
232
 
246
- // 8. Cache payload state
247
- this.regen.processState(blockRootHex, postPayloadState);
248
- if (postPayloadState.slot % SLOTS_PER_EPOCH === 0) {
249
- const {checkpoint} = postPayloadState.computeAnchorCheckpoint();
250
- this.regen.addCheckpointState(checkpoint, postPayloadState);
233
+ // 7. Queue notifyForkchoiceUpdate to engine api
234
+ const head = this.forkChoice.getHead();
235
+ if (!this.opts.disableImportExecutionFcU && blockRootHex === head.blockRoot) {
236
+ const safeBlockHash = getSafeExecutionBlockHash(this.forkChoice);
237
+ const finalizedBlockHash = this.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
238
+ this.executionEngine.notifyForkchoiceUpdate(fork, blockHashHex, safeBlockHash, finalizedBlockHash).catch((e) => {
239
+ if (!isErrorAborted(e) && !isQueueErrorAborted(e)) {
240
+ this.logger.error("Error pushing notifyForkchoiceUpdate()", {blockHashHex, finalizedBlockHash}, e);
241
+ }
242
+ });
251
243
  }
252
244
 
253
- // 9. Record metrics for payload envelope and column sources
245
+ // 8. Record metrics for payload envelope and column sources
254
246
  this.metrics?.importPayload.bySource.inc({source: payloadInput.getPayloadEnvelopeSource().source});
255
247
  for (const {source} of payloadInput.getSampledColumnsWithSource()) {
256
248
  this.metrics?.importPayload.columnsBySource.inc({source});
257
249
  }
258
250
 
259
- const stateRootHex = toRootHex(envelope.stateRoot);
260
-
261
- // 10. Emit event after payload is fully verified and imported to fork choice, only for recent enough payloads
262
- if (this.clock.currentSlot - envelope.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
251
+ // 9. Emit event after payload is fully verified and imported to fork choice, only for recent enough payloads
252
+ if (this.clock.currentSlot - slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
263
253
  this.emitter.emit(routes.events.EventType.executionPayload, {
264
- slot: envelope.slot,
254
+ slot,
265
255
  builderIndex: envelope.builderIndex,
266
256
  blockHash: blockHashHex,
267
257
  blockRoot: blockRootHex,
268
- stateRoot: stateRootHex,
269
258
  // TODO GLOAS: revisit once we support optimistic import
270
259
  executionOptimistic: false,
271
260
  });
272
261
  }
273
262
 
274
263
  this.logger.verbose("Execution payload imported", {
275
- slot: envelope.slot,
264
+ slot,
276
265
  builderIndex: envelope.builderIndex,
277
266
  blockRoot: blockRootHex,
278
267
  blockHash: blockHashHex,
279
- stateRoot: stateRootHex,
280
268
  });
281
269
  }
270
+
271
+ /**
272
+ * Process an execution payload envelope end-to-end: wait for DA, then import.
273
+ *
274
+ * Used by the PayloadEnvelopeProcessor queue (gossip / API / unknown-payload sync) — i.e.
275
+ * callers that have NOT already awaited DA themselves. Range sync's inline dispatch in
276
+ * processBlocks skips this wrapper and calls `importExecutionPayload` directly, since
277
+ * `verifyBlocksInEpoch` already awaited DA for the segment.
278
+ */
279
+ export async function processExecutionPayload(
280
+ this: BeaconChain,
281
+ payloadInput: PayloadEnvelopeInput,
282
+ signal: AbortSignal,
283
+ opts: ImportPayloadOpts = {}
284
+ ): Promise<void> {
285
+ const {dataAvailabilityStatuses} = await verifyPayloadsDataAvailability([payloadInput], signal);
286
+ await importExecutionPayload.call(this, payloadInput, dataAvailabilityStatuses[0], opts);
287
+ }
@@ -1,4 +1,4 @@
1
- import {SignedBeaconBlock} from "@lodestar/types";
1
+ import {SignedBeaconBlock, Slot} from "@lodestar/types";
2
2
  import {isErrorAborted, toRootHex} from "@lodestar/utils";
3
3
  import {Metrics} from "../../metrics/metrics.js";
4
4
  import {nextEventLoop} from "../../util/eventLoop.js";
@@ -8,6 +8,8 @@ import {BlockError, BlockErrorCode, isBlockErrorAborted} from "../errors/index.j
8
8
  import {BlockProcessOpts} from "../options.js";
9
9
  import {IBlockInput} from "./blockInput/types.js";
10
10
  import {importBlock} from "./importBlock.js";
11
+ import {importExecutionPayload} from "./importExecutionPayload.js";
12
+ import {PayloadEnvelopeInput} from "./payloadEnvelopeInput/payloadEnvelopeInput.js";
11
13
  import {FullyVerifiedBlock, ImportBlockOpts} from "./types.js";
12
14
  import {assertLinearChainSegment} from "./utils/chainSegment.js";
13
15
  import {verifyBlocksInEpoch} from "./verifyBlock.js";
@@ -21,20 +23,24 @@ const QUEUE_MAX_LENGTH = 256;
21
23
  * BlockProcessor processes block jobs in a queued fashion, one after the other.
22
24
  */
23
25
  export class BlockProcessor {
24
- readonly jobQueue: JobItemQueue<[IBlockInput[], ImportBlockOpts], void>;
26
+ readonly jobQueue: JobItemQueue<[IBlockInput[], Map<Slot, PayloadEnvelopeInput> | null, ImportBlockOpts], void>;
25
27
 
26
28
  constructor(chain: BeaconChain, metrics: Metrics | null, opts: BlockProcessOpts, signal: AbortSignal) {
27
- this.jobQueue = new JobItemQueue<[IBlockInput[], ImportBlockOpts], void>(
28
- (job, importOpts) => {
29
- return processBlocks.call(chain, job, {...opts, ...importOpts});
29
+ this.jobQueue = new JobItemQueue<[IBlockInput[], Map<Slot, PayloadEnvelopeInput> | null, ImportBlockOpts], void>(
30
+ (job, payloadEnvelopes, importOpts) => {
31
+ return processBlocks.call(chain, job, payloadEnvelopes, {...opts, ...importOpts});
30
32
  },
31
33
  {maxLength: QUEUE_MAX_LENGTH, noYieldIfOneItem: true, signal},
32
34
  metrics?.blockProcessorQueue ?? undefined
33
35
  );
34
36
  }
35
37
 
36
- async processBlocksJob(job: IBlockInput[], opts: ImportBlockOpts = {}): Promise<void> {
37
- await this.jobQueue.push(job, opts);
38
+ async processBlocksJob(
39
+ job: IBlockInput[],
40
+ payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
41
+ opts: ImportBlockOpts = {}
42
+ ): Promise<void> {
43
+ await this.jobQueue.push(job, payloadEnvelopes, opts);
38
44
  }
39
45
  }
40
46
 
@@ -51,16 +57,13 @@ export class BlockProcessor {
51
57
  export async function processBlocks(
52
58
  this: BeaconChain,
53
59
  blocks: IBlockInput[],
60
+ payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
54
61
  opts: BlockProcessOpts & ImportBlockOpts
55
62
  ): Promise<void> {
56
63
  if (blocks.length === 0) {
57
64
  return; // TODO: or throw?
58
65
  }
59
66
 
60
- if (blocks.length > 1) {
61
- assertLinearChainSegment(this.config, blocks);
62
- }
63
-
64
67
  try {
65
68
  const {relevantBlocks, parentSlots, parentBlock} = verifyBlocksSanityChecks(this, blocks, opts);
66
69
 
@@ -70,10 +73,31 @@ export async function processBlocks(
70
73
  return;
71
74
  }
72
75
 
76
+ const {warnings: orphanedPayloads} = assertLinearChainSegment(
77
+ this.config,
78
+ relevantBlocks,
79
+ payloadEnvelopes,
80
+ parentBlock
81
+ );
82
+ if (orphanedPayloads != null) {
83
+ for (const orphaned of orphanedPayloads) {
84
+ this.logger.debug("Orphaned payload envelope in chain segment", {
85
+ slot: orphaned.slot,
86
+ blockRoot: orphaned.payloadEnvelopeInput.blockRootHex,
87
+ });
88
+ }
89
+ }
90
+
73
91
  // Fully verify a block to be imported immediately after. Does not produce any side-effects besides adding intermediate
74
92
  // states in the state cache through regen.
75
- const {postStates, dataAvailabilityStatuses, proposerBalanceDeltas, segmentExecStatus, indexedAttestationsByBlock} =
76
- await verifyBlocksInEpoch.call(this, parentBlock, relevantBlocks, opts);
93
+ const {
94
+ postStates,
95
+ blockDAStatuses,
96
+ payloadDAStatuses,
97
+ proposerBalanceDeltas,
98
+ segmentExecStatus,
99
+ indexedAttestationsByBlock,
100
+ } = await verifyBlocksInEpoch.call(this, parentBlock, relevantBlocks, payloadEnvelopes, opts);
77
101
 
78
102
  // If segmentExecStatus has lvhForkchoice then, the entire segment should be invalid
79
103
  // and we need to further propagate
@@ -89,11 +113,10 @@ export async function processBlocks(
89
113
  (block, i): FullyVerifiedBlock => ({
90
114
  blockInput: block,
91
115
  postState: postStates[i],
92
- postPayloadState: null,
93
116
  parentBlockSlot: parentSlots[i],
94
117
  executionStatus: executionStatuses[i],
95
118
  // start supporting optimistic syncing/processing
96
- dataAvailabilityStatus: dataAvailabilityStatuses[i],
119
+ dataAvailabilityStatus: blockDAStatuses[i],
97
120
  proposerBalanceDelta: proposerBalanceDeltas[i],
98
121
  indexedAttestations: indexedAttestationsByBlock[i],
99
122
  // TODO: Make this param mandatory and capture in gossip
@@ -104,6 +127,22 @@ export async function processBlocks(
104
127
  for (const fullyVerifiedBlock of fullyVerifiedBlocks) {
105
128
  // TODO: Consider batching importBlock too if it takes significant time
106
129
  await importBlock.call(this, fullyVerifiedBlock, opts);
130
+
131
+ const slot = fullyVerifiedBlock.blockInput.getBlock().message.slot;
132
+ const payloadInput = payloadEnvelopes?.get(slot);
133
+ if (payloadInput?.hasPayloadEnvelope()) {
134
+ if (!payloadInput.isComplete()) {
135
+ // we validated DA before reaching this
136
+ throw new Error(`Payload envelope for slot ${slot} not complete after DA verification`);
137
+ }
138
+ // we already awaited DA in verifyBlocksInEpoch for this segment
139
+ const payloadDA = payloadDAStatuses.get(slot);
140
+ if (payloadDA === undefined) {
141
+ throw new Error(`Missing payload DA status for slot ${slot}`);
142
+ }
143
+ await importExecutionPayload.call(this, payloadInput, payloadDA, {validSignature: false});
144
+ }
145
+
107
146
  await nextEventLoop();
108
147
  }
109
148
  } catch (e) {
@@ -64,6 +64,7 @@ export class PayloadEnvelopeInput {
64
64
  readonly proposerIndex: ValidatorIndex;
65
65
  readonly bid: gloas.ExecutionPayloadBid;
66
66
  readonly versionedHashes: VersionedHashes;
67
+ readonly daOutOfRange: boolean;
67
68
 
68
69
  private columnsCache = new Map<ColumnIndex, ColumnWithSource>();
69
70
 
@@ -87,6 +88,7 @@ export class PayloadEnvelopeInput {
87
88
  sampledColumns: ColumnIndex[];
88
89
  custodyColumns: ColumnIndex[];
89
90
  timeCreatedSec: number;
91
+ daOutOfRange: boolean;
90
92
  }) {
91
93
  this.blockRootHex = props.blockRootHex;
92
94
  this.slot = props.slot;
@@ -97,13 +99,14 @@ export class PayloadEnvelopeInput {
97
99
  this.sampledColumns = props.sampledColumns;
98
100
  this.custodyColumns = props.custodyColumns;
99
101
  this.timeCreatedSec = props.timeCreatedSec;
102
+ this.daOutOfRange = props.daOutOfRange;
100
103
  this.payloadEnvelopeDataPromise = createPromise();
101
104
  this.allDataPromise = createPromise();
102
105
  this.columnsDataPromise = createPromise();
103
106
 
104
107
  const noBlobs = props.bid.blobKzgCommitments.length === 0;
105
108
  const noSampledColumns = props.sampledColumns.length === 0;
106
- const hasAllData = noBlobs || noSampledColumns;
109
+ const hasAllData = props.daOutOfRange || noBlobs || noSampledColumns;
107
110
 
108
111
  if (hasAllData) {
109
112
  this.state = {hasPayload: false, hasAllData: true, hasComputedAllData: true};
@@ -125,6 +128,7 @@ export class PayloadEnvelopeInput {
125
128
  sampledColumns: props.sampledColumns,
126
129
  custodyColumns: props.custodyColumns,
127
130
  timeCreatedSec: props.timeCreatedSec,
131
+ daOutOfRange: props.daOutOfRange,
128
132
  });
129
133
  }
130
134
 
@@ -27,6 +27,7 @@ export type CreateFromBlockProps = {
27
27
  sampledColumns: ColumnIndex[];
28
28
  custodyColumns: ColumnIndex[];
29
29
  timeCreatedSec: number;
30
+ daOutOfRange: boolean;
30
31
  };
31
32
 
32
33
  export type AddPayloadEnvelopeProps = SourceMeta & {
@@ -2,7 +2,7 @@ import {Metrics} from "../../metrics/metrics.js";
2
2
  import {JobItemQueue} from "../../util/queue/index.js";
3
3
  import type {BeaconChain} from "../chain.js";
4
4
  import {PayloadEnvelopeInput} from "../seenCache/seenPayloadEnvelopeInput.js";
5
- import {importExecutionPayload} from "./importExecutionPayload.js";
5
+ import {processExecutionPayload} from "./importExecutionPayload.js";
6
6
  import {ImportPayloadOpts} from "./types.js";
7
7
 
8
8
  // TODO GLOAS: Set to be equal to DEFAULT_MAX_PENDING_UNFINALIZED_PAYLOAD_ENVELOPE_WRITES for now
@@ -30,7 +30,7 @@ export class PayloadEnvelopeProcessor {
30
30
  this.jobQueue = new JobItemQueue<[PayloadEnvelopeInput, ImportPayloadOpts], void>(
31
31
  (payloadInput, opts) => {
32
32
  this.importStatus.set(payloadInput, PayloadEnvelopeImportStatus.importing);
33
- return importExecutionPayload.call(chain, payloadInput, signal, opts);
33
+ return processExecutionPayload.call(chain, payloadInput, signal, opts);
34
34
  },
35
35
  {maxLength: QUEUE_MAX_LENGTH, noYieldIfOneItem: true, signal},
36
36
  metrics?.payloadEnvelopeProcessorQueue ?? undefined
@@ -1,5 +1,5 @@
1
1
  import type {ChainForkConfig} from "@lodestar/config";
2
- import {BlockExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
2
+ import type {BlockExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
3
3
  import {ForkSeq} from "@lodestar/params";
4
4
  import {DataAvailabilityStatus, IBeaconStateView, computeEpochAtSlot} from "@lodestar/state-transition";
5
5
  import type {IndexedAttestation, Slot, fulu} from "@lodestar/types";
@@ -43,8 +43,9 @@ export enum BlobSidecarValidation {
43
43
 
44
44
  export type ImportPayloadOpts = {
45
45
  /**
46
- * Set to true if envelope signature was already verified (e.g., during gossip/API validation).
47
- * When false/undefined, signature will be verified during import.
46
+ * Set to true when the envelope was already validated upstream (e.g., gossip/API validation):
47
+ * signature is trusted and execution_requests_root was already verified against the bid.
48
+ * When false/undefined, both are verified during import.
48
49
  */
49
50
  validSignature?: boolean;
50
51
  };
@@ -88,7 +89,14 @@ export type ImportBlockOpts = {
88
89
  seenTimestampSec?: number;
89
90
  };
90
91
 
91
- type FullyVerifiedBlockBase = {
92
+ /**
93
+ * A wrapper around a `SignedBeaconBlock` that indicates that this block is fully verified and ready to import.
94
+ *
95
+ * `executionStatus` reflects the outcome of execution payload verification at block-import time:
96
+ * - pre-gloas: Valid | Syncing | PreMerge (from EL notifyNewPayload against the in-block payload)
97
+ * - post-gloas: PayloadSeparated (payload arrives separately as an envelope and is imported later)
98
+ */
99
+ export type FullyVerifiedBlock = {
92
100
  blockInput: IBlockInput;
93
101
  postState: IBeaconStateView;
94
102
  parentBlockSlot: Slot;
@@ -98,25 +106,6 @@ type FullyVerifiedBlockBase = {
98
106
  indexedAttestations: IndexedAttestation[];
99
107
  /** Seen timestamp seconds */
100
108
  seenTimestampSec: number;
109
+ /** If the execution payload couldn't be verified because of EL syncing status, used in optimistic sync */
110
+ executionStatus: BlockExecutionStatus | PayloadExecutionStatus;
101
111
  };
102
-
103
- /**
104
- * A wrapper around a `SignedBeaconBlock` that indicates that this block is fully verified and ready to import.
105
- *
106
- * Discriminated union on `postPayloadState`:
107
- * - `null` → block has no pre-verified envelope; `executionStatus` is any `BlockExecutionStatus`
108
- * - non-null → envelope was pre-verified during state transition; `executionStatus` is narrowed to
109
- * `Valid | Syncing` (matching what `forkChoice.onExecutionPayload` expects)
110
- */
111
- export type FullyVerifiedBlock = FullyVerifiedBlockBase &
112
- (
113
- | {
114
- postPayloadState: null;
115
- /** If the execution payload couldn't be verified because of EL syncing status, used in optimistic sync or for merge block */
116
- executionStatus: BlockExecutionStatus;
117
- }
118
- | {
119
- postPayloadState: IBeaconStateView;
120
- executionStatus: PayloadExecutionStatus;
121
- }
122
- );