From 7903820a428a4a5dcc01bc33b521dc5bc310ccdb Mon Sep 17 00:00:00 2001 From: harkamal Date: Mon, 18 Sep 2023 22:57:20 +0530 Subject: [PATCH] feat: implement eip7514 to limit the validatior activation limit deneb onwards --- .../config/src/chainConfig/presets/mainnet.ts | 1 + .../config/src/chainConfig/presets/minimal.ts | 1 + packages/config/src/chainConfig/types.ts | 2 ++ .../state-transition/src/cache/epochCache.ts | 16 +++++++++++++++- .../src/epoch/processRegistryUpdates.ts | 3 ++- packages/state-transition/src/util/validator.ts | 5 +++++ packages/validator/src/util/params.ts | 1 + 7 files changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/config/src/chainConfig/presets/mainnet.ts b/packages/config/src/chainConfig/presets/mainnet.ts index dcce1d82cf9b..ac9c14efd7cd 100644 --- a/packages/config/src/chainConfig/presets/mainnet.ts +++ b/packages/config/src/chainConfig/presets/mainnet.ts @@ -70,6 +70,7 @@ export const chainConfig: ChainConfig = { MIN_PER_EPOCH_CHURN_LIMIT: 4, // 2**16 (= 65,536) CHURN_LIMIT_QUOTIENT: 65536, + MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8, PROPOSER_SCORE_BOOST: 40, // Deposit contract diff --git a/packages/config/src/chainConfig/presets/minimal.ts b/packages/config/src/chainConfig/presets/minimal.ts index fc72cbff72de..57c4f8430777 100644 --- a/packages/config/src/chainConfig/presets/minimal.ts +++ b/packages/config/src/chainConfig/presets/minimal.ts @@ -68,6 +68,7 @@ export const chainConfig: ChainConfig = { MIN_PER_EPOCH_CHURN_LIMIT: 4, // [customized] scale queue churn at much lower validator counts for testing CHURN_LIMIT_QUOTIENT: 32, + MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8, PROPOSER_SCORE_BOOST: 40, // Deposit contract diff --git a/packages/config/src/chainConfig/types.ts b/packages/config/src/chainConfig/types.ts index b2568d6fba57..aec0ca64e0df 100644 --- a/packages/config/src/chainConfig/types.ts +++ b/packages/config/src/chainConfig/types.ts @@ -54,6 +54,7 @@ export type ChainConfig = { EJECTION_BALANCE: number; MIN_PER_EPOCH_CHURN_LIMIT: number; CHURN_LIMIT_QUOTIENT: number; + MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: number; // Proposer boost PROPOSER_SCORE_BOOST: number; @@ -106,6 +107,7 @@ export const chainConfigTypes: SpecTypes = { EJECTION_BALANCE: "number", MIN_PER_EPOCH_CHURN_LIMIT: "number", CHURN_LIMIT_QUOTIENT: "number", + MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: "number", // Proposer boost PROPOSER_SCORE_BOOST: "number", diff --git a/packages/state-transition/src/cache/epochCache.ts b/packages/state-transition/src/cache/epochCache.ts index aeefc4769aca..9f2e9a687db8 100644 --- a/packages/state-transition/src/cache/epochCache.ts +++ b/packages/state-transition/src/cache/epochCache.ts @@ -145,6 +145,10 @@ export class EpochCache { * change through the epoch. It's used in initiateValidatorExit(). Must be update after changing active indexes. */ churnLimit: number; + /** + * Modified ("limited") churn limit as per the fork dependent activation of EIP-7514 + */ + activationChurnLimit: number; /** * Closest epoch with available churn for validators to exit at. May be updated every block as validators are * initiateValidatorExit(). This value may vary on each fork of the state. @@ -213,6 +217,7 @@ export class EpochCache { epoch: Epoch; syncPeriod: SyncPeriod; }) { + this.epoch = data.epoch; this.config = data.config; this.pubkey2index = data.pubkey2index; this.index2pubkey = data.index2pubkey; @@ -227,14 +232,19 @@ export class EpochCache { this.syncProposerReward = data.syncProposerReward; this.baseRewardPerIncrement = data.baseRewardPerIncrement; this.totalActiveBalanceIncrements = data.totalActiveBalanceIncrements; + this.churnLimit = data.churnLimit; + this.activationChurnLimit = + this.epoch >= this.config.DENEB_FORK_EPOCH + ? Math.min(this.config.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT, this.churnLimit) + : this.churnLimit; + this.exitQueueEpoch = data.exitQueueEpoch; this.exitQueueChurn = data.exitQueueChurn; this.currentTargetUnslashedBalanceIncrements = data.currentTargetUnslashedBalanceIncrements; this.previousTargetUnslashedBalanceIncrements = data.previousTargetUnslashedBalanceIncrements; this.currentSyncCommitteeIndexed = data.currentSyncCommitteeIndexed; this.nextSyncCommitteeIndexed = data.nextSyncCommitteeIndexed; - this.epoch = data.epoch; this.syncPeriod = data.syncPeriod; } @@ -503,6 +513,10 @@ export class EpochCache { // the first block of the epoch process_block() call. So churnLimit must be computed at the end of the before epoch // transition and the result is valid until the end of the next epoch transition this.churnLimit = getChurnLimit(this.config, this.currentShuffling.activeIndices.length); + this.activationChurnLimit = + this.config.DENEB_FORK_EPOCH >= this.epoch + ? Math.min(this.config.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT, this.churnLimit) + : this.churnLimit; // Maybe advance exitQueueEpoch at the end of the epoch if there haven't been any exists for a while const exitQueueEpoch = computeActivationExitEpoch(currEpoch); diff --git a/packages/state-transition/src/epoch/processRegistryUpdates.ts b/packages/state-transition/src/epoch/processRegistryUpdates.ts index 831b3cd80550..c28f100366d2 100644 --- a/packages/state-transition/src/epoch/processRegistryUpdates.ts +++ b/packages/state-transition/src/epoch/processRegistryUpdates.ts @@ -38,7 +38,8 @@ export function processRegistryUpdates(state: CachedBeaconStateAllForks, cache: const finalityEpoch = state.finalizedCheckpoint.epoch; // dequeue validators for activation up to churn limit - for (const index of cache.indicesEligibleForActivation.slice(0, epochCtx.churnLimit)) { + // - use fork dependent churn limit for activation (EIP-7514) + for (const index of cache.indicesEligibleForActivation.slice(0, epochCtx.activationChurnLimit)) { const validator = validators.get(index); // placement in queue is finalized if (validator.activationEligibilityEpoch > finalityEpoch) { diff --git a/packages/state-transition/src/util/validator.ts b/packages/state-transition/src/util/validator.ts index 958fa0a157af..897791ebd3c9 100644 --- a/packages/state-transition/src/util/validator.ts +++ b/packages/state-transition/src/util/validator.ts @@ -38,3 +38,8 @@ export function getActiveValidatorIndices(state: BeaconStateAllForks, epoch: Epo export function getChurnLimit(config: ChainForkConfig, activeValidatorCount: number): number { return Math.max(config.MIN_PER_EPOCH_CHURN_LIMIT, intDiv(activeValidatorCount, config.CHURN_LIMIT_QUOTIENT)); } + +// Just for completeness sake, epochCtx directly uses churnLimit to get the final churn limit +export function getctivationChurnLimit(config: ChainForkConfig, activeValidatorCount: number): number { + return Math.min(config.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT, getChurnLimit(config, activeValidatorCount)); +} diff --git a/packages/validator/src/util/params.ts b/packages/validator/src/util/params.ts index 61034c133028..db69c15ff306 100644 --- a/packages/validator/src/util/params.ts +++ b/packages/validator/src/util/params.ts @@ -119,6 +119,7 @@ function getSpecCriticalParams(localConfig: ChainConfig): Record