@lodestar/beacon-node 1.42.0-dev.7df0e2c8fa → 1.42.0-dev.8300b502a6

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 (295) 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/archiveStore/archiveStore.d.ts.map +1 -1
  26. package/lib/chain/archiveStore/archiveStore.js +1 -0
  27. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  28. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +3 -3
  29. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  30. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +6 -4
  31. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  32. package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts +2 -2
  33. package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts.map +1 -1
  34. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -0
  35. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
  36. package/lib/chain/archiveStore/historicalState/types.d.ts +2 -0
  37. package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
  38. package/lib/chain/archiveStore/historicalState/types.js.map +1 -1
  39. package/lib/chain/archiveStore/historicalState/worker.js +1 -4
  40. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  41. package/lib/chain/archiveStore/interface.d.ts +1 -0
  42. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  43. package/lib/chain/blocks/blockInput/blockInput.d.ts +5 -5
  44. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  45. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  46. package/lib/chain/blocks/blockInput/types.d.ts +4 -4
  47. package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
  48. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  49. package/lib/chain/blocks/importBlock.js +34 -20
  50. package/lib/chain/blocks/importBlock.js.map +1 -1
  51. package/lib/chain/blocks/importExecutionPayload.d.ts +10 -8
  52. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  53. package/lib/chain/blocks/importExecutionPayload.js +86 -49
  54. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  55. package/lib/chain/blocks/index.d.ts.map +1 -1
  56. package/lib/chain/blocks/index.js +2 -1
  57. package/lib/chain/blocks/index.js.map +1 -1
  58. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +14 -6
  59. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  60. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +33 -2
  61. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  62. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +2 -1
  63. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  64. package/lib/chain/blocks/types.d.ts +20 -14
  65. package/lib/chain/blocks/types.d.ts.map +1 -1
  66. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +2 -2
  67. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  68. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +4 -3
  69. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  70. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  71. package/lib/chain/blocks/verifyBlocksSignatures.js +4 -2
  72. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  73. package/lib/chain/chain.d.ts +3 -2
  74. package/lib/chain/chain.d.ts.map +1 -1
  75. package/lib/chain/chain.js +68 -28
  76. package/lib/chain/chain.js.map +1 -1
  77. package/lib/chain/emitter.d.ts +29 -7
  78. package/lib/chain/emitter.d.ts.map +1 -1
  79. package/lib/chain/emitter.js +12 -3
  80. package/lib/chain/emitter.js.map +1 -1
  81. package/lib/chain/errors/blockError.d.ts +6 -1
  82. package/lib/chain/errors/blockError.d.ts.map +1 -1
  83. package/lib/chain/errors/blockError.js +2 -0
  84. package/lib/chain/errors/blockError.js.map +1 -1
  85. package/lib/chain/errors/dataColumnSidecarError.d.ts +31 -1
  86. package/lib/chain/errors/dataColumnSidecarError.d.ts.map +1 -1
  87. package/lib/chain/errors/dataColumnSidecarError.js +7 -0
  88. package/lib/chain/errors/dataColumnSidecarError.js.map +1 -1
  89. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  90. package/lib/chain/forkChoice/index.js +10 -8
  91. package/lib/chain/forkChoice/index.js.map +1 -1
  92. package/lib/chain/interface.d.ts +4 -2
  93. package/lib/chain/interface.d.ts.map +1 -1
  94. package/lib/chain/lightClient/index.d.ts +2 -2
  95. package/lib/chain/lightClient/index.d.ts.map +1 -1
  96. package/lib/chain/lightClient/index.js +7 -0
  97. package/lib/chain/lightClient/index.js.map +1 -1
  98. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  99. package/lib/chain/opPools/aggregatedAttestationPool.js +5 -2
  100. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  101. package/lib/chain/opPools/executionPayloadBidPool.d.ts +2 -2
  102. package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -1
  103. package/lib/chain/opPools/executionPayloadBidPool.js +2 -2
  104. package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -1
  105. package/lib/chain/options.d.ts +1 -0
  106. package/lib/chain/options.d.ts.map +1 -1
  107. package/lib/chain/options.js +1 -0
  108. package/lib/chain/options.js.map +1 -1
  109. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  110. package/lib/chain/prepareNextSlot.js +7 -1
  111. package/lib/chain/prepareNextSlot.js.map +1 -1
  112. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +3 -3
  113. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  114. package/lib/chain/produceBlock/computeNewStateRoot.js +8 -8
  115. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  116. package/lib/chain/produceBlock/produceBlockBody.d.ts +5 -5
  117. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  118. package/lib/chain/produceBlock/produceBlockBody.js +23 -4
  119. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  120. package/lib/chain/seenCache/seenGossipBlockInput.d.ts +1 -1
  121. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  122. package/lib/chain/seenCache/seenGossipBlockInput.js +2 -2
  123. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  124. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +1 -1
  125. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  126. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +2 -2
  127. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  128. package/lib/chain/validation/block.d.ts.map +1 -1
  129. package/lib/chain/validation/block.js +14 -5
  130. package/lib/chain/validation/block.js.map +1 -1
  131. package/lib/chain/validation/dataColumnSidecar.d.ts +11 -4
  132. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  133. package/lib/chain/validation/dataColumnSidecar.js +184 -5
  134. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  135. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  136. package/lib/chain/validation/executionPayloadBid.js +7 -4
  137. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  138. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  139. package/lib/chain/validation/executionPayloadEnvelope.js +6 -1
  140. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  141. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  142. package/lib/chain/validation/payloadAttestationMessage.js +4 -1
  143. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  144. package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
  145. package/lib/chain/validation/syncCommittee.js +4 -0
  146. package/lib/chain/validation/syncCommittee.js.map +1 -1
  147. package/lib/chain/validation/syncCommitteeContributionAndProof.js +4 -1
  148. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  149. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  150. package/lib/chain/validatorMonitor.js +3 -3
  151. package/lib/chain/validatorMonitor.js.map +1 -1
  152. package/lib/db/buckets.d.ts +2 -2
  153. package/lib/db/buckets.d.ts.map +1 -1
  154. package/lib/db/buckets.js +2 -2
  155. package/lib/db/buckets.js.map +1 -1
  156. package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
  157. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  158. package/lib/db/repositories/dataColumnSidecar.d.ts.map +1 -1
  159. package/lib/db/repositories/dataColumnSidecar.js +4 -2
  160. package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
  161. package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
  162. package/lib/db/repositories/dataColumnSidecarArchive.js +4 -2
  163. package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
  164. package/lib/metrics/metrics/lodestar.d.ts +20 -0
  165. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  166. package/lib/metrics/metrics/lodestar.js +33 -0
  167. package/lib/metrics/metrics/lodestar.js.map +1 -1
  168. package/lib/network/interface.d.ts +3 -2
  169. package/lib/network/interface.d.ts.map +1 -1
  170. package/lib/network/libp2p/index.d.ts.map +1 -1
  171. package/lib/network/libp2p/index.js +19 -13
  172. package/lib/network/libp2p/index.js.map +1 -1
  173. package/lib/network/network.d.ts +3 -2
  174. package/lib/network/network.d.ts.map +1 -1
  175. package/lib/network/network.js +3 -0
  176. package/lib/network/network.js.map +1 -1
  177. package/lib/network/options.d.ts.map +1 -1
  178. package/lib/network/options.js +7 -2
  179. package/lib/network/options.js.map +1 -1
  180. package/lib/network/processor/extractSlotRootFns.d.ts +1 -1
  181. package/lib/network/processor/extractSlotRootFns.d.ts.map +1 -1
  182. package/lib/network/processor/extractSlotRootFns.js +25 -5
  183. package/lib/network/processor/extractSlotRootFns.js.map +1 -1
  184. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  185. package/lib/network/processor/gossipHandlers.js +260 -73
  186. package/lib/network/processor/gossipHandlers.js.map +1 -1
  187. package/lib/network/processor/index.d.ts +11 -1
  188. package/lib/network/processor/index.d.ts.map +1 -1
  189. package/lib/network/processor/index.js +234 -22
  190. package/lib/network/processor/index.js.map +1 -1
  191. package/lib/network/reqresp/types.d.ts +3 -3
  192. package/lib/network/reqresp/types.d.ts.map +1 -1
  193. package/lib/network/reqresp/types.js +9 -3
  194. package/lib/network/reqresp/types.js.map +1 -1
  195. package/lib/node/nodejs.d.ts.map +1 -1
  196. package/lib/node/nodejs.js +4 -1
  197. package/lib/node/nodejs.js.map +1 -1
  198. package/lib/node/notifier.d.ts.map +1 -1
  199. package/lib/node/notifier.js +2 -2
  200. package/lib/node/notifier.js.map +1 -1
  201. package/lib/sync/unknownBlock.js +2 -2
  202. package/lib/sync/unknownBlock.js.map +1 -1
  203. package/lib/sync/utils/downloadByRange.d.ts +3 -3
  204. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  205. package/lib/sync/utils/downloadByRange.js +4 -2
  206. package/lib/sync/utils/downloadByRange.js.map +1 -1
  207. package/lib/sync/utils/downloadByRoot.d.ts +3 -3
  208. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  209. package/lib/sync/utils/downloadByRoot.js +10 -5
  210. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  211. package/lib/util/blobs.d.ts +3 -3
  212. package/lib/util/blobs.d.ts.map +1 -1
  213. package/lib/util/blobs.js +21 -10
  214. package/lib/util/blobs.js.map +1 -1
  215. package/lib/util/dataColumns.d.ts +18 -11
  216. package/lib/util/dataColumns.d.ts.map +1 -1
  217. package/lib/util/dataColumns.js +51 -17
  218. package/lib/util/dataColumns.js.map +1 -1
  219. package/lib/util/execution.d.ts +6 -2
  220. package/lib/util/execution.d.ts.map +1 -1
  221. package/lib/util/execution.js +49 -25
  222. package/lib/util/execution.js.map +1 -1
  223. package/lib/util/sszBytes.d.ts +25 -1
  224. package/lib/util/sszBytes.d.ts.map +1 -1
  225. package/lib/util/sszBytes.js +189 -2
  226. package/lib/util/sszBytes.js.map +1 -1
  227. package/package.json +15 -15
  228. package/src/api/impl/beacon/blocks/index.ts +32 -15
  229. package/src/api/impl/beacon/pool/index.ts +4 -0
  230. package/src/api/impl/beacon/state/index.ts +15 -15
  231. package/src/api/impl/debug/index.ts +2 -2
  232. package/src/api/impl/lodestar/index.ts +4 -0
  233. package/src/api/impl/validator/index.ts +9 -2
  234. package/src/chain/ColumnReconstructionTracker.ts +6 -5
  235. package/src/chain/GetBlobsTracker.ts +14 -12
  236. package/src/chain/archiveStore/archiveStore.ts +1 -0
  237. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +6 -5
  238. package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +2 -1
  239. package/src/chain/archiveStore/historicalState/types.ts +2 -0
  240. package/src/chain/archiveStore/historicalState/worker.ts +1 -5
  241. package/src/chain/archiveStore/interface.ts +1 -0
  242. package/src/chain/blocks/blockInput/blockInput.ts +8 -8
  243. package/src/chain/blocks/blockInput/types.ts +4 -4
  244. package/src/chain/blocks/importBlock.ts +45 -23
  245. package/src/chain/blocks/importExecutionPayload.ts +94 -53
  246. package/src/chain/blocks/index.ts +2 -1
  247. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +53 -12
  248. package/src/chain/blocks/payloadEnvelopeInput/types.ts +2 -1
  249. package/src/chain/blocks/types.ts +25 -14
  250. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +6 -5
  251. package/src/chain/blocks/verifyBlocksSignatures.ts +9 -2
  252. package/src/chain/chain.ts +77 -32
  253. package/src/chain/emitter.ts +25 -7
  254. package/src/chain/errors/blockError.ts +4 -1
  255. package/src/chain/errors/dataColumnSidecarError.ts +32 -1
  256. package/src/chain/forkChoice/index.ts +11 -8
  257. package/src/chain/interface.ts +4 -2
  258. package/src/chain/lightClient/index.ts +15 -3
  259. package/src/chain/opPools/aggregatedAttestationPool.ts +6 -1
  260. package/src/chain/opPools/executionPayloadBidPool.ts +3 -3
  261. package/src/chain/options.ts +2 -0
  262. package/src/chain/prepareNextSlot.ts +8 -0
  263. package/src/chain/produceBlock/computeNewStateRoot.ts +11 -10
  264. package/src/chain/produceBlock/produceBlockBody.ts +40 -10
  265. package/src/chain/seenCache/seenGossipBlockInput.ts +2 -2
  266. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +2 -2
  267. package/src/chain/validation/block.ts +15 -7
  268. package/src/chain/validation/dataColumnSidecar.ts +230 -7
  269. package/src/chain/validation/executionPayloadBid.ts +7 -3
  270. package/src/chain/validation/executionPayloadEnvelope.ts +10 -1
  271. package/src/chain/validation/payloadAttestationMessage.ts +4 -0
  272. package/src/chain/validation/syncCommittee.ts +5 -1
  273. package/src/chain/validation/syncCommitteeContributionAndProof.ts +5 -1
  274. package/src/chain/validatorMonitor.ts +3 -2
  275. package/src/db/buckets.ts +2 -2
  276. package/src/db/repositories/dataColumnSidecar.ts +4 -2
  277. package/src/db/repositories/dataColumnSidecarArchive.ts +4 -2
  278. package/src/metrics/metrics/lodestar.ts +34 -0
  279. package/src/network/interface.ts +3 -2
  280. package/src/network/libp2p/index.ts +21 -15
  281. package/src/network/network.ts +7 -4
  282. package/src/network/options.ts +7 -2
  283. package/src/network/processor/extractSlotRootFns.ts +32 -6
  284. package/src/network/processor/gossipHandlers.ts +325 -86
  285. package/src/network/processor/index.ts +304 -22
  286. package/src/network/reqresp/types.ts +13 -5
  287. package/src/node/nodejs.ts +5 -2
  288. package/src/node/notifier.ts +7 -2
  289. package/src/sync/unknownBlock.ts +3 -3
  290. package/src/sync/utils/downloadByRange.ts +9 -7
  291. package/src/sync/utils/downloadByRoot.ts +16 -12
  292. package/src/util/blobs.ts +35 -15
  293. package/src/util/dataColumns.ts +69 -25
  294. package/src/util/execution.ts +49 -30
  295. package/src/util/sszBytes.ts +245 -3
@@ -7,6 +7,7 @@ export type HistoricalStateRegenInitModules = {
7
7
  opts: {
8
8
  genesisTime: number;
9
9
  dbLocation: string;
10
+ nativeStateView: boolean;
10
11
  };
11
12
  config: BeaconConfig;
12
13
  logger: LoggerNode;
@@ -26,6 +27,7 @@ export type HistoricalStateWorkerData = {
26
27
  dbLocation: string;
27
28
  metricsEnabled: boolean;
28
29
  loggerOpts: LoggerNodeOpts;
30
+ nativeStateView: boolean;
29
31
  };
30
32
 
31
33
  export type HistoricalStateWorkerApi = {
@@ -3,7 +3,6 @@ import {Transfer, expose} from "@chainsafe/threads/worker";
3
3
  import {chainConfigFromJson, createBeaconConfig} from "@lodestar/config";
4
4
  import {LevelDbController} from "@lodestar/db/controller/level";
5
5
  import {getNodeLogger} from "@lodestar/logger/node";
6
- import {createPubkeyCache} from "@lodestar/state-transition";
7
6
  import {BeaconDb} from "../../../db/index.js";
8
7
  import {RegistryMetricCreator, collectNodeJSMetrics} from "../../../metrics/index.js";
9
8
  import {JobFnQueue} from "../../../util/queue/fnQueue.js";
@@ -52,9 +51,6 @@ const queue = new JobFnQueue(
52
51
  queueMetrics
53
52
  );
54
53
 
55
- // Reuse a single pubkey cache across all historical state regen calls in this worker
56
- const pubkeyCache = createPubkeyCache();
57
-
58
54
  const api: HistoricalStateWorkerApi = {
59
55
  async close() {
60
56
  abortController.abort();
@@ -66,7 +62,7 @@ const api: HistoricalStateWorkerApi = {
66
62
  historicalStateRegenMetrics?.regenRequestCount.inc();
67
63
 
68
64
  const stateBytes = await queue.push<Uint8Array>(() =>
69
- getHistoricalState(slot, config, db, pubkeyCache, historicalStateRegenMetrics)
65
+ getHistoricalState(slot, config, db, workerData.nativeStateView, historicalStateRegenMetrics)
70
66
  );
71
67
  const result = Transfer(stateBytes, [stateBytes.buffer]) as unknown as Uint8Array;
72
68
 
@@ -25,6 +25,7 @@ export type ArchiveStoreOpts = StatesArchiveOpts & {
25
25
  archiveDataEpochs?: number;
26
26
  pruneHistory?: boolean;
27
27
  serveHistoricalState?: boolean;
28
+ nativeStateView?: boolean;
28
29
  };
29
30
 
30
31
  export type ProposalStats = {
@@ -617,7 +617,7 @@ type BlockInputColumnsState =
617
617
  * - The block is not yet seen and all required sampled columns are seen
618
618
  * - The block is not yet seen and all required sampled columns are not yet seen
619
619
  */
620
- export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.DataColumnSidecars> {
620
+ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.DataColumnSidecar[]> {
621
621
  type = DAType.Columns as const;
622
622
 
623
623
  state: BlockInputColumnsState;
@@ -630,7 +630,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
630
630
  *
631
631
  * This is different from `dataPromise` which resolves when all data is available or could become available (e.g. through reconstruction)
632
632
  */
633
- protected computedDataPromise = createPromise<fulu.DataColumnSidecars>();
633
+ protected computedDataPromise = createPromise<fulu.DataColumnSidecar[]>();
634
634
 
635
635
  private constructor(
636
636
  init: BlockInputInit,
@@ -854,8 +854,8 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
854
854
  return this.state.versionedHashes;
855
855
  }
856
856
 
857
- getCustodyColumns(): fulu.DataColumnSidecars {
858
- const columns: fulu.DataColumnSidecars = [];
857
+ getCustodyColumns(): fulu.DataColumnSidecar[] {
858
+ const columns: fulu.DataColumnSidecar[] = [];
859
859
  for (const index of this.custodyColumns) {
860
860
  const column = this.columnsCache.get(index);
861
861
  if (column) {
@@ -876,8 +876,8 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
876
876
  return columns;
877
877
  }
878
878
 
879
- getSampledColumns(): fulu.DataColumnSidecars {
880
- const columns: fulu.DataColumnSidecars = [];
879
+ getSampledColumns(): fulu.DataColumnSidecar[] {
880
+ const columns: fulu.DataColumnSidecar[] = [];
881
881
  for (const index of this.sampledColumns) {
882
882
  const column = this.columnsCache.get(index);
883
883
  if (column) {
@@ -891,7 +891,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
891
891
  return [...this.columnsCache.values()];
892
892
  }
893
893
 
894
- getAllColumns(): fulu.DataColumnSidecars {
894
+ getAllColumns(): fulu.DataColumnSidecar[] {
895
895
  return this.getAllColumnsWithSource().map(({columnSidecar}) => columnSidecar);
896
896
  }
897
897
 
@@ -919,7 +919,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
919
919
  return this.state.hasComputedAllData;
920
920
  }
921
921
 
922
- waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<fulu.DataColumnSidecars> {
922
+ waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<fulu.DataColumnSidecar[]> {
923
923
  if (!this.state.hasComputedAllData) {
924
924
  return withTimeout(() => this.computedDataPromise.promise, timeout, signal);
925
925
  }
@@ -1,5 +1,5 @@
1
1
  import {ForkName} from "@lodestar/params";
2
- import {ColumnIndex, DataColumnSidecars, RootHex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
2
+ import {ColumnIndex, DataColumnSidecar, RootHex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
3
3
  import {VersionedHashes} from "../../../execution/index.js";
4
4
 
5
5
  export enum DAType {
@@ -9,7 +9,7 @@ export enum DAType {
9
9
  NoData = "no-data",
10
10
  }
11
11
 
12
- export type DAData = null | deneb.BlobSidecars | fulu.DataColumnSidecars;
12
+ export type DAData = null | deneb.BlobSidecars | fulu.DataColumnSidecar[];
13
13
 
14
14
  /**
15
15
  * Represents were input originated. Blocks and Data can come from different
@@ -108,9 +108,9 @@ export type MissingColumnMeta = {
108
108
  export interface IDataColumnsInput {
109
109
  readonly slot: Slot;
110
110
  readonly blockRootHex: string;
111
- getCustodyColumns(): DataColumnSidecars;
111
+ getCustodyColumns(): DataColumnSidecar[];
112
112
  hasComputedAllData(): boolean;
113
- waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<DataColumnSidecars>;
113
+ waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<DataColumnSidecar[]>;
114
114
  }
115
115
 
116
116
  /**
@@ -3,6 +3,7 @@ import {routes} from "@lodestar/api";
3
3
  import {
4
4
  AncestorStatus,
5
5
  EpochDifference,
6
+ ExecutionStatus,
6
7
  ForkChoiceError,
7
8
  ForkChoiceErrorCode,
8
9
  NotReorgedReason,
@@ -24,6 +25,8 @@ import {
24
25
  computeStartSlotAtEpoch,
25
26
  computeTimeAtSlot,
26
27
  isStartSlotOfEpoch,
28
+ isStatePostAltair,
29
+ isStatePostBellatrix,
27
30
  } from "@lodestar/state-transition";
28
31
  import {
29
32
  Attestation,
@@ -84,7 +87,7 @@ export async function importBlock(
84
87
  fullyVerifiedBlock: FullyVerifiedBlock,
85
88
  opts: ImportBlockOpts
86
89
  ): Promise<void> {
87
- const {blockInput, postState, parentBlockSlot, executionStatus, dataAvailabilityStatus, indexedAttestations} =
90
+ const {blockInput, postBlockState, parentBlockSlot, executionStatus, dataAvailabilityStatus, indexedAttestations} =
88
91
  fullyVerifiedBlock;
89
92
  const block = blockInput.getBlock();
90
93
  const source = blockInput.getBlockSource();
@@ -96,7 +99,7 @@ export async function importBlock(
96
99
  const blockEpoch = computeEpochAtSlot(blockSlot);
97
100
  const prevFinalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
98
101
  const blockDelaySec =
99
- fullyVerifiedBlock.seenTimestampSec - computeTimeAtSlot(this.config, blockSlot, postState.genesisTime);
102
+ fullyVerifiedBlock.seenTimestampSec - computeTimeAtSlot(this.config, blockSlot, postBlockState.genesisTime);
100
103
  const recvToValLatency = Date.now() / 1000 - (opts.seenTimestampSec ?? Date.now() / 1000);
101
104
  const fork = this.config.getForkSeq(blockSlot);
102
105
 
@@ -119,13 +122,13 @@ export async function importBlock(
119
122
  // 2. Import block to fork choice
120
123
 
121
124
  // Should compute checkpoint balances before forkchoice.onBlock
122
- this.checkpointBalancesCache.processState(blockRootHex, postState);
125
+ this.checkpointBalancesCache.processState(blockRootHex, postBlockState);
123
126
  const blockSummary = this.forkChoice.onBlock(
124
127
  block.message,
125
- postState,
128
+ postBlockState,
126
129
  blockDelaySec,
127
130
  currentSlot,
128
- executionStatus,
131
+ fork >= ForkSeq.gloas ? ExecutionStatus.PayloadSeparated : executionStatus,
129
132
  dataAvailabilityStatus
130
133
  );
131
134
 
@@ -135,13 +138,14 @@ export async function importBlock(
135
138
  // Post-Gloas: blockSummary.payloadStatus is always PENDING, so payloadPresent = false (block state only, no payload processing yet)
136
139
  const payloadPresent = !isGloasBlock(blockSummary);
137
140
  // processState manages both block state and payload state variants together for memory/disk management
138
- this.regen.processBlockState(blockRootHex, postState);
141
+ this.regen.processBlockState(blockRootHex, postBlockState);
139
142
 
140
143
  // For Gloas blocks, create PayloadEnvelopeInput so it's available for later payload import
141
144
  if (fork >= ForkSeq.gloas) {
142
- this.seenPayloadEnvelopeInputCache.add({
145
+ const payloadInput = this.seenPayloadEnvelopeInputCache.add({
143
146
  blockRootHex,
144
147
  block: block as SignedBeaconBlock<ForkPostGloas>,
148
+ forkName: blockInput.forkName,
145
149
  sampledColumns: this.custodyConfig.sampledColumns,
146
150
  custodyColumns: this.custodyConfig.custodyColumns,
147
151
  timeCreatedSec: fullyVerifiedBlock.seenTimestampSec,
@@ -152,6 +156,22 @@ export async function importBlock(
152
156
  source: source.source,
153
157
  ...(opts.seenTimestampSec !== undefined ? {recvToImport: Date.now() / 1000 - opts.seenTimestampSec} : {}),
154
158
  });
159
+
160
+ // Immediately attempt fetch of data columns from execution engine as the bid contains kzg commitments
161
+ // which is all the information we need so there is no reason to delay until execution payload arrives
162
+ // TODO GLOAS: If we want EL retries after this initial attempt, add an explicit retry policy here
163
+ // (for example later in the slot). Do not couple retries to incoming gossip columns.
164
+ this.getBlobsTracker.triggerGetBlobs(payloadInput, () => {
165
+ // TODO GLOAS: come up with a better mechanism to trigger processExecutionPayload after data becomes available,
166
+ // similar to how pre-gloas uses waitForBlockAndAllData with a cutoff timeout and incompleteBlockInput event
167
+ this.processExecutionPayload(payloadInput, {validSignature: true}).catch((e) => {
168
+ this.logger.debug(
169
+ "Error processing execution payload after getBlobs",
170
+ {slot: blockSlot, root: blockRootHex},
171
+ e as Error
172
+ );
173
+ });
174
+ });
155
175
  }
156
176
 
157
177
  this.metrics?.importBlock.bySource.inc({source: source.source});
@@ -171,7 +191,7 @@ export async function importBlock(
171
191
  (opts.importAttestations !== AttestationImportOpt.Skip && blockEpoch >= currentEpoch - FORK_CHOICE_ATT_EPOCH_LIMIT)
172
192
  ) {
173
193
  const attestations = block.message.body.attestations;
174
- const rootCache = new RootCache(postState);
194
+ const rootCache = new RootCache(postBlockState);
175
195
  const invalidAttestationErrorsByCode = new Map<string, {error: Error; count: number}>();
176
196
 
177
197
  const addAttestation = fork >= ForkSeq.electra ? addAttestationPostElectra : addAttestationPreElectra;
@@ -185,7 +205,7 @@ export async function importBlock(
185
205
  const attDataRoot = toRootHex(ssz.phase0.AttestationData.hashTreeRoot(indexedAttestation.data));
186
206
  addAttestation.call(
187
207
  this,
188
- postState,
208
+ postBlockState,
189
209
  target,
190
210
  attDataRoot,
191
211
  attestation as Attestation<ForkPostElectra>,
@@ -300,7 +320,7 @@ export async function importBlock(
300
320
 
301
321
  if (newHead.blockRoot !== oldHead.blockRoot) {
302
322
  // Set head state as strong reference
303
- this.regen.updateHeadState(newHead, postState);
323
+ this.regen.updateHeadState(newHead, postBlockState);
304
324
 
305
325
  try {
306
326
  this.emitter.emit(routes.events.EventType.head, {
@@ -370,11 +390,13 @@ export async function importBlock(
370
390
  // we want to import block asap so do this in the next event loop
371
391
  callInNextEventLoop(() => {
372
392
  try {
373
- this.lightClientServer?.onImportBlockHead(
374
- block.message as BeaconBlock<ForkPostAltair>,
375
- postState,
376
- parentBlockSlot
377
- );
393
+ if (isStatePostAltair(postBlockState)) {
394
+ this.lightClientServer?.onImportBlockHead(
395
+ block.message as BeaconBlock<ForkPostAltair>,
396
+ postBlockState,
397
+ parentBlockSlot
398
+ );
399
+ }
378
400
  } catch (e) {
379
401
  this.logger.verbose("Error lightClientServer.onImportBlock", {slot: blockSlot}, e as Error);
380
402
  }
@@ -393,11 +415,11 @@ export async function importBlock(
393
415
  // and the block is weak and can potentially be reorged out.
394
416
  let shouldOverrideFcu = false;
395
417
 
396
- if (blockSlot >= currentSlot && postState.isExecutionStateType) {
418
+ if (blockSlot >= currentSlot && isStatePostBellatrix(postBlockState) && postBlockState.isExecutionStateType) {
397
419
  let notOverrideFcuReason = NotReorgedReason.Unknown;
398
420
  const proposalSlot = blockSlot + 1;
399
421
  try {
400
- const proposerIndex = postState.getBeaconProposer(proposalSlot);
422
+ const proposerIndex = postBlockState.getBeaconProposer(proposalSlot);
401
423
  const feeRecipient = this.beaconProposerCache.get(proposerIndex);
402
424
 
403
425
  if (feeRecipient) {
@@ -477,20 +499,20 @@ export async function importBlock(
477
499
  }
478
500
  }
479
501
 
480
- if (!postState.isStateValidatorsNodesPopulated()) {
481
- this.logger.verbose("After importBlock caching postState without SSZ cache", {slot: postState.slot});
502
+ if (!postBlockState.isStateValidatorsNodesPopulated()) {
503
+ this.logger.verbose("After importBlock caching postState without SSZ cache", {slot: postBlockState.slot});
482
504
  }
483
505
 
484
506
  // Cache shufflings when crossing an epoch boundary
485
507
  const parentEpoch = computeEpochAtSlot(parentBlockSlot);
486
508
  if (parentEpoch < blockEpoch) {
487
- this.shufflingCache.processState(postState);
509
+ this.shufflingCache.processState(postBlockState);
488
510
  this.logger.verbose("Processed shuffling for next epoch", {parentEpoch, blockEpoch, slot: blockSlot});
489
511
  }
490
512
 
491
513
  if (blockSlot % SLOTS_PER_EPOCH === 0) {
492
514
  // Cache state to preserve epoch transition work
493
- const checkpointState = postState;
515
+ const checkpointState = postBlockState;
494
516
  const cp = getCheckpointFromState(checkpointState);
495
517
  this.regen.addCheckpointState(cp, checkpointState, payloadPresent);
496
518
  // consumers should not mutate state ever
@@ -580,11 +602,11 @@ export async function importBlock(
580
602
  this.metrics?.parentBlockDistance.observe(blockSlot - parentBlockSlot);
581
603
  this.metrics?.proposerBalanceDeltaAny.observe(fullyVerifiedBlock.proposerBalanceDelta);
582
604
  this.validatorMonitor?.registerImportedBlock(block.message, fullyVerifiedBlock);
583
- if (this.config.getForkSeq(blockSlot) >= ForkSeq.altair) {
605
+ if (isStatePostAltair(fullyVerifiedBlock.postBlockState)) {
584
606
  this.validatorMonitor?.registerSyncAggregateInBlock(
585
607
  blockEpoch,
586
608
  (block as altair.SignedBeaconBlock).message.body.syncAggregate,
587
- fullyVerifiedBlock.postState.currentSyncCommitteeIndexed.validatorIndices
609
+ fullyVerifiedBlock.postBlockState.currentSyncCommitteeIndexed.validatorIndices
588
610
  );
589
611
  }
590
612
 
@@ -1,6 +1,7 @@
1
1
  import {routes} from "@lodestar/api";
2
- import {ForkName} from "@lodestar/params";
3
- import {getExecutionPayloadEnvelopeSignatureSet} from "@lodestar/state-transition";
2
+ import {ExecutionStatus, PayloadExecutionStatus} from "@lodestar/fork-choice";
3
+ import {SLOTS_PER_EPOCH} from "@lodestar/params";
4
+ import {getExecutionPayloadEnvelopeSignatureSet, isStatePostGloas} from "@lodestar/state-transition";
4
5
  import {byteArrayEquals, fromHex, toRootHex} from "@lodestar/utils";
5
6
  import {ExecutionPayloadStatus} from "../../execution/index.js";
6
7
  import {isQueueErrorAborted} from "../../util/queue/index.js";
@@ -51,18 +52,33 @@ export class PayloadError extends Error {
51
52
  }
52
53
  }
53
54
 
55
+ function toForkChoiceExecutionStatus(status: ExecutionPayloadStatus): PayloadExecutionStatus {
56
+ switch (status) {
57
+ case ExecutionPayloadStatus.VALID:
58
+ return ExecutionStatus.Valid;
59
+ // TODO GLOAS: Handle optimistic import for payload
60
+ case ExecutionPayloadStatus.SYNCING:
61
+ case ExecutionPayloadStatus.ACCEPTED:
62
+ return ExecutionStatus.Syncing;
63
+ default:
64
+ throw new Error(`Unexpected execution payload status for fork choice: ${status}`);
65
+ }
66
+ }
67
+
54
68
  /**
55
69
  * Import an execution payload envelope after all data is available.
56
70
  *
57
71
  * This function:
58
- * 1. Gets the ProtoBlock from fork choice
59
- * 2. Applies write-queue backpressure (waitForSpace) early, before verification
60
- * 3. Regenerates the block state
61
- * 4. Runs EL verification (notifyNewPayload) in parallel with signature verification and processExecutionPayloadEnvelope
62
- * 5. Persists verified payload envelope to hot DB
63
- * 6. Updates fork choice
64
- * 7. Caches the post-execution payload state
65
- * 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
66
82
  *
67
83
  */
68
84
  export async function importExecutionPayload(
@@ -70,10 +86,24 @@ export async function importExecutionPayload(
70
86
  payloadInput: PayloadEnvelopeInput,
71
87
  opts: ImportPayloadOpts = {}
72
88
  ): Promise<void> {
73
- const envelope = payloadInput.getPayloadEnvelope();
89
+ const signedEnvelope = payloadInput.getPayloadEnvelope();
90
+ const envelope = signedEnvelope.message;
74
91
  const blockRootHex = payloadInput.blockRootHex;
92
+ const blockHashHex = payloadInput.getBlockHashHex();
93
+ const fork = this.config.getForkName(envelope.slot);
94
+
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
+ }
75
105
 
76
- // 1. Get ProtoBlock for parent root lookup
106
+ // 2. Get ProtoBlock for parent root lookup
77
107
  const protoBlock = this.forkChoice.getBlockHexDefaultStatus(blockRootHex);
78
108
  if (!protoBlock) {
79
109
  throw new PayloadError({
@@ -82,11 +112,11 @@ export async function importExecutionPayload(
82
112
  });
83
113
  }
84
114
 
85
- // 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.
86
116
  // The actual DB write is deferred until after verification succeeds.
87
117
  await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();
88
118
 
89
- // 3. Get pre-state for processExecutionPayloadEnvelope
119
+ // 4. Get pre-state for processExecutionPayloadEnvelope
90
120
  // We need the block state (post-block, pre-payload) to process the envelope
91
121
  const blockState = await this.regen.getBlockSlotState(
92
122
  protoBlock,
@@ -94,17 +124,23 @@ export async function importExecutionPayload(
94
124
  {dontTransferCache: true},
95
125
  RegenCaller.processBlock
96
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
+ }
97
133
 
98
- // 4. Run verification steps in parallel
134
+ // 5. Run verification steps in parallel
99
135
  // Note: No data availability check needed here - importExecutionPayload is only
100
136
  // called when payloadInput.isComplete() is true, so all data is already available.
101
137
  const [execResult, signatureValid, postPayloadResult] = await Promise.all([
102
138
  this.executionEngine.notifyNewPayload(
103
- ForkName.gloas,
104
- envelope.message.payload,
139
+ fork,
140
+ envelope.payload,
105
141
  payloadInput.getVersionedHashes(),
106
142
  fromHex(protoBlock.parentRoot),
107
- envelope.message.executionRequests
143
+ envelope.executionRequests
108
144
  ),
109
145
 
110
146
  opts.validSignature === true
@@ -114,7 +150,7 @@ export async function importExecutionPayload(
114
150
  this.config,
115
151
  this.pubkeyCache,
116
152
  blockState,
117
- envelope,
153
+ signedEnvelope,
118
154
  payloadInput.proposerIndex
119
155
  );
120
156
  return this.bls.verifySignatureSets([signatureSet]);
@@ -125,7 +161,7 @@ export async function importExecutionPayload(
125
161
  (async () => {
126
162
  try {
127
163
  return {
128
- postPayloadState: blockState.processExecutionPayloadEnvelope(envelope, {
164
+ postPayloadState: blockState.processExecutionPayloadEnvelope(signedEnvelope, {
129
165
  verifySignature: false,
130
166
  verifyStateRoot: false,
131
167
  }),
@@ -142,12 +178,12 @@ export async function importExecutionPayload(
142
178
  })(),
143
179
  ]);
144
180
 
145
- // 4b. Check signature verification result
181
+ // 5a. Check signature verification result
146
182
  if (!signatureValid) {
147
183
  throw new PayloadError({code: PayloadErrorCode.INVALID_SIGNATURE});
148
184
  }
149
185
 
150
- // 5. Handle EL response
186
+ // 5b. Handle EL response
151
187
  switch (execResult.status) {
152
188
  case ExecutionPayloadStatus.VALID:
153
189
  break;
@@ -161,12 +197,7 @@ export async function importExecutionPayload(
161
197
 
162
198
  case ExecutionPayloadStatus.ACCEPTED:
163
199
  case ExecutionPayloadStatus.SYNCING:
164
- // TODO GLOAS: Handle optimistic import for payload - for now treat as error
165
- throw new PayloadError({
166
- code: PayloadErrorCode.EXECUTION_ENGINE_ERROR,
167
- execStatus: execResult.status,
168
- errorMessage: execResult.validationError ?? "EL syncing, payload not yet validated",
169
- });
200
+ break;
170
201
 
171
202
  case ExecutionPayloadStatus.INVALID_BLOCK_HASH:
172
203
  case ExecutionPayloadStatus.ELERROR:
@@ -178,59 +209,69 @@ export async function importExecutionPayload(
178
209
  });
179
210
  }
180
211
 
181
- // 5b. Verify envelope state root matches post-state
212
+ // 5c. Verify envelope state root matches post-state
182
213
  const postPayloadState = postPayloadResult.postPayloadState;
183
214
  const postPayloadStateRoot = postPayloadState.hashTreeRoot();
184
- if (!byteArrayEquals(envelope.message.stateRoot, postPayloadStateRoot)) {
215
+ if (!byteArrayEquals(envelope.stateRoot, postPayloadStateRoot)) {
185
216
  throw new PayloadError({
186
217
  code: PayloadErrorCode.STATE_TRANSITION_ERROR,
187
- 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)}`,
188
219
  });
189
220
  }
190
221
 
191
- // 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)
192
223
  this.unfinalizedPayloadEnvelopeWrites.push(payloadInput).catch((e) => {
193
224
  if (!isQueueErrorAborted(e)) {
194
225
  this.logger.error(
195
226
  "Error pushing payload envelope to unfinalized write queue",
196
- {slot: payloadInput.slot, root: blockRootHex},
227
+ {slot: envelope.slot, blockRoot: blockRootHex},
197
228
  e as Error
198
229
  );
199
230
  }
200
231
  });
201
232
 
202
- // 6. Update fork choice
233
+ // 7. Update fork choice
203
234
  this.forkChoice.onExecutionPayload(
204
235
  blockRootHex,
205
- payloadInput.getBlockHashHex(),
206
- envelope.message.payload.blockNumber,
207
- toRootHex(postPayloadStateRoot)
236
+ blockHashHex,
237
+ envelope.payload.blockNumber,
238
+ toRootHex(postPayloadStateRoot),
239
+ toForkChoiceExecutionStatus(execResult.status)
208
240
  );
209
241
 
210
- // 7. Cache payload state
211
- // TODO GLOAS: Enable when PR #8868 merged (adds processPayloadState)
212
- // this.regen.processPayloadState(postPayloadState);
213
- // if epoch boundary also call
214
- // this.regen.addCheckpointState(cp, checkpointState, true);
242
+ // 8. Cache payload state
243
+ this.regen.processPayloadState(postPayloadState);
244
+ if (postPayloadState.slot % SLOTS_PER_EPOCH === 0) {
245
+ const {checkpoint} = postPayloadState.computeAnchorCheckpoint();
246
+ this.regen.addCheckpointState(checkpoint, postPayloadState, true);
247
+ }
215
248
 
216
- // 8. Record metrics for payload envelope and column sources
249
+ // 9. Record metrics for payload envelope and column sources
217
250
  this.metrics?.importPayload.bySource.inc({source: payloadInput.getPayloadEnvelopeSource().source});
218
251
  for (const {source} of payloadInput.getSampledColumnsWithSource()) {
219
252
  this.metrics?.importPayload.columnsBySource.inc({source});
220
253
  }
221
254
 
222
- this.logger.verbose("Execution payload imported", {
223
- slot: payloadInput.slot,
224
- root: blockRootHex,
225
- blockHash: payloadInput.getBlockHashHex(),
226
- });
255
+ const stateRootHex = toRootHex(envelope.stateRoot);
227
256
 
228
- // 9. Emit event after payload is fully verified and imported to fork choice, only for recent enough payloads
229
- const currentSlot = this.clock.currentSlot;
230
- if (currentSlot - payloadInput.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
231
- this.emitter.emit(routes.events.EventType.executionPayloadAvailable, {
232
- 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,
233
263
  blockRoot: blockRootHex,
264
+ stateRoot: stateRootHex,
265
+ // TODO GLOAS: revisit once we support optimistic import
266
+ executionOptimistic: false,
234
267
  });
235
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
+ });
236
277
  }
@@ -88,7 +88,8 @@ export async function processBlocks(
88
88
  const fullyVerifiedBlocks = relevantBlocks.map(
89
89
  (block, i): FullyVerifiedBlock => ({
90
90
  blockInput: block,
91
- postState: postStates[i],
91
+ postBlockState: postStates[i],
92
+ postPayloadState: null,
92
93
  parentBlockSlot: parentSlots[i],
93
94
  executionStatus: executionStatuses[i],
94
95
  // start supporting optimistic syncing/processing