Skip to content

Commit

Permalink
Add skipCreateStateCacheIfAvailable (#4319)
Browse files Browse the repository at this point in the history
  • Loading branch information
dapplion committed Jul 18, 2022
1 parent 9fe2fb3 commit eccde2f
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 10 deletions.
27 changes: 18 additions & 9 deletions packages/beacon-node/src/chain/chain.ts
Expand Up @@ -7,6 +7,7 @@ import {
createCachedBeaconState,
EffectiveBalanceIncrements,
getEffectiveBalanceIncrementsZeroInactive,
isCachedBeaconState,
Index2PubkeyCache,
PubkeyIndexMap,
} from "@lodestar/state-transition";
Expand Down Expand Up @@ -158,19 +159,27 @@ export class BeaconChain implements IBeaconChain {
this.seenAggregatedAttestations = new SeenAggregatedAttestations(metrics);
this.seenContributionAndProof = new SeenContributionAndProof(metrics);

// Initialize single global instance of state caches
this.pubkey2index = new PubkeyIndexMap();
this.index2pubkey = [];

this.beaconProposerCache = new BeaconProposerCache(opts);
this.checkpointBalancesCache = new CheckpointBalancesCache();

// Restore state caches
const cachedState = createCachedBeaconState(anchorState, {
config,
pubkey2index: this.pubkey2index,
index2pubkey: this.index2pubkey,
});
// anchorState may already by a CachedBeaconState. If so, don't create the cache again, since deserializing all
// pubkeys takes ~30 seconds for 350k keys (mainnet 2022Q2).
// When the BeaconStateCache is created in eth1 genesis builder it may be incorrect. Until we can ensure that
// it's safe to re-use _ANY_ BeaconStateCache, this option is disabled by default and only used in tests.
const cachedState =
isCachedBeaconState(anchorState) && opts.skipCreateStateCacheIfAvailable
? anchorState
: createCachedBeaconState(anchorState, {
config,
pubkey2index: new PubkeyIndexMap(),
index2pubkey: [],
});

// Persist single global instance of state caches
this.pubkey2index = cachedState.epochCtx.pubkey2index;
this.index2pubkey = cachedState.epochCtx.index2pubkey;

const {checkpoint} = computeAnchorCheckpoint(config, anchorState);
stateCache.add(cachedState);
checkpointStateCache.add(checkpoint, cachedState);
Expand Down
1 change: 1 addition & 0 deletions packages/beacon-node/src/chain/options.ts
Expand Up @@ -13,6 +13,7 @@ export type IChainOptions = BlockProcessOpts &
blsVerifyAllMultiThread?: boolean;
persistInvalidSszObjects?: boolean;
persistInvalidSszObjectsDir?: string;
skipCreateStateCacheIfAvailable?: boolean;
defaultFeeRecipient: string;
};

Expand Down
Expand Up @@ -83,6 +83,7 @@ describe("verify+import blocks - range sync perf test", () => {
safeSlotsToImportOptimistically: SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY,
disableArchiveOnCheckpoint: true,
defaultFeeRecipient: defaultValidatorOptions.defaultFeeRecipient,
skipCreateStateCacheIfAvailable: true,
},
{
config: state.config,
Expand Down
9 changes: 9 additions & 0 deletions packages/state-transition/src/cache/stateCache.ts
Expand Up @@ -158,3 +158,12 @@ export function getCachedBeaconState<T extends BeaconStateAllForks>(

return cachedState;
}

/**
* Typeguard to check if a state contains a BeaconStateCache
*/
export function isCachedBeaconState<T extends BeaconStateAllForks>(
state: T | (T & BeaconStateCache)
): state is T & BeaconStateCache {
return (state as T & BeaconStateCache).epochCtx !== undefined;
}
2 changes: 1 addition & 1 deletion packages/state-transition/src/index.ts
Expand Up @@ -17,7 +17,7 @@ export {
} from "./types.js";

// Main state caches
export {createCachedBeaconState, BeaconStateCache} from "./cache/stateCache.js";
export {createCachedBeaconState, BeaconStateCache, isCachedBeaconState} from "./cache/stateCache.js";
export {EpochContext, EpochContextImmutableData, createEmptyEpochContextImmutableData} from "./cache/epochContext.js";
export {EpochProcess, beforeProcessEpoch} from "./cache/epochProcess.js";

Expand Down

0 comments on commit eccde2f

Please sign in to comment.