/// <summary> /// Slash the validator with index ``slashed_index``. /// </summary> public void SlashValidator(BeaconState state, ValidatorIndex slashedIndex, ValidatorIndex?optionalWhistleblowerIndex) { RewardsAndPenalties rewardsAndPenalties = _rewardsAndPenaltiesOptions.CurrentValue; StateListLengths stateListLengths = _stateListLengthOptions.CurrentValue; Epoch epoch = _beaconStateAccessor.GetCurrentEpoch(state); InitiateValidatorExit(state, slashedIndex); Validator validator = state.Validators[(int)slashedIndex]; validator.SetSlashed(); Epoch slashedWithdrawableEpoch = (Epoch)(epoch + stateListLengths.EpochsPerSlashingsVector); Epoch withdrawableEpoch = Epoch.Max(validator.WithdrawableEpoch, slashedWithdrawableEpoch); validator.SetWithdrawableEpoch(withdrawableEpoch); Epoch slashingsIndex = (Epoch)(epoch % stateListLengths.EpochsPerSlashingsVector); state.SetSlashings(slashingsIndex, validator.EffectiveBalance); Gwei slashingPenalty = validator.EffectiveBalance / rewardsAndPenalties.MinimumSlashingPenaltyQuotient; DecreaseBalance(state, slashedIndex, slashingPenalty); // Apply proposer and whistleblower rewards ValidatorIndex proposerIndex = _beaconStateAccessor.GetBeaconProposerIndex(state); ValidatorIndex whistleblowerIndex = optionalWhistleblowerIndex ?? proposerIndex; Gwei whistleblowerReward = validator.EffectiveBalance / rewardsAndPenalties.WhistleblowerRewardQuotient; Gwei proposerReward = whistleblowerReward / rewardsAndPenalties.ProposerRewardQuotient; IncreaseBalance(state, proposerIndex, proposerReward); IncreaseBalance(state, whistleblowerIndex, whistleblowerReward - proposerReward); }
public void ProcessFinalUpdates(BeaconState state) { _logger.LogInformation(Event.ProcessFinalUpdates, "Process epoch final updates state {BeaconState}", state); var timeParameters = _timeParameterOptions.CurrentValue; var gweiValues = _gweiValueOptions.CurrentValue; var stateListLengths = _stateListLengthOptions.CurrentValue; var currentEpoch = _beaconStateAccessor.GetCurrentEpoch(state); var nextEpoch = currentEpoch + new Epoch(1); // Reset eth1 data votes var nextSlot = state.Slot + new Slot(1); if (nextSlot % timeParameters.SlotsPerEth1VotingPeriod == Slot.Zero) { state.ClearEth1DataVotes(); } // Update effective balances with hysteresis var halfIncrement = gweiValues.EffectiveBalanceIncrement / 2; for (var index = 0; index < state.Validators.Count; index++) { var validator = state.Validators[index]; var balance = state.Balances[index]; if (balance < validator.EffectiveBalance || (validator.EffectiveBalance + (halfIncrement * 3)) < balance) { var roundedBalance = balance - (balance % gweiValues.EffectiveBalanceIncrement); var effectiveBalance = Gwei.Min(roundedBalance, gweiValues.MaximumEffectiveBalance); validator.SetEffectiveBalance(effectiveBalance); } } // Reset slashings var slashingsIndex = nextEpoch % stateListLengths.EpochsPerSlashingsVector; state.SetSlashings(slashingsIndex, Gwei.Zero); // Set randao mix var randaoIndex = nextEpoch % stateListLengths.EpochsPerHistoricalVector; var randaoMix = _beaconStateAccessor.GetRandaoMix(state, currentEpoch); state.SetRandaoMix(randaoIndex, randaoMix); // Set historical root accumulator var divisor = timeParameters.SlotsPerHistoricalRoot / timeParameters.SlotsPerEpoch; if ((ulong)nextEpoch % divisor == 0) { var historicalBatch = new HistoricalBatch(state.BlockRoots.ToArray(), state.StateRoots.ToArray()); var historicalRoot = historicalBatch.HashTreeRoot(); state.AddHistoricalRoot(historicalRoot); } // Rotate current/previous epoch attestations state.SetPreviousEpochAttestations(state.CurrentEpochAttestations); state.SetCurrentEpochAttestations(new PendingAttestation[0]); }
private void SlashValidators(IServiceProvider testServiceProvider, BeaconState state, IEnumerable <int> indices, IEnumerable <Epoch> outEpochs) { StateListLengths stateListLengths = testServiceProvider.GetService <IOptions <StateListLengths> >().Value; BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>(); BeaconStateMutator beaconStateMutator = testServiceProvider.GetService <BeaconStateMutator>(); Gwei totalSlashedBalance = Gwei.Zero; var items = indices.Zip(outEpochs, (index, outEpoch) => new { index, outEpoch }); foreach (var item in items) { Validator validator = state.Validators[item.index]; validator.SetSlashed(); beaconStateMutator.InitiateValidatorExit(state, new ValidatorIndex((ulong)item.index)); validator.SetWithdrawableEpoch(item.outEpoch); totalSlashedBalance += validator.EffectiveBalance; } Epoch currentEpoch = beaconStateAccessor.GetCurrentEpoch(state); Epoch slashingsIndex = (Epoch)(currentEpoch % stateListLengths.EpochsPerSlashingsVector); state.SetSlashings(slashingsIndex, totalSlashedBalance); }
/// <summary> /// Slash the validator with index ``slashed_index``. /// </summary> public void SlashValidator(BeaconState state, ValidatorIndex slashedIndex, ValidatorIndex whistleblowerIndex) { var rewardsAndPenalties = _rewardsAndPenaltiesOptions.CurrentValue; var stateListLengths = _stateListLengthOptions.CurrentValue; var epoch = _beaconStateAccessor.GetCurrentEpoch(state); InitiateValidatorExit(state, slashedIndex); var validator = state.Validators[(int)(ulong)slashedIndex]; validator.SetSlashed(); var slashedWithdrawableEpoch = epoch + stateListLengths.EpochsPerSlashingsVector; var withdrawableEpoch = Epoch.Max(validator.WithdrawableEpoch, slashedWithdrawableEpoch); validator.SetWithdrawableEpoch(withdrawableEpoch); var slashingsIndex = epoch % stateListLengths.EpochsPerSlashingsVector; state.SetSlashings(slashingsIndex, validator.EffectiveBalance); var slashingPenalty = validator.EffectiveBalance / rewardsAndPenalties.MinimumSlashingPenaltyQuotient; DecreaseBalance(state, slashedIndex, slashingPenalty); // Apply proposer and whistleblower rewards var proposerIndex = _beaconStateAccessor.GetBeaconProposerIndex(state); if (whistleblowerIndex == ValidatorIndex.None) { whistleblowerIndex = proposerIndex; } var whistleblowerReward = validator.EffectiveBalance / rewardsAndPenalties.WhistleblowerRewardQuotient; var proposerReward = whistleblowerReward / rewardsAndPenalties.ProposerRewardQuotient; IncreaseBalance(state, proposerIndex, proposerReward); IncreaseBalance(state, whistleblowerIndex, whistleblowerReward - proposerReward); }