@lodestar/beacon-node 1.39.0-dev.075956b855 → 1.39.0-dev.0bce7eb9f1

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 (164) hide show
  1. package/README.md +1 -1
  2. package/lib/api/impl/beacon/state/utils.d.ts +2 -7
  3. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  4. package/lib/api/impl/beacon/state/utils.js +0 -12
  5. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  6. package/lib/api/impl/lodestar/index.js +1 -1
  7. package/lib/api/impl/lodestar/index.js.map +1 -1
  8. package/lib/api/impl/proof/index.d.ts.map +1 -1
  9. package/lib/api/impl/proof/index.js +1 -2
  10. package/lib/api/impl/proof/index.js.map +1 -1
  11. package/lib/api/impl/validator/index.d.ts.map +1 -1
  12. package/lib/api/impl/validator/index.js +1 -3
  13. package/lib/api/impl/validator/index.js.map +1 -1
  14. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  15. package/lib/chain/blocks/importBlock.js +8 -2
  16. package/lib/chain/blocks/importBlock.js.map +1 -1
  17. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  18. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +1 -0
  19. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  20. package/lib/chain/chain.d.ts +7 -9
  21. package/lib/chain/chain.d.ts.map +1 -1
  22. package/lib/chain/chain.js +17 -10
  23. package/lib/chain/chain.js.map +1 -1
  24. package/lib/chain/interface.d.ts +6 -9
  25. package/lib/chain/interface.d.ts.map +1 -1
  26. package/lib/chain/interface.js.map +1 -1
  27. package/lib/chain/lightClient/proofs.d.ts.map +1 -1
  28. package/lib/chain/lightClient/proofs.js +0 -2
  29. package/lib/chain/lightClient/proofs.js.map +1 -1
  30. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +2 -3
  31. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  32. package/lib/chain/opPools/aggregatedAttestationPool.js +5 -130
  33. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  34. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  35. package/lib/chain/prepareNextSlot.js +4 -7
  36. package/lib/chain/prepareNextSlot.js.map +1 -1
  37. package/lib/chain/produceBlock/produceBlockBody.js +1 -1
  38. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  39. package/lib/chain/regen/interface.d.ts +1 -5
  40. package/lib/chain/regen/interface.d.ts.map +1 -1
  41. package/lib/chain/regen/queued.d.ts +4 -7
  42. package/lib/chain/regen/queued.d.ts.map +1 -1
  43. package/lib/chain/regen/queued.js +15 -25
  44. package/lib/chain/regen/queued.js.map +1 -1
  45. package/lib/chain/regen/regen.d.ts +1 -1
  46. package/lib/chain/regen/regen.d.ts.map +1 -1
  47. package/lib/chain/regen/regen.js +13 -17
  48. package/lib/chain/regen/regen.js.map +1 -1
  49. package/lib/chain/shufflingCache.d.ts +5 -12
  50. package/lib/chain/shufflingCache.d.ts.map +1 -1
  51. package/lib/chain/shufflingCache.js +12 -50
  52. package/lib/chain/shufflingCache.js.map +1 -1
  53. package/lib/chain/stateCache/blockStateCacheImpl.d.ts +1 -2
  54. package/lib/chain/stateCache/blockStateCacheImpl.d.ts.map +1 -1
  55. package/lib/chain/stateCache/blockStateCacheImpl.js +2 -2
  56. package/lib/chain/stateCache/blockStateCacheImpl.js.map +1 -1
  57. package/lib/chain/stateCache/fifoBlockStateCache.d.ts +1 -2
  58. package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
  59. package/lib/chain/stateCache/fifoBlockStateCache.js +4 -4
  60. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  61. package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts +4 -5
  62. package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts.map +1 -1
  63. package/lib/chain/stateCache/inMemoryCheckpointsCache.js +9 -10
  64. package/lib/chain/stateCache/inMemoryCheckpointsCache.js.map +1 -1
  65. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +5 -6
  66. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  67. package/lib/chain/stateCache/persistentCheckpointsCache.js +17 -17
  68. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  69. package/lib/chain/stateCache/types.d.ts +5 -6
  70. package/lib/chain/stateCache/types.d.ts.map +1 -1
  71. package/lib/chain/stateCache/types.js.map +1 -1
  72. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  73. package/lib/chain/validation/attesterSlashing.js +1 -1
  74. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  75. package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
  76. package/lib/chain/validation/blobSidecar.js +2 -3
  77. package/lib/chain/validation/blobSidecar.js.map +1 -1
  78. package/lib/chain/validation/blsToExecutionChange.d.ts.map +1 -1
  79. package/lib/chain/validation/blsToExecutionChange.js +9 -2
  80. package/lib/chain/validation/blsToExecutionChange.js.map +1 -1
  81. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  82. package/lib/chain/validation/dataColumnSidecar.js +2 -3
  83. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  84. package/lib/chain/validation/proposerSlashing.js +2 -1
  85. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  86. package/lib/db/repositories/stateArchive.d.ts +1 -1
  87. package/lib/db/repositories/stateArchive.d.ts.map +1 -1
  88. package/lib/db/repositories/stateArchive.js +2 -2
  89. package/lib/db/repositories/stateArchive.js.map +1 -1
  90. package/lib/execution/engine/mock.d.ts +9 -6
  91. package/lib/execution/engine/mock.d.ts.map +1 -1
  92. package/lib/execution/engine/mock.js +34 -7
  93. package/lib/execution/engine/mock.js.map +1 -1
  94. package/lib/metrics/metrics/lodestar.d.ts +1 -6
  95. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  96. package/lib/metrics/metrics/lodestar.js +3 -17
  97. package/lib/metrics/metrics/lodestar.js.map +1 -1
  98. package/lib/network/peers/discover.d.ts.map +1 -1
  99. package/lib/network/peers/discover.js.map +1 -1
  100. package/lib/network/reqresp/utils/dataColumnResponseValidation.js +1 -1
  101. package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
  102. package/lib/node/nodejs.d.ts.map +1 -1
  103. package/lib/node/nodejs.js +17 -2
  104. package/lib/node/nodejs.js.map +1 -1
  105. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  106. package/lib/sync/backfill/backfill.js +2 -2
  107. package/lib/sync/backfill/backfill.js.map +1 -1
  108. package/lib/sync/backfill/verify.d.ts +2 -2
  109. package/lib/sync/backfill/verify.d.ts.map +1 -1
  110. package/lib/sync/backfill/verify.js +2 -2
  111. package/lib/sync/backfill/verify.js.map +1 -1
  112. package/lib/util/sszBytes.js +1 -1
  113. package/lib/util/sszBytes.js.map +1 -1
  114. package/package.json +28 -20
  115. package/src/api/impl/beacon/state/utils.ts +2 -22
  116. package/src/api/impl/lodestar/index.ts +1 -1
  117. package/src/api/impl/proof/index.ts +1 -2
  118. package/src/api/impl/validator/index.ts +1 -3
  119. package/src/chain/blocks/importBlock.ts +9 -2
  120. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +1 -0
  121. package/src/chain/chain.ts +27 -15
  122. package/src/chain/interface.ts +6 -8
  123. package/src/chain/lightClient/proofs.ts +0 -2
  124. package/src/chain/opPools/aggregatedAttestationPool.ts +6 -181
  125. package/src/chain/prepareNextSlot.ts +2 -6
  126. package/src/chain/produceBlock/produceBlockBody.ts +1 -1
  127. package/src/chain/regen/interface.ts +1 -5
  128. package/src/chain/regen/queued.ts +15 -34
  129. package/src/chain/regen/regen.ts +12 -18
  130. package/src/chain/shufflingCache.ts +15 -61
  131. package/src/chain/stateCache/blockStateCacheImpl.ts +2 -3
  132. package/src/chain/stateCache/fifoBlockStateCache.ts +4 -5
  133. package/src/chain/stateCache/inMemoryCheckpointsCache.ts +9 -15
  134. package/src/chain/stateCache/persistentCheckpointsCache.ts +17 -25
  135. package/src/chain/stateCache/types.ts +5 -10
  136. package/src/chain/validation/attesterSlashing.ts +8 -1
  137. package/src/chain/validation/blobSidecar.ts +3 -3
  138. package/src/chain/validation/blsToExecutionChange.ts +9 -7
  139. package/src/chain/validation/dataColumnSidecar.ts +3 -3
  140. package/src/chain/validation/proposerSlashing.ts +2 -1
  141. package/src/db/repositories/stateArchive.ts +2 -2
  142. package/src/execution/engine/mock.ts +40 -13
  143. package/src/metrics/metrics/lodestar.ts +3 -17
  144. package/src/network/peers/discover.ts +3 -3
  145. package/src/network/reqresp/utils/dataColumnResponseValidation.ts +1 -1
  146. package/src/node/nodejs.ts +18 -3
  147. package/src/sync/backfill/backfill.ts +2 -14
  148. package/src/sync/backfill/verify.ts +1 -7
  149. package/src/util/sszBytes.ts +1 -1
  150. package/lib/chain/rewards/attestationsRewards.d.ts +0 -8
  151. package/lib/chain/rewards/attestationsRewards.d.ts.map +0 -1
  152. package/lib/chain/rewards/attestationsRewards.js +0 -112
  153. package/lib/chain/rewards/attestationsRewards.js.map +0 -1
  154. package/lib/chain/rewards/blockRewards.d.ts +0 -15
  155. package/lib/chain/rewards/blockRewards.d.ts.map +0 -1
  156. package/lib/chain/rewards/blockRewards.js +0 -94
  157. package/lib/chain/rewards/blockRewards.js.map +0 -1
  158. package/lib/chain/rewards/syncCommitteeRewards.d.ts +0 -7
  159. package/lib/chain/rewards/syncCommitteeRewards.d.ts.map +0 -1
  160. package/lib/chain/rewards/syncCommitteeRewards.js +0 -36
  161. package/lib/chain/rewards/syncCommitteeRewards.js.map +0 -1
  162. package/src/chain/rewards/attestationsRewards.ts +0 -206
  163. package/src/chain/rewards/blockRewards.ts +0 -153
  164. package/src/chain/rewards/syncCommitteeRewards.ts +0 -60
@@ -4,7 +4,6 @@ import {RootHex} from "@lodestar/types";
4
4
  import {toRootHex} from "@lodestar/utils";
5
5
  import {Metrics} from "../../metrics/index.js";
6
6
  import {LinkedList} from "../../util/array.js";
7
- import {StateRegenerationOpts} from "../regen/interface.js";
8
7
  import {MapTracker} from "./mapMetrics.js";
9
8
  import {BlockStateCache} from "./types.js";
10
9
 
@@ -86,14 +85,14 @@ export class FIFOBlockStateCache implements BlockStateCache {
86
85
  }
87
86
 
88
87
  const firstState = firstValue.value;
89
- // don't transfer cache because consumer only use this cache to reload another state from disc
90
- return firstState.clone(true);
88
+ // consumers should not mutate the returned state
89
+ return firstState;
91
90
  }
92
91
 
93
92
  /**
94
93
  * Get a state from this cache given a state root hex.
95
94
  */
96
- get(rootHex: RootHex, opts?: StateRegenerationOpts): CachedBeaconStateAllForks | null {
95
+ get(rootHex: RootHex): CachedBeaconStateAllForks | null {
97
96
  this.metrics?.lookups.inc();
98
97
  const item = this.cache.get(rootHex);
99
98
  if (!item) {
@@ -103,7 +102,7 @@ export class FIFOBlockStateCache implements BlockStateCache {
103
102
  this.metrics?.hits.inc();
104
103
  this.metrics?.stateClonedCount.observe(item.clonedCount);
105
104
 
106
- return item.clone(opts?.dontTransferCache);
105
+ return item;
107
106
  }
108
107
 
109
108
  /**
@@ -3,7 +3,6 @@ import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
3
3
  import {Epoch, RootHex, phase0} from "@lodestar/types";
4
4
  import {MapDef, toRootHex} from "@lodestar/utils";
5
5
  import {Metrics} from "../../metrics/index.js";
6
- import {StateRegenerationOpts} from "../regen/interface.js";
7
6
  import {MapTracker} from "./mapMetrics.js";
8
7
  import {CacheItemType, CheckpointStateCache} from "./types.js";
9
8
 
@@ -42,21 +41,16 @@ export class InMemoryCheckpointStateCache implements CheckpointStateCache {
42
41
  this.maxEpochs = maxEpochs;
43
42
  }
44
43
 
45
- async getOrReload(cp: CheckpointHex, opts?: StateRegenerationOpts): Promise<CachedBeaconStateAllForks | null> {
46
- return this.get(cp, opts);
44
+ async getOrReload(cp: CheckpointHex): Promise<CachedBeaconStateAllForks | null> {
45
+ return this.get(cp);
47
46
  }
48
47
 
49
48
  async getStateOrBytes(cp: CheckpointHex): Promise<Uint8Array | CachedBeaconStateAllForks | null> {
50
- // no need to transfer cache for this api
51
- return this.get(cp, {dontTransferCache: true});
49
+ return this.get(cp);
52
50
  }
53
51
 
54
- async getOrReloadLatest(
55
- rootHex: string,
56
- maxEpoch: number,
57
- opts?: StateRegenerationOpts
58
- ): Promise<CachedBeaconStateAllForks | null> {
59
- return this.getLatest(rootHex, maxEpoch, opts);
52
+ async getOrReloadLatest(rootHex: string, maxEpoch: number): Promise<CachedBeaconStateAllForks | null> {
53
+ return this.getLatest(rootHex, maxEpoch);
60
54
  }
61
55
 
62
56
  async processState(): Promise<number> {
@@ -64,7 +58,7 @@ export class InMemoryCheckpointStateCache implements CheckpointStateCache {
64
58
  return 0;
65
59
  }
66
60
 
67
- get(cp: CheckpointHex, opts?: StateRegenerationOpts): CachedBeaconStateAllForks | null {
61
+ get(cp: CheckpointHex): CachedBeaconStateAllForks | null {
68
62
  this.metrics?.lookups.inc();
69
63
  const cpKey = toCheckpointKey(cp);
70
64
  const item = this.cache.get(cpKey);
@@ -81,7 +75,7 @@ export class InMemoryCheckpointStateCache implements CheckpointStateCache {
81
75
 
82
76
  this.metrics?.stateClonedCount.observe(item.clonedCount);
83
77
 
84
- return item.clone(opts?.dontTransferCache);
78
+ return item;
85
79
  }
86
80
 
87
81
  add(cp: phase0.Checkpoint, item: CachedBeaconStateAllForks): void {
@@ -98,14 +92,14 @@ export class InMemoryCheckpointStateCache implements CheckpointStateCache {
98
92
  /**
99
93
  * Searches for the latest cached state with a `root`, starting with `epoch` and descending
100
94
  */
101
- getLatest(rootHex: RootHex, maxEpoch: Epoch, opts?: StateRegenerationOpts): CachedBeaconStateAllForks | null {
95
+ getLatest(rootHex: RootHex, maxEpoch: Epoch): CachedBeaconStateAllForks | null {
102
96
  // sort epochs in descending order, only consider epochs lte `epoch`
103
97
  const epochs = Array.from(this.epochIndex.keys())
104
98
  .sort((a, b) => b - a)
105
99
  .filter((e) => e <= maxEpoch);
106
100
  for (const epoch of epochs) {
107
101
  if (this.epochIndex.get(epoch)?.has(rootHex)) {
108
- return this.get({rootHex, epoch}, opts);
102
+ return this.get({rootHex, epoch});
109
103
  }
110
104
  }
111
105
  return null;
@@ -11,7 +11,6 @@ import {Logger, MapDef, fromHex, sleep, toHex, toRootHex} from "@lodestar/utils"
11
11
  import {Metrics} from "../../metrics/index.js";
12
12
  import {AllocSource, BufferPool, BufferWithKey} from "../../util/bufferPool.js";
13
13
  import {IClock} from "../../util/clock.js";
14
- import {StateRegenerationOpts} from "../regen/interface.js";
15
14
  import {serializeState} from "../serializeState.js";
16
15
  import {CPStateDatastore, DatastoreKey} from "./datastore/index.js";
17
16
  import {MapTracker} from "./mapMetrics.js";
@@ -204,10 +203,10 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
204
203
  * - Get block for processing
205
204
  * - Regen head state
206
205
  */
207
- async getOrReload(cp: CheckpointHex, opts?: StateRegenerationOpts): Promise<CachedBeaconStateAllForks | null> {
208
- const stateOrStateBytesData = await this.getStateOrLoadDb(cp, opts);
206
+ async getOrReload(cp: CheckpointHex): Promise<CachedBeaconStateAllForks | null> {
207
+ const stateOrStateBytesData = await this.getStateOrLoadDb(cp);
209
208
  if (stateOrStateBytesData === null || isCachedBeaconState(stateOrStateBytesData)) {
210
- return stateOrStateBytesData?.clone(opts?.dontTransferCache) ?? null;
209
+ return stateOrStateBytesData ?? null;
211
210
  }
212
211
  const {persistedKey, stateBytes} = stateOrStateBytesData;
213
212
  const logMeta = {persistedKey: toHex(persistedKey)};
@@ -233,7 +232,8 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
233
232
  sszTimer?.();
234
233
  const timer = this.metrics?.cpStateCache.stateReloadDuration.startTimer();
235
234
  const newCachedState = loadCachedBeaconState(seedState, stateBytes, {}, validatorsBytes);
236
- newCachedState.commit();
235
+ // hashTreeRoot() calls the commit() inside
236
+ // there is no modification inside the state, it's just that we want to compute and cache all roots
237
237
  const stateRoot = toRootHex(newCachedState.hashTreeRoot());
238
238
  timer?.();
239
239
 
@@ -252,7 +252,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
252
252
  this.cache.set(cpKey, {type: CacheItemType.inMemory, state: newCachedState, persistedKey});
253
253
  this.epochIndex.getOrDefault(cp.epoch).add(cp.rootHex);
254
254
  // don't prune from memory here, call it at the last 1/3 of slot 0 of an epoch
255
- return newCachedState.clone(opts?.dontTransferCache);
255
+ return newCachedState;
256
256
  } catch (e) {
257
257
  this.logger.debug("Reload: error loading cached state", logMeta, e as Error);
258
258
  return null;
@@ -263,8 +263,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
263
263
  * Return either state or state bytes loaded from db.
264
264
  */
265
265
  async getStateOrBytes(cp: CheckpointHex): Promise<CachedBeaconStateAllForks | Uint8Array | null> {
266
- // don't have to transfer cache for this specific api
267
- const stateOrLoadedState = await this.getStateOrLoadDb(cp, {dontTransferCache: true});
266
+ const stateOrLoadedState = await this.getStateOrLoadDb(cp);
268
267
  if (stateOrLoadedState === null || isCachedBeaconState(stateOrLoadedState)) {
269
268
  return stateOrLoadedState;
270
269
  }
@@ -274,12 +273,9 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
274
273
  /**
275
274
  * Return either state or state bytes with persisted key loaded from db.
276
275
  */
277
- async getStateOrLoadDb(
278
- cp: CheckpointHex,
279
- opts?: StateRegenerationOpts
280
- ): Promise<CachedBeaconStateAllForks | LoadedStateBytesData | null> {
276
+ async getStateOrLoadDb(cp: CheckpointHex): Promise<CachedBeaconStateAllForks | LoadedStateBytesData | null> {
281
277
  const cpKey = toCacheKey(cp);
282
- const inMemoryState = this.get(cpKey, opts);
278
+ const inMemoryState = this.get(cpKey);
283
279
  if (inMemoryState) {
284
280
  return inMemoryState;
285
281
  }
@@ -308,7 +304,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
308
304
  /**
309
305
  * Similar to get() api without reloading from disk
310
306
  */
311
- get(cpOrKey: CheckpointHex | string, opts?: StateRegenerationOpts): CachedBeaconStateAllForks | null {
307
+ get(cpOrKey: CheckpointHex | string): CachedBeaconStateAllForks | null {
312
308
  this.metrics?.cpStateCache.lookups.inc();
313
309
  const cpKey = typeof cpOrKey === "string" ? cpOrKey : toCacheKey(cpOrKey);
314
310
  const cacheItem = this.cache.get(cpKey);
@@ -326,7 +322,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
326
322
  if (isInMemoryCacheItem(cacheItem)) {
327
323
  const {state} = cacheItem;
328
324
  this.metrics?.cpStateCache.stateClonedCount.observe(state.clonedCount);
329
- return state.clone(opts?.dontTransferCache);
325
+ return state;
330
326
  }
331
327
 
332
328
  return null;
@@ -360,14 +356,14 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
360
356
  /**
361
357
  * Searches in-memory state for the latest cached state with a `root` without reload, starting with `epoch` and descending
362
358
  */
363
- getLatest(rootHex: RootHex, maxEpoch: Epoch, opts?: StateRegenerationOpts): CachedBeaconStateAllForks | null {
359
+ getLatest(rootHex: RootHex, maxEpoch: Epoch): CachedBeaconStateAllForks | null {
364
360
  // sort epochs in descending order, only consider epochs lte `epoch`
365
361
  const epochs = Array.from(this.epochIndex.keys())
366
362
  .sort((a, b) => b - a)
367
363
  .filter((e) => e <= maxEpoch);
368
364
  for (const epoch of epochs) {
369
365
  if (this.epochIndex.get(epoch)?.has(rootHex)) {
370
- const inMemoryClonedState = this.get({rootHex, epoch}, opts);
366
+ const inMemoryClonedState = this.get({rootHex, epoch});
371
367
  if (inMemoryClonedState) {
372
368
  return inMemoryClonedState;
373
369
  }
@@ -383,11 +379,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
383
379
  * - Get block for processing
384
380
  * - Regen head state
385
381
  */
386
- async getOrReloadLatest(
387
- rootHex: RootHex,
388
- maxEpoch: Epoch,
389
- opts?: StateRegenerationOpts
390
- ): Promise<CachedBeaconStateAllForks | null> {
382
+ async getOrReloadLatest(rootHex: RootHex, maxEpoch: Epoch): Promise<CachedBeaconStateAllForks | null> {
391
383
  // sort epochs in descending order, only consider epochs lte `epoch`
392
384
  const epochs = Array.from(this.epochIndex.keys())
393
385
  .sort((a, b) => b - a)
@@ -395,9 +387,9 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
395
387
  for (const epoch of epochs) {
396
388
  if (this.epochIndex.get(epoch)?.has(rootHex)) {
397
389
  try {
398
- const clonedState = await this.getOrReload({rootHex, epoch}, opts);
399
- if (clonedState) {
400
- return clonedState;
390
+ const state = await this.getOrReload({rootHex, epoch});
391
+ if (state) {
392
+ return state;
401
393
  }
402
394
  } catch (e) {
403
395
  this.logger.debug("Error get or reload state", {epoch, rootHex}, e as Error);
@@ -1,7 +1,6 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
3
3
  import {Epoch, RootHex, phase0} from "@lodestar/types";
4
- import {StateRegenerationOpts} from "../regen/interface.js";
5
4
 
6
5
  export type CheckpointHex = {epoch: Epoch; rootHex: RootHex};
7
6
 
@@ -21,7 +20,7 @@ export type CheckpointHex = {epoch: Epoch; rootHex: RootHex};
21
20
  * The cache key is state root
22
21
  */
23
22
  export interface BlockStateCache {
24
- get(rootHex: RootHex, opts?: StateRegenerationOpts): CachedBeaconStateAllForks | null;
23
+ get(rootHex: RootHex): CachedBeaconStateAllForks | null;
25
24
  add(item: CachedBeaconStateAllForks): void;
26
25
  setHeadState(item: CachedBeaconStateAllForks | null): void;
27
26
  /**
@@ -60,16 +59,12 @@ export interface BlockStateCache {
60
59
  */
61
60
  export interface CheckpointStateCache {
62
61
  init?: () => Promise<void>;
63
- getOrReload(cp: CheckpointHex, opts?: StateRegenerationOpts): Promise<CachedBeaconStateAllForks | null>;
62
+ getOrReload(cp: CheckpointHex): Promise<CachedBeaconStateAllForks | null>;
64
63
  getStateOrBytes(cp: CheckpointHex): Promise<CachedBeaconStateAllForks | Uint8Array | null>;
65
- get(cpOrKey: CheckpointHex | string, opts?: StateRegenerationOpts): CachedBeaconStateAllForks | null;
64
+ get(cpOrKey: CheckpointHex | string): CachedBeaconStateAllForks | null;
66
65
  add(cp: phase0.Checkpoint, state: CachedBeaconStateAllForks): void;
67
- getLatest(rootHex: RootHex, maxEpoch: Epoch, opts?: StateRegenerationOpts): CachedBeaconStateAllForks | null;
68
- getOrReloadLatest(
69
- rootHex: RootHex,
70
- maxEpoch: Epoch,
71
- opts?: StateRegenerationOpts
72
- ): Promise<CachedBeaconStateAllForks | null>;
66
+ getLatest(rootHex: RootHex, maxEpoch: Epoch): CachedBeaconStateAllForks | null;
67
+ getOrReloadLatest(rootHex: RootHex, maxEpoch: Epoch): Promise<CachedBeaconStateAllForks | null>;
73
68
  updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null;
74
69
  prune(finalizedEpoch: Epoch, justifiedEpoch: Epoch): void;
75
70
  pruneFinalized(finalizedEpoch: Epoch): void;
@@ -43,7 +43,14 @@ export async function validateAttesterSlashing(
43
43
  // [REJECT] All of the conditions within process_attester_slashing pass validation.
44
44
  try {
45
45
  // verifySignature = false, verified in batch below
46
- assertValidAttesterSlashing(chain.index2pubkey, state, attesterSlashing, false);
46
+ assertValidAttesterSlashing(
47
+ chain.config,
48
+ chain.index2pubkey,
49
+ state.slot,
50
+ state.validators.length,
51
+ attesterSlashing,
52
+ false
53
+ );
47
54
  } catch (e) {
48
55
  throw new AttesterSlashingError(GossipAction.REJECT, {
49
56
  code: AttesterSlashingErrorCode.INVALID,
@@ -138,8 +138,9 @@ export async function validateGossipBlobSidecar(
138
138
  const signature = blobSidecar.signedBlockHeader.signature;
139
139
  if (!chain.seenBlockInputCache.isVerifiedProposerSignature(blobSlot, blockHex, signature)) {
140
140
  const signatureSet = getBlockHeaderProposerSignatureSetByParentStateSlot(
141
+ chain.config,
141
142
  chain.index2pubkey,
142
- blockState,
143
+ blockState.slot,
143
144
  blobSidecar.signedBlockHeader
144
145
  );
145
146
  // Don't batch so verification is not delayed
@@ -243,10 +244,9 @@ export async function validateBlockBlobSidecars(
243
244
  const blockRootHex = toRootHex(blockRoot);
244
245
  const signature = firstSidecarSignedBlockHeader.signature;
245
246
  if (!chain.seenBlockInputCache.isVerifiedProposerSignature(blockSlot, blockRootHex, signature)) {
246
- const headState = await chain.getHeadState();
247
247
  const signatureSet = getBlockHeaderProposerSignatureSetByHeaderSlot(
248
+ chain.config,
248
249
  chain.index2pubkey,
249
- headState,
250
250
  firstSidecarSignedBlockHeader
251
251
  );
252
252
 
@@ -1,8 +1,4 @@
1
- import {
2
- CachedBeaconStateCapella,
3
- getBlsToExecutionChangeSignatureSet,
4
- isValidBlsToExecutionChange,
5
- } from "@lodestar/state-transition";
1
+ import {getBlsToExecutionChangeSignatureSet, isValidBlsToExecutionChange} from "@lodestar/state-transition";
6
2
  import {capella} from "@lodestar/types";
7
3
  import {BlsToExecutionChangeError, BlsToExecutionChangeErrorCode, GossipAction} from "../errors/index.js";
8
4
  import {IBeaconChain} from "../index.js";
@@ -42,10 +38,16 @@ async function validateBlsToExecutionChange(
42
38
  // and chanes relevant to `isValidBlsToExecutionChange()` happen only on processBlock(), not processEpoch()
43
39
  const state = chain.getHeadState();
44
40
  const {config} = chain;
45
-
41
+ const addressChange = blsToExecutionChange.message;
42
+ if (addressChange.validatorIndex >= state.validators.length) {
43
+ throw new BlsToExecutionChangeError(GossipAction.REJECT, {
44
+ code: BlsToExecutionChangeErrorCode.INVALID,
45
+ });
46
+ }
47
+ const validator = state.validators.getReadonly(addressChange.validatorIndex);
46
48
  // [REJECT] All of the conditions within process_bls_to_execution_change pass validation.
47
49
  // verifySignature = false, verified in batch below
48
- const {valid} = isValidBlsToExecutionChange(state as CachedBeaconStateCapella, blsToExecutionChange, false);
50
+ const {valid} = isValidBlsToExecutionChange(config, validator, blsToExecutionChange, false);
49
51
  if (!valid) {
50
52
  throw new BlsToExecutionChangeError(GossipAction.REJECT, {
51
53
  code: BlsToExecutionChangeErrorCode.INVALID,
@@ -135,8 +135,9 @@ export async function validateGossipDataColumnSidecar(
135
135
  const signature = dataColumnSidecar.signedBlockHeader.signature;
136
136
  if (!chain.seenBlockInputCache.isVerifiedProposerSignature(blockHeader.slot, blockRootHex, signature)) {
137
137
  const signatureSet = getBlockHeaderProposerSignatureSetByParentStateSlot(
138
+ chain.config,
138
139
  chain.index2pubkey,
139
- blockState,
140
+ blockState.slot,
140
141
  dataColumnSidecar.signedBlockHeader
141
142
  );
142
143
 
@@ -336,10 +337,9 @@ export async function validateBlockDataColumnSidecars(
336
337
  const slot = firstSidecarSignedBlockHeader.message.slot;
337
338
  const signature = firstSidecarSignedBlockHeader.signature;
338
339
  if (!chain.seenBlockInputCache.isVerifiedProposerSignature(slot, rootHex, signature)) {
339
- const headState = await chain.getHeadState();
340
340
  const signatureSet = getBlockHeaderProposerSignatureSetByHeaderSlot(
341
+ chain.config,
341
342
  chain.index2pubkey,
342
- headState,
343
343
  firstSidecarSignedBlockHeader
344
344
  );
345
345
 
@@ -35,8 +35,9 @@ async function validateProposerSlashing(
35
35
 
36
36
  // [REJECT] All of the conditions within process_proposer_slashing pass validation.
37
37
  try {
38
+ const proposer = state.validators.getReadonly(proposerSlashing.signedHeader1.message.proposerIndex);
38
39
  // verifySignature = false, verified in batch below
39
- assertValidProposerSlashing(state, proposerSlashing, false);
40
+ assertValidProposerSlashing(chain.config, chain.index2pubkey, state.slot, proposerSlashing, proposer, false);
40
41
  } catch (e) {
41
42
  throw new ProposerSlashingError(GossipAction.REJECT, {
42
43
  code: ProposerSlashingErrorCode.INVALID,
@@ -42,10 +42,10 @@ export class StateArchiveRepository extends Repository<Slot, BeaconStateAllForks
42
42
 
43
43
  // Index Root -> Slot
44
44
 
45
- async getByRoot(stateRoot: Root): Promise<BeaconStateAllForks | null> {
45
+ async getBinaryByRoot(stateRoot: Root): Promise<Uint8Array | null> {
46
46
  const slot = await this.getSlotByRoot(stateRoot);
47
47
  if (slot !== null && Number.isInteger(slot)) {
48
- return this.get(slot);
48
+ return this.getBinary(slot);
49
49
  }
50
50
  return null;
51
51
  }
@@ -1,4 +1,5 @@
1
1
  import crypto from "node:crypto";
2
+ import {ChainConfig} from "@lodestar/config";
2
3
  import {
3
4
  BLOB_TX_TYPE,
4
5
  BYTES_PER_FIELD_ELEMENT,
@@ -7,7 +8,9 @@ import {
7
8
  ForkPostBellatrix,
8
9
  ForkPostCapella,
9
10
  ForkSeq,
11
+ SLOTS_PER_EPOCH,
10
12
  } from "@lodestar/params";
13
+ import {computeTimeAtSlot} from "@lodestar/state-transition";
11
14
  import {ExecutionPayload, RootHex, bellatrix, deneb, ssz} from "@lodestar/types";
12
15
  import {fromHex, toRootHex} from "@lodestar/utils";
13
16
  import {ZERO_HASH_HEX} from "../../constants/index.js";
@@ -34,14 +37,11 @@ const INTEROP_GAS_LIMIT = 30e6;
34
37
  const PRUNE_PAYLOAD_ID_AFTER_MS = 5000;
35
38
 
36
39
  export type ExecutionEngineMockOpts = {
37
- genesisBlockHash: string;
40
+ genesisBlockHash?: string;
38
41
  eth1BlockHash?: string;
39
42
  onlyPredefinedResponses?: boolean;
40
- capellaForkTimestamp?: number;
41
- denebForkTimestamp?: number;
42
- electraForkTimestamp?: number;
43
- fuluForkTimestamp?: number;
44
- gloasForkTimestamp?: number;
43
+ genesisTime?: number;
44
+ config?: ChainConfig;
45
45
  };
46
46
 
47
47
  type ExecutionBlock = {
@@ -74,17 +74,21 @@ export class ExecutionEngineMockBackend implements JsonRpcBackend {
74
74
  /** Preparing payloads to be retrieved via engine_getPayloadV1 */
75
75
  private readonly preparingPayloads = new Map<number, PreparedPayload>();
76
76
  private readonly payloadsForDeletion = new Map<number, number>();
77
-
78
77
  private readonly predefinedPayloadStatuses = new Map<RootHex, PayloadStatus>();
79
78
 
80
79
  private payloadId = 0;
80
+ private capellaForkTimestamp: number;
81
+ private denebForkTimestamp: number;
82
+ private electraForkTimestamp: number;
83
+ private fuluForkTimestamp: number;
84
+ private gloasForkTimestamp: number;
81
85
 
82
86
  readonly handlers: {
83
87
  [K in keyof EngineApiRpcParamTypes]: (...args: EngineApiRpcParamTypes[K]) => EngineApiRpcReturnTypes[K];
84
88
  };
85
89
 
86
90
  constructor(private readonly opts: ExecutionEngineMockOpts) {
87
- this.validBlocks.set(opts.genesisBlockHash, {
91
+ this.validBlocks.set(opts.genesisBlockHash ?? ZERO_HASH_HEX, {
88
92
  parentHash: ZERO_HASH_HEX,
89
93
  blockHash: ZERO_HASH_HEX,
90
94
  timestamp: 0,
@@ -100,6 +104,29 @@ export class ExecutionEngineMockBackend implements JsonRpcBackend {
100
104
  blockNumber: 1,
101
105
  });
102
106
 
107
+ const {config} = opts;
108
+
109
+ this.capellaForkTimestamp =
110
+ opts.genesisTime && config
111
+ ? computeTimeAtSlot(config, config.CAPELLA_FORK_EPOCH * SLOTS_PER_EPOCH, opts.genesisTime)
112
+ : Infinity;
113
+ this.denebForkTimestamp =
114
+ opts.genesisTime && config
115
+ ? computeTimeAtSlot(config, config.DENEB_FORK_EPOCH * SLOTS_PER_EPOCH, opts.genesisTime)
116
+ : Infinity;
117
+ this.electraForkTimestamp =
118
+ opts.genesisTime && config
119
+ ? computeTimeAtSlot(config, config.ELECTRA_FORK_EPOCH * SLOTS_PER_EPOCH, opts.genesisTime)
120
+ : Infinity;
121
+ this.fuluForkTimestamp =
122
+ opts.genesisTime && config
123
+ ? computeTimeAtSlot(config, config.FULU_FORK_EPOCH * SLOTS_PER_EPOCH, opts.genesisTime)
124
+ : Infinity;
125
+ this.gloasForkTimestamp =
126
+ opts.genesisTime && config
127
+ ? computeTimeAtSlot(config, config.GLOAS_FORK_EPOCH * SLOTS_PER_EPOCH, opts.genesisTime)
128
+ : Infinity;
129
+
103
130
  this.handlers = {
104
131
  engine_newPayloadV1: this.notifyNewPayload.bind(this),
105
132
  engine_newPayloadV2: this.notifyNewPayload.bind(this),
@@ -448,11 +475,11 @@ export class ExecutionEngineMockBackend implements JsonRpcBackend {
448
475
  }
449
476
 
450
477
  private timestampToFork(timestamp: number): ForkPostBellatrix {
451
- if (timestamp >= (this.opts.gloasForkTimestamp ?? Infinity)) return ForkName.gloas;
452
- if (timestamp >= (this.opts.fuluForkTimestamp ?? Infinity)) return ForkName.fulu;
453
- if (timestamp >= (this.opts.electraForkTimestamp ?? Infinity)) return ForkName.electra;
454
- if (timestamp >= (this.opts.denebForkTimestamp ?? Infinity)) return ForkName.deneb;
455
- if (timestamp >= (this.opts.capellaForkTimestamp ?? Infinity)) return ForkName.capella;
478
+ if (timestamp >= this.gloasForkTimestamp) return ForkName.gloas;
479
+ if (timestamp >= this.fuluForkTimestamp) return ForkName.fulu;
480
+ if (timestamp >= this.electraForkTimestamp) return ForkName.electra;
481
+ if (timestamp >= this.denebForkTimestamp) return ForkName.deneb;
482
+ if (timestamp >= this.capellaForkTimestamp) return ForkName.capella;
456
483
  return ForkName.bellatrix;
457
484
  }
458
485
  }
@@ -1308,33 +1308,19 @@ export function createLodestarMetrics(
1308
1308
  name: "lodestar_shuffling_cache_miss_count",
1309
1309
  help: "Count of shuffling cache miss",
1310
1310
  }),
1311
- shufflingBuiltMultipleTimes: register.gauge({
1312
- name: "lodestar_shuffling_cache_recalculated_shuffling_count",
1313
- help: "Count of shuffling that were build multiple times",
1314
- }),
1315
- shufflingPromiseNotResolvedAndThrownAway: register.gauge({
1316
- name: "lodestar_shuffling_cache_promise_not_resolved_and_thrown_away_count",
1317
- help: "Count of shuffling cache promises that were discarded and the shuffling was built synchronously",
1311
+ shufflingSetMultipleTimes: register.gauge({
1312
+ name: "lodestar_shuffling_cache_set_multiple_times_count",
1313
+ help: "Count of shuffling that were set multiple times",
1318
1314
  }),
1319
1315
  shufflingPromiseNotResolved: register.gauge({
1320
1316
  name: "lodestar_shuffling_cache_promise_not_resolved_count",
1321
1317
  help: "Count of shuffling cache promises that were requested before the promise was resolved",
1322
1318
  }),
1323
- nextShufflingNotOnEpochCache: register.gauge({
1324
- name: "lodestar_shuffling_cache_next_shuffling_not_on_epoch_cache",
1325
- help: "The next shuffling was not on the epoch cache before the epoch transition",
1326
- }),
1327
1319
  shufflingPromiseResolutionTime: register.histogram({
1328
1320
  name: "lodestar_shuffling_cache_promise_resolution_time_seconds",
1329
1321
  help: "Time from promise insertion until promise resolution when shuffling was ready in seconds",
1330
1322
  buckets: [0.5, 1, 1.5, 2],
1331
1323
  }),
1332
- shufflingCalculationTime: register.histogram<{source: "build" | "getSync"}>({
1333
- name: "lodestar_shuffling_cache_shuffling_calculation_time_seconds",
1334
- help: "Run time of shuffling calculation",
1335
- buckets: [0.5, 0.75, 1, 1.25, 1.5],
1336
- labelNames: ["source"],
1337
- }),
1338
1324
  },
1339
1325
 
1340
1326
  seenCache: {
@@ -1,4 +1,4 @@
1
- import type {PeerId, PeerInfo, PrivateKey} from "@libp2p/interface";
1
+ import type {PeerId, PeerInfo, PendingDial, PrivateKey} from "@libp2p/interface";
2
2
  import {Multiaddr} from "@multiformats/multiaddr";
3
3
  import {ENR} from "@chainsafe/enr";
4
4
  import {BeaconConfig} from "@lodestar/config";
@@ -217,7 +217,7 @@ export class PeerDiscovery {
217
217
  const pendingDials = new Set(
218
218
  this.libp2p.services.components.connectionManager
219
219
  .getDialQueue()
220
- .map((pendingDial) => pendingDial.peerId?.toString())
220
+ .map((pendingDial: PendingDial) => pendingDial.peerId?.toString())
221
221
  );
222
222
  for (const [id, cachedENR] of this.cachedENRs.entries()) {
223
223
  if (
@@ -458,7 +458,7 @@ export class PeerDiscovery {
458
458
  if (
459
459
  this.libp2p.services.components.connectionManager
460
460
  .getDialQueue()
461
- .find((pendingDial) => pendingDial.peerId?.equals(peerId))
461
+ .find((pendingDial: PendingDial) => pendingDial.peerId?.equals(peerId))
462
462
  ) {
463
463
  return DiscoveredPeerStatus.already_dialing;
464
464
  }
@@ -55,7 +55,7 @@ export async function handleColumnSidecarUnavailability({
55
55
  const blobsCount = getBlobKzgCommitmentsCountFromSignedBeaconBlockSerialized(chain.config, blockBytes);
56
56
 
57
57
  // There are zero blobs for that column index, so we can safely return without any error
58
- if (blobsCount > 0) return;
58
+ if (blobsCount === 0) return;
59
59
 
60
60
  // There are blobs for that column index so we should have synced for it
61
61
  // We need to inform to peers that we don't have that expected data
@@ -6,9 +6,10 @@ import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
6
6
  import {BeaconApiMethods} from "@lodestar/api/beacon/server";
7
7
  import {BeaconConfig} from "@lodestar/config";
8
8
  import type {LoggerNode} from "@lodestar/logger/node";
9
- import {CachedBeaconStateAllForks, Index2PubkeyCache} from "@lodestar/state-transition";
9
+ import {ZERO_HASH_HEX} from "@lodestar/params";
10
+ import {CachedBeaconStateAllForks, Index2PubkeyCache, isExecutionCachedStateType} from "@lodestar/state-transition";
10
11
  import {phase0} from "@lodestar/types";
11
- import {sleep} from "@lodestar/utils";
12
+ import {sleep, toRootHex} from "@lodestar/utils";
12
13
  import {ProcessShutdownCallback} from "@lodestar/validator";
13
14
  import {BeaconRestApiServer, getApi} from "../api/index.js";
14
15
  import {BeaconChain, IBeaconChain, initBeaconMetrics} from "../chain/index.js";
@@ -221,6 +222,20 @@ export class BeaconNode {
221
222
  )
222
223
  : null;
223
224
 
225
+ let executionEngineOpts = opts.executionEngine;
226
+ if (opts.executionEngine.mode === "mock") {
227
+ const eth1BlockHash = isExecutionCachedStateType(anchorState)
228
+ ? toRootHex(anchorState.latestExecutionPayloadHeader.blockHash)
229
+ : undefined;
230
+ executionEngineOpts = {
231
+ ...opts.executionEngine,
232
+ genesisBlockHash: ZERO_HASH_HEX,
233
+ eth1BlockHash,
234
+ genesisTime: anchorState.genesisTime,
235
+ config,
236
+ };
237
+ }
238
+
224
239
  const chain = new BeaconChain(opts.chain, {
225
240
  privateKey,
226
241
  config,
@@ -236,7 +251,7 @@ export class BeaconNode {
236
251
  validatorMonitor,
237
252
  anchorState,
238
253
  isAnchorStateFinalized,
239
- executionEngine: initializeExecutionEngine(opts.executionEngine, {
254
+ executionEngine: initializeExecutionEngine(executionEngineOpts, {
240
255
  metrics,
241
256
  signal,
242
257
  logger: logger.child({module: LoggerModule.execution}),
@@ -750,13 +750,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter}
750
750
 
751
751
  // GENESIS_SLOT doesn't has valid signature
752
752
  if (anchorBlock.message.slot === GENESIS_SLOT) return;
753
- await verifyBlockProposerSignature(
754
- this.chain.config,
755
- this.chain.index2pubkey,
756
- this.chain.bls,
757
- this.chain.getHeadState(),
758
- [anchorBlock]
759
- );
753
+ await verifyBlockProposerSignature(this.chain.config, this.chain.index2pubkey, this.chain.bls, [anchorBlock]);
760
754
 
761
755
  // We can write to the disk if this is ahead of prevFinalizedCheckpointBlock otherwise
762
756
  // we will need to go make checks on the top of sync loop before writing as it might
@@ -821,13 +815,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter}
821
815
 
822
816
  // If any of the block's proposer signature fail, we can't trust this peer at all
823
817
  if (verifiedBlocks.length > 0) {
824
- await verifyBlockProposerSignature(
825
- this.chain.config,
826
- this.chain.index2pubkey,
827
- this.chain.bls,
828
- this.chain.getHeadState(),
829
- verifiedBlocks
830
- );
818
+ await verifyBlockProposerSignature(this.chain.config, this.chain.index2pubkey, this.chain.bls, verifiedBlocks);
831
819
 
832
820
  // This is bad, like super bad. Abort the backfill
833
821
  if (!nextAnchor)
@@ -1,11 +1,6 @@
1
1
  import {BeaconConfig} from "@lodestar/config";
2
2
  import {GENESIS_SLOT} from "@lodestar/params";
3
- import {
4
- CachedBeaconStateAllForks,
5
- ISignatureSet,
6
- Index2PubkeyCache,
7
- getBlockProposerSignatureSet,
8
- } from "@lodestar/state-transition";
3
+ import {ISignatureSet, Index2PubkeyCache, getBlockProposerSignatureSet} from "@lodestar/state-transition";
9
4
  import {Root, SignedBeaconBlock, Slot, ssz} from "@lodestar/types";
10
5
  import {IBlsVerifier} from "../../chain/bls/index.js";
11
6
  import {BackfillSyncError, BackfillSyncErrorCode} from "./errors.js";
@@ -49,7 +44,6 @@ export async function verifyBlockProposerSignature(
49
44
  config: BeaconConfig,
50
45
  index2pubkey: Index2PubkeyCache,
51
46
  bls: IBlsVerifier,
52
- state: CachedBeaconStateAllForks,
53
47
  blocks: SignedBeaconBlock[]
54
48
  ): Promise<void> {
55
49
  if (blocks.length === 1 && blocks[0].message.slot === GENESIS_SLOT) return;