@lodestar/beacon-node 1.43.0-dev.aef3645690 → 1.43.0-dev.e5b13221e5
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.
- package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/blocks/index.js +1 -4
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +1 -4
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/GetBlobsTracker.d.ts +1 -1
- package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
- package/lib/chain/GetBlobsTracker.js +1 -2
- package/lib/chain/GetBlobsTracker.js.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +2 -4
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +27 -35
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +19 -26
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.js +1 -1
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +3 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +20 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +5 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeProcessor.js +6 -4
- package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
- package/lib/chain/blocks/types.d.ts +1 -1
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts +14 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js +25 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -0
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +17 -37
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +13 -1
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/emitter.js +5 -0
- package/lib/chain/emitter.js.map +1 -1
- package/lib/chain/errors/attestationError.d.ts +8 -1
- package/lib/chain/errors/attestationError.d.ts.map +1 -1
- package/lib/chain/errors/attestationError.js +4 -0
- package/lib/chain/errors/attestationError.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +12 -4
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +22 -16
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts +3 -9
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +5 -32
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -8
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +29 -19
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/errors.d.ts +1 -11
- package/lib/chain/regen/errors.d.ts.map +1 -1
- package/lib/chain/regen/errors.js +0 -2
- package/lib/chain/regen/errors.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +6 -12
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/queued.d.ts +6 -11
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +8 -40
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts +0 -5
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +7 -34
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/stateCache/datastore/db.d.ts +5 -4
- package/lib/chain/stateCache/datastore/db.d.ts.map +1 -1
- package/lib/chain/stateCache/datastore/db.js +10 -32
- package/lib/chain/stateCache/datastore/db.js.map +1 -1
- package/lib/chain/stateCache/datastore/file.d.ts +1 -1
- package/lib/chain/stateCache/datastore/file.d.ts.map +1 -1
- package/lib/chain/stateCache/datastore/file.js +5 -5
- package/lib/chain/stateCache/datastore/file.js.map +1 -1
- package/lib/chain/stateCache/datastore/types.d.ts +1 -1
- package/lib/chain/stateCache/datastore/types.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts +1 -7
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.js +0 -8
- package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +13 -30
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +120 -216
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +8 -15
- package/lib/chain/stateCache/types.d.ts.map +1 -1
- package/lib/chain/stateCache/types.js.map +1 -1
- package/lib/chain/validation/aggregateAndProof.js +12 -0
- package/lib/chain/validation/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +12 -0
- package/lib/chain/validation/attestation.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +10 -10
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +4 -3
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +21 -14
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +1 -0
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/mock.d.ts.map +1 -1
- package/lib/execution/engine/mock.js +6 -0
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/execution/engine/types.d.ts +20 -0
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js +18 -0
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +23 -2
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/network.js +1 -1
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +22 -6
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +4 -2
- package/lib/node/nodejs.js.map +1 -1
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +16 -3
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +16 -16
- package/src/api/impl/beacon/blocks/index.ts +1 -4
- package/src/api/impl/validator/index.ts +3 -6
- package/src/chain/GetBlobsTracker.ts +1 -2
- package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +2 -4
- package/src/chain/blocks/importBlock.ts +26 -39
- package/src/chain/blocks/importExecutionPayload.ts +20 -26
- package/src/chain/blocks/index.ts +1 -1
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +27 -0
- package/src/chain/blocks/payloadEnvelopeProcessor.ts +6 -5
- package/src/chain/blocks/types.ts +1 -1
- package/src/chain/blocks/verifyPayloadsDataAvailability.ts +38 -0
- package/src/chain/chain.ts +16 -47
- package/src/chain/emitter.ts +12 -0
- package/src/chain/errors/attestationError.ts +6 -1
- package/src/chain/forkChoice/index.ts +12 -4
- package/src/chain/prepareNextSlot.ts +25 -16
- package/src/chain/produceBlock/computeNewStateRoot.ts +6 -43
- package/src/chain/produceBlock/produceBlockBody.ts +40 -20
- package/src/chain/regen/errors.ts +1 -6
- package/src/chain/regen/interface.ts +6 -12
- package/src/chain/regen/queued.ts +12 -48
- package/src/chain/regen/regen.ts +8 -36
- package/src/chain/stateCache/datastore/db.ts +10 -33
- package/src/chain/stateCache/datastore/file.ts +5 -6
- package/src/chain/stateCache/datastore/types.ts +2 -3
- package/src/chain/stateCache/fifoBlockStateCache.ts +1 -10
- package/src/chain/stateCache/persistentCheckpointsCache.ts +139 -247
- package/src/chain/stateCache/types.ts +8 -14
- package/src/chain/validation/aggregateAndProof.ts +13 -0
- package/src/chain/validation/attestation.ts +13 -0
- package/src/chain/validation/executionPayloadEnvelope.ts +10 -10
- package/src/chain/validation/payloadAttestationMessage.ts +5 -3
- package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
- package/src/execution/engine/http.ts +21 -14
- package/src/execution/engine/interface.ts +1 -0
- package/src/execution/engine/mock.ts +8 -1
- package/src/execution/engine/types.ts +41 -0
- package/src/network/network.ts +1 -1
- package/src/network/processor/gossipHandlers.ts +26 -10
- package/src/node/nodejs.ts +4 -2
- package/src/util/sszBytes.ts +21 -3
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
2
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
|
-
import {CheckpointWithPayloadStatus} from "@lodestar/fork-choice";
|
|
4
3
|
import {IBeaconStateView, computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
5
4
|
import {Epoch, RootHex, phase0} from "@lodestar/types";
|
|
6
5
|
import {Logger, MapDef, fromHex, sleep, toHex, toRootHex} from "@lodestar/utils";
|
|
@@ -10,7 +9,7 @@ import {IClock} from "../../util/clock.js";
|
|
|
10
9
|
import {serializeState} from "../serializeState.js";
|
|
11
10
|
import {CPStateDatastore, DatastoreKey} from "./datastore/index.js";
|
|
12
11
|
import {MapTracker} from "./mapMetrics.js";
|
|
13
|
-
import {BlockStateCache, CacheItemType,
|
|
12
|
+
import {BlockStateCache, CacheItemType, CheckpointHex, CheckpointStateCache} from "./types.js";
|
|
14
13
|
|
|
15
14
|
export type PersistentCheckpointStateCacheOpts = {
|
|
16
15
|
/** Keep max n state epochs in memory, persist the rest to disk */
|
|
@@ -50,22 +49,6 @@ type CacheItem = InMemoryCacheItem | PersistedCacheItem;
|
|
|
50
49
|
|
|
51
50
|
type LoadedStateBytesData = {persistedKey: DatastoreKey; stateBytes: Uint8Array};
|
|
52
51
|
|
|
53
|
-
/** Bitmask for tracking which payload variants exist per root in the epochIndex */
|
|
54
|
-
enum PayloadAvailability {
|
|
55
|
-
NOT_PRESENT = 1,
|
|
56
|
-
PRESENT = 2,
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const PAYLOAD_AVAILABILITY_ALL = [PayloadAvailability.NOT_PRESENT, PayloadAvailability.PRESENT] as const;
|
|
60
|
-
|
|
61
|
-
function toPayloadAvailability(payloadPresent: boolean): PayloadAvailability {
|
|
62
|
-
return payloadPresent ? PayloadAvailability.PRESENT : PayloadAvailability.NOT_PRESENT;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function fromPayloadAvailability(flag: PayloadAvailability): boolean {
|
|
66
|
-
return flag === PayloadAvailability.PRESENT;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
52
|
/**
|
|
70
53
|
* Before n-historical states, lodestar keeps all checkpoint states since finalized
|
|
71
54
|
* Since Sep 2024, lodestar stores 3 most recent checkpoint states in memory and the rest on disk. The finalized state
|
|
@@ -118,8 +101,8 @@ const PROCESS_CHECKPOINT_STATES_BPS = 6667;
|
|
|
118
101
|
*/
|
|
119
102
|
export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
120
103
|
private readonly cache: MapTracker<CacheKey, CacheItem>;
|
|
121
|
-
/** Epoch ->
|
|
122
|
-
private readonly epochIndex = new MapDef<Epoch,
|
|
104
|
+
/** Epoch -> Set<blockRoot> */
|
|
105
|
+
private readonly epochIndex = new MapDef<Epoch, Set<RootHex>>(() => new Set<string>());
|
|
123
106
|
private readonly config: BeaconConfig;
|
|
124
107
|
private readonly metrics: Metrics | null | undefined;
|
|
125
108
|
private readonly logger: Logger;
|
|
@@ -215,18 +198,13 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
215
198
|
* - Get block for processing
|
|
216
199
|
* - Regen head state
|
|
217
200
|
*/
|
|
218
|
-
async getOrReload(cp:
|
|
201
|
+
async getOrReload(cp: CheckpointHex): Promise<IBeaconStateView | null> {
|
|
219
202
|
const stateOrStateBytesData = await this.getStateOrLoadDb(cp);
|
|
220
203
|
if (stateOrStateBytesData === null || isBeaconStateView(stateOrStateBytesData)) {
|
|
221
204
|
return stateOrStateBytesData ?? null;
|
|
222
205
|
}
|
|
223
206
|
const {persistedKey, stateBytes} = stateOrStateBytesData;
|
|
224
|
-
const logMeta = {
|
|
225
|
-
epoch: cp.epoch,
|
|
226
|
-
rootHex: cp.rootHex,
|
|
227
|
-
payloadPresent: cp.payloadPresent,
|
|
228
|
-
persistedKey: toHex(persistedKey),
|
|
229
|
-
};
|
|
207
|
+
const logMeta = {persistedKey: toHex(persistedKey)};
|
|
230
208
|
this.logger.debug("Reload: read state successful", logMeta);
|
|
231
209
|
this.metrics?.cpStateCache.stateReloadSecFromSlot.observe(
|
|
232
210
|
this.clock?.secFromSlot(this.clock?.currentSlot ?? 0) ?? 0
|
|
@@ -248,7 +226,10 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
248
226
|
}
|
|
249
227
|
sszTimer?.();
|
|
250
228
|
const timer = this.metrics?.cpStateCache.stateReloadDuration.startTimer();
|
|
251
|
-
|
|
229
|
+
// preload validators and balances for faster state transition
|
|
230
|
+
const newCachedState = seedState.loadOtherState(stateBytes, validatorsBytes, {
|
|
231
|
+
preloadValidatorsAndBalances: true,
|
|
232
|
+
});
|
|
252
233
|
// hashTreeRoot() calls the commit() inside
|
|
253
234
|
// there is no modification inside the state, it's just that we want to compute and cache all roots
|
|
254
235
|
const stateRoot = toRootHex(newCachedState.hashTreeRoot());
|
|
@@ -264,7 +245,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
264
245
|
// only remove persisted state once we reload successfully
|
|
265
246
|
const cpKey = toCacheKey(cp);
|
|
266
247
|
this.cache.set(cpKey, {type: CacheItemType.inMemory, state: newCachedState, persistedKey});
|
|
267
|
-
this.
|
|
248
|
+
this.epochIndex.getOrDefault(cp.epoch).add(cp.rootHex);
|
|
268
249
|
// don't prune from memory here, call it at the last 1/3 of slot 0 of an epoch
|
|
269
250
|
return newCachedState;
|
|
270
251
|
} catch (e) {
|
|
@@ -276,7 +257,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
276
257
|
/**
|
|
277
258
|
* Return either state or state bytes loaded from db.
|
|
278
259
|
*/
|
|
279
|
-
async getStateOrBytes(cp:
|
|
260
|
+
async getStateOrBytes(cp: CheckpointHex): Promise<IBeaconStateView | Uint8Array | null> {
|
|
280
261
|
const stateOrLoadedState = await this.getStateOrLoadDb(cp);
|
|
281
262
|
if (stateOrLoadedState === null || isBeaconStateView(stateOrLoadedState)) {
|
|
282
263
|
return stateOrLoadedState;
|
|
@@ -287,7 +268,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
287
268
|
/**
|
|
288
269
|
* Return either state or state bytes with persisted key loaded from db.
|
|
289
270
|
*/
|
|
290
|
-
async getStateOrLoadDb(cp:
|
|
271
|
+
async getStateOrLoadDb(cp: CheckpointHex): Promise<IBeaconStateView | LoadedStateBytesData | null> {
|
|
291
272
|
const cpKey = toCacheKey(cp);
|
|
292
273
|
const inMemoryState = this.get(cpKey);
|
|
293
274
|
if (inMemoryState) {
|
|
@@ -318,7 +299,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
318
299
|
/**
|
|
319
300
|
* Similar to get() api without reloading from disk
|
|
320
301
|
*/
|
|
321
|
-
get(cpOrKey:
|
|
302
|
+
get(cpOrKey: CheckpointHex | CacheKey): IBeaconStateView | null {
|
|
322
303
|
this.metrics?.cpStateCache.lookups.inc();
|
|
323
304
|
const cpKey = typeof cpOrKey === "string" ? cpOrKey : toCacheKey(cpOrKey);
|
|
324
305
|
const cacheItem = this.cache.get(cpKey);
|
|
@@ -344,11 +325,9 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
344
325
|
|
|
345
326
|
/**
|
|
346
327
|
* Add a state of a checkpoint to this cache, prune from memory if necessary.
|
|
347
|
-
* @param payloadPresent - For Gloas: true if this is payload state, false if block state.
|
|
348
|
-
* Always true for pre-Gloas.
|
|
349
328
|
*/
|
|
350
|
-
add(cp: phase0.Checkpoint, state: IBeaconStateView
|
|
351
|
-
const cpHex =
|
|
329
|
+
add(cp: phase0.Checkpoint, state: IBeaconStateView): void {
|
|
330
|
+
const cpHex = toCheckpointHex(cp);
|
|
352
331
|
const key = toCacheKey(cpHex);
|
|
353
332
|
const cacheItem = this.cache.get(key);
|
|
354
333
|
this.metrics?.cpStateCache.adds.inc();
|
|
@@ -359,32 +338,27 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
359
338
|
this.logger.verbose("Added checkpoint state to memory but a persisted key existed", {
|
|
360
339
|
epoch: cp.epoch,
|
|
361
340
|
rootHex: cpHex.rootHex,
|
|
362
|
-
payloadPresent,
|
|
363
341
|
persistedKey: toHex(persistedKey),
|
|
364
342
|
});
|
|
365
343
|
} else {
|
|
366
344
|
this.cache.set(key, {type: CacheItemType.inMemory, state});
|
|
367
|
-
this.logger.verbose("Added checkpoint state to memory", {
|
|
368
|
-
epoch: cp.epoch,
|
|
369
|
-
rootHex: cpHex.rootHex,
|
|
370
|
-
payloadPresent,
|
|
371
|
-
});
|
|
345
|
+
this.logger.verbose("Added checkpoint state to memory", {epoch: cp.epoch, rootHex: cpHex.rootHex});
|
|
372
346
|
}
|
|
373
|
-
this.
|
|
347
|
+
this.epochIndex.getOrDefault(cp.epoch).add(cpHex.rootHex);
|
|
374
348
|
this.prunePersistedStates();
|
|
375
349
|
}
|
|
376
350
|
|
|
377
351
|
/**
|
|
378
352
|
* Searches in-memory state for the latest cached state with a `root` without reload, starting with `epoch` and descending
|
|
379
353
|
*/
|
|
380
|
-
getLatest(rootHex: RootHex, maxEpoch: Epoch
|
|
354
|
+
getLatest(rootHex: RootHex, maxEpoch: Epoch): IBeaconStateView | null {
|
|
381
355
|
// sort epochs in descending order, only consider epochs lte `epoch`
|
|
382
356
|
const epochs = Array.from(this.epochIndex.keys())
|
|
383
357
|
.sort((a, b) => b - a)
|
|
384
358
|
.filter((e) => e <= maxEpoch);
|
|
385
359
|
for (const epoch of epochs) {
|
|
386
|
-
if (this.
|
|
387
|
-
const inMemoryClonedState = this.get({rootHex, epoch
|
|
360
|
+
if (this.epochIndex.get(epoch)?.has(rootHex)) {
|
|
361
|
+
const inMemoryClonedState = this.get({rootHex, epoch});
|
|
388
362
|
if (inMemoryClonedState) {
|
|
389
363
|
return inMemoryClonedState;
|
|
390
364
|
}
|
|
@@ -400,24 +374,20 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
400
374
|
* - Get block for processing
|
|
401
375
|
* - Regen head state
|
|
402
376
|
*/
|
|
403
|
-
async getOrReloadLatest(
|
|
404
|
-
rootHex: RootHex,
|
|
405
|
-
maxEpoch: Epoch,
|
|
406
|
-
payloadPresent: boolean
|
|
407
|
-
): Promise<IBeaconStateView | null> {
|
|
377
|
+
async getOrReloadLatest(rootHex: RootHex, maxEpoch: Epoch): Promise<IBeaconStateView | null> {
|
|
408
378
|
// sort epochs in descending order, only consider epochs lte `epoch`
|
|
409
379
|
const epochs = Array.from(this.epochIndex.keys())
|
|
410
380
|
.sort((a, b) => b - a)
|
|
411
381
|
.filter((e) => e <= maxEpoch);
|
|
412
382
|
for (const epoch of epochs) {
|
|
413
|
-
if (this.
|
|
383
|
+
if (this.epochIndex.get(epoch)?.has(rootHex)) {
|
|
414
384
|
try {
|
|
415
|
-
const state = await this.getOrReload({rootHex, epoch
|
|
385
|
+
const state = await this.getOrReload({rootHex, epoch});
|
|
416
386
|
if (state) {
|
|
417
387
|
return state;
|
|
418
388
|
}
|
|
419
389
|
} catch (e) {
|
|
420
|
-
this.logger.debug("Error get or reload state", {epoch, rootHex
|
|
390
|
+
this.logger.debug("Error get or reload state", {epoch, rootHex}, e as Error);
|
|
421
391
|
}
|
|
422
392
|
}
|
|
423
393
|
}
|
|
@@ -427,12 +397,10 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
427
397
|
/**
|
|
428
398
|
* Update the precomputed checkpoint and return the number of hits for the
|
|
429
399
|
* previous one (if any).
|
|
430
|
-
* @param payloadPresent - For Gloas: true if head block has FULL payload, false if EMPTY.
|
|
431
|
-
* Always true for pre-Gloas.
|
|
432
400
|
*/
|
|
433
|
-
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch
|
|
401
|
+
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null {
|
|
434
402
|
const previousHits = this.preComputedCheckpointHits;
|
|
435
|
-
this.preComputedCheckpoint = toCacheKey({rootHex, epoch
|
|
403
|
+
this.preComputedCheckpoint = toCacheKey({rootHex, epoch});
|
|
436
404
|
this.preComputedCheckpointHits = 0;
|
|
437
405
|
return previousHits;
|
|
438
406
|
}
|
|
@@ -506,9 +474,6 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
506
474
|
* - 2 then we'll persist {root: b2, epoch n-2} checkpoint state to disk, there are also 2 checkpoint states in memory at epoch n, same to the above (maxEpochsInMemory=1)
|
|
507
475
|
*
|
|
508
476
|
* As of Mar 2024, it takes <=350ms to persist a holesky state on fast server
|
|
509
|
-
*
|
|
510
|
-
* For Gloas: Processes both block state and payload state variants together. The decision of which roots to persist/prune
|
|
511
|
-
* is based on root canonicality (from state's view), not payload presence. Both variants are managed as a unit.
|
|
512
477
|
*/
|
|
513
478
|
async processState(blockRootHex: RootHex, state: IBeaconStateView): Promise<number> {
|
|
514
479
|
let persistCount = 0;
|
|
@@ -579,7 +544,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
579
544
|
*
|
|
580
545
|
* Use seed state from the block cache if cannot find any seed states within this cache.
|
|
581
546
|
*/
|
|
582
|
-
findSeedStateToReload(reloadedCp:
|
|
547
|
+
findSeedStateToReload(reloadedCp: CheckpointHex): IBeaconStateView {
|
|
583
548
|
const maxEpoch = Math.max(...Array.from(this.epochIndex.keys()));
|
|
584
549
|
const reloadedCpSlot = computeStartSlotAtEpoch(reloadedCp.epoch);
|
|
585
550
|
let firstState: IBeaconStateView | null = null;
|
|
@@ -592,35 +557,31 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
592
557
|
return firstState;
|
|
593
558
|
}
|
|
594
559
|
|
|
595
|
-
for (const
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
560
|
+
for (const rootHex of this.epochIndex.get(epoch) || []) {
|
|
561
|
+
const cpKey = toCacheKey({rootHex, epoch});
|
|
562
|
+
const cacheItem = this.cache.get(cpKey);
|
|
563
|
+
if (cacheItem === undefined) {
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
if (isInMemoryCacheItem(cacheItem)) {
|
|
567
|
+
const {state} = cacheItem;
|
|
568
|
+
if (firstState === null) {
|
|
569
|
+
firstState = state;
|
|
603
570
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
reloadedCpSlot < state.slot &&
|
|
615
|
-
toRootHex(state.getBlockRootAtSlot(reloadedCpSlot)) === reloadedCp.rootHex
|
|
616
|
-
) {
|
|
617
|
-
this.logger.verbose("Reload: use checkpoint state as seed state", {...cpLog, ...logCtx});
|
|
618
|
-
return state;
|
|
619
|
-
}
|
|
620
|
-
} catch (e) {
|
|
621
|
-
// getBlockRootAtSlot may throw error
|
|
622
|
-
this.logger.debug("Error finding checkpoint state to reload", {...cpLog, ...logCtx}, e as Error);
|
|
571
|
+
const cpLog = {cpEpoch: epoch, cpRoot: rootHex};
|
|
572
|
+
|
|
573
|
+
try {
|
|
574
|
+
// amongst states of the same epoch, choose the one with the same view of reloadedCp
|
|
575
|
+
if (
|
|
576
|
+
reloadedCpSlot < state.slot &&
|
|
577
|
+
toRootHex(state.getBlockRootAtSlot(reloadedCpSlot)) === reloadedCp.rootHex
|
|
578
|
+
) {
|
|
579
|
+
this.logger.verbose("Reload: use checkpoint state as seed state", {...cpLog, ...logCtx});
|
|
580
|
+
return state;
|
|
623
581
|
}
|
|
582
|
+
} catch (e) {
|
|
583
|
+
// getBlockRootAtSlot may throw error
|
|
584
|
+
this.logger.debug("Error finding checkpoint state to reload", {...cpLog, ...logCtx}, e as Error);
|
|
624
585
|
}
|
|
625
586
|
}
|
|
626
587
|
}
|
|
@@ -637,31 +598,6 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
637
598
|
this.epochIndex.clear();
|
|
638
599
|
}
|
|
639
600
|
|
|
640
|
-
private addToEpochIndex(epoch: Epoch, rootHex: RootHex, payloadPresent: boolean): void {
|
|
641
|
-
const rootMap = this.epochIndex.getOrDefault(epoch);
|
|
642
|
-
rootMap.set(rootHex, (rootMap.get(rootHex) ?? 0) | toPayloadAvailability(payloadPresent));
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
private removeFromEpochIndex(epoch: Epoch, rootHex: RootHex, payloadPresent: boolean): void {
|
|
646
|
-
const rootMap = this.epochIndex.get(epoch);
|
|
647
|
-
if (rootMap === undefined) return;
|
|
648
|
-
const existing = rootMap.get(rootHex);
|
|
649
|
-
if (existing === undefined) return;
|
|
650
|
-
const updated = existing & ~toPayloadAvailability(payloadPresent);
|
|
651
|
-
if (updated === 0) {
|
|
652
|
-
rootMap.delete(rootHex);
|
|
653
|
-
if (rootMap.size === 0) {
|
|
654
|
-
this.epochIndex.delete(epoch);
|
|
655
|
-
}
|
|
656
|
-
} else {
|
|
657
|
-
rootMap.set(rootHex, updated);
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
private hasPayloadVariant(epoch: Epoch, rootHex: RootHex, payloadPresent: boolean): boolean {
|
|
662
|
-
return Boolean((this.epochIndex.get(epoch)?.get(rootHex) ?? 0) & toPayloadAvailability(payloadPresent));
|
|
663
|
-
}
|
|
664
|
-
|
|
665
601
|
/** ONLY FOR DEBUGGING PURPOSES. For lodestar debug API */
|
|
666
602
|
dumpSummary(): routes.lodestar.StateCacheItem[] {
|
|
667
603
|
return Array.from(this.cache.keys()).map((key) => {
|
|
@@ -736,7 +672,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
736
672
|
const prevEpochRoot = toRootHex(state.getBlockRootAtSlot(epochBoundarySlot - 1));
|
|
737
673
|
|
|
738
674
|
// for each epoch, usually there are 2 rootHexes respective to the 2 checkpoint states: Previous Root Checkpoint State and Current Root Checkpoint State
|
|
739
|
-
const
|
|
675
|
+
const cpRootHexes = this.epochIndex.get(epoch) ?? [];
|
|
740
676
|
const persistedRootHexes = new Set<RootHex>();
|
|
741
677
|
|
|
742
678
|
// 1) if there is no CRCS, persist PRCS (block 0 of epoch is skipped). In this case prevEpochRoot === epochBoundaryHex
|
|
@@ -745,81 +681,82 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
745
681
|
persistedRootHexes.add(epochBoundaryHex);
|
|
746
682
|
|
|
747
683
|
// 3) persist any states with unknown roots to this state
|
|
748
|
-
for (const rootHex of
|
|
684
|
+
for (const rootHex of cpRootHexes) {
|
|
749
685
|
if (rootHex !== epochBoundaryHex && rootHex !== prevEpochRoot) {
|
|
750
686
|
persistedRootHexes.add(rootHex);
|
|
751
687
|
}
|
|
752
688
|
}
|
|
753
689
|
|
|
754
|
-
for (const
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
const payloadPresent = fromPayloadAvailability(flag);
|
|
758
|
-
const cpKey = toCacheKey({epoch: epoch, rootHex, payloadPresent});
|
|
759
|
-
const cacheItem = this.cache.get(cpKey);
|
|
690
|
+
for (const rootHex of cpRootHexes) {
|
|
691
|
+
const cpKey = toCacheKey({epoch: epoch, rootHex});
|
|
692
|
+
const cacheItem = this.cache.get(cpKey);
|
|
760
693
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
if (
|
|
773
|
-
if
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
this.
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
(
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
694
|
+
if (cacheItem !== undefined && isInMemoryCacheItem(cacheItem)) {
|
|
695
|
+
let {persistedKey} = cacheItem;
|
|
696
|
+
const {state} = cacheItem;
|
|
697
|
+
const logMeta = {
|
|
698
|
+
stateSlot: state.slot,
|
|
699
|
+
rootHex,
|
|
700
|
+
epochBoundaryHex,
|
|
701
|
+
persistedKey: persistedKey ? toHex(persistedKey) : "",
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
if (persistedRootHexes.has(rootHex)) {
|
|
705
|
+
if (persistedKey) {
|
|
706
|
+
// we don't care if the checkpoint state is already persisted
|
|
707
|
+
this.logger.verbose("Pruned checkpoint state from memory but no need to persist", logMeta);
|
|
708
|
+
} else {
|
|
709
|
+
// persist and do not update epochIndex
|
|
710
|
+
this.metrics?.cpStateCache.statePersistSecFromSlot.observe(
|
|
711
|
+
this.clock?.secFromSlot(this.clock?.currentSlot ?? 0) ?? 0
|
|
712
|
+
);
|
|
713
|
+
const cpPersist = {epoch: epoch, root: fromHex(rootHex)};
|
|
714
|
+
// It's not sustainable to allocate ~240MB for each state every epoch, so we use buffer pool to reuse the memory.
|
|
715
|
+
// As monitored on holesky as of Jan 2024:
|
|
716
|
+
// - This does not increase heap allocation while gc time is the same
|
|
717
|
+
// - It helps stabilize persist time and save ~300ms in average (1.5s vs 1.2s)
|
|
718
|
+
// - It also helps the state reload to save ~500ms in average (4.3s vs 3.8s)
|
|
719
|
+
// - Also `serializeState.test.ts` perf test shows a lot of differences allocating ~240MB once vs per state serialization
|
|
720
|
+
const timer = this.metrics?.stateSerializeDuration.startTimer({
|
|
721
|
+
source: AllocSource.PERSISTENT_CHECKPOINTS_CACHE_STATE,
|
|
722
|
+
});
|
|
723
|
+
persistedKey = await serializeState(
|
|
724
|
+
state,
|
|
725
|
+
AllocSource.PERSISTENT_CHECKPOINTS_CACHE_STATE,
|
|
726
|
+
(stateBytes) => {
|
|
727
|
+
timer?.();
|
|
728
|
+
return this.datastore.write(cpPersist, stateBytes);
|
|
729
|
+
},
|
|
730
|
+
this.bufferPool
|
|
731
|
+
);
|
|
732
|
+
|
|
733
|
+
persistCount++;
|
|
734
|
+
this.logger.verbose("Pruned checkpoint state from memory and persisted to disk", {
|
|
735
|
+
...logMeta,
|
|
736
|
+
persistedKey: toHex(persistedKey),
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
// overwrite cpKey, this means the state is deleted from memory
|
|
740
|
+
this.cache.set(cpKey, {type: CacheItemType.persisted, value: persistedKey});
|
|
741
|
+
} else {
|
|
742
|
+
if (persistedKey) {
|
|
743
|
+
// persisted file will be eventually deleted by the archive task
|
|
744
|
+
// this also means the state is deleted from memory
|
|
808
745
|
this.cache.set(cpKey, {type: CacheItemType.persisted, value: persistedKey});
|
|
746
|
+
// do not update epochIndex
|
|
809
747
|
} else {
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
this.removeFromEpochIndex(epoch, rootHex, payloadPresent);
|
|
748
|
+
// delete the state from memory
|
|
749
|
+
this.cache.delete(cpKey);
|
|
750
|
+
const rootSet = this.epochIndex.get(epoch);
|
|
751
|
+
if (rootSet) {
|
|
752
|
+
rootSet.delete(rootHex);
|
|
753
|
+
if (rootSet.size === 0) {
|
|
754
|
+
this.epochIndex.delete(epoch);
|
|
755
|
+
}
|
|
819
756
|
}
|
|
820
|
-
this.metrics?.cpStateCache.statePruneFromMemoryCount.inc();
|
|
821
|
-
this.logger.verbose("Pruned checkpoint state from memory", logMeta);
|
|
822
757
|
}
|
|
758
|
+
this.metrics?.cpStateCache.statePruneFromMemoryCount.inc();
|
|
759
|
+
this.logger.verbose("Pruned checkpoint state from memory", logMeta);
|
|
823
760
|
}
|
|
824
761
|
}
|
|
825
762
|
}
|
|
@@ -832,40 +769,26 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
832
769
|
*/
|
|
833
770
|
private async deleteAllEpochItems(epoch: Epoch): Promise<void> {
|
|
834
771
|
let persistCount = 0;
|
|
835
|
-
const
|
|
836
|
-
for (const
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
const
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
await this.datastore.remove(persistedKey);
|
|
847
|
-
persistCount++;
|
|
848
|
-
this.metrics?.cpStateCache.persistedStateRemoveCount.inc();
|
|
849
|
-
}
|
|
772
|
+
const rootHexes = this.epochIndex.get(epoch) || [];
|
|
773
|
+
for (const rootHex of rootHexes) {
|
|
774
|
+
const key = toCacheKey({rootHex, epoch});
|
|
775
|
+
const cacheItem = this.cache.get(key);
|
|
776
|
+
|
|
777
|
+
if (cacheItem) {
|
|
778
|
+
const persistedKey = isPersistedCacheItem(cacheItem) ? cacheItem.value : cacheItem.persistedKey;
|
|
779
|
+
if (persistedKey) {
|
|
780
|
+
await this.datastore.remove(persistedKey);
|
|
781
|
+
persistCount++;
|
|
782
|
+
this.metrics?.cpStateCache.persistedStateRemoveCount.inc();
|
|
850
783
|
}
|
|
851
|
-
this.cache.delete(key);
|
|
852
|
-
this.logger.verbose("Pruned checkpoint state", {
|
|
853
|
-
epoch,
|
|
854
|
-
rootHex,
|
|
855
|
-
payloadPresent,
|
|
856
|
-
type: cacheItem ? (isPersistedCacheItem(cacheItem) ? "persisted" : "in-memory") : "missing",
|
|
857
|
-
});
|
|
858
784
|
}
|
|
785
|
+
this.cache.delete(key);
|
|
859
786
|
}
|
|
860
787
|
this.epochIndex.delete(epoch);
|
|
861
|
-
this.logger.verbose("Pruned
|
|
788
|
+
this.logger.verbose("Pruned checkpoint states for epoch", {
|
|
862
789
|
epoch,
|
|
863
790
|
persistCount,
|
|
864
|
-
|
|
865
|
-
.flatMap(([rootHex, bitmask]) =>
|
|
866
|
-
PAYLOAD_AVAILABILITY_ALL.filter((f) => bitmask & f).map((f) => `${rootHex}:${fromPayloadAvailability(f)}`)
|
|
867
|
-
)
|
|
868
|
-
.join(","),
|
|
791
|
+
rootHexes: Array.from(rootHexes).join(","),
|
|
869
792
|
});
|
|
870
793
|
}
|
|
871
794
|
|
|
@@ -916,57 +839,26 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
916
839
|
}
|
|
917
840
|
}
|
|
918
841
|
|
|
919
|
-
export function
|
|
842
|
+
export function toCheckpointHex(checkpoint: phase0.Checkpoint): CheckpointHex {
|
|
920
843
|
return {
|
|
921
844
|
epoch: checkpoint.epoch,
|
|
922
845
|
rootHex: toRootHex(checkpoint.root),
|
|
923
|
-
payloadPresent,
|
|
924
|
-
};
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
/**
|
|
928
|
-
* Convert fork-choice CheckpointWithPayloadStatus to beacon-node CheckpointHexPayload.
|
|
929
|
-
* Maps PayloadStatus enum to boolean payloadPresent.
|
|
930
|
-
* @throws Error if checkpoint has PENDING payload status (ambiguous which variant to use)
|
|
931
|
-
*/
|
|
932
|
-
export function fcCheckpointToHexPayload(checkpoint: CheckpointWithPayloadStatus): CheckpointHexPayload {
|
|
933
|
-
const PayloadStatus = {PENDING: 0, EMPTY: 1, FULL: 2} as const;
|
|
934
|
-
|
|
935
|
-
if (checkpoint.payloadStatus === PayloadStatus.PENDING) {
|
|
936
|
-
throw Error(
|
|
937
|
-
`Cannot convert checkpoint with PENDING payload status at epoch ${checkpoint.epoch} root ${checkpoint.rootHex}`
|
|
938
|
-
);
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
return {
|
|
942
|
-
epoch: checkpoint.epoch,
|
|
943
|
-
rootHex: checkpoint.rootHex,
|
|
944
|
-
payloadPresent: checkpoint.payloadStatus === PayloadStatus.FULL,
|
|
945
846
|
};
|
|
946
847
|
}
|
|
947
848
|
|
|
948
|
-
export function toCheckpointKey(cp:
|
|
949
|
-
return `${cp.rootHex}:${cp.epoch}
|
|
849
|
+
export function toCheckpointKey(cp: CheckpointHex): string {
|
|
850
|
+
return `${cp.rootHex}:${cp.epoch}`;
|
|
950
851
|
}
|
|
951
852
|
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
* Format: `{rootHex}_{epoch}_{payloadPresent}`
|
|
955
|
-
*/
|
|
956
|
-
function toCacheKey(cp: CheckpointHexPayload): CacheKey {
|
|
957
|
-
return `${cp.rootHex}_${cp.epoch}_${cp.payloadPresent}`;
|
|
853
|
+
function toCacheKey(cp: CheckpointHex): CacheKey {
|
|
854
|
+
return `${cp.rootHex}_${cp.epoch}`;
|
|
958
855
|
}
|
|
959
856
|
|
|
960
|
-
function fromCacheKey(key: CacheKey):
|
|
961
|
-
const
|
|
962
|
-
const rootHex = parts[0];
|
|
963
|
-
const epoch = Number(parts[1]);
|
|
964
|
-
// For backward compatibility with old format (rootHex_epoch), default to true
|
|
965
|
-
const payloadPresent = parts.length > 2 ? parts[2] === "true" : true;
|
|
857
|
+
function fromCacheKey(key: CacheKey): CheckpointHex {
|
|
858
|
+
const [rootHex, epoch] = key.split("_");
|
|
966
859
|
return {
|
|
967
860
|
rootHex,
|
|
968
|
-
epoch,
|
|
969
|
-
payloadPresent,
|
|
861
|
+
epoch: Number(epoch),
|
|
970
862
|
};
|
|
971
863
|
}
|
|
972
864
|
|
|
@@ -2,11 +2,7 @@ import {routes} from "@lodestar/api";
|
|
|
2
2
|
import {IBeaconStateView} from "@lodestar/state-transition";
|
|
3
3
|
import {Epoch, RootHex, phase0} from "@lodestar/types";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
* Checkpoint hex representation for state cache keys.
|
|
7
|
-
* Extends CheckpointWithHex (from fork-choice) with payloadPresent.
|
|
8
|
-
*/
|
|
9
|
-
export type CheckpointHexPayload = {epoch: Epoch; rootHex: RootHex; payloadPresent: boolean};
|
|
5
|
+
export type CheckpointHex = {epoch: Epoch; rootHex: RootHex};
|
|
10
6
|
|
|
11
7
|
/**
|
|
12
8
|
* Lodestar currently keeps two state caches around.
|
|
@@ -35,8 +31,6 @@ export interface BlockStateCache {
|
|
|
35
31
|
size: number;
|
|
36
32
|
prune(headStateRootHex: RootHex): void;
|
|
37
33
|
deleteAllBeforeEpoch(finalizedEpoch: Epoch): void;
|
|
38
|
-
/** Upgrade cache capacity for Gloas fork (2x states for block + payload states) */
|
|
39
|
-
upgradeToGloas(): void;
|
|
40
34
|
dumpSummary(): routes.lodestar.StateCacheItem[];
|
|
41
35
|
/** Expose beacon states stored in cache. Use with caution */
|
|
42
36
|
getStates(): IterableIterator<IBeaconStateView>;
|
|
@@ -65,13 +59,13 @@ export interface BlockStateCache {
|
|
|
65
59
|
*/
|
|
66
60
|
export interface CheckpointStateCache {
|
|
67
61
|
init?: () => Promise<void>;
|
|
68
|
-
getOrReload(cp:
|
|
69
|
-
getStateOrBytes(cp:
|
|
70
|
-
get(cpOrKey:
|
|
71
|
-
add(cp: phase0.Checkpoint, state: IBeaconStateView
|
|
72
|
-
getLatest(rootHex: RootHex, maxEpoch: Epoch
|
|
73
|
-
getOrReloadLatest(rootHex: RootHex, maxEpoch: Epoch
|
|
74
|
-
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch
|
|
62
|
+
getOrReload(cp: CheckpointHex): Promise<IBeaconStateView | null>;
|
|
63
|
+
getStateOrBytes(cp: CheckpointHex): Promise<IBeaconStateView | Uint8Array | null>;
|
|
64
|
+
get(cpOrKey: CheckpointHex | string): IBeaconStateView | null;
|
|
65
|
+
add(cp: phase0.Checkpoint, state: IBeaconStateView): void;
|
|
66
|
+
getLatest(rootHex: RootHex, maxEpoch: Epoch): IBeaconStateView | null;
|
|
67
|
+
getOrReloadLatest(rootHex: RootHex, maxEpoch: Epoch): Promise<IBeaconStateView | null>;
|
|
68
|
+
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null;
|
|
75
69
|
prune(finalizedEpoch: Epoch, justifiedEpoch: Epoch): void;
|
|
76
70
|
pruneFinalized(finalizedEpoch: Epoch): void;
|
|
77
71
|
processState(blockRootHex: RootHex, state: IBeaconStateView): Promise<number>;
|