Beispiel #1
0
        /// <summary>
        /// Initiate the exit of the validator with index ``index``.
        /// </summary>
        public void InitiateValidatorExit(BeaconState state, ValidatorIndex index)
        {
            // Return if validator already initiated exit
            var validator = state.Validators[(int)(ulong)index];

            if (validator.ExitEpoch != _chainConstants.FarFutureEpoch)
            {
                return;
            }

            // Compute exit queue epoch
            var exitEpochs = state.Validators
                             .Where(x => x.ExitEpoch != _chainConstants.FarFutureEpoch)
                             .Select(x => x.ExitEpoch);
            var maxExitEpoch        = exitEpochs.DefaultIfEmpty().Max();
            var currentEpoch        = _beaconStateAccessor.GetCurrentEpoch(state);
            var activationExitEpoch = _beaconChainUtility.ComputeActivationExitEpoch(currentEpoch);
            var exitQueueEpoch      = Epoch.Max(maxExitEpoch, activationExitEpoch);
            var exitQueueChurn      = state.Validators.Where(x => x.ExitEpoch == exitQueueEpoch).Count();
            var validatorChurnLimit = _beaconStateAccessor.GetValidatorChurnLimit(state);

            if ((ulong)exitQueueChurn >= validatorChurnLimit)
            {
                exitQueueEpoch += new Epoch(1);
            }

            // Set validator exit epoch and withdrawable epoch
            validator.SetExitEpoch(exitQueueEpoch);
            var withdrawableEpoch = validator.ExitEpoch + _timeParameterOptions.CurrentValue.MinimumValidatorWithdrawabilityDelay;

            validator.SetWithdrawableEpoch(withdrawableEpoch);
        }
        public void ProcessRegistryUpdates(BeaconState state)
        {
            _logger.LogInformation(Event.ProcessRegistryUpdates, "Process epoch registry updates state {BeaconState}", state);

            var gweiValues = _gweiValueOptions.CurrentValue;

            // Process activation eligibility and ejections
            var currentEpoch = _beaconStateAccessor.GetCurrentEpoch(state);

            for (var index = 0; index < state.Validators.Count; index++)
            {
                var validator = state.Validators[index];
                if (validator.ActivationEligibilityEpoch == _chainConstants.FarFutureEpoch &&
                    validator.EffectiveBalance == gweiValues.MaximumEffectiveBalance)
                {
                    validator.SetEligible(currentEpoch);
                }

                var isActive = _beaconChainUtility.IsActiveValidator(validator, currentEpoch);
                if (isActive && validator.EffectiveBalance <= gweiValues.EjectionBalance)
                {
                    _beaconStateMutator.InitiateValidatorExit(state, new ValidatorIndex((ulong)index));
                }
            }

            // Queue validators eligible for activation and not dequeued for activation prior to finalized epoch
            var activationExitEpoch = _beaconChainUtility.ComputeActivationExitEpoch(state.FinalizedCheckpoint.Epoch);

            var activationQueue = state.Validators
                                  .Select((validator, index) => new { index, validator })
                                  .Where(x => x.validator.ActivationEligibilityEpoch != _chainConstants.FarFutureEpoch &&
                                         x.validator.ActivationEpoch >= activationExitEpoch)
                                  .OrderBy(x => x.validator.ActivationEligibilityEpoch)
                                  .Select(x => x.index);

            // Dequeued validators for activation up to churn limit (without resetting activation epoch)
            var validatorChurnLimit = _beaconStateAccessor.GetValidatorChurnLimit(state);
            var activationEpoch     = _beaconChainUtility.ComputeActivationExitEpoch(currentEpoch);

            foreach (var index in activationQueue.Take((int)validatorChurnLimit))
            {
                var validator = state.Validators[index];
                if (validator.ActivationEpoch == _chainConstants.FarFutureEpoch)
                {
                    validator.SetActive(activationEpoch);
                }
            }
        }