Skip to content

Commit 5e455b2

Browse files
committed
fix: prune checkpoint states at syncing time
1 parent b78cb92 commit 5e455b2

File tree

3 files changed

+8
-22
lines changed

3 files changed

+8
-22
lines changed

packages/beacon-node/src/chain/chain.ts

-1
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,6 @@ export class BeaconChain implements IBeaconChain {
293293
metrics,
294294
logger,
295295
clock,
296-
shufflingCache: this.shufflingCache,
297296
blockStateCache,
298297
bufferPool: this.bufferPool,
299298
datastore: fileDataStore

packages/beacon-node/src/chain/stateCache/persistentCheckpointsCache.ts

+2-15
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,20 @@ import {AllocSource, BufferPool, BufferWithKey} from "../../util/bufferPool.js";
99
import {IClock} from "../../util/clock.js";
1010
import {StateCloneOpts} from "../regen/interface.js";
1111
import {serializeState} from "../serializeState.js";
12-
import {ShufflingCache} from "../shufflingCache.js";
1312
import {CPStateDatastore, DatastoreKey, datastoreKeyToCheckpoint} from "./datastore/index.js";
1413
import {MapTracker} from "./mapMetrics.js";
1514
import {BlockStateCache, CacheItemType, CheckpointHex, CheckpointStateCache} from "./types.js";
1615

1716
export type PersistentCheckpointStateCacheOpts = {
1817
/** Keep max n states in memory, persist the rest to disk */
1918
maxCPStateEpochsInMemory?: number;
20-
/** for testing only */
21-
processLateBlock?: boolean;
2219
};
2320

2421
type PersistentCheckpointStateCacheModules = {
2522
metrics?: Metrics | null;
2623
logger: Logger;
2724
clock?: IClock | null;
2825
signal?: AbortSignal;
29-
shufflingCache: ShufflingCache;
3026
datastore: CPStateDatastore;
3127
blockStateCache: BlockStateCache;
3228
bufferPool?: BufferPool | null;
@@ -102,10 +98,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
10298
private preComputedCheckpoint: string | null = null;
10399
private preComputedCheckpointHits: number | null = null;
104100
private readonly maxEpochsInMemory: number;
105-
// only for testing, default false for production
106-
private readonly processLateBlock: boolean;
107101
private readonly datastore: CPStateDatastore;
108-
private readonly shufflingCache: ShufflingCache;
109102
private readonly blockStateCache: BlockStateCache;
110103
private readonly bufferPool?: BufferPool | null;
111104

@@ -115,7 +108,6 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
115108
logger,
116109
clock,
117110
signal,
118-
shufflingCache,
119111
datastore,
120112
blockStateCache,
121113
bufferPool,
@@ -153,10 +145,8 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
153145
throw new Error("maxEpochsInMemory must be >= 0");
154146
}
155147
this.maxEpochsInMemory = opts.maxCPStateEpochsInMemory ?? DEFAULT_MAX_CP_STATE_EPOCHS_IN_MEMORY;
156-
this.processLateBlock = opts.processLateBlock ?? false;
157148
// Specify different datastore for testing
158149
this.datastore = datastore;
159-
this.shufflingCache = shufflingCache;
160150
this.blockStateCache = blockStateCache;
161151
this.bufferPool = bufferPool;
162152
}
@@ -487,12 +477,9 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
487477
// 2/3 of slot is the most free time of every slot, take that chance to persist checkpoint states
488478
// normally it should only persist checkpoint states at 2/3 of slot 0 of epoch
489479
await sleep(secToTwoThirdsSlot * 1000, this.signal);
490-
} else if (!this.processLateBlock) {
491-
// normally the block persist happens at 2/3 of slot 0 of epoch, if it's already late then just skip to allow other tasks to run
492-
// there are plenty of chances in the same epoch to persist checkpoint states, also if block is late it could be reorged
493-
this.logger.verbose("Skip persist checkpoint states", {blockSlot, root: blockRootHex});
494-
return 0;
495480
}
481+
// at syncing time, it's critical to persist checkpoint states as soon as possible to avoid OOM during unfinality time
482+
// if node is synced this is not a hot time because block comes late, we'll likely miss attestation already, or the block is orphaned
496483

497484
const persistEpochs = sortedEpochs.slice(0, sortedEpochs.length - this.maxEpochsInMemory);
498485
for (const lowestEpoch of persistEpochs) {

packages/beacon-node/test/unit/chain/stateCache/persistentCheckpointsCache.test.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ describe("PersistentCheckpointStateCache", () => {
9393
shufflingCache: new ShufflingCache(),
9494
blockStateCache: new FIFOBlockStateCache({}, {}),
9595
},
96-
{maxCPStateEpochsInMemory: 2, processLateBlock: true}
96+
{maxCPStateEpochsInMemory: 2}
9797
);
9898
cache.add(cp0a, states["cp0a"]);
9999
cache.add(cp0b, states["cp0b"]);
@@ -168,7 +168,7 @@ describe("PersistentCheckpointStateCache", () => {
168168
shufflingCache: new ShufflingCache(),
169169
blockStateCache: new FIFOBlockStateCache({}, {}),
170170
},
171-
{maxCPStateEpochsInMemory: 2, processLateBlock: true}
171+
{maxCPStateEpochsInMemory: 2}
172172
);
173173
cache.add(cp0a, states["cp0a"]);
174174
cache.add(cp0b, states["cp0b"]);
@@ -245,7 +245,7 @@ describe("PersistentCheckpointStateCache", () => {
245245
shufflingCache: new ShufflingCache(),
246246
blockStateCache: new FIFOBlockStateCache({}, {}),
247247
},
248-
{maxCPStateEpochsInMemory: 2, processLateBlock: true}
248+
{maxCPStateEpochsInMemory: 2}
249249
);
250250
cache.add(cp0a, states["cp0a"]);
251251
cache.add(cp0b, states["cp0b"]);
@@ -551,7 +551,7 @@ describe("PersistentCheckpointStateCache", () => {
551551
shufflingCache: new ShufflingCache(),
552552
blockStateCache: new FIFOBlockStateCache({}, {}),
553553
},
554-
{maxCPStateEpochsInMemory: 1, processLateBlock: true}
554+
{maxCPStateEpochsInMemory: 1}
555555
);
556556
cache.add(cp0a, states["cp0a"]);
557557
cache.add(cp0b, states["cp0b"]);
@@ -823,7 +823,7 @@ describe("PersistentCheckpointStateCache", () => {
823823
shufflingCache: new ShufflingCache(),
824824
blockStateCache: new FIFOBlockStateCache({}, {}),
825825
},
826-
{maxCPStateEpochsInMemory: 0, processLateBlock: true}
826+
{maxCPStateEpochsInMemory: 0}
827827
);
828828
cache.add(cp0a, states["cp0a"]);
829829
cache.add(cp0b, states["cp0b"]);
@@ -914,7 +914,7 @@ describe("PersistentCheckpointStateCache", () => {
914914
shufflingCache: new ShufflingCache(),
915915
blockStateCache: new FIFOBlockStateCache({}, {}),
916916
},
917-
{maxCPStateEpochsInMemory: 0, processLateBlock: true}
917+
{maxCPStateEpochsInMemory: 0}
918918
);
919919

920920
const root1a = Buffer.alloc(32, 100);

0 commit comments

Comments
 (0)