@lodestar/beacon-node 1.42.0-rc.0 → 1.43.0-dev.0bc48d3b54

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 (268) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +20 -0
  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/lodestar/attesterSlashing.d.ts +8 -0
  11. package/lib/api/impl/lodestar/attesterSlashing.d.ts.map +1 -0
  12. package/lib/api/impl/lodestar/attesterSlashing.js +29 -0
  13. package/lib/api/impl/lodestar/attesterSlashing.js.map +1 -0
  14. package/lib/api/impl/lodestar/index.d.ts.map +1 -1
  15. package/lib/api/impl/lodestar/index.js +39 -0
  16. package/lib/api/impl/lodestar/index.js.map +1 -1
  17. package/lib/api/impl/validator/index.d.ts.map +1 -1
  18. package/lib/api/impl/validator/index.js +11 -4
  19. package/lib/api/impl/validator/index.js.map +1 -1
  20. package/lib/chain/GetBlobsTracker.d.ts +1 -1
  21. package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
  22. package/lib/chain/GetBlobsTracker.js +1 -2
  23. package/lib/chain/GetBlobsTracker.js.map +1 -1
  24. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
  25. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +2 -4
  26. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
  27. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  28. package/lib/chain/blocks/importBlock.js +29 -35
  29. package/lib/chain/blocks/importBlock.js.map +1 -1
  30. package/lib/chain/blocks/importExecutionPayload.d.ts +1 -1
  31. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  32. package/lib/chain/blocks/importExecutionPayload.js +24 -13
  33. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  34. package/lib/chain/blocks/index.js +2 -2
  35. package/lib/chain/blocks/index.js.map +1 -1
  36. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +3 -0
  37. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  38. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +20 -0
  39. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  40. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +5 -0
  41. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -1
  42. package/lib/chain/blocks/payloadEnvelopeProcessor.js +6 -4
  43. package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
  44. package/lib/chain/blocks/types.d.ts +4 -4
  45. package/lib/chain/blocks/types.d.ts.map +1 -1
  46. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  47. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +3 -2
  48. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  49. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  50. package/lib/chain/blocks/verifyBlocksSignatures.js +4 -2
  51. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  52. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts +14 -0
  53. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -0
  54. package/lib/chain/blocks/verifyPayloadsDataAvailability.js +25 -0
  55. package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -0
  56. package/lib/chain/chain.d.ts +2 -1
  57. package/lib/chain/chain.d.ts.map +1 -1
  58. package/lib/chain/chain.js +30 -36
  59. package/lib/chain/chain.js.map +1 -1
  60. package/lib/chain/emitter.d.ts +13 -1
  61. package/lib/chain/emitter.d.ts.map +1 -1
  62. package/lib/chain/emitter.js +5 -0
  63. package/lib/chain/emitter.js.map +1 -1
  64. package/lib/chain/errors/attestationError.d.ts +8 -1
  65. package/lib/chain/errors/attestationError.d.ts.map +1 -1
  66. package/lib/chain/errors/attestationError.js +4 -0
  67. package/lib/chain/errors/attestationError.js.map +1 -1
  68. package/lib/chain/errors/blockError.d.ts +11 -1
  69. package/lib/chain/errors/blockError.d.ts.map +1 -1
  70. package/lib/chain/errors/blockError.js +4 -0
  71. package/lib/chain/errors/blockError.js.map +1 -1
  72. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  73. package/lib/chain/forkChoice/index.js +22 -12
  74. package/lib/chain/forkChoice/index.js.map +1 -1
  75. package/lib/chain/interface.d.ts +2 -1
  76. package/lib/chain/interface.d.ts.map +1 -1
  77. package/lib/chain/interface.js.map +1 -1
  78. package/lib/chain/lightClient/index.d.ts +2 -2
  79. package/lib/chain/lightClient/index.d.ts.map +1 -1
  80. package/lib/chain/lightClient/index.js +7 -0
  81. package/lib/chain/lightClient/index.js.map +1 -1
  82. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  83. package/lib/chain/opPools/aggregatedAttestationPool.js +5 -2
  84. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  85. package/lib/chain/opPools/executionPayloadBidPool.d.ts +2 -2
  86. package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -1
  87. package/lib/chain/opPools/executionPayloadBidPool.js +2 -2
  88. package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -1
  89. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  90. package/lib/chain/prepareNextSlot.js +22 -10
  91. package/lib/chain/prepareNextSlot.js.map +1 -1
  92. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +1 -7
  93. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  94. package/lib/chain/produceBlock/computeNewStateRoot.js +1 -28
  95. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  96. package/lib/chain/produceBlock/produceBlockBody.d.ts +5 -10
  97. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  98. package/lib/chain/produceBlock/produceBlockBody.js +46 -19
  99. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  100. package/lib/chain/regen/errors.d.ts +1 -11
  101. package/lib/chain/regen/errors.d.ts.map +1 -1
  102. package/lib/chain/regen/errors.js +0 -2
  103. package/lib/chain/regen/errors.js.map +1 -1
  104. package/lib/chain/regen/interface.d.ts +6 -12
  105. package/lib/chain/regen/interface.d.ts.map +1 -1
  106. package/lib/chain/regen/queued.d.ts +6 -11
  107. package/lib/chain/regen/queued.d.ts.map +1 -1
  108. package/lib/chain/regen/queued.js +8 -40
  109. package/lib/chain/regen/queued.js.map +1 -1
  110. package/lib/chain/regen/regen.d.ts +0 -5
  111. package/lib/chain/regen/regen.d.ts.map +1 -1
  112. package/lib/chain/regen/regen.js +7 -34
  113. package/lib/chain/regen/regen.js.map +1 -1
  114. package/lib/chain/stateCache/datastore/db.d.ts +5 -4
  115. package/lib/chain/stateCache/datastore/db.d.ts.map +1 -1
  116. package/lib/chain/stateCache/datastore/db.js +10 -32
  117. package/lib/chain/stateCache/datastore/db.js.map +1 -1
  118. package/lib/chain/stateCache/datastore/file.d.ts +1 -1
  119. package/lib/chain/stateCache/datastore/file.d.ts.map +1 -1
  120. package/lib/chain/stateCache/datastore/file.js +5 -5
  121. package/lib/chain/stateCache/datastore/file.js.map +1 -1
  122. package/lib/chain/stateCache/datastore/types.d.ts +1 -1
  123. package/lib/chain/stateCache/datastore/types.d.ts.map +1 -1
  124. package/lib/chain/stateCache/fifoBlockStateCache.d.ts +1 -7
  125. package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
  126. package/lib/chain/stateCache/fifoBlockStateCache.js +0 -8
  127. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  128. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +13 -30
  129. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  130. package/lib/chain/stateCache/persistentCheckpointsCache.js +120 -216
  131. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  132. package/lib/chain/stateCache/types.d.ts +8 -15
  133. package/lib/chain/stateCache/types.d.ts.map +1 -1
  134. package/lib/chain/stateCache/types.js.map +1 -1
  135. package/lib/chain/validation/aggregateAndProof.js +12 -0
  136. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  137. package/lib/chain/validation/attestation.d.ts.map +1 -1
  138. package/lib/chain/validation/attestation.js +12 -0
  139. package/lib/chain/validation/attestation.js.map +1 -1
  140. package/lib/chain/validation/block.d.ts.map +1 -1
  141. package/lib/chain/validation/block.js +27 -5
  142. package/lib/chain/validation/block.js.map +1 -1
  143. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  144. package/lib/chain/validation/executionPayloadBid.js +7 -4
  145. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  146. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  147. package/lib/chain/validation/executionPayloadEnvelope.js +8 -3
  148. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  149. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  150. package/lib/chain/validation/payloadAttestationMessage.js +8 -4
  151. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  152. package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
  153. package/lib/chain/validation/syncCommittee.js +4 -0
  154. package/lib/chain/validation/syncCommittee.js.map +1 -1
  155. package/lib/chain/validation/syncCommitteeContributionAndProof.js +4 -1
  156. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  157. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  158. package/lib/chain/validatorMonitor.js +3 -3
  159. package/lib/chain/validatorMonitor.js.map +1 -1
  160. package/lib/execution/engine/http.d.ts.map +1 -1
  161. package/lib/execution/engine/http.js +21 -14
  162. package/lib/execution/engine/http.js.map +1 -1
  163. package/lib/execution/engine/interface.d.ts +1 -0
  164. package/lib/execution/engine/interface.d.ts.map +1 -1
  165. package/lib/execution/engine/mock.d.ts.map +1 -1
  166. package/lib/execution/engine/mock.js +3 -0
  167. package/lib/execution/engine/mock.js.map +1 -1
  168. package/lib/execution/engine/types.d.ts +20 -0
  169. package/lib/execution/engine/types.d.ts.map +1 -1
  170. package/lib/execution/engine/types.js +18 -0
  171. package/lib/execution/engine/types.js.map +1 -1
  172. package/lib/network/gossip/topic.d.ts +729 -0
  173. package/lib/network/gossip/topic.d.ts.map +1 -1
  174. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  175. package/lib/network/processor/gossipHandlers.js +23 -3
  176. package/lib/network/processor/gossipHandlers.js.map +1 -1
  177. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  178. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +2 -1
  179. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  180. package/lib/network/reqresp/handlers/beaconBlocksByRoot.d.ts.map +1 -1
  181. package/lib/network/reqresp/handlers/beaconBlocksByRoot.js +2 -0
  182. package/lib/network/reqresp/handlers/beaconBlocksByRoot.js.map +1 -1
  183. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts +2 -2
  184. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
  185. package/lib/network/reqresp/handlers/blobSidecarsByRange.js +7 -3
  186. package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
  187. package/lib/network/reqresp/handlers/blobSidecarsByRoot.d.ts.map +1 -1
  188. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js +6 -0
  189. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js.map +1 -1
  190. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts +2 -2
  191. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  192. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +7 -3
  193. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  194. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
  195. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +2 -1
  196. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
  197. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -1
  198. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +3 -8
  199. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
  200. package/lib/node/nodejs.d.ts.map +1 -1
  201. package/lib/node/nodejs.js +6 -1
  202. package/lib/node/nodejs.js.map +1 -1
  203. package/lib/node/notifier.d.ts.map +1 -1
  204. package/lib/node/notifier.js +2 -2
  205. package/lib/node/notifier.js.map +1 -1
  206. package/package.json +16 -16
  207. package/src/api/impl/beacon/blocks/index.ts +29 -0
  208. package/src/api/impl/beacon/pool/index.ts +4 -0
  209. package/src/api/impl/beacon/state/index.ts +15 -15
  210. package/src/api/impl/lodestar/attesterSlashing.ts +43 -0
  211. package/src/api/impl/lodestar/index.ts +51 -1
  212. package/src/api/impl/validator/index.ts +13 -5
  213. package/src/chain/GetBlobsTracker.ts +1 -2
  214. package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +2 -4
  215. package/src/chain/blocks/importBlock.ts +33 -42
  216. package/src/chain/blocks/importExecutionPayload.ts +26 -12
  217. package/src/chain/blocks/index.ts +2 -2
  218. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +27 -0
  219. package/src/chain/blocks/payloadEnvelopeProcessor.ts +6 -5
  220. package/src/chain/blocks/types.ts +4 -4
  221. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +2 -1
  222. package/src/chain/blocks/verifyBlocksSignatures.ts +9 -2
  223. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +38 -0
  224. package/src/chain/chain.ts +38 -47
  225. package/src/chain/emitter.ts +12 -0
  226. package/src/chain/errors/attestationError.ts +6 -1
  227. package/src/chain/errors/blockError.ts +7 -1
  228. package/src/chain/forkChoice/index.ts +23 -12
  229. package/src/chain/interface.ts +5 -0
  230. package/src/chain/lightClient/index.ts +15 -3
  231. package/src/chain/opPools/aggregatedAttestationPool.ts +6 -1
  232. package/src/chain/opPools/executionPayloadBidPool.ts +3 -3
  233. package/src/chain/prepareNextSlot.ts +26 -9
  234. package/src/chain/produceBlock/computeNewStateRoot.ts +1 -37
  235. package/src/chain/produceBlock/produceBlockBody.ts +71 -23
  236. package/src/chain/regen/errors.ts +1 -6
  237. package/src/chain/regen/interface.ts +6 -12
  238. package/src/chain/regen/queued.ts +12 -48
  239. package/src/chain/regen/regen.ts +8 -36
  240. package/src/chain/stateCache/datastore/db.ts +10 -33
  241. package/src/chain/stateCache/datastore/file.ts +5 -6
  242. package/src/chain/stateCache/datastore/types.ts +2 -3
  243. package/src/chain/stateCache/fifoBlockStateCache.ts +1 -10
  244. package/src/chain/stateCache/persistentCheckpointsCache.ts +139 -247
  245. package/src/chain/stateCache/types.ts +8 -14
  246. package/src/chain/validation/aggregateAndProof.ts +13 -0
  247. package/src/chain/validation/attestation.ts +13 -0
  248. package/src/chain/validation/block.ts +30 -7
  249. package/src/chain/validation/executionPayloadBid.ts +7 -3
  250. package/src/chain/validation/executionPayloadEnvelope.ts +12 -3
  251. package/src/chain/validation/payloadAttestationMessage.ts +9 -3
  252. package/src/chain/validation/syncCommittee.ts +5 -1
  253. package/src/chain/validation/syncCommitteeContributionAndProof.ts +5 -1
  254. package/src/chain/validatorMonitor.ts +3 -2
  255. package/src/execution/engine/http.ts +21 -14
  256. package/src/execution/engine/interface.ts +1 -0
  257. package/src/execution/engine/mock.ts +3 -0
  258. package/src/execution/engine/types.ts +41 -0
  259. package/src/network/processor/gossipHandlers.ts +28 -7
  260. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +3 -1
  261. package/src/network/reqresp/handlers/beaconBlocksByRoot.ts +3 -0
  262. package/src/network/reqresp/handlers/blobSidecarsByRange.ts +15 -3
  263. package/src/network/reqresp/handlers/blobSidecarsByRoot.ts +11 -0
  264. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +19 -3
  265. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +3 -1
  266. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +3 -12
  267. package/src/node/nodejs.ts +7 -2
  268. package/src/node/notifier.ts +7 -2
@@ -2,23 +2,14 @@ import path from "node:path";
2
2
  import {PrivateKey} from "@libp2p/interface";
3
3
  import {Type} from "@chainsafe/ssz";
4
4
  import {BeaconConfig} from "@lodestar/config";
5
- import {
6
- CheckpointWithPayloadStatus,
7
- IForkChoice,
8
- PayloadStatus,
9
- ProtoBlock,
10
- UpdateHeadOpt,
11
- getCheckpointPayloadStatus,
12
- } from "@lodestar/fork-choice";
5
+ import {CheckpointWithPayloadStatus, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
13
6
  import {LoggerNode} from "@lodestar/logger/node";
14
7
  import {
15
- BUILDER_INDEX_SELF_BUILD,
16
8
  EFFECTIVE_BALANCE_INCREMENT,
17
9
  type ForkPostFulu,
18
10
  type ForkPostGloas,
19
11
  GENESIS_SLOT,
20
12
  SLOTS_PER_EPOCH,
21
- isForkPostElectra,
22
13
  isForkPostGloas,
23
14
  } from "@lodestar/params";
24
15
  import {
@@ -30,6 +21,8 @@ import {
30
21
  computeEpochAtSlot,
31
22
  computeStartSlotAtEpoch,
32
23
  getEffectiveBalancesFromStateBytes,
24
+ isStatePostAltair,
25
+ isStatePostElectra,
33
26
  } from "@lodestar/state-transition";
34
27
  import {
35
28
  BeaconBlock,
@@ -98,8 +91,8 @@ import {
98
91
  } from "./opPools/index.js";
99
92
  import {IChainOptions} from "./options.js";
100
93
  import {PrepareNextSlotScheduler} from "./prepareNextSlot.js";
101
- import {computeEnvelopeStateRoot, computeNewStateRoot} from "./produceBlock/computeNewStateRoot.js";
102
- import {AssembledBlockType, BlockType, ProduceFullGloas, ProduceResult} from "./produceBlock/index.js";
94
+ import {computeNewStateRoot} from "./produceBlock/computeNewStateRoot.js";
95
+ import {AssembledBlockType, BlockType, ProduceResult} from "./produceBlock/index.js";
103
96
  import {BlockAttributes, produceBlockBody, produceCommonBlockBody} from "./produceBlock/produceBlockBody.js";
104
97
  import {QueuedStateRegenerator, RegenCaller} from "./regen/index.js";
105
98
  import {ReprocessController} from "./reprocess.js";
@@ -123,7 +116,7 @@ import {DbCPStateDatastore, checkpointToDatastoreKey} from "./stateCache/datasto
123
116
  import {FileCPStateDatastore} from "./stateCache/datastore/file.js";
124
117
  import {CPStateDatastore} from "./stateCache/datastore/types.js";
125
118
  import {FIFOBlockStateCache} from "./stateCache/fifoBlockStateCache.js";
126
- import {PersistentCheckpointStateCache, fcCheckpointToHexPayload} from "./stateCache/persistentCheckpointsCache.js";
119
+ import {PersistentCheckpointStateCache} from "./stateCache/persistentCheckpointsCache.js";
127
120
  import {CheckpointStateCache} from "./stateCache/types.js";
128
121
  import {ValidatorMonitor} from "./validatorMonitor.js";
129
122
 
@@ -388,8 +381,7 @@ export class BeaconChain implements IBeaconChain {
388
381
  const {checkpoint} = anchorState.computeAnchorCheckpoint();
389
382
  blockStateCache.add(anchorState);
390
383
  blockStateCache.setHeadState(anchorState);
391
- const payloadPresent = getCheckpointPayloadStatus(config, anchorState, checkpoint.epoch) === PayloadStatus.FULL;
392
- checkpointStateCache.add(checkpoint, anchorState, payloadPresent);
384
+ checkpointStateCache.add(checkpoint, anchorState);
393
385
 
394
386
  const forkChoice = initializeForkChoice(
395
387
  config,
@@ -683,7 +675,7 @@ export class BeaconChain implements IBeaconChain {
683
675
 
684
676
  // TODO GLOAS: Need to revisit the design of this api. Currently we just retrieve FULL state of the checkpoint for backwards compatibility.
685
677
  // because pre-gloas we always store FULL checkpoint state.
686
- const persistedKey = checkpointToDatastoreKey(checkpoint, true);
678
+ const persistedKey = checkpointToDatastoreKey(checkpoint);
687
679
  return this.cpStateDatastore.read(persistedKey);
688
680
  }
689
681
 
@@ -691,8 +683,8 @@ export class BeaconChain implements IBeaconChain {
691
683
  checkpoint: CheckpointWithPayloadStatus
692
684
  ): {state: IBeaconStateView; executionOptimistic: boolean; finalized: boolean} | null {
693
685
  // finalized or justified checkpoint states maynot be available with PersistentCheckpointStateCache, use getCheckpointStateOrBytes() api to get Uint8Array
694
- const checkpointHexPayload = fcCheckpointToHexPayload(checkpoint);
695
- const cachedStateCtx = this.regen.getCheckpointStateSync(checkpointHexPayload);
686
+ const checkpointHex = {epoch: checkpoint.epoch, rootHex: checkpoint.rootHex};
687
+ const cachedStateCtx = this.regen.getCheckpointStateSync(checkpointHex);
696
688
  if (cachedStateCtx) {
697
689
  const block = this.forkChoice.getBlockDefaultStatus(
698
690
  ssz.phase0.BeaconBlockHeader.hashTreeRoot(cachedStateCtx.latestBlockHeader)
@@ -711,8 +703,8 @@ export class BeaconChain implements IBeaconChain {
711
703
  async getStateOrBytesByCheckpoint(
712
704
  checkpoint: CheckpointWithPayloadStatus
713
705
  ): Promise<{state: IBeaconStateView | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null> {
714
- const checkpointHexPayload = fcCheckpointToHexPayload(checkpoint);
715
- const cachedStateCtx = await this.regen.getCheckpointStateOrBytes(checkpointHexPayload);
706
+ const checkpointHex = {epoch: checkpoint.epoch, rootHex: checkpoint.rootHex};
707
+ const cachedStateCtx = await this.regen.getCheckpointStateOrBytes(checkpointHex);
716
708
  if (cachedStateCtx) {
717
709
  const block = this.forkChoice.getBlockDefaultStatus(checkpoint.root);
718
710
  const finalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
@@ -878,6 +870,22 @@ export class BeaconChain implements IBeaconChain {
878
870
  );
879
871
  }
880
872
 
873
+ async getExecutionPayloadEnvelope(
874
+ blockSlot: Slot,
875
+ blockRootHex: string
876
+ ): Promise<gloas.SignedExecutionPayloadEnvelope | null> {
877
+ const payloadInput = this.seenPayloadEnvelopeInputCache.get(blockRootHex);
878
+ if (payloadInput?.hasPayloadEnvelope()) {
879
+ return payloadInput.getPayloadEnvelope();
880
+ }
881
+
882
+ return (
883
+ (await this.db.executionPayloadEnvelope.get(fromHex(blockRootHex))) ??
884
+ (await this.db.executionPayloadEnvelopeArchive.get(blockSlot)) ??
885
+ null
886
+ );
887
+ }
888
+
881
889
  async getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<DataColumnSidecar[]> {
882
890
  const fork = this.config.getForkName(blockSlot);
883
891
 
@@ -1052,7 +1060,7 @@ export class BeaconChain implements IBeaconChain {
1052
1060
  body,
1053
1061
  } as AssembledBlockType<T>;
1054
1062
 
1055
- const {newStateRoot, proposerReward, postState} = computeNewStateRoot(this.metrics, state, block);
1063
+ const {newStateRoot, proposerReward} = computeNewStateRoot(this.metrics, state, block);
1056
1064
  block.stateRoot = newStateRoot;
1057
1065
  const blockRoot =
1058
1066
  produceResult.type === BlockType.Full
@@ -1061,23 +1069,9 @@ export class BeaconChain implements IBeaconChain {
1061
1069
  const blockRootHex = toRootHex(blockRoot);
1062
1070
 
1063
1071
  const fork = this.config.getForkName(slot);
1064
- if (isForkPostGloas(fork)) {
1065
- // TODO GLOAS: we should retire BlockType post-gloas, may need a new enum for self vs non-self built
1066
- if (produceResult.type !== BlockType.Full) {
1067
- throw Error(`Unexpected block type=${produceResult.type} for post-gloas fork=${fork}`);
1068
- }
1069
-
1070
- const gloasResult = produceResult as ProduceFullGloas;
1071
- const envelope: gloas.ExecutionPayloadEnvelope = {
1072
- payload: gloasResult.executionPayload,
1073
- executionRequests: gloasResult.executionRequests,
1074
- builderIndex: BUILDER_INDEX_SELF_BUILD,
1075
- beaconBlockRoot: blockRoot,
1076
- slot,
1077
- stateRoot: ZERO_HASH,
1078
- };
1079
- const envelopeStateRoot = computeEnvelopeStateRoot(this.metrics, postState, envelope);
1080
- gloasResult.envelopeStateRoot = envelopeStateRoot;
1072
+ // TODO GLOAS: we should retire BlockType post-gloas, may need a new enum for self vs non-self built
1073
+ if (isForkPostGloas(fork) && produceResult.type !== BlockType.Full) {
1074
+ throw Error(`Unexpected block type=${produceResult.type} for post-gloas fork=${fork}`);
1081
1075
  }
1082
1076
 
1083
1077
  // Track the produced block for consensus broadcast validations, later validation, etc.
@@ -1325,8 +1319,8 @@ export class BeaconChain implements IBeaconChain {
1325
1319
  checkpoint: CheckpointWithPayloadStatus,
1326
1320
  blockState: IBeaconStateView
1327
1321
  ): {state: IBeaconStateView; stateId: string; shouldWarn: boolean} {
1328
- const checkpointHexPayload = fcCheckpointToHexPayload(checkpoint);
1329
- const state = this.regen.getCheckpointStateSync(checkpointHexPayload);
1322
+ const checkpointHex = {epoch: checkpoint.epoch, rootHex: checkpoint.rootHex};
1323
+ const state = this.regen.getCheckpointStateSync(checkpointHex);
1330
1324
  if (state) {
1331
1325
  return {state, stateId: "checkpoint_state", shouldWarn: false};
1332
1326
  }
@@ -1404,9 +1398,7 @@ export class BeaconChain implements IBeaconChain {
1404
1398
  metrics.chain.blacklistedBlocks.set(this.blacklistedBlocks.size);
1405
1399
 
1406
1400
  const headState = this.getHeadState();
1407
- const fork = this.config.getForkName(headState.slot);
1408
-
1409
- if (isForkPostElectra(fork)) {
1401
+ if (isStatePostElectra(headState)) {
1410
1402
  metrics.pendingDeposits.set(headState.pendingDepositsCount);
1411
1403
  metrics.pendingPartialWithdrawals.set(headState.pendingPartialWithdrawalsCount);
1412
1404
  metrics.pendingConsolidations.set(headState.pendingConsolidationsCount);
@@ -1452,10 +1444,6 @@ export class BeaconChain implements IBeaconChain {
1452
1444
  private onClockEpoch(epoch: Epoch): void {
1453
1445
  this.metrics?.clockEpoch.set(epoch);
1454
1446
 
1455
- if (epoch === this.config.GLOAS_FORK_EPOCH) {
1456
- this.regen.upgradeForGloas(epoch);
1457
- }
1458
-
1459
1447
  this.seenAttesters.prune(epoch);
1460
1448
  this.seenAggregators.prune(epoch);
1461
1449
  this.seenPayloadAttesters.prune(epoch);
@@ -1653,6 +1641,9 @@ export class BeaconChain implements IBeaconChain {
1653
1641
  }
1654
1642
 
1655
1643
  preState = preState.processSlots(block.slot); // Dial preState's slot to block.slot
1644
+ if (!isStatePostAltair(preState)) {
1645
+ throw new Error("Sync committee rewards are not supported before Altair");
1646
+ }
1656
1647
 
1657
1648
  return preState.computeSyncCommitteeRewards(block, validatorIds ?? []);
1658
1649
  }
@@ -7,6 +7,7 @@ import {DataColumnSidecar, RootHex, deneb, phase0} from "@lodestar/types";
7
7
  import {SignedExecutionPayloadEnvelope} from "@lodestar/types/gloas";
8
8
  import {PeerIdStr} from "../util/peerId.js";
9
9
  import {BlockInputSource, IBlockInput} from "./blocks/blockInput/types.js";
10
+ import {PayloadEnvelopeInput} from "./blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
10
11
 
11
12
  /**
12
13
  * Important chain events that occur during normal chain operation.
@@ -76,6 +77,11 @@ export enum ChainEvent {
76
77
  * cut-off window passes for waiting on gossip
77
78
  */
78
79
  incompleteBlockInput = "incompleteBlockInput",
80
+ /**
81
+ * Post-gloas: trigger BlockInputSync for payload envelopes whose envelope and/or sampled columns are partially
82
+ * received via gossip but are not complete by time the cut-off window passes for waiting on gossip
83
+ */
84
+ incompletePayloadEnvelope = "incompletePayloadEnvelope",
79
85
  }
80
86
 
81
87
  export type HeadEventData = routes.events.EventData[routes.events.EventType.head];
@@ -93,6 +99,11 @@ export type ChainEventData = {
93
99
  };
94
100
  [ChainEvent.unknownBlockRoot]: {rootHex: RootHex; peer?: PeerIdStr; source: BlockInputSource};
95
101
  [ChainEvent.incompleteBlockInput]: {blockInput: IBlockInput; peer: PeerIdStr; source: BlockInputSource};
102
+ [ChainEvent.incompletePayloadEnvelope]: {
103
+ payloadInput: PayloadEnvelopeInput;
104
+ peer: PeerIdStr;
105
+ source: BlockInputSource;
106
+ };
96
107
  [ChainEvent.unknownEnvelopeBlockRoot]: {rootHex: RootHex; peer?: PeerIdStr; source: BlockInputSource};
97
108
  };
98
109
 
@@ -116,6 +127,7 @@ export type IChainEvents = ApiEvents & {
116
127
  [ChainEvent.envelopeUnknownBlock]: (data: ChainEventData[ChainEvent.envelopeUnknownBlock]) => void;
117
128
  [ChainEvent.unknownBlockRoot]: (data: ChainEventData[ChainEvent.unknownBlockRoot]) => void;
118
129
  [ChainEvent.incompleteBlockInput]: (data: ChainEventData[ChainEvent.incompleteBlockInput]) => void;
130
+ [ChainEvent.incompletePayloadEnvelope]: (data: ChainEventData[ChainEvent.incompletePayloadEnvelope]) => void;
119
131
  [ChainEvent.unknownEnvelopeBlockRoot]: (data: ChainEventData[ChainEvent.unknownEnvelopeBlockRoot]) => void;
120
132
  };
121
133
 
@@ -147,6 +147,10 @@ export enum AttestationErrorCode {
147
147
  * Gloas: Current slot attestation is marking payload as present
148
148
  */
149
149
  PREMATURELY_INDICATED_PAYLOAD_PRESENT = "ATTESTATION_ERROR_PREMATURELY_INDICATED_PAYLOAD_PRESENT",
150
+ /**
151
+ * Gloas: index-1 attestation but the execution payload has not been seen yet
152
+ */
153
+ EXECUTION_PAYLOAD_NOT_SEEN = "ATTESTATION_ERROR_EXECUTION_PAYLOAD_NOT_SEEN",
150
154
  }
151
155
 
152
156
  export type AttestationErrorType =
@@ -185,7 +189,8 @@ export type AttestationErrorType =
185
189
  | {code: AttestationErrorCode.NON_ZERO_ATTESTATION_DATA_INDEX}
186
190
  | {code: AttestationErrorCode.ATTESTER_NOT_IN_COMMITTEE}
187
191
  | {code: AttestationErrorCode.INVALID_PAYLOAD_STATUS_VALUE; attDataIndex: number}
188
- | {code: AttestationErrorCode.PREMATURELY_INDICATED_PAYLOAD_PRESENT};
192
+ | {code: AttestationErrorCode.PREMATURELY_INDICATED_PAYLOAD_PRESENT}
193
+ | {code: AttestationErrorCode.EXECUTION_PAYLOAD_NOT_SEEN; beaconBlockRoot: RootHex};
189
194
 
190
195
  export class AttestationError extends GossipActionError<AttestationErrorType> {
191
196
  getMetadata(): Record<string, string | number | null> {
@@ -70,6 +70,10 @@ export enum BlockErrorCode {
70
70
  TOO_MANY_KZG_COMMITMENTS = "BLOCK_ERROR_TOO_MANY_KZG_COMMITMENTS",
71
71
  /** Bid parent block root does not match block parent root */
72
72
  BID_PARENT_ROOT_MISMATCH = "BLOCK_ERROR_BID_PARENT_ROOT_MISMATCH",
73
+ /** The parent block's execution payload has been verified as invalid */
74
+ PARENT_EXECUTION_INVALID = "BLOCK_ERROR_PARENT_EXECUTION_INVALID",
75
+ /** The block's parent execution payload (defined by bid.parent_block_hash) has not been seen */
76
+ PARENT_PAYLOAD_UNKNOWN = "BLOCK_ERROR_PARENT_PAYLOAD_UNKNOWN",
73
77
  }
74
78
 
75
79
  type ExecutionErrorStatus = Exclude<
@@ -114,7 +118,9 @@ export type BlockErrorType =
114
118
  | {code: BlockErrorCode.EXECUTION_ENGINE_ERROR; execStatus: ExecutionErrorStatus; errorMessage: string}
115
119
  | {code: BlockErrorCode.DATA_UNAVAILABLE}
116
120
  | {code: BlockErrorCode.TOO_MANY_KZG_COMMITMENTS; blobKzgCommitmentsLen: number; commitmentLimit: number}
117
- | {code: BlockErrorCode.BID_PARENT_ROOT_MISMATCH; bidParentRoot: RootHex; blockParentRoot: RootHex};
121
+ | {code: BlockErrorCode.BID_PARENT_ROOT_MISMATCH; bidParentRoot: RootHex; blockParentRoot: RootHex}
122
+ | {code: BlockErrorCode.PARENT_EXECUTION_INVALID; parentRoot: RootHex}
123
+ | {code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN; parentBlockHash: RootHex};
118
124
 
119
125
  export class BlockGossipError extends GossipActionError<BlockErrorType> {}
120
126
 
@@ -10,12 +10,14 @@ import {
10
10
  ForkChoiceOpts as RawForkChoiceOpts,
11
11
  getCheckpointPayloadStatus,
12
12
  } from "@lodestar/fork-choice";
13
- import {ForkSeq, ZERO_HASH_HEX} from "@lodestar/params";
13
+ import {ZERO_HASH_HEX} from "@lodestar/params";
14
14
  import {
15
15
  DataAvailabilityStatus,
16
16
  IBeaconStateView,
17
17
  computeEpochAtSlot,
18
18
  computeStartSlotAtEpoch,
19
+ isStatePostBellatrix,
20
+ isStatePostGloas,
19
21
  } from "@lodestar/state-transition";
20
22
  import {Slot, ssz} from "@lodestar/types";
21
23
  import {Logger, toRootHex} from "@lodestar/utils";
@@ -103,10 +105,14 @@ export function initializeForkChoiceFromFinalizedState(
103
105
  const isForkPostGloas = computeEpochAtSlot(state.slot) >= config.GLOAS_FORK_EPOCH;
104
106
 
105
107
  // Determine justified checkpoint payload status
106
- const justifiedPayloadStatus = getCheckpointPayloadStatus(config, state, justifiedCheckpoint.epoch);
108
+ const justifiedPayloadStatus = isForkPostGloas
109
+ ? PayloadStatus.PENDING
110
+ : getCheckpointPayloadStatus(config, state, justifiedCheckpoint.epoch);
107
111
 
108
112
  // Determine finalized checkpoint payload status
109
- const finalizedPayloadStatus = getCheckpointPayloadStatus(config, state, finalizedCheckpoint.epoch);
113
+ const finalizedPayloadStatus = isForkPostGloas
114
+ ? PayloadStatus.PENDING
115
+ : getCheckpointPayloadStatus(config, state, finalizedCheckpoint.epoch);
110
116
 
111
117
  return new forkchoiceConstructor(
112
118
  config,
@@ -142,19 +148,21 @@ export function initializeForkChoiceFromFinalizedState(
142
148
  unrealizedFinalizedEpoch: finalizedCheckpoint.epoch,
143
149
  unrealizedFinalizedRoot: toRootHex(finalizedCheckpoint.root),
144
150
 
145
- ...(state.isExecutionStateType && state.isMergeTransitionComplete
151
+ ...(isStatePostBellatrix(state) && state.isExecutionStateType && state.isMergeTransitionComplete
146
152
  ? {
147
- executionPayloadBlockHash: toRootHex(state.latestBlockHash),
153
+ executionPayloadBlockHash: isStatePostGloas(state)
154
+ ? toRootHex(state.latestBlockHash)
155
+ : toRootHex(state.latestExecutionPayloadHeader.blockHash),
148
156
  // TODO GLOAS: executionPayloadNumber is not tracked in BeaconState post-gloas (EIP-7732 removed
149
157
  // latestExecutionPayloadHeader). Using 0 as unavailable fallback until a solution is found.
150
- executionPayloadNumber: config.getForkSeq(state.slot) >= ForkSeq.gloas ? 0 : state.payloadBlockNumber,
158
+ executionPayloadNumber: isStatePostGloas(state) ? 0 : state.payloadBlockNumber,
151
159
  executionStatus: blockHeader.slot === GENESIS_SLOT ? ExecutionStatus.Valid : ExecutionStatus.Syncing,
152
160
  }
153
161
  : {executionPayloadBlockHash: null, executionStatus: ExecutionStatus.PreMerge}),
154
162
 
155
163
  dataAvailabilityStatus: DataAvailabilityStatus.PreData,
156
164
  payloadStatus: isForkPostGloas ? PayloadStatus.PENDING : PayloadStatus.FULL, // TODO GLOAS: Post-gloas how do we know if the checkpoint payload is FULL or EMPTY?
157
- parentBlockHash: isForkPostGloas ? toRootHex(state.latestBlockHash) : null,
165
+ parentBlockHash: isStatePostGloas(state) ? toRootHex(state.latestBlockHash) : null,
158
166
  },
159
167
  currentSlot
160
168
  ),
@@ -237,20 +245,23 @@ export function initializeForkChoiceFromUnfinalizedState(
237
245
  unrealizedFinalizedEpoch: finalizedCheckpoint.epoch,
238
246
  unrealizedFinalizedRoot: toRootHex(finalizedCheckpoint.root),
239
247
 
240
- ...(unfinalizedState.isExecutionStateType && unfinalizedState.isMergeTransitionComplete
248
+ ...(isStatePostBellatrix(unfinalizedState) &&
249
+ unfinalizedState.isExecutionStateType &&
250
+ unfinalizedState.isMergeTransitionComplete
241
251
  ? {
242
- executionPayloadBlockHash: toRootHex(unfinalizedState.latestBlockHash),
252
+ executionPayloadBlockHash: isStatePostGloas(unfinalizedState)
253
+ ? toRootHex(unfinalizedState.latestBlockHash)
254
+ : toRootHex(unfinalizedState.latestExecutionPayloadHeader.blockHash),
243
255
  // TODO GLOAS: executionPayloadNumber is not tracked in BeaconState post-gloas (EIP-7732 removed
244
256
  // latestExecutionPayloadHeader). Using 0 as unavailable fallback until a solution is found.
245
- executionPayloadNumber:
246
- config.getForkSeq(unfinalizedState.slot) >= ForkSeq.gloas ? 0 : unfinalizedState.payloadBlockNumber,
257
+ executionPayloadNumber: isStatePostGloas(unfinalizedState) ? 0 : unfinalizedState.payloadBlockNumber,
247
258
  executionStatus: blockHeader.slot === GENESIS_SLOT ? ExecutionStatus.Valid : ExecutionStatus.Syncing,
248
259
  }
249
260
  : {executionPayloadBlockHash: null, executionStatus: ExecutionStatus.PreMerge}),
250
261
 
251
262
  dataAvailabilityStatus: DataAvailabilityStatus.PreData,
252
263
  payloadStatus: isForkPostGloas ? PayloadStatus.PENDING : PayloadStatus.FULL, // TODO GLOAS: Post-gloas how do we know if the checkpoint payload is FULL or EMPTY?
253
- parentBlockHash: isForkPostGloas ? toRootHex(unfinalizedState.latestBlockHash) : null,
264
+ parentBlockHash: isStatePostGloas(unfinalizedState) ? toRootHex(unfinalizedState.latestBlockHash) : null,
254
265
  };
255
266
 
256
267
  const parentSlot = blockHeader.slot - 1;
@@ -18,6 +18,7 @@ import {
18
18
  altair,
19
19
  capella,
20
20
  deneb,
21
+ gloas,
21
22
  phase0,
22
23
  rewards,
23
24
  } from "@lodestar/types";
@@ -226,6 +227,10 @@ export interface IBeaconChain {
226
227
  indices: number[]
227
228
  ): Promise<(Uint8Array | undefined)[]>;
228
229
  getSerializedExecutionPayloadEnvelope(blockSlot: Slot, blockRootHex: string): Promise<Uint8Array | null>;
230
+ getExecutionPayloadEnvelope(
231
+ blockSlot: Slot,
232
+ blockRootHex: string
233
+ ): Promise<gloas.SignedExecutionPayloadEnvelope | null>;
229
234
 
230
235
  produceCommonBlockBody(blockAttributes: BlockAttributes): Promise<CommonBlockBody>;
231
236
  produceBlock(blockAttributes: BlockAttributes & {commonBlockBodyPromise: Promise<CommonBlockBody>}): Promise<{
@@ -21,7 +21,7 @@ import {
21
21
  isForkPostElectra,
22
22
  } from "@lodestar/params";
23
23
  import {
24
- IBeaconStateView,
24
+ type IBeaconStateViewAltair,
25
25
  computeStartSlotAtEpoch,
26
26
  computeSyncPeriodAtEpoch,
27
27
  computeSyncPeriodAtSlot,
@@ -260,7 +260,11 @@ export class LightClientServer {
260
260
  * - Persist state witness
261
261
  * - Use block's syncAggregate
262
262
  */
263
- onImportBlockHead(block: BeaconBlock<ForkPostAltair>, postState: IBeaconStateView, parentBlockSlot: Slot): void {
263
+ onImportBlockHead(
264
+ block: BeaconBlock<ForkPostAltair>,
265
+ postState: IBeaconStateViewAltair,
266
+ parentBlockSlot: Slot
267
+ ): void {
264
268
  // TEMP: To disable this functionality for fork_choice spec tests.
265
269
  // Since the tests have deep-reorgs attested data is not available often printing lots of error logs.
266
270
  // While this function is only called for head blocks, best to disable.
@@ -268,6 +272,14 @@ export class LightClientServer {
268
272
  return;
269
273
  }
270
274
 
275
+ // TODO GLOAS: Light client updates for gloas are not yet updated in the spec.
276
+ // The block body no longer contains execution payload, so `blockToLightClientHeader`
277
+ // cannot construct a header from a gloas block. Skip all light client processing
278
+ // for post-gloas blocks, revisit once there is a spec for it.
279
+ if (this.config.getForkSeq(block.slot) >= ForkSeq.gloas) {
280
+ return;
281
+ }
282
+
271
283
  // What is the syncAggregate signing?
272
284
  // From the state-transition
273
285
  // ```
@@ -396,7 +408,7 @@ export class LightClientServer {
396
408
 
397
409
  private async persistPostBlockImportData(
398
410
  block: BeaconBlock<ForkPostAltair>,
399
- postState: IBeaconStateView,
411
+ postState: IBeaconStateViewAltair,
400
412
  parentBlockSlot: Slot
401
413
  ): Promise<void> {
402
414
  const blockSlot = block.slot;
@@ -26,6 +26,8 @@ import {
26
26
  computeSlotsSinceEpochStart,
27
27
  computeStartSlotAtEpoch,
28
28
  getAttestationParticipationStatus,
29
+ isStatePostAltair,
30
+ isStatePostGloas,
29
31
  } from "@lodestar/state-transition";
30
32
  import {Attestation, Epoch, RootHex, Slot, electra, isElectraAttestation, phase0, ssz} from "@lodestar/types";
31
33
  import {MapDef, assert, toRootHex} from "@lodestar/utils";
@@ -359,7 +361,7 @@ export class AggregatedAttestationPool {
359
361
  inclusionDistance,
360
362
  stateEpoch,
361
363
  rootCache,
362
- ForkSeq[fork] >= ForkSeq.gloas ? state.executionPayloadAvailability : null
364
+ isStatePostGloas(state) ? state.executionPayloadAvailability : null
363
365
  );
364
366
 
365
367
  const weight =
@@ -742,6 +744,9 @@ export function getNotSeenValidatorsFn(
742
744
  if (config.getForkName(stateSlot) === ForkName.phase0) {
743
745
  throw new Error("getNotSeenValidatorsFn is not supported phase0 state");
744
746
  }
747
+ if (!isStatePostAltair(state)) {
748
+ throw new Error("Expected Altair state for participation tracking");
749
+ }
745
750
 
746
751
  // altair and future forks
747
752
  // Get attestations to be included in an altair block.
@@ -59,13 +59,13 @@ export class ExecutionPayloadBidPool {
59
59
  }
60
60
 
61
61
  /**
62
- * Return the highest-value bid matching slot, parent block root, and parent block hash.
62
+ * Return the highest-value bid matching slot, parent block hash, and parent block root.
63
63
  * Used for gossip validation and block production.
64
64
  */
65
65
  getBestBid(
66
- parentBlockRoot: BlockRootHex,
66
+ slot: Slot,
67
67
  parentBlockHash: BlockHashHex,
68
- slot: Slot
68
+ parentBlockRoot: BlockRootHex
69
69
  ): gloas.ExecutionPayloadBid | null {
70
70
  const bidByParentHash = this.bidByParentHashByParentRootBySlot.get(slot)?.get(parentBlockRoot);
71
71
  return bidByParentHash?.get(parentBlockHash) ?? null;
@@ -1,14 +1,16 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {ChainForkConfig} from "@lodestar/config";
3
- import {PayloadStatus, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
3
+ import {getSafeExecutionBlockHash} from "@lodestar/fork-choice";
4
4
  import {ForkPostBellatrix, ForkSeq, SLOTS_PER_EPOCH, isForkPostBellatrix} from "@lodestar/params";
5
5
  import {
6
6
  IBeaconStateView,
7
7
  StateHashTreeRootSource,
8
8
  computeEpochAtSlot,
9
9
  computeTimeAtSlot,
10
+ isStatePostBellatrix,
11
+ isStatePostGloas,
10
12
  } from "@lodestar/state-transition";
11
- import {Slot} from "@lodestar/types";
13
+ import {Bytes32, Slot} from "@lodestar/types";
12
14
  import {Logger, fromHex, isErrorAborted, sleep} from "@lodestar/utils";
13
15
  import {GENESIS_SLOT, ZERO_HASH_HEX} from "../constants/constants.js";
14
16
  import {BuilderStatus} from "../execution/builder/http.js";
@@ -80,6 +82,8 @@ export class PrepareNextSlotScheduler {
80
82
  // calling updateHead() here before we produce a block to reduce reorg possibility
81
83
  const headBlock = this.chain.recomputeForkChoiceHead(ForkchoiceCaller.prepareNextSlot);
82
84
  const {slot: headSlot, blockRoot: headRoot} = headBlock;
85
+ // may be updated below if we predict a proposer-boost-reorg
86
+ let updatedHeadRoot = headRoot;
83
87
 
84
88
  // PS: previously this was comparing slots, but that gave no leway on the skipped
85
89
  // slots on epoch bounday. Making it more fluid.
@@ -122,7 +126,6 @@ export class PrepareNextSlotScheduler {
122
126
  const proposerIndex = prepareState.getBeaconProposer(prepareSlot);
123
127
  const feeRecipient = this.chain.beaconProposerCache.get(proposerIndex);
124
128
  let updatedPrepareState = prepareState;
125
- let updatedHeadRoot = headRoot;
126
129
 
127
130
  if (feeRecipient) {
128
131
  // If we are proposing next slot, we need to predict if we can proposer-boost-reorg or not
@@ -155,7 +158,22 @@ export class PrepareNextSlotScheduler {
155
158
  this.logger.error("Builder disabled as the check status api failed", {prepareSlot}, e as Error);
156
159
  });
157
160
  }
161
+ }
162
+
163
+ if (!isStatePostBellatrix(updatedPrepareState)) {
164
+ throw new Error("Expected Bellatrix state for payload attributes");
165
+ }
158
166
 
167
+ let parentBlockHash: Bytes32;
168
+ if (isStatePostGloas(updatedPrepareState)) {
169
+ parentBlockHash = this.chain.forkChoice.shouldExtendPayload(updatedHeadRoot)
170
+ ? updatedPrepareState.latestExecutionPayloadBid.blockHash
171
+ : updatedPrepareState.latestExecutionPayloadBid.parentBlockHash;
172
+ } else {
173
+ parentBlockHash = updatedPrepareState.latestExecutionPayloadHeader.blockHash;
174
+ }
175
+
176
+ if (feeRecipient) {
159
177
  const preparationTime =
160
178
  computeTimeAtSlot(this.config, prepareSlot, this.chain.genesisTime) - Date.now() / 1000;
161
179
  this.metrics?.blockPayload.payloadAdvancePrepTime.observe(preparationTime);
@@ -163,14 +181,16 @@ export class PrepareNextSlotScheduler {
163
181
  const safeBlockHash = getSafeExecutionBlockHash(this.chain.forkChoice);
164
182
  const finalizedBlockHash =
165
183
  this.chain.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
184
+
166
185
  // awaiting here instead of throwing an async call because there is no other task
167
- // left for scheduler and this gives nice sematics to catch and log errors in the
186
+ // left for scheduler and this gives nice semantics to catch and log errors in the
168
187
  // try/catch wrapper here.
169
188
  await prepareExecutionPayload(
170
189
  this.chain,
171
190
  this.logger,
172
191
  fork as ForkPostBellatrix, // State is of execution type
173
192
  fromHex(updatedHeadRoot),
193
+ parentBlockHash,
174
194
  safeBlockHash,
175
195
  finalizedBlockHash,
176
196
  updatedPrepareState,
@@ -194,6 +214,7 @@ export class PrepareNextSlotScheduler {
194
214
  prepareState: updatedPrepareState,
195
215
  prepareSlot,
196
216
  parentBlockRoot: fromHex(headRoot),
217
+ parentBlockHash,
197
218
  // The likely consumers of this API are builders and will anyway ignore the
198
219
  // feeRecipient, so just pass zero hash for now till a real use case arises
199
220
  feeRecipient: "0x0000000000000000000000000000000000000000000000000000000000000000",
@@ -209,11 +230,7 @@ export class PrepareNextSlotScheduler {
209
230
  // + if next slot is a skipped slot, it'd help getting target checkpoint state faster to validate attestations
210
231
  if (isEpochTransition) {
211
232
  this.metrics?.precomputeNextEpochTransition.count.inc({result: "success"}, 1);
212
- // Determine payloadPresent from head block's payload status
213
- // Pre-Gloas: payloadStatus is always FULL → payloadPresent = true
214
- // Post-Gloas: FULL → true, EMPTY → false, PENDING → false (conservative, treat as block state)
215
- const payloadPresent = headBlock.payloadStatus === PayloadStatus.FULL;
216
- const previousHits = this.chain.regen.updatePreComputedCheckpoint(headRoot, nextEpoch, payloadPresent);
233
+ const previousHits = this.chain.regen.updatePreComputedCheckpoint(headRoot, nextEpoch);
217
234
  if (previousHits === 0) {
218
235
  this.metrics?.precomputeNextEpochTransition.waste.inc();
219
236
  }
@@ -1,11 +1,10 @@
1
1
  import {
2
2
  DataAvailabilityStatus,
3
3
  ExecutionPayloadStatus,
4
- G2_POINT_AT_INFINITY,
5
4
  IBeaconStateView,
6
5
  StateHashTreeRootSource,
7
6
  } from "@lodestar/state-transition";
8
- import {BeaconBlock, BlindedBeaconBlock, Gwei, Root, gloas} from "@lodestar/types";
7
+ import {BeaconBlock, BlindedBeaconBlock, Gwei, Root} from "@lodestar/types";
9
8
  import {ZERO_HASH} from "../../constants/index.js";
10
9
  import {Metrics} from "../../metrics/index.js";
11
10
 
@@ -52,38 +51,3 @@ export function computeNewStateRoot(
52
51
 
53
52
  return {newStateRoot, proposerReward, postState};
54
53
  }
55
-
56
- /**
57
- * Compute the state root after processing an execution payload envelope.
58
- * Similar to `computeNewStateRoot` but for payload envelope processing.
59
- *
60
- */
61
- export function computeEnvelopeStateRoot(
62
- metrics: Metrics | null,
63
- postBlockState: IBeaconStateView,
64
- envelope: gloas.ExecutionPayloadEnvelope
65
- ): Root {
66
- const signedEnvelope: gloas.SignedExecutionPayloadEnvelope = {
67
- message: envelope,
68
- signature: G2_POINT_AT_INFINITY,
69
- };
70
-
71
- const processEnvelopeTimer = metrics?.blockPayload.executionPayloadEnvelopeProcessingTime.startTimer();
72
- const postEnvelopeState = postBlockState.processExecutionPayloadEnvelope(signedEnvelope, {
73
- // Signature is zero-ed (G2_POINT_AT_INFINITY), skip verification
74
- verifySignature: false,
75
- // State root is being computed here, the envelope doesn't have it yet
76
- verifyStateRoot: false,
77
- // Preserve cache in source state, since the resulting state is not added to the state cache
78
- dontTransferCache: true,
79
- });
80
- processEnvelopeTimer?.();
81
-
82
- const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({
83
- source: StateHashTreeRootSource.computeEnvelopeStateRoot,
84
- });
85
- const stateRoot = postEnvelopeState.hashTreeRoot();
86
- hashTreeRootTimer?.();
87
-
88
- return stateRoot;
89
- }