@lodestar/beacon-node 1.42.0-dev.5007abf468 → 1.42.0-dev.5295e30d5c

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 (291) 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 +7 -1
  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 +64 -24
  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/dataColumnSidecarError.d.ts +31 -1
  82. package/lib/chain/errors/dataColumnSidecarError.d.ts.map +1 -1
  83. package/lib/chain/errors/dataColumnSidecarError.js +7 -0
  84. package/lib/chain/errors/dataColumnSidecarError.js.map +1 -1
  85. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  86. package/lib/chain/forkChoice/index.js +10 -8
  87. package/lib/chain/forkChoice/index.js.map +1 -1
  88. package/lib/chain/interface.d.ts +4 -2
  89. package/lib/chain/interface.d.ts.map +1 -1
  90. package/lib/chain/lightClient/index.d.ts +2 -2
  91. package/lib/chain/lightClient/index.d.ts.map +1 -1
  92. package/lib/chain/lightClient/index.js +7 -0
  93. package/lib/chain/lightClient/index.js.map +1 -1
  94. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  95. package/lib/chain/opPools/aggregatedAttestationPool.js +5 -2
  96. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  97. package/lib/chain/opPools/executionPayloadBidPool.d.ts +2 -2
  98. package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -1
  99. package/lib/chain/opPools/executionPayloadBidPool.js +2 -2
  100. package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -1
  101. package/lib/chain/options.d.ts +1 -0
  102. package/lib/chain/options.d.ts.map +1 -1
  103. package/lib/chain/options.js +1 -0
  104. package/lib/chain/options.js.map +1 -1
  105. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  106. package/lib/chain/prepareNextSlot.js +7 -1
  107. package/lib/chain/prepareNextSlot.js.map +1 -1
  108. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +2 -2
  109. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  110. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  111. package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -3
  112. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  113. package/lib/chain/produceBlock/produceBlockBody.js +10 -1
  114. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  115. package/lib/chain/seenCache/seenGossipBlockInput.d.ts +1 -1
  116. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  117. package/lib/chain/seenCache/seenGossipBlockInput.js +2 -2
  118. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  119. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +1 -1
  120. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  121. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +2 -2
  122. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  123. package/lib/chain/validation/block.d.ts.map +1 -1
  124. package/lib/chain/validation/block.js +2 -2
  125. package/lib/chain/validation/block.js.map +1 -1
  126. package/lib/chain/validation/dataColumnSidecar.d.ts +11 -4
  127. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  128. package/lib/chain/validation/dataColumnSidecar.js +184 -5
  129. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  130. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  131. package/lib/chain/validation/executionPayloadBid.js +7 -4
  132. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  133. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  134. package/lib/chain/validation/executionPayloadEnvelope.js +4 -1
  135. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  136. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  137. package/lib/chain/validation/payloadAttestationMessage.js +4 -1
  138. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  139. package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
  140. package/lib/chain/validation/syncCommittee.js +4 -0
  141. package/lib/chain/validation/syncCommittee.js.map +1 -1
  142. package/lib/chain/validation/syncCommitteeContributionAndProof.js +4 -1
  143. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  144. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  145. package/lib/chain/validatorMonitor.js +3 -3
  146. package/lib/chain/validatorMonitor.js.map +1 -1
  147. package/lib/db/buckets.d.ts +2 -2
  148. package/lib/db/buckets.d.ts.map +1 -1
  149. package/lib/db/buckets.js +2 -2
  150. package/lib/db/buckets.js.map +1 -1
  151. package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
  152. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  153. package/lib/db/repositories/dataColumnSidecar.d.ts.map +1 -1
  154. package/lib/db/repositories/dataColumnSidecar.js +4 -2
  155. package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
  156. package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
  157. package/lib/db/repositories/dataColumnSidecarArchive.js +4 -2
  158. package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
  159. package/lib/metrics/metrics/lodestar.d.ts +20 -0
  160. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  161. package/lib/metrics/metrics/lodestar.js +33 -0
  162. package/lib/metrics/metrics/lodestar.js.map +1 -1
  163. package/lib/network/gossip/topic.d.ts +727 -0
  164. package/lib/network/gossip/topic.d.ts.map +1 -1
  165. package/lib/network/interface.d.ts +3 -2
  166. package/lib/network/interface.d.ts.map +1 -1
  167. package/lib/network/libp2p/index.d.ts.map +1 -1
  168. package/lib/network/libp2p/index.js +19 -13
  169. package/lib/network/libp2p/index.js.map +1 -1
  170. package/lib/network/network.d.ts +3 -2
  171. package/lib/network/network.d.ts.map +1 -1
  172. package/lib/network/network.js +3 -0
  173. package/lib/network/network.js.map +1 -1
  174. package/lib/network/options.d.ts.map +1 -1
  175. package/lib/network/options.js +7 -2
  176. package/lib/network/options.js.map +1 -1
  177. package/lib/network/processor/extractSlotRootFns.d.ts +1 -1
  178. package/lib/network/processor/extractSlotRootFns.d.ts.map +1 -1
  179. package/lib/network/processor/extractSlotRootFns.js +25 -5
  180. package/lib/network/processor/extractSlotRootFns.js.map +1 -1
  181. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  182. package/lib/network/processor/gossipHandlers.js +260 -73
  183. package/lib/network/processor/gossipHandlers.js.map +1 -1
  184. package/lib/network/processor/index.d.ts +11 -1
  185. package/lib/network/processor/index.d.ts.map +1 -1
  186. package/lib/network/processor/index.js +234 -22
  187. package/lib/network/processor/index.js.map +1 -1
  188. package/lib/network/reqresp/types.d.ts +3 -3
  189. package/lib/network/reqresp/types.d.ts.map +1 -1
  190. package/lib/network/reqresp/types.js +9 -3
  191. package/lib/network/reqresp/types.js.map +1 -1
  192. package/lib/node/nodejs.d.ts.map +1 -1
  193. package/lib/node/nodejs.js +4 -1
  194. package/lib/node/nodejs.js.map +1 -1
  195. package/lib/node/notifier.d.ts.map +1 -1
  196. package/lib/node/notifier.js +2 -2
  197. package/lib/node/notifier.js.map +1 -1
  198. package/lib/sync/unknownBlock.js +2 -2
  199. package/lib/sync/unknownBlock.js.map +1 -1
  200. package/lib/sync/utils/downloadByRange.d.ts +3 -3
  201. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  202. package/lib/sync/utils/downloadByRange.js +4 -2
  203. package/lib/sync/utils/downloadByRange.js.map +1 -1
  204. package/lib/sync/utils/downloadByRoot.d.ts +3 -3
  205. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  206. package/lib/sync/utils/downloadByRoot.js +10 -5
  207. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  208. package/lib/util/blobs.d.ts +3 -3
  209. package/lib/util/blobs.d.ts.map +1 -1
  210. package/lib/util/blobs.js +21 -10
  211. package/lib/util/blobs.js.map +1 -1
  212. package/lib/util/dataColumns.d.ts +18 -11
  213. package/lib/util/dataColumns.d.ts.map +1 -1
  214. package/lib/util/dataColumns.js +51 -17
  215. package/lib/util/dataColumns.js.map +1 -1
  216. package/lib/util/execution.d.ts +6 -2
  217. package/lib/util/execution.d.ts.map +1 -1
  218. package/lib/util/execution.js +49 -25
  219. package/lib/util/execution.js.map +1 -1
  220. package/lib/util/sszBytes.d.ts +25 -1
  221. package/lib/util/sszBytes.d.ts.map +1 -1
  222. package/lib/util/sszBytes.js +189 -2
  223. package/lib/util/sszBytes.js.map +1 -1
  224. package/package.json +15 -15
  225. package/src/api/impl/beacon/blocks/index.ts +32 -15
  226. package/src/api/impl/beacon/pool/index.ts +4 -0
  227. package/src/api/impl/beacon/state/index.ts +15 -15
  228. package/src/api/impl/debug/index.ts +2 -2
  229. package/src/api/impl/lodestar/index.ts +4 -0
  230. package/src/api/impl/validator/index.ts +7 -0
  231. package/src/chain/ColumnReconstructionTracker.ts +6 -5
  232. package/src/chain/GetBlobsTracker.ts +14 -12
  233. package/src/chain/archiveStore/archiveStore.ts +1 -0
  234. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +6 -5
  235. package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +2 -1
  236. package/src/chain/archiveStore/historicalState/types.ts +2 -0
  237. package/src/chain/archiveStore/historicalState/worker.ts +1 -5
  238. package/src/chain/archiveStore/interface.ts +1 -0
  239. package/src/chain/blocks/blockInput/blockInput.ts +8 -8
  240. package/src/chain/blocks/blockInput/types.ts +4 -4
  241. package/src/chain/blocks/importBlock.ts +45 -23
  242. package/src/chain/blocks/importExecutionPayload.ts +94 -53
  243. package/src/chain/blocks/index.ts +2 -1
  244. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +53 -12
  245. package/src/chain/blocks/payloadEnvelopeInput/types.ts +2 -1
  246. package/src/chain/blocks/types.ts +25 -14
  247. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +6 -5
  248. package/src/chain/blocks/verifyBlocksSignatures.ts +9 -2
  249. package/src/chain/chain.ts +73 -28
  250. package/src/chain/emitter.ts +25 -7
  251. package/src/chain/errors/dataColumnSidecarError.ts +32 -1
  252. package/src/chain/forkChoice/index.ts +11 -8
  253. package/src/chain/interface.ts +4 -2
  254. package/src/chain/lightClient/index.ts +15 -3
  255. package/src/chain/opPools/aggregatedAttestationPool.ts +6 -1
  256. package/src/chain/opPools/executionPayloadBidPool.ts +3 -3
  257. package/src/chain/options.ts +2 -0
  258. package/src/chain/prepareNextSlot.ts +8 -0
  259. package/src/chain/produceBlock/computeNewStateRoot.ts +2 -1
  260. package/src/chain/produceBlock/produceBlockBody.ts +25 -5
  261. package/src/chain/seenCache/seenGossipBlockInput.ts +2 -2
  262. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +2 -2
  263. package/src/chain/validation/block.ts +2 -1
  264. package/src/chain/validation/dataColumnSidecar.ts +230 -7
  265. package/src/chain/validation/executionPayloadBid.ts +7 -3
  266. package/src/chain/validation/executionPayloadEnvelope.ts +8 -1
  267. package/src/chain/validation/payloadAttestationMessage.ts +4 -0
  268. package/src/chain/validation/syncCommittee.ts +5 -1
  269. package/src/chain/validation/syncCommitteeContributionAndProof.ts +5 -1
  270. package/src/chain/validatorMonitor.ts +3 -2
  271. package/src/db/buckets.ts +2 -2
  272. package/src/db/repositories/dataColumnSidecar.ts +4 -2
  273. package/src/db/repositories/dataColumnSidecarArchive.ts +4 -2
  274. package/src/metrics/metrics/lodestar.ts +34 -0
  275. package/src/network/interface.ts +3 -2
  276. package/src/network/libp2p/index.ts +21 -15
  277. package/src/network/network.ts +7 -4
  278. package/src/network/options.ts +7 -2
  279. package/src/network/processor/extractSlotRootFns.ts +32 -6
  280. package/src/network/processor/gossipHandlers.ts +325 -86
  281. package/src/network/processor/index.ts +304 -22
  282. package/src/network/reqresp/types.ts +13 -5
  283. package/src/node/nodejs.ts +5 -2
  284. package/src/node/notifier.ts +7 -2
  285. package/src/sync/unknownBlock.ts +3 -3
  286. package/src/sync/utils/downloadByRange.ts +9 -7
  287. package/src/sync/utils/downloadByRoot.ts +16 -12
  288. package/src/util/blobs.ts +35 -15
  289. package/src/util/dataColumns.ts +69 -25
  290. package/src/util/execution.ts +49 -30
  291. package/src/util/sszBytes.ts +245 -3
@@ -1,17 +1,14 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {ApplicationMethods} from "@lodestar/api/server";
3
- import {
4
- EPOCHS_PER_HISTORICAL_VECTOR,
5
- SLOTS_PER_EPOCH,
6
- SYNC_COMMITTEE_SUBNET_SIZE,
7
- isForkPostElectra,
8
- isForkPostFulu,
9
- } from "@lodestar/params";
3
+ import {EPOCHS_PER_HISTORICAL_VECTOR, SLOTS_PER_EPOCH, SYNC_COMMITTEE_SUBNET_SIZE} from "@lodestar/params";
10
4
  import {
11
5
  IBeaconStateView,
12
6
  computeEpochAtSlot,
13
7
  computeStartSlotAtEpoch,
14
8
  getCurrentEpoch,
9
+ isStatePostAltair,
10
+ isStatePostElectra,
11
+ isStatePostFulu,
15
12
  } from "@lodestar/state-transition";
16
13
  import {ValidatorIndex, getValidatorStatus, ssz} from "@lodestar/types";
17
14
  import {ApiError} from "../../errors.js";
@@ -303,6 +300,9 @@ export function getBeaconStateApi({
303
300
  if (stateEpoch < config.ALTAIR_FORK_EPOCH) {
304
301
  throw new ApiError(400, "Requested state before ALTAIR_FORK_EPOCH");
305
302
  }
303
+ if (!isStatePostAltair(state)) {
304
+ throw new Error("Expected Altair state for sync committee lookup");
305
+ }
306
306
 
307
307
  const syncCommitteeCache = state.getIndexedSyncCommitteeAtEpoch(epoch ?? stateEpoch);
308
308
  const validatorIndices = new Array<ValidatorIndex>(...syncCommitteeCache.validatorIndices);
@@ -324,9 +324,9 @@ export function getBeaconStateApi({
324
324
 
325
325
  async getPendingDeposits({stateId}, context) {
326
326
  const {state, executionOptimistic, finalized} = await getState(stateId);
327
- const fork = config.getForkName(state.slot);
327
+ const fork = state.forkName;
328
328
 
329
- if (!isForkPostElectra(fork)) {
329
+ if (!isStatePostElectra(state)) {
330
330
  throw new ApiError(400, `Cannot retrieve pending deposits for pre-electra state fork=${fork}`);
331
331
  }
332
332
 
@@ -340,9 +340,9 @@ export function getBeaconStateApi({
340
340
 
341
341
  async getPendingPartialWithdrawals({stateId}, context) {
342
342
  const {state, executionOptimistic, finalized} = await getState(stateId);
343
- const fork = config.getForkName(state.slot);
343
+ const fork = state.forkName;
344
344
 
345
- if (!isForkPostElectra(fork)) {
345
+ if (!isStatePostElectra(state)) {
346
346
  throw new ApiError(400, `Cannot retrieve pending partial withdrawals for pre-electra state fork=${fork}`);
347
347
  }
348
348
 
@@ -358,9 +358,9 @@ export function getBeaconStateApi({
358
358
 
359
359
  async getPendingConsolidations({stateId}, context) {
360
360
  const {state, executionOptimistic, finalized} = await getState(stateId);
361
- const fork = config.getForkName(state.slot);
361
+ const fork = state.forkName;
362
362
 
363
- if (!isForkPostElectra(fork)) {
363
+ if (!isStatePostElectra(state)) {
364
364
  throw new ApiError(400, `Cannot retrieve pending consolidations for pre-electra state fork=${fork}`);
365
365
  }
366
366
 
@@ -376,9 +376,9 @@ export function getBeaconStateApi({
376
376
 
377
377
  async getProposerLookahead({stateId}, context) {
378
378
  const {state, executionOptimistic, finalized} = await getState(stateId);
379
- const fork = config.getForkName(state.slot);
379
+ const fork = state.forkName;
380
380
 
381
- if (!isForkPostFulu(fork)) {
381
+ if (!isStatePostFulu(state)) {
382
382
  throw new ApiError(400, `Cannot retrieve proposer lookahead for pre-fulu state fork=${fork}`);
383
383
  }
384
384
 
@@ -2,7 +2,7 @@ import {routes} from "@lodestar/api";
2
2
  import {ApplicationMethods} from "@lodestar/api/server";
3
3
  import {ExecutionStatus} from "@lodestar/fork-choice";
4
4
  import {ForkPostDeneb, ZERO_HASH_HEX, isForkPostDeneb, isForkPostFulu} from "@lodestar/params";
5
- import {BeaconState, DataColumnSidecars, type SignedBeaconBlock, sszTypesFor} from "@lodestar/types";
5
+ import {BeaconState, DataColumnSidecar, DataColumnSidecars, type SignedBeaconBlock, sszTypesFor} from "@lodestar/types";
6
6
  import {toRootHex} from "@lodestar/utils";
7
7
  import {getBlobKzgCommitments} from "../../../util/dataColumns.js";
8
8
  import {isOptimisticBlock} from "../../../util/forkChoice.js";
@@ -98,7 +98,7 @@ export function getDebugApi({
98
98
  const fork = config.getForkName(block.message.slot);
99
99
  const blockRoot = sszTypesFor(fork).BeaconBlock.hashTreeRoot(block.message);
100
100
 
101
- let dataColumnSidecars: DataColumnSidecars;
101
+ let dataColumnSidecars: DataColumnSidecar[];
102
102
 
103
103
  const blobCount = isForkPostDeneb(fork)
104
104
  ? getBlobKzgCommitments(fork, block as SignedBeaconBlock<ForkPostDeneb>).length
@@ -3,6 +3,7 @@ import {ApplicationMethods} from "@lodestar/api/server";
3
3
  import {ChainForkConfig} from "@lodestar/config";
4
4
  import {Repository} from "@lodestar/db";
5
5
  import {ForkSeq, SLOTS_PER_EPOCH} from "@lodestar/params";
6
+ import {isStatePostCapella} from "@lodestar/state-transition";
6
7
  import {ssz} from "@lodestar/types";
7
8
  import {Checkpoint} from "@lodestar/types/phase0";
8
9
  import {fromHex, toHex, toRootHex} from "@lodestar/utils";
@@ -218,6 +219,9 @@ export function getLodestarApi({
218
219
  if (ForkSeq[fork] < ForkSeq.capella) {
219
220
  throw new Error("Historical summaries are not supported before Capella");
220
221
  }
222
+ if (!isStatePostCapella(stateView)) {
223
+ throw new Error("Expected Capella state for historical summaries");
224
+ }
221
225
 
222
226
  const {gindex} = ssz[fork].BeaconState.getPathInfo(["historicalSummaries"]);
223
227
  const proof = stateView.getSingleProof(gindex);
@@ -25,6 +25,7 @@ import {
25
25
  computeStartSlotAtEpoch,
26
26
  computeTimeAtSlot,
27
27
  getCurrentSlot,
28
+ isStatePostAltair,
28
29
  proposerShufflingDecisionRoot,
29
30
  } from "@lodestar/state-transition";
30
31
  import {
@@ -1282,6 +1283,9 @@ export function getValidatorApi(
1282
1283
  if (indices.length === 0) {
1283
1284
  throw new ApiError(400, "No validator to get attester duties");
1284
1285
  }
1286
+ if (epoch < config.ALTAIR_FORK_EPOCH) {
1287
+ throw new ApiError(400, "Sync committee duties are not supported before Altair");
1288
+ }
1285
1289
 
1286
1290
  // May request for an epoch that's in the future
1287
1291
  await waitForNextClosestEpoch();
@@ -1291,6 +1295,9 @@ export function getValidatorApi(
1291
1295
  // Note: does not support requesting past duties
1292
1296
  const head = chain.forkChoice.getHead();
1293
1297
  const state = chain.getHeadState();
1298
+ if (!isStatePostAltair(state)) {
1299
+ throw new ApiError(400, "Sync committee duties are not available before Altair");
1300
+ }
1294
1301
 
1295
1302
  // Check that all validatorIndex belong to the state before calling getCommitteeAssignments()
1296
1303
  const pubkeys = getPubkeysForIndices(state, indices);
@@ -3,6 +3,7 @@ import {Logger, sleep} from "@lodestar/utils";
3
3
  import {Metrics} from "../metrics/metrics.js";
4
4
  import {DataColumnReconstructionCode, recoverDataColumnSidecars} from "../util/dataColumns.js";
5
5
  import {BlockInputColumns} from "./blocks/blockInput/index.js";
6
+ import {PayloadEnvelopeInput} from "./blocks/payloadEnvelopeInput/index.js";
6
7
  import {ChainEventEmitter} from "./emitter.js";
7
8
 
8
9
  /**
@@ -53,25 +54,25 @@ export class ColumnReconstructionTracker {
53
54
  this.maxDelayMs = this.config.getSlotComponentDurationMs(RECONSTRUCTION_DELAY_MAX_BPS);
54
55
  }
55
56
 
56
- triggerColumnReconstruction(blockInput: BlockInputColumns): void {
57
+ triggerColumnReconstruction(input: BlockInputColumns | PayloadEnvelopeInput): void {
57
58
  if (this.running) {
58
59
  return;
59
60
  }
60
61
 
61
- if (this.lastBlockRootHex === blockInput.blockRootHex) {
62
+ if (this.lastBlockRootHex === input.blockRootHex) {
62
63
  return;
63
64
  }
64
65
 
65
66
  // We don't care about the outcome of this call,
66
67
  // just that it has been triggered for this block root.
67
68
  this.running = true;
68
- this.lastBlockRootHex = blockInput.blockRootHex;
69
+ this.lastBlockRootHex = input.blockRootHex;
69
70
  const delay = this.minDelayMs + Math.random() * (this.maxDelayMs - this.minDelayMs);
70
71
  sleep(delay)
71
72
  .then(() => {
72
- const logCtx = {slot: blockInput.slot, root: blockInput.blockRootHex};
73
+ const logCtx = {slot: input.slot, root: input.blockRootHex};
73
74
  this.logger.debug("Attempting data column sidecar reconstruction", logCtx);
74
- recoverDataColumnSidecars(blockInput, this.emitter, this.metrics)
75
+ recoverDataColumnSidecars(input, this.emitter, this.metrics)
75
76
  .then((result) => {
76
77
  this.metrics?.recoverDataColumnSidecars.reconstructionResult.inc({result});
77
78
  this.logger.debug("Data column sidecar reconstruction complete", {...logCtx, result});
@@ -11,6 +11,7 @@ import {
11
11
  getDataColumnSidecarsFromExecution,
12
12
  } from "../util/execution.js";
13
13
  import {IBlockInput, isBlockInputBlobs} from "./blocks/blockInput/index.js";
14
+ import {PayloadEnvelopeInput} from "./blocks/payloadEnvelopeInput/index.js";
14
15
  import {ChainEventEmitter} from "./emitter.js";
15
16
 
16
17
  export type GetBlobsTrackerInit = {
@@ -43,22 +44,22 @@ export class GetBlobsTracker {
43
44
  this.config = init.config;
44
45
  }
45
46
 
46
- triggerGetBlobs(blockInput: IBlockInput): void {
47
- if (this.activeReconstructions.has(blockInput.blockRootHex)) {
47
+ triggerGetBlobs(input: IBlockInput | PayloadEnvelopeInput, onComplete?: () => void): void {
48
+ if (this.activeReconstructions.has(input.blockRootHex)) {
48
49
  return;
49
50
  }
50
51
 
51
- if (isBlockInputBlobs(blockInput)) {
52
+ if (!(input instanceof PayloadEnvelopeInput) && isBlockInputBlobs(input)) {
52
53
  // there is not preallocation for blob sidecars like there is for columns sidecars so no need to
53
54
  // store the index for the preallocated buffers
54
- this.activeReconstructions.add(blockInput.blockRootHex);
55
+ this.activeReconstructions.add(input.blockRootHex);
55
56
  callInNextEventLoop(() => {
56
- const logCtx = {slot: blockInput.slot, root: blockInput.blockRootHex};
57
+ const logCtx = {slot: input.slot, root: input.blockRootHex};
57
58
  this.logger.verbose("Trigger getBlobsV1 for block", logCtx);
58
- getBlobSidecarsFromExecution(this.config, this.executionEngine, this.metrics, this.emitter, blockInput).finally(
59
+ getBlobSidecarsFromExecution(this.config, this.executionEngine, this.metrics, this.emitter, input).finally(
59
60
  () => {
60
61
  this.logger.verbose("Completed getBlobsV1 for block", logCtx);
61
- this.activeReconstructions.delete(blockInput.blockRootHex);
62
+ this.activeReconstructions.delete(input.blockRootHex);
62
63
  }
63
64
  );
64
65
  });
@@ -72,7 +73,7 @@ export class GetBlobsTracker {
72
73
  this.blobsAndProofsBuffers[freeIndex] = {inUse: false, buffers: []};
73
74
  }
74
75
 
75
- const maxBlobs = this.config.getMaxBlobsPerBlock(computeEpochAtSlot(blockInput.slot));
76
+ const maxBlobs = this.config.getMaxBlobsPerBlock(computeEpochAtSlot(input.slot));
76
77
  // double check that there is enough pre-allocated space (blob schedule may have changed since the last use)
77
78
  const timer = this.metrics?.peerDas.getBlobsV2PreAllocationTime.startTimer();
78
79
  for (let i = 0; i < maxBlobs; i++) {
@@ -84,22 +85,23 @@ export class GetBlobsTracker {
84
85
 
85
86
  // We don't care about the outcome of this call,
86
87
  // just that it has been triggered for this block root.
87
- this.activeReconstructions.add(blockInput.blockRootHex);
88
+ this.activeReconstructions.add(input.blockRootHex);
88
89
  this.blobsAndProofsBuffers[freeIndex].inUse = true;
89
90
  callInNextEventLoop(() => {
90
- const logCtx = {slot: blockInput.slot, root: blockInput.blockRootHex};
91
+ const logCtx = {slot: input.slot, root: input.blockRootHex};
91
92
  this.logger.verbose("Trigger getBlobsV2 for block", logCtx);
92
93
  getDataColumnSidecarsFromExecution(
93
94
  this.config,
94
95
  this.executionEngine,
95
96
  this.emitter,
96
- blockInput,
97
+ input,
97
98
  this.metrics,
98
99
  this.blobsAndProofsBuffers[freeIndex].buffers
99
100
  )
100
101
  .then((result) => {
101
102
  this.logger.debug("getBlobsV2 result for block", {...logCtx, result});
102
103
  this.metrics?.dataColumns.dataColumnEngineResult.inc({result});
104
+ onComplete?.();
103
105
  })
104
106
  .catch((error) => {
105
107
  this.logger.debug("Error during getBlobsV2 for block", logCtx, error as Error);
@@ -107,7 +109,7 @@ export class GetBlobsTracker {
107
109
  })
108
110
  .finally(() => {
109
111
  this.logger.verbose("Completed getBlobsV2 for block", logCtx);
110
- this.activeReconstructions.delete(blockInput.blockRootHex);
112
+ this.activeReconstructions.delete(input.blockRootHex);
111
113
  this.blobsAndProofsBuffers[freeIndex].inUse = false;
112
114
  });
113
115
  });
@@ -120,6 +120,7 @@ export class ArchiveStore {
120
120
  opts: {
121
121
  genesisTime: this.chain.clock.genesisTime,
122
122
  dbLocation: this.opts.dbName,
123
+ nativeStateView: this.opts.nativeStateView ?? false,
123
124
  },
124
125
  config: this.chain.config,
125
126
  metrics: this.metrics,
@@ -3,7 +3,6 @@ import {
3
3
  DataAvailabilityStatus,
4
4
  ExecutionPayloadStatus,
5
5
  IBeaconStateView,
6
- type PubkeyCache,
7
6
  createBeaconStateViewForHistoricalRegen,
8
7
  } from "@lodestar/state-transition";
9
8
  import {byteArrayEquals} from "@lodestar/utils";
@@ -18,7 +17,7 @@ export async function getNearestState(
18
17
  slot: number,
19
18
  config: BeaconConfig,
20
19
  db: IBeaconDb,
21
- pubkeyCache: PubkeyCache
20
+ nativeStateView: boolean
22
21
  ): Promise<IBeaconStateView> {
23
22
  const stateBytesArr = await db.stateArchive.binaries({limit: 1, lte: slot, reverse: true});
24
23
  if (!stateBytesArr.length) {
@@ -26,7 +25,9 @@ export async function getNearestState(
26
25
  }
27
26
 
28
27
  const stateBytes = stateBytesArr[0];
29
- return createBeaconStateViewForHistoricalRegen(config, stateBytes, pubkeyCache);
28
+ return nativeStateView
29
+ ? createBeaconStateViewForHistoricalRegen({useNative: true, stateBytes})
30
+ : createBeaconStateViewForHistoricalRegen({useNative: false, config, stateBytes});
30
31
  }
31
32
 
32
33
  /**
@@ -36,13 +37,13 @@ export async function getHistoricalState(
36
37
  slot: number,
37
38
  config: BeaconConfig,
38
39
  db: IBeaconDb,
39
- pubkeyCache: PubkeyCache,
40
+ nativeStateView: boolean,
40
41
  metrics?: HistoricalStateRegenMetrics
41
42
  ): Promise<Uint8Array> {
42
43
  const regenTimer = metrics?.regenTime.startTimer();
43
44
 
44
45
  const loadStateTimer = metrics?.loadStateTime.startTimer();
45
- let state = await getNearestState(slot, config, db, pubkeyCache).catch((e) => {
46
+ let state = await getNearestState(slot, config, db, nativeStateView).catch((e) => {
46
47
  metrics?.regenErrorCount.inc({reason: RegenErrorType.loadState});
47
48
  throw e;
48
49
  });
@@ -20,7 +20,7 @@ export class HistoricalStateRegen implements HistoricalStateWorkerApi {
20
20
  private readonly api: ModuleThread<HistoricalStateWorkerApi>;
21
21
  private readonly logger: LoggerNode;
22
22
 
23
- constructor(modules: HistoricalStateRegenModules) {
23
+ private constructor(modules: HistoricalStateRegenModules) {
24
24
  this.api = modules.api;
25
25
  this.logger = modules.logger;
26
26
  modules.signal?.addEventListener("abort", () => this.close(), {once: true});
@@ -35,6 +35,7 @@ export class HistoricalStateRegen implements HistoricalStateWorkerApi {
35
35
  dbLocation: modules.opts.dbLocation,
36
36
  metricsEnabled: Boolean(modules.metrics),
37
37
  loggerOpts: modules.logger.toOpts(),
38
+ nativeStateView: modules.opts.nativeStateView,
38
39
  };
39
40
 
40
41
  const worker = new Worker(path.join(WORKER_DIR, "worker.js"), {
@@ -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