@lodestar/beacon-node 1.50.0-dev.cc4428df4b → 1.50.0-dev.ce0e732118

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 (249) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +6 -1
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/index.js +13 -0
  6. package/lib/api/impl/beacon/index.js.map +1 -1
  7. package/lib/api/impl/beacon/pool/index.js +4 -4
  8. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  9. package/lib/api/impl/validator/index.d.ts +1 -0
  10. package/lib/api/impl/validator/index.d.ts.map +1 -1
  11. package/lib/api/impl/validator/index.js +17 -1
  12. package/lib/api/impl/validator/index.js.map +1 -1
  13. package/lib/chain/archiveStore/archiveStore.d.ts +1 -0
  14. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  15. package/lib/chain/archiveStore/archiveStore.js +7 -3
  16. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  17. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +2 -2
  18. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  19. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +5 -7
  20. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  21. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -1
  22. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
  23. package/lib/chain/archiveStore/historicalState/types.d.ts +2 -2
  24. package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/worker.js +1 -1
  26. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  27. package/lib/chain/archiveStore/interface.d.ts +1 -1
  28. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  29. package/lib/chain/archiveStore/utils/pruneHistory.d.ts +4 -1
  30. package/lib/chain/archiveStore/utils/pruneHistory.d.ts.map +1 -1
  31. package/lib/chain/archiveStore/utils/pruneHistory.js +4 -3
  32. package/lib/chain/archiveStore/utils/pruneHistory.js.map +1 -1
  33. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  34. package/lib/chain/blocks/importBlock.js +4 -0
  35. package/lib/chain/blocks/importBlock.js.map +1 -1
  36. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +2 -1
  37. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  38. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  39. package/lib/chain/blocks/verifyBlock.js +1 -1
  40. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  41. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +2 -1
  42. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  43. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +5 -4
  44. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  45. package/lib/chain/chain.d.ts +6 -4
  46. package/lib/chain/chain.d.ts.map +1 -1
  47. package/lib/chain/chain.js +43 -16
  48. package/lib/chain/chain.js.map +1 -1
  49. package/lib/chain/emitter.d.ts +7 -1
  50. package/lib/chain/emitter.d.ts.map +1 -1
  51. package/lib/chain/emitter.js +5 -0
  52. package/lib/chain/emitter.js.map +1 -1
  53. package/lib/chain/errors/envelopeReconstructionError.d.ts +5 -0
  54. package/lib/chain/errors/envelopeReconstructionError.d.ts.map +1 -1
  55. package/lib/chain/errors/envelopeReconstructionError.js +2 -0
  56. package/lib/chain/errors/envelopeReconstructionError.js.map +1 -1
  57. package/lib/chain/errors/gossipValidation.d.ts +3 -1
  58. package/lib/chain/errors/gossipValidation.d.ts.map +1 -1
  59. package/lib/chain/errors/gossipValidation.js +2 -0
  60. package/lib/chain/errors/gossipValidation.js.map +1 -1
  61. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  62. package/lib/chain/forkChoice/index.js +2 -0
  63. package/lib/chain/forkChoice/index.js.map +1 -1
  64. package/lib/chain/initState.d.ts +2 -9
  65. package/lib/chain/initState.d.ts.map +1 -1
  66. package/lib/chain/initState.js +5 -38
  67. package/lib/chain/initState.js.map +1 -1
  68. package/lib/chain/interface.d.ts +2 -2
  69. package/lib/chain/interface.d.ts.map +1 -1
  70. package/lib/chain/opPools/opPool.d.ts +5 -4
  71. package/lib/chain/opPools/opPool.d.ts.map +1 -1
  72. package/lib/chain/opPools/opPool.js +62 -18
  73. package/lib/chain/opPools/opPool.js.map +1 -1
  74. package/lib/chain/opPools/proposerPreferencesPool.d.ts +4 -4
  75. package/lib/chain/opPools/proposerPreferencesPool.d.ts.map +1 -1
  76. package/lib/chain/opPools/proposerPreferencesPool.js +14 -11
  77. package/lib/chain/opPools/proposerPreferencesPool.js.map +1 -1
  78. package/lib/chain/opPools/utils.d.ts +4 -1
  79. package/lib/chain/opPools/utils.d.ts.map +1 -1
  80. package/lib/chain/opPools/utils.js +11 -1
  81. package/lib/chain/opPools/utils.js.map +1 -1
  82. package/lib/chain/options.d.ts +1 -1
  83. package/lib/chain/options.d.ts.map +1 -1
  84. package/lib/chain/options.js +1 -1
  85. package/lib/chain/options.js.map +1 -1
  86. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  87. package/lib/chain/prepareNextSlot.js +5 -2
  88. package/lib/chain/prepareNextSlot.js.map +1 -1
  89. package/lib/chain/produceBlock/computeNewStateRoot.js +1 -1
  90. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  91. package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -1
  92. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  93. package/lib/chain/produceBlock/produceBlockBody.js +6 -2
  94. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  95. package/lib/chain/regen/regen.d.ts +2 -0
  96. package/lib/chain/regen/regen.d.ts.map +1 -1
  97. package/lib/chain/regen/regen.js +10 -4
  98. package/lib/chain/regen/regen.js.map +1 -1
  99. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +9 -2
  100. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  101. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +23 -13
  102. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  103. package/lib/chain/validation/attesterSlashing.d.ts +4 -4
  104. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  105. package/lib/chain/validation/attesterSlashing.js +3 -0
  106. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  107. package/lib/chain/validation/proposerSlashing.d.ts +3 -3
  108. package/lib/chain/validation/proposerSlashing.d.ts.map +1 -1
  109. package/lib/chain/validation/proposerSlashing.js +3 -0
  110. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  111. package/lib/chain/validatorMonitor.d.ts +5 -1
  112. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  113. package/lib/chain/validatorMonitor.js +64 -54
  114. package/lib/chain/validatorMonitor.js.map +1 -1
  115. package/lib/db/beacon.d.ts.map +1 -1
  116. package/lib/db/beacon.js +2 -0
  117. package/lib/db/beacon.js.map +1 -1
  118. package/lib/db/repositories/proposerSlashing.d.ts +1 -0
  119. package/lib/db/repositories/proposerSlashing.d.ts.map +1 -1
  120. package/lib/db/repositories/proposerSlashing.js +5 -1
  121. package/lib/db/repositories/proposerSlashing.js.map +1 -1
  122. package/lib/execution/engine/disabled.d.ts +0 -2
  123. package/lib/execution/engine/disabled.d.ts.map +1 -1
  124. package/lib/execution/engine/disabled.js +0 -6
  125. package/lib/execution/engine/disabled.js.map +1 -1
  126. package/lib/execution/engine/http.d.ts +1 -3
  127. package/lib/execution/engine/http.d.ts.map +1 -1
  128. package/lib/execution/engine/http.js +7 -21
  129. package/lib/execution/engine/http.js.map +1 -1
  130. package/lib/execution/engine/interface.d.ts +2 -4
  131. package/lib/execution/engine/interface.d.ts.map +1 -1
  132. package/lib/execution/engine/mock.d.ts +0 -2
  133. package/lib/execution/engine/mock.d.ts.map +1 -1
  134. package/lib/execution/engine/mock.js +0 -8
  135. package/lib/execution/engine/mock.js.map +1 -1
  136. package/lib/execution/engine/types.d.ts +0 -8
  137. package/lib/execution/engine/types.d.ts.map +1 -1
  138. package/lib/execution/engine/types.js.map +1 -1
  139. package/lib/index.d.ts +1 -1
  140. package/lib/index.d.ts.map +1 -1
  141. package/lib/index.js +1 -1
  142. package/lib/index.js.map +1 -1
  143. package/lib/metrics/metrics/beacon.d.ts +1 -1
  144. package/lib/metrics/metrics/beacon.d.ts.map +1 -1
  145. package/lib/metrics/metrics/beacon.js.map +1 -1
  146. package/lib/metrics/metrics.d.ts +7 -3
  147. package/lib/metrics/metrics.d.ts.map +1 -1
  148. package/lib/metrics/metrics.js +4 -4
  149. package/lib/metrics/metrics.js.map +1 -1
  150. package/lib/network/metadata.d.ts +1 -1
  151. package/lib/network/metadata.d.ts.map +1 -1
  152. package/lib/network/metadata.js +17 -17
  153. package/lib/network/metadata.js.map +1 -1
  154. package/lib/network/peers/datastore.d.ts +9 -9
  155. package/lib/network/peers/datastore.d.ts.map +1 -1
  156. package/lib/network/peers/datastore.js +36 -36
  157. package/lib/network/peers/datastore.js.map +1 -1
  158. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  159. package/lib/network/processor/gossipHandlers.js +7 -4
  160. package/lib/network/processor/gossipHandlers.js.map +1 -1
  161. package/lib/network/processor/gossipValidatorFn.d.ts +7 -3
  162. package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
  163. package/lib/network/processor/gossipValidatorFn.js +7 -3
  164. package/lib/network/processor/gossipValidatorFn.js.map +1 -1
  165. package/lib/network/processor/index.d.ts +9 -0
  166. package/lib/network/processor/index.d.ts.map +1 -1
  167. package/lib/network/processor/index.js +77 -10
  168. package/lib/network/processor/index.js.map +1 -1
  169. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -1
  170. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +41 -26
  171. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
  172. package/lib/node/nodejs.d.ts.map +1 -1
  173. package/lib/node/nodejs.js +25 -3
  174. package/lib/node/nodejs.js.map +1 -1
  175. package/lib/sync/range/batch.d.ts +6 -0
  176. package/lib/sync/range/batch.d.ts.map +1 -1
  177. package/lib/sync/range/batch.js +10 -0
  178. package/lib/sync/range/batch.js.map +1 -1
  179. package/lib/sync/range/chain.d.ts.map +1 -1
  180. package/lib/sync/range/chain.js +5 -1
  181. package/lib/sync/range/chain.js.map +1 -1
  182. package/lib/sync/range/range.d.ts.map +1 -1
  183. package/lib/sync/range/range.js +50 -18
  184. package/lib/sync/range/range.js.map +1 -1
  185. package/lib/sync/unknownBlock.d.ts +9 -5
  186. package/lib/sync/unknownBlock.d.ts.map +1 -1
  187. package/lib/sync/unknownBlock.js +88 -46
  188. package/lib/sync/unknownBlock.js.map +1 -1
  189. package/lib/util/execution.d.ts +11 -11
  190. package/lib/util/execution.d.ts.map +1 -1
  191. package/lib/util/execution.js +11 -7
  192. package/lib/util/execution.js.map +1 -1
  193. package/package.json +16 -16
  194. package/src/api/impl/beacon/blocks/index.ts +7 -4
  195. package/src/api/impl/beacon/index.ts +15 -0
  196. package/src/api/impl/beacon/pool/index.ts +4 -4
  197. package/src/api/impl/validator/index.ts +16 -2
  198. package/src/chain/archiveStore/archiveStore.ts +10 -4
  199. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +5 -7
  200. package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +1 -1
  201. package/src/chain/archiveStore/historicalState/types.ts +2 -2
  202. package/src/chain/archiveStore/historicalState/worker.ts +1 -2
  203. package/src/chain/archiveStore/interface.ts +1 -1
  204. package/src/chain/archiveStore/utils/pruneHistory.ts +6 -4
  205. package/src/chain/blocks/importBlock.ts +4 -0
  206. package/src/chain/blocks/payloadEnvelopeInput/types.ts +2 -1
  207. package/src/chain/blocks/verifyBlock.ts +1 -0
  208. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +6 -3
  209. package/src/chain/chain.ts +50 -19
  210. package/src/chain/emitter.ts +7 -1
  211. package/src/chain/errors/envelopeReconstructionError.ts +3 -0
  212. package/src/chain/errors/gossipValidation.ts +2 -0
  213. package/src/chain/forkChoice/index.ts +2 -0
  214. package/src/chain/initState.ts +8 -60
  215. package/src/chain/interface.ts +2 -2
  216. package/src/chain/opPools/opPool.ts +91 -18
  217. package/src/chain/opPools/proposerPreferencesPool.ts +14 -10
  218. package/src/chain/opPools/utils.ts +31 -3
  219. package/src/chain/options.ts +2 -2
  220. package/src/chain/prepareNextSlot.ts +6 -3
  221. package/src/chain/produceBlock/computeNewStateRoot.ts +1 -1
  222. package/src/chain/produceBlock/produceBlockBody.ts +8 -1
  223. package/src/chain/regen/regen.ts +12 -4
  224. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +31 -13
  225. package/src/chain/validation/attesterSlashing.ts +7 -4
  226. package/src/chain/validation/proposerSlashing.ts +7 -4
  227. package/src/chain/validatorMonitor.ts +75 -57
  228. package/src/db/beacon.ts +2 -0
  229. package/src/db/repositories/proposerSlashing.ts +6 -1
  230. package/src/execution/engine/disabled.ts +0 -8
  231. package/src/execution/engine/http.ts +7 -34
  232. package/src/execution/engine/interface.ts +2 -6
  233. package/src/execution/engine/mock.ts +1 -19
  234. package/src/execution/engine/types.ts +0 -10
  235. package/src/index.ts +1 -1
  236. package/src/metrics/metrics/beacon.ts +1 -1
  237. package/src/metrics/metrics.ts +21 -6
  238. package/src/network/metadata.ts +17 -17
  239. package/src/network/peers/datastore.ts +36 -36
  240. package/src/network/processor/gossipHandlers.ts +7 -4
  241. package/src/network/processor/gossipValidatorFn.ts +13 -3
  242. package/src/network/processor/index.ts +89 -10
  243. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +42 -28
  244. package/src/node/nodejs.ts +31 -3
  245. package/src/sync/range/batch.ts +11 -0
  246. package/src/sync/range/chain.ts +6 -1
  247. package/src/sync/range/range.ts +50 -18
  248. package/src/sync/unknownBlock.ts +99 -50
  249. package/src/util/execution.ts +26 -14
@@ -189,6 +189,7 @@ export enum EngineBlockSelectionReason {
189
189
  BuilderTimeout = "builder_timeout",
190
190
  BuilderPending = "builder_pending",
191
191
  BuilderNoBid = "builder_no_bid",
192
+ BuilderCircuitBreaker = "builder_circuit_breaker",
192
193
  BuilderCensorship = "builder_censorship",
193
194
  BlockValue = "block_value",
194
195
  EnginePreferred = "engine_preferred",
@@ -1160,8 +1161,21 @@ export function getValidatorApi(
1160
1161
  : {}),
1161
1162
  };
1162
1163
 
1163
- // handle shouldOverrideBuilder separately
1164
- if (
1164
+ if (circuitBreakerActive && engineResult.status === "fulfilled") {
1165
+ source = ProducedBlockSource.engine;
1166
+ bestResult = engineResult;
1167
+ metrics?.blockProductionSelectionResults.inc({
1168
+ source: ProducedBlockSource.engine,
1169
+ reason: EngineBlockSelectionReason.BuilderCircuitBreaker,
1170
+ });
1171
+ logger.info("Selected local block: builder circuit breaker is active", {
1172
+ reason: EngineBlockSelectionReason.BuilderCircuitBreaker,
1173
+ ...logCtx,
1174
+ durationMs: engineResult.durationMs,
1175
+ ...getBlockValueLogInfo(engineResult.value),
1176
+ });
1177
+ } else if (
1178
+ // handle shouldOverrideBuilder separately
1165
1179
  engineResult.status === "fulfilled" &&
1166
1180
  engineResult.value.shouldOverrideBuilder &&
1167
1181
  (builderBidExpected || bidBlockResult.status === "fulfilled")
@@ -1,6 +1,7 @@
1
1
  import {CheckpointWithHex} from "@lodestar/fork-choice";
2
2
  import {LoggerNode} from "@lodestar/logger/node";
3
3
  import {SLOTS_PER_EPOCH} from "@lodestar/params";
4
+ import {Slot} from "@lodestar/types";
4
5
  import {Checkpoint} from "@lodestar/types/phase0";
5
6
  import {callFnWhenAwait} from "@lodestar/utils";
6
7
  import {IBeaconDb} from "../../db/index.js";
@@ -47,6 +48,8 @@ export class ArchiveStore {
47
48
  private jobQueue: JobItemQueue<[CheckpointWithHex], void>;
48
49
 
49
50
  private archiveDataEpochs?: number;
51
+ // Finalized state writes are monotonic; reset on restart to include the newly persisted anchor.
52
+ private statePruneFromSlot: Slot = 0;
50
53
  private readonly statesArchiverStrategy: StateArchiveStrategy;
51
54
  private readonly chain: IBeaconChain;
52
55
  private readonly db: IBeaconDb;
@@ -103,7 +106,7 @@ export class ArchiveStore {
103
106
  if (this.opts.pruneHistory) {
104
107
  // prune ALL stale data before starting
105
108
  this.logger.info("Pruning historical data");
106
- await callFnWhenAwait(
109
+ const {stateCutoffSlot} = await callFnWhenAwait(
107
110
  pruneHistory(
108
111
  this.chain.config,
109
112
  this.db,
@@ -116,6 +119,7 @@ export class ArchiveStore {
116
119
  30_000,
117
120
  this.signal
118
121
  );
122
+ this.statePruneFromSlot = stateCutoffSlot;
119
123
  }
120
124
 
121
125
  // Initialize earliestAvailableSlot from the earliest block actually retained (after any pruning
@@ -144,7 +148,7 @@ export class ArchiveStore {
144
148
  genesisTime: this.chain.clock.genesisTime,
145
149
  dbLocation: this.opts.dbName,
146
150
  dataColumnDir: this.opts.dataColumnDir,
147
- nativeStateView: this.opts.nativeStateView ?? false,
151
+ nativeStateTransition: this.opts.nativeStateTransition ?? false,
148
152
  },
149
153
  config: this.chain.config,
150
154
  metrics: this.metrics,
@@ -255,14 +259,16 @@ export class ArchiveStore {
255
259
 
256
260
  if (this.opts.pruneHistory) {
257
261
  timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
258
- const blockCutoffSlot = await pruneHistory(
262
+ const {blockCutoffSlot, stateCutoffSlot} = await pruneHistory(
259
263
  this.chain.config,
260
264
  this.db,
261
265
  this.logger,
262
266
  this.metrics,
263
267
  finalizedEpoch,
264
- this.chain.clock.currentEpoch
268
+ this.chain.clock.currentEpoch,
269
+ this.statePruneFromSlot
265
270
  );
271
+ this.statePruneFromSlot = stateCutoffSlot;
266
272
  this.chain.earliestAvailableSlot = Math.max(this.chain.earliestAvailableSlot, blockCutoffSlot);
267
273
  timer?.({source: ArchiveStoreTask.PruneHistory});
268
274
  }
@@ -17,7 +17,7 @@ export async function getNearestState(
17
17
  slot: number,
18
18
  config: BeaconConfig,
19
19
  db: IBeaconDb,
20
- nativeStateView: boolean
20
+ nativeStateTransition: boolean
21
21
  ): Promise<IBeaconStateView> {
22
22
  const stateBytesArr = await db.stateArchive.binaries({limit: 1, lte: slot, reverse: true});
23
23
  if (!stateBytesArr.length) {
@@ -25,9 +25,7 @@ export async function getNearestState(
25
25
  }
26
26
 
27
27
  const stateBytes = stateBytesArr[0];
28
- return nativeStateView
29
- ? createBeaconStateViewForHistoricalRegen({useNative: true, stateBytes})
30
- : createBeaconStateViewForHistoricalRegen({useNative: false, config, stateBytes});
28
+ return createBeaconStateViewForHistoricalRegen({nativeStateTransition: nativeStateTransition, config, stateBytes});
31
29
  }
32
30
 
33
31
  /**
@@ -37,13 +35,13 @@ export async function getHistoricalState(
37
35
  slot: number,
38
36
  config: BeaconConfig,
39
37
  db: IBeaconDb,
40
- nativeStateView: boolean,
38
+ nativeStateTransition: boolean,
41
39
  metrics?: HistoricalStateRegenMetrics
42
40
  ): Promise<Uint8Array> {
43
41
  const regenTimer = metrics?.regenTime.startTimer();
44
42
 
45
43
  const loadStateTimer = metrics?.loadStateTime.startTimer();
46
- let state = await getNearestState(slot, config, db, nativeStateView).catch((e) => {
44
+ let state = await getNearestState(slot, config, db, nativeStateTransition).catch((e) => {
47
45
  metrics?.regenErrorCount.inc({reason: RegenErrorType.loadState});
48
46
  throw e;
49
47
  });
@@ -54,7 +52,7 @@ export async function getHistoricalState(
54
52
  for await (const block of db.blockArchive.valuesStream({gt: state.slot, lte: slot})) {
55
53
  try {
56
54
  state = state.stateTransition(
57
- block,
55
+ {block},
58
56
  {
59
57
  verifyProposer: false,
60
58
  verifySignatures: false,
@@ -36,7 +36,7 @@ export class HistoricalStateRegen implements HistoricalStateWorkerApi {
36
36
  dataColumnDir: modules.opts.dataColumnDir,
37
37
  metricsEnabled: Boolean(modules.metrics),
38
38
  loggerOpts: modules.logger.toOpts(),
39
- nativeStateView: modules.opts.nativeStateView,
39
+ nativeStateTransition: modules.opts.nativeStateTransition,
40
40
  };
41
41
 
42
42
  const worker = new Worker(path.join(WORKER_DIR, "worker.js"), {
@@ -8,7 +8,7 @@ export type HistoricalStateRegenInitModules = {
8
8
  genesisTime: number;
9
9
  dbLocation: string;
10
10
  dataColumnDir: string;
11
- nativeStateView: boolean;
11
+ nativeStateTransition: boolean;
12
12
  };
13
13
  config: BeaconConfig;
14
14
  logger: LoggerNode;
@@ -29,7 +29,7 @@ export type HistoricalStateWorkerData = {
29
29
  dataColumnDir: string;
30
30
  metricsEnabled: boolean;
31
31
  loggerOpts: LoggerNodeOpts;
32
- nativeStateView: boolean;
32
+ nativeStateTransition: boolean;
33
33
  };
34
34
 
35
35
  export type HistoricalStateWorkerApi = {
@@ -36,7 +36,6 @@ const abortController = new AbortController();
36
36
  const metricsRegister = workerData.metricsEnabled ? new RegistryMetricCreator() : null;
37
37
  let historicalStateRegenMetrics: HistoricalStateRegenMetrics | undefined;
38
38
  let queueMetrics: QueueMetrics | undefined;
39
-
40
39
  if (metricsRegister) {
41
40
  const closeMetrics = collectNodeJSMetrics(metricsRegister, "lodestar_historical_state_worker_");
42
41
  abortController.signal.addEventListener("abort", closeMetrics, {once: true});
@@ -65,7 +64,7 @@ const api: HistoricalStateWorkerApi = {
65
64
  historicalStateRegenMetrics?.regenRequestCount.inc();
66
65
 
67
66
  const stateBytes = await queue.push<Uint8Array>(() =>
68
- getHistoricalState(slot, config, db, workerData.nativeStateView, historicalStateRegenMetrics)
67
+ getHistoricalState(slot, config, db, workerData.nativeStateTransition, historicalStateRegenMetrics)
69
68
  );
70
69
  const result = Transfer(stateBytes, [stateBytes.buffer]) as unknown as Uint8Array;
71
70
 
@@ -25,7 +25,7 @@ export type ArchiveStoreOpts = StatesArchiveOpts & {
25
25
  archiveDataEpochs?: number;
26
26
  pruneHistory?: boolean;
27
27
  serveHistoricalState?: boolean;
28
- nativeStateView?: boolean;
28
+ nativeStateTransition?: boolean;
29
29
  };
30
30
 
31
31
  export type ProposalStats = {
@@ -11,8 +11,9 @@ export async function pruneHistory(
11
11
  logger: Logger,
12
12
  metrics: Metrics | null | undefined,
13
13
  finalizedEpoch: Epoch,
14
- currentEpoch: Epoch
15
- ): Promise<Slot> {
14
+ currentEpoch: Epoch,
15
+ statePruneFromSlot: Slot = 0
16
+ ): Promise<{blockCutoffSlot: Slot; stateCutoffSlot: Slot}> {
16
17
  const blockCutoffEpoch = Math.min(
17
18
  // set by config, with underflow protection
18
19
  Math.max(currentEpoch - config.MIN_EPOCHS_FOR_BLOCK_REQUESTS, 0),
@@ -28,6 +29,7 @@ export async function pruneHistory(
28
29
  currentEpoch,
29
30
  finalizedEpoch,
30
31
  blockCutoffEpoch,
32
+ statePruneFromSlot,
31
33
  stateCutoffSlot,
32
34
  });
33
35
 
@@ -35,7 +37,7 @@ export async function pruneHistory(
35
37
  const [blocks, envelopes, states] = await Promise.all([
36
38
  db.blockArchive.keys({gte: 0, lt: blockCutoffSlot}),
37
39
  db.executionPayloadEnvelopeArchive.keys({gte: 0, lt: blockCutoffSlot}),
38
- db.stateArchive.keys({gte: 0, lt: stateCutoffSlot}),
40
+ stateCutoffSlot > statePruneFromSlot ? db.stateArchive.keys({gte: statePruneFromSlot, lt: stateCutoffSlot}) : [],
39
41
  ]);
40
42
  step0?.();
41
43
 
@@ -64,5 +66,5 @@ export async function pruneHistory(
64
66
 
65
67
  metrics?.pruneHistory.pruneCount.inc();
66
68
 
67
- return blockCutoffSlot;
69
+ return {blockCutoffSlot, stateCutoffSlot};
68
70
  }
@@ -538,6 +538,10 @@ export async function importBlock(
538
538
  block: blockRootHex,
539
539
  slot: blockSlot,
540
540
  executionOptimistic: blockSummary != null && isOptimisticBlock(blockSummary),
541
+ ...(isGloasBeaconBlock(block.message) && {
542
+ blockHash: toRootHex(block.message.body.signedExecutionPayloadBid.message.blockHash),
543
+ builderIndex: block.message.body.signedExecutionPayloadBid.message.builderIndex,
544
+ }),
541
545
  });
542
546
  }
543
547
  if (this.emitter.listenerCount(routes.events.EventType.voluntaryExit)) {
@@ -22,8 +22,9 @@ export enum PayloadEnvelopeInputSource {
22
22
  * - finalized: below the finalized slot
23
23
  * - prune: explicit prune by root
24
24
  * - cap: insertion-order backstop cap (MAX_PAYLOAD_ENVELOPE_INPUT_CACHE_SIZE)
25
+ * - invalid: the cached envelope failed import with a definitive invalid verdict
25
26
  */
26
- export type PayloadEnvelopeInputPruneReason = "belowParent" | "finalized" | "remove" | "cap";
27
+ export type PayloadEnvelopeInputPruneReason = "belowParent" | "finalized" | "remove" | "cap" | "invalid";
27
28
 
28
29
  export type SourceMeta = {
29
30
  source: PayloadEnvelopeInputSource;
@@ -188,6 +188,7 @@ export async function verifyBlocksInEpoch(
188
188
  blockInputs,
189
189
  // hack availability for state transition eval as availability is separately determined
190
190
  blocks.map(() => DataAvailabilityStatus.Available),
191
+ this.serializedCache,
191
192
  this.logger,
192
193
  this.metrics,
193
194
  this.validatorMonitor,
@@ -7,6 +7,7 @@ import {
7
7
  import {ErrorAborted, Logger, byteArrayEquals} from "@lodestar/utils";
8
8
  import {Metrics} from "../../metrics/index.js";
9
9
  import {nextEventLoop} from "../../util/eventLoop.js";
10
+ import {SerializedCache} from "../../util/serializedCache.js";
10
11
  import {BlockError, BlockErrorCode} from "../errors/index.js";
11
12
  import {BlockProcessOpts} from "../options.js";
12
13
  import {ValidatorMonitor} from "../validatorMonitor.js";
@@ -25,6 +26,7 @@ export async function verifyBlocksStateTransitionOnly(
25
26
  preState0: IBeaconStateView,
26
27
  blocks: IBlockInput[],
27
28
  dataAvailabilityStatuses: DataAvailabilityStatus[],
29
+ serializedCache: SerializedCache,
28
30
  logger: Logger,
29
31
  metrics: Metrics | null,
30
32
  validatorMonitor: ValidatorMonitor | null,
@@ -37,7 +39,8 @@ export async function verifyBlocksStateTransitionOnly(
37
39
 
38
40
  for (let i = 0; i < blocks.length; i++) {
39
41
  const {validProposerSignature, validSignatures} = opts;
40
- const block = blocks[i].getBlock();
42
+ const blockInput = blocks[i];
43
+ const block = blockInput.getBlock();
41
44
  const preState = i === 0 ? preState0 : postStates[i - 1];
42
45
  const dataAvailabilityStatus = dataAvailabilityStatuses[i];
43
46
 
@@ -47,7 +50,7 @@ export async function verifyBlocksStateTransitionOnly(
47
50
  let postState: IBeaconStateView;
48
51
  try {
49
52
  postState = preState.stateTransition(
50
- block,
53
+ {block, ssz: serializedCache.get(block)},
51
54
  {
52
55
  // NOTE: Assume valid for now while sending payload to execution engine in parallel
53
56
  // Latter verifyBlocksInEpoch() will make sure that payload is indeed valid
@@ -60,7 +63,7 @@ export async function verifyBlocksStateTransitionOnly(
60
63
  verifySignatures: !useBlsBatchVerify && !validSignatures,
61
64
  dontTransferCache: false,
62
65
  },
63
- {metrics, validatorMonitor}
66
+ {metrics: metrics?.stateTransition, validatorMonitor}
64
67
  );
65
68
  } catch (e) {
66
69
  throw new BlockError(block, {
@@ -71,7 +71,7 @@ import {BufferPool} from "../util/bufferPool.js";
71
71
  import {Clock, ClockEvent, IClock} from "../util/clock.js";
72
72
  import {CustodyConfig, getValidatorsCustodyRequirement} from "../util/dataColumns.js";
73
73
  import {callInNextEventLoop} from "../util/eventLoop.js";
74
- import {ReconstructMismatchPolicy, isRebuildMiss, reconstructExecutionPayloadEnvelopes} from "../util/execution.js";
74
+ import {ReconstructMissPolicy, isRebuildMiss, reconstructExecutionPayloadEnvelopes} from "../util/execution.js";
75
75
  import {ensureDir, writeIfNotExist} from "../util/file.js";
76
76
  import {isOptimisticBlock} from "../util/forkChoice.js";
77
77
  import {JobItemQueue} from "../util/queue/itemQueue.js";
@@ -244,6 +244,7 @@ export class BeaconChain implements IBeaconChain {
244
244
  protected readonly blockProcessor: BlockProcessor;
245
245
  protected readonly payloadEnvelopeProcessor: PayloadEnvelopeProcessor;
246
246
  protected readonly db: IBeaconDb;
247
+ private genesisStateRoot?: RootHex | null;
247
248
  // this is only available if nHistoricalStates is enabled
248
249
  private readonly cpStateDatastore?: CPStateDatastore;
249
250
  private abortController = new AbortController();
@@ -432,6 +433,7 @@ export class BeaconChain implements IBeaconChain {
432
433
  blockStateCache,
433
434
  checkpointStateCache,
434
435
  seenBlockInputCache: this.seenBlockInputCache,
436
+ serializedCache: this.serializedCache,
435
437
  db,
436
438
  metrics,
437
439
  validatorMonitor,
@@ -611,7 +613,7 @@ export class BeaconChain implements IBeaconChain {
611
613
  /** Populate in-memory caches with persisted data. Call at least once on startup */
612
614
  async loadFromDisk(): Promise<void> {
613
615
  await this.regen.init();
614
- await this.opPool.fromPersisted(this.db);
616
+ await this.opPool.fromPersisted(this.db, this.getHeadState(), this.bls, this.clock.currentSlot);
615
617
  }
616
618
 
617
619
  /** Persist in-memory data to the DB. Call at least once before stopping the process */
@@ -702,6 +704,37 @@ export class BeaconChain implements IBeaconChain {
702
704
  stateRoot: RootHex,
703
705
  opts?: StateGetOpts
704
706
  ): Promise<{state: IBeaconStateView | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null> {
707
+ const finalizedBlock = this.forkChoice.getFinalizedBlock();
708
+ const finalizedCheckpoint = this.forkChoice.getFinalizedCheckpoint();
709
+ // Checkpoint state only equals the block post-state if the block is at the epoch start slot
710
+ if (
711
+ finalizedBlock.stateRoot === stateRoot &&
712
+ finalizedBlock.slot === computeStartSlotAtEpoch(finalizedCheckpoint.epoch)
713
+ ) {
714
+ const state = this.regen.getCheckpointStateSync({
715
+ epoch: finalizedCheckpoint.epoch,
716
+ rootHex: finalizedCheckpoint.rootHex,
717
+ });
718
+ if (state) {
719
+ return {
720
+ state,
721
+ executionOptimistic: isOptimisticBlock(finalizedBlock),
722
+ finalized: finalizedCheckpoint.epoch !== GENESIS_EPOCH,
723
+ };
724
+ }
725
+ }
726
+
727
+ if (this.genesisStateRoot === undefined) {
728
+ const genesisBlock = await this.db.blockArchive.get(GENESIS_SLOT);
729
+ this.genesisStateRoot = genesisBlock ? toRootHex(genesisBlock.message.stateRoot) : null;
730
+ }
731
+ if (this.genesisStateRoot === stateRoot) {
732
+ const state = await this.db.stateArchive.getBinary(GENESIS_SLOT);
733
+ if (state) {
734
+ return {state, executionOptimistic: false, finalized: finalizedCheckpoint.epoch !== GENESIS_EPOCH};
735
+ }
736
+ }
737
+
705
738
  if (opts?.allowRegen) {
706
739
  const state = await this.regen.getState(stateRoot, RegenCaller.restApi);
707
740
  const block = this.forkChoice.getBlockDefaultStatus(
@@ -934,12 +967,13 @@ export class BeaconChain implements IBeaconChain {
934
967
 
935
968
  /**
936
969
  * Batch variant: archived header envelopes are rebuilt 32 per EL round-trip. Aligned with `requests`.
937
- * A body root mismatch is a local inconsistency: `"throw"` surfaces it, `"omit"` logs it and
938
- * returns null for that entry, for peer-facing paths where the spec allows omission.
970
+ * An archived envelope that cannot be rebuilt (EL-unavailable body or body root mismatch) is not the
971
+ * same as an unknown one: `"throw"` surfaces it, `"omit"` returns null for that entry, for
972
+ * peer-facing paths where the spec allows omission.
939
973
  */
940
974
  async getSerializedExecutionPayloadEnvelopes(
941
975
  requests: {blockSlot: Slot; blockRootHex: RootHex}[],
942
- onMismatch: ReconstructMismatchPolicy = "throw"
976
+ onMiss: ReconstructMissPolicy = "throw"
943
977
  ): Promise<(Uint8Array | null)[]> {
944
978
  const out: (Uint8Array | null)[] = new Array(requests.length).fill(null);
945
979
  const headerEnvelopes: gloas.SignedExecutionPayloadHeaderEnvelope[] = [];
@@ -978,14 +1012,14 @@ export class BeaconChain implements IBeaconChain {
978
1012
  for (let j = 0; j < rebuilt.length; j++) {
979
1013
  const result = rebuilt[j];
980
1014
  if (isRebuildMiss(result)) {
981
- if (result.reason === "mismatch") {
982
- if (onMismatch === "throw") throw result.error;
983
- this.logger.debug(
984
- "Archived envelope failed body root check against EL bodies",
985
- {slot: result.slot},
986
- result.error
987
- );
988
- }
1015
+ if (onMiss === "throw") throw result.error;
1016
+ this.logger.debug(
1017
+ result.reason === "mismatch"
1018
+ ? "Archived envelope failed body root check against EL bodies"
1019
+ : "EL cannot serve bodies for archived envelope, omitting",
1020
+ {slot: result.slot},
1021
+ result.error
1022
+ );
989
1023
  continue;
990
1024
  }
991
1025
  out[headerEnvelopeIdxs[j]] = ssz.gloas.SignedExecutionPayloadEnvelope.serialize(result);
@@ -1016,10 +1050,7 @@ export class BeaconChain implements IBeaconChain {
1016
1050
  const [result] = await reconstructExecutionPayloadEnvelopes(this.executionEngine, this.metrics, [
1017
1051
  archived.headerEnvelope,
1018
1052
  ]);
1019
- if (isRebuildMiss(result)) {
1020
- if (result.reason === "mismatch") throw result.error;
1021
- return null;
1022
- }
1053
+ if (isRebuildMiss(result)) throw result.error;
1023
1054
  return result;
1024
1055
  }
1025
1056
 
@@ -1329,13 +1360,13 @@ export class BeaconChain implements IBeaconChain {
1329
1360
  };
1330
1361
 
1331
1362
  try {
1332
- await validateApiProposerSlashing(this, proposerSlashing);
1363
+ const verifiedDomain = await validateApiProposerSlashing(this, proposerSlashing);
1364
+ this.opPool.insertProposerSlashing(proposerSlashing, verifiedDomain);
1333
1365
  } catch (e) {
1334
1366
  this.logger.debug("Produced proposer slashing is not valid", {slot: blockSlot, proposerIndex}, e as Error);
1335
1367
  return;
1336
1368
  }
1337
1369
 
1338
- this.opPool.insertProposerSlashing(proposerSlashing);
1339
1370
  this.emitter.emit(routes.events.EventType.proposerSlashing, proposerSlashing);
1340
1371
  this.emitter.emit(ChainEvent.publishProposerSlashing, proposerSlashing);
1341
1372
  this.metrics?.opPool.proposerSlashingsProduced.inc();
@@ -1,7 +1,7 @@
1
1
  import {EventEmitter} from "node:events";
2
2
  import {StrictEventEmitter} from "strict-event-emitter-types";
3
3
  import {routes} from "@lodestar/api";
4
- import {CheckpointWithHex} from "@lodestar/fork-choice";
4
+ import {CheckpointWithHex, PtcQuorumEvent} from "@lodestar/fork-choice";
5
5
  import {IBeaconStateView} from "@lodestar/state-transition";
6
6
  import {DataColumnSidecar, RootHex, Slot, deneb, phase0} from "@lodestar/types";
7
7
  import {PeerIdStr} from "../util/peerId.js";
@@ -36,6 +36,11 @@ export enum ChainEvent {
36
36
  * This event is guaranteed to be triggered whenever the fork choice finalized checkpoint is updated. This is either in response to a newly processed block or a new clock tick.
37
37
  */
38
38
  forkChoiceFinalized = "forkChoice:finalized",
39
+ /**
40
+ * This event signals that the PTC verdict on a block was decided: a majority against payload presence or blob data
41
+ * availability, or a majority for both.
42
+ */
43
+ forkChoicePtcQuorum = "forkChoice:ptcQuorum",
39
44
  /**
40
45
  * This event signals that dependent services (e.g. custody sampling) should update to account for the new target group count.
41
46
  */
@@ -112,6 +117,7 @@ export type IChainEvents = ApiEvents & {
112
117
 
113
118
  [ChainEvent.forkChoiceJustified]: (checkpoint: CheckpointWithHex) => void;
114
119
  [ChainEvent.forkChoiceFinalized]: (checkpoint: CheckpointWithHex) => void;
120
+ [ChainEvent.forkChoicePtcQuorum]: (data: PtcQuorumEvent) => void;
115
121
 
116
122
  [ChainEvent.updateTargetCustodyGroupCount]: (targetGroupCount: number) => void;
117
123
 
@@ -4,6 +4,8 @@ import {LodestarError} from "@lodestar/utils";
4
4
  export enum EnvelopeReconstructionErrorCode {
5
5
  /** The EL failed to answer engine_getPayloadBodiesByHashV2 (transport / EL down). Transient. */
6
6
  ENGINE_UNAVAILABLE = "ENVELOPE_RECONSTRUCTION_ERROR_ENGINE_UNAVAILABLE",
7
+ /** The EL does not have the block or its block access list (pruned, or not yet re-indexed after a restart). May recover. */
8
+ BODY_UNAVAILABLE = "ENVELOPE_RECONSTRUCTION_ERROR_BODY_UNAVAILABLE",
7
9
  /** A body returned by the EL does not hash to the root stored in the header envelope. Local DB/EL inconsistency. */
8
10
  BODY_ROOT_MISMATCH = "ENVELOPE_RECONSTRUCTION_ERROR_BODY_ROOT_MISMATCH",
9
11
  /** A by-range stream stopped short at a slot that cannot be served; the response so far is still valid */
@@ -12,6 +14,7 @@ export enum EnvelopeReconstructionErrorCode {
12
14
 
13
15
  export type EnvelopeReconstructionErrorType =
14
16
  | {code: EnvelopeReconstructionErrorCode.ENGINE_UNAVAILABLE}
17
+ | {code: EnvelopeReconstructionErrorCode.BODY_UNAVAILABLE; slot: Slot}
15
18
  | {
16
19
  code: EnvelopeReconstructionErrorCode.BODY_ROOT_MISMATCH;
17
20
  slot: Slot;
@@ -9,6 +9,8 @@ export enum GossipErrorCode {
9
9
  INVALID_SERIALIZED_BYTES_ERROR_CODE = "GOSSIP_ERROR_INVALID_SERIALIZED_BYTES",
10
10
  PAST_SLOT = "GOSSIP_ERROR_PAST_SLOT",
11
11
  FUTURE_SLOT = "GOSSIP_ERROR_FUTURE_SLOT",
12
+ FATAL_PEER = "GOSSIP_ERROR_FATAL_PEER",
13
+ INVALID_SLOT = "GOSSIP_ERROR_INVALID_SLOT",
12
14
  }
13
15
 
14
16
  export class GossipActionError<T extends {code: string}> extends LodestarError<T> {
@@ -124,6 +124,7 @@ export function initializeForkChoiceFromFinalizedState(
124
124
  onFinalized: (cp) => emitter.emit(ChainEvent.forkChoiceFinalized, cp),
125
125
  onFastConfirmation: ({block, slot, currentSlot}) =>
126
126
  emitter.emit(routes.events.EventType.fastConfirmation, {block, slot, currentSlot}),
127
+ onPtcQuorum: (data) => emitter.emit(ChainEvent.forkChoicePtcQuorum, data),
127
128
  }
128
129
  ),
129
130
 
@@ -222,6 +223,7 @@ export function initializeForkChoiceFromUnfinalizedState(
222
223
  onFinalized: (cp) => emitter.emit(ChainEvent.forkChoiceFinalized, cp),
223
224
  onFastConfirmation: ({block, slot, currentSlot}) =>
224
225
  emitter.emit(routes.events.EventType.fastConfirmation, {block, slot, currentSlot}),
226
+ onPtcQuorum: (data) => emitter.emit(ChainEvent.forkChoicePtcQuorum, data),
225
227
  }
226
228
  );
227
229
 
@@ -1,14 +1,8 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
2
  import {ForkPostGloas, ForkSeq, ZERO_HASH} from "@lodestar/params";
3
- import {
4
- BeaconStateAllForks,
5
- BeaconStateGloas,
6
- IBeaconStateView,
7
- computeEpochAtSlot,
8
- computeStartSlotAtEpoch,
9
- } from "@lodestar/state-transition";
3
+ import {BeaconStateAllForks, IBeaconStateView, computeEpochAtSlot, isStatePostGloas} from "@lodestar/state-transition";
10
4
  import {SignedBeaconBlock, ssz} from "@lodestar/types";
11
- import {Logger, byteArrayEquals, toHex, toRootHex} from "@lodestar/utils";
5
+ import {LodestarError, Logger, byteArrayEquals, toRootHex} from "@lodestar/utils";
12
6
  import {GENESIS_SLOT} from "../constants/index.js";
13
7
  import {IBeaconDb} from "../db/index.js";
14
8
  import {Metrics} from "../metrics/index.js";
@@ -17,7 +11,7 @@ import {getStateTypeFromBytes} from "../util/multifork.js";
17
11
  export async function persistAnchorState(
18
12
  config: ChainForkConfig,
19
13
  db: IBeaconDb,
20
- anchorState: BeaconStateAllForks,
14
+ anchorState: IBeaconStateView,
21
15
  anchorStateBytes: Uint8Array
22
16
  ): Promise<void> {
23
17
  if (anchorState.slot === GENESIS_SLOT) {
@@ -33,7 +27,8 @@ export async function persistAnchorState(
33
27
  const latestBlockRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(latestBlockHeader);
34
28
 
35
29
  if (!byteArrayEquals(blockRoot, latestBlockRoot)) {
36
- throw Error(
30
+ throw new LodestarError(
31
+ {code: "GENESIS_BLOCK_ROOT_MISMATCH"},
37
32
  `Genesis block root ${toRootHex(blockRoot)} does not match genesis state latest block root ${toRootHex(latestBlockRoot)}`
38
33
  );
39
34
  }
@@ -48,16 +43,15 @@ export async function persistAnchorState(
48
43
  }
49
44
  }
50
45
 
51
- export function createGenesisBlock(config: ChainForkConfig, genesisState: BeaconStateAllForks): SignedBeaconBlock {
46
+ export function createGenesisBlock(config: ChainForkConfig, genesisState: IBeaconStateView): SignedBeaconBlock {
52
47
  const types = config.getForkTypes(GENESIS_SLOT);
53
48
  const genesisBlock = types.SignedBeaconBlock.defaultValue();
54
49
  const stateRoot = genesisState.hashTreeRoot();
55
50
  genesisBlock.message.stateRoot = stateRoot;
56
51
 
57
- if (config.getForkSeq(GENESIS_SLOT) >= ForkSeq.gloas) {
52
+ if (config.getForkSeq(GENESIS_SLOT) >= ForkSeq.gloas && isStatePostGloas(genesisState)) {
58
53
  const gloasBlock = genesisBlock as SignedBeaconBlock<ForkPostGloas>;
59
- const gloasState = genesisState as BeaconStateGloas;
60
- gloasBlock.message.body.signedExecutionPayloadBid.message = gloasState.latestExecutionPayloadBid.toValue();
54
+ gloasBlock.message.body.signedExecutionPayloadBid.message = genesisState.latestExecutionPayloadBid;
61
55
  }
62
56
 
63
57
  return genesisBlock;
@@ -86,52 +80,6 @@ export async function initStateFromDb(
86
80
  return state;
87
81
  }
88
82
 
89
- /**
90
- * Initialize and persist an anchor state (either weak subjectivity or genesis)
91
- */
92
- export async function checkAndPersistAnchorState(
93
- config: ChainForkConfig,
94
- db: IBeaconDb,
95
- logger: Logger,
96
- anchorState: BeaconStateAllForks,
97
- anchorStateBytes: Uint8Array,
98
- {
99
- isWithinWeakSubjectivityPeriod,
100
- isCheckpointState,
101
- }: {isWithinWeakSubjectivityPeriod: boolean; isCheckpointState: boolean}
102
- ): Promise<void> {
103
- const expectedFork = config.getForkInfo(computeStartSlotAtEpoch(anchorState.fork.epoch));
104
- const expectedForkVersion = toHex(expectedFork.version);
105
- const stateFork = toHex(anchorState.fork.currentVersion);
106
- if (stateFork !== expectedForkVersion) {
107
- throw Error(
108
- `State current fork version ${stateFork} not equal to current config ${expectedForkVersion}. Maybe caused by importing a state from a different network`
109
- );
110
- }
111
-
112
- const stateInfo = isCheckpointState ? "checkpoint" : "db";
113
- if (isWithinWeakSubjectivityPeriod) {
114
- logger.info(`Initializing beacon from a valid ${stateInfo} state`, {
115
- slot: anchorState.slot,
116
- epoch: computeEpochAtSlot(anchorState.slot),
117
- stateRoot: toRootHex(anchorState.hashTreeRoot()),
118
- isWithinWeakSubjectivityPeriod,
119
- });
120
- } else {
121
- logger.warn(`Initializing from a stale ${stateInfo} state vulnerable to long range attacks`, {
122
- slot: anchorState.slot,
123
- epoch: computeEpochAtSlot(anchorState.slot),
124
- stateRoot: toRootHex(anchorState.hashTreeRoot()),
125
- isWithinWeakSubjectivityPeriod,
126
- });
127
- logger.warn("Checkpoint sync recommended, please use --help to see checkpoint sync options");
128
- }
129
-
130
- if (isCheckpointState || anchorState.slot === GENESIS_SLOT) {
131
- await persistAnchorState(config, db, anchorState, anchorStateBytes);
132
- }
133
- }
134
-
135
83
  export function initBeaconMetrics(metrics: Metrics, state: IBeaconStateView): void {
136
84
  metrics.headSlot.set(state.slot);
137
85
  metrics.previousJustifiedEpoch.set(state.previousJustifiedCheckpoint.epoch);
@@ -30,7 +30,7 @@ import {Metrics} from "../metrics/metrics.js";
30
30
  import {BufferPool} from "../util/bufferPool.js";
31
31
  import {IClock} from "../util/clock.js";
32
32
  import {CustodyConfig} from "../util/dataColumns.js";
33
- import {ReconstructMismatchPolicy} from "../util/execution.js";
33
+ import {ReconstructMissPolicy} from "../util/execution.js";
34
34
  import {SerializedCache} from "../util/serializedCache.js";
35
35
  import {IArchiveStore} from "./archiveStore/interface.js";
36
36
  import {CheckpointBalancesCache} from "./balancesCache.js";
@@ -239,7 +239,7 @@ export interface IBeaconChain {
239
239
  getSerializedExecutionPayloadEnvelope(blockSlot: Slot, blockRootHex: string): Promise<Uint8Array | null>;
240
240
  getSerializedExecutionPayloadEnvelopes(
241
241
  requests: {blockSlot: Slot; blockRootHex: RootHex}[],
242
- onMismatch?: ReconstructMismatchPolicy
242
+ onMiss?: ReconstructMissPolicy
243
243
  ): Promise<(Uint8Array | null)[]>;
244
244
  getExecutionPayloadEnvelope(
245
245
  blockSlot: Slot,