Skip to content

Commit

Permalink
Update initiateValidatorExit
Browse files Browse the repository at this point in the history
  • Loading branch information
ensi321 committed Apr 30, 2024
1 parent 524f1dd commit 1553e6c
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 18 deletions.
36 changes: 22 additions & 14 deletions packages/state-transition/src/block/initiateValidatorExit.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {CompositeViewDU} from "@chainsafe/ssz";
import {FAR_FUTURE_EPOCH} from "@lodestar/params";
import {FAR_FUTURE_EPOCH, ForkSeq} from "@lodestar/params";
import {ssz} from "@lodestar/types";
import {CachedBeaconStateAllForks} from "../types.js";
import {CachedBeaconStateAllForks, CachedBeaconStateElectra} from "../types.js";
import { computeExitEpochAndUpdateChurn } from "../util/epoch.js";

/**
* Initiate the exit of the validator with index ``index``.
Expand All @@ -24,6 +25,7 @@ import {CachedBeaconStateAllForks} from "../types.js";
* Forcing consumers to pass the SubTree of `validator` directly mitigates this issue.
*/
export function initiateValidatorExit(
fork: ForkSeq,
state: CachedBeaconStateAllForks,
validator: CompositeViewDU<typeof ssz.phase0.Validator>
): void {
Expand All @@ -34,18 +36,24 @@ export function initiateValidatorExit(
return;
}

// Limits the number of validators that can exit on each epoch.
// Expects all state.validators to follow this rule, i.e. no validator.exitEpoch is greater than exitQueueEpoch.
// If there the churnLimit is reached at this current exitQueueEpoch, advance epoch and reset churn.
if (epochCtx.exitQueueChurn >= epochCtx.churnLimit) {
epochCtx.exitQueueEpoch += 1;
epochCtx.exitQueueChurn = 1; // = 1 to account for this validator with exitQueueEpoch
if (fork < ForkSeq.electra) {
// Limits the number of validators that can exit on each epoch.
// Expects all state.validators to follow this rule, i.e. no validator.exitEpoch is greater than exitQueueEpoch.
// If there the churnLimit is reached at this current exitQueueEpoch, advance epoch and reset churn.
if (epochCtx.exitQueueChurn >= epochCtx.churnLimit) {
epochCtx.exitQueueEpoch += 1;
epochCtx.exitQueueChurn = 1; // = 1 to account for this validator with exitQueueEpoch
} else {
// Add this validator to the current exitQueueEpoch churn
epochCtx.exitQueueChurn += 1;
}

// set validator exit epoch
validator.exitEpoch = epochCtx.exitQueueEpoch;
} else {
// Add this validator to the current exitQueueEpoch churn
epochCtx.exitQueueChurn += 1;
// set validator exit epoch
// Note we don't use epochCtx.exitQueueChurn and exitQueueEpoch anymore
validator.exitEpoch = computeExitEpochAndUpdateChurn(state as CachedBeaconStateElectra, BigInt(validator.effectiveBalance));
}

// set validator exit epoch and withdrawable epoch
validator.exitEpoch = epochCtx.exitQueueEpoch; // TODO Electra: calculate exit epoch
validator.withdrawableEpoch = epochCtx.exitQueueEpoch + config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY;
validator.withdrawableEpoch = validator.exitEpoch + config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
MIN_ACTIVATION_BALANCE,
PENDING_PARTIAL_WITHDRAWALS_LIMIT,
FULL_EXIT_REQUEST_AMOUNT,
ForkSeq,
} from "@lodestar/params";

import {CachedBeaconStateElectra} from "../types.js";
Expand Down Expand Up @@ -50,7 +51,7 @@ export function processExecutionLayerWithdrawRequest(
if (isFullExitRequest) {
// only exit validator if it has no pending withdrawals in the queue
if (pendingBalanceToWithdraw === 0) {
initiateValidatorExit(state, validator);
initiateValidatorExit(ForkSeq.electra, state, validator);
} else {
// Full request can't be fulfilled because still has pending withdrawals.
// TODO Electra: add log here
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function processVoluntaryExit(
}

const validator = state.validators.get(signedVoluntaryExit.message.validatorIndex);
initiateValidatorExit(state, validator);
initiateValidatorExit(fork, state, validator);
}

export function isValidVoluntaryExit(
Expand Down
2 changes: 1 addition & 1 deletion packages/state-transition/src/block/slashValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function slashValidator(
const validator = state.validators.get(slashedIndex);

// TODO: Bellatrix initiateValidatorExit validators.update() with the one below
initiateValidatorExit(state, validator);
initiateValidatorExit(fork, state, validator);

validator.slashed = true;
validator.withdrawableEpoch = Math.max(validator.withdrawableEpoch, epoch + EPOCHS_PER_SLASHINGS_VECTOR);
Expand Down
2 changes: 2 additions & 0 deletions packages/state-transition/src/cache/epochCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,15 @@ export class EpochCache {
* initiateValidatorExit(). This value may vary on each fork of the state.
*
* NOTE: Changes block to block
* NOTE: No longer used by initiateValidatorExit post-electra
*/
exitQueueEpoch: Epoch;
/**
* Number of validators initiating an exit at exitQueueEpoch. May be updated every block as validators are
* initiateValidatorExit(). This value may vary on each fork of the state.
*
* NOTE: Changes block to block
* NOTE: No longer used by initiateValidatorExit post-electra
*/
exitQueueChurn: number;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function processRegistryUpdates(
for (const index of cache.indicesToEject) {
// set validator exit epoch and withdrawable epoch
// TODO: Figure out a way to quickly set properties on the validators tree
initiateValidatorExit(state, validators.get(index));
initiateValidatorExit(fork, state, validators.get(index));
}

// TODO Electra: New logic to set validator.activation_epoch
Expand Down

0 comments on commit 1553e6c

Please sign in to comment.