/// <summary> /// Initiate the exit of the validator with index ``index``. /// </summary> public void InitiateValidatorExit(BeaconState state, ValidatorIndex index) { // Return if validator already initiated exit Validator validator = state.Validators[(int)index]; if (validator.ExitEpoch != _chainConstants.FarFutureEpoch) { return; } // Compute exit queue epoch IEnumerable <Epoch> exitEpochs = state.Validators .Where(x => x.ExitEpoch != _chainConstants.FarFutureEpoch) .Select(x => x.ExitEpoch); Epoch maxExitEpoch = exitEpochs.DefaultIfEmpty().Max(); Epoch currentEpoch = _beaconStateAccessor.GetCurrentEpoch(state); Epoch activationExitEpoch = _beaconChainUtility.ComputeActivationExitEpoch(currentEpoch); Epoch exitQueueEpoch = Epoch.Max(maxExitEpoch, activationExitEpoch); int exitQueueChurn = state.Validators.Count(x => x.ExitEpoch == exitQueueEpoch); ulong validatorChurnLimit = _beaconStateAccessor.GetValidatorChurnLimit(state); if ((ulong)exitQueueChurn >= validatorChurnLimit) { exitQueueEpoch += new Epoch(1); } // Set validator exit epoch and withdrawable epoch validator.SetExitEpoch(exitQueueEpoch); Epoch withdrawableEpoch = validator.ExitEpoch + _timeParameterOptions.CurrentValue.MinimumValidatorWithdrawabilityDelay; validator.SetWithdrawableEpoch(withdrawableEpoch); }