diff --git a/beacon-chain/core/epoch/epoch_processing.go b/beacon-chain/core/epoch/epoch_processing.go index 4444406e13..d630254d2b 100644 --- a/beacon-chain/core/epoch/epoch_processing.go +++ b/beacon-chain/core/epoch/epoch_processing.go @@ -147,10 +147,11 @@ func ProcessRegistryUpdates(state *stateTrie.BeaconState) (*stateTrie.BeaconStat // def process_slashings(state: BeaconState) -> None: // epoch = get_current_epoch(state) // total_balance = get_total_active_balance(state) +// adjusted_total_slashing_balance = min(sum(state.slashings) * PROPORTIONAL_SLASHING_MULTIPLIER, total_balance) // for index, validator in enumerate(state.validators): // if validator.slashed and epoch + EPOCHS_PER_SLASHINGS_VECTOR // 2 == validator.withdrawable_epoch: // increment = EFFECTIVE_BALANCE_INCREMENT # Factored out from penalty numerator to avoid uint64 overflow -// penalty_numerator = validator.effective_balance // increment * min(sum(state.slashings) * 3, total_balance) +// penalty_numerator = validator.effective_balance // increment * adjusted_total_slashing_balance // penalty = penalty_numerator // total_balance * increment // decrease_balance(state, ValidatorIndex(index), penalty) func ProcessSlashings(state *stateTrie.BeaconState) (*stateTrie.BeaconState, error) { @@ -173,10 +174,10 @@ func ProcessSlashings(state *stateTrie.BeaconState) (*stateTrie.BeaconState, err // a callback is used here to apply the following actions to all validators // below equally. increment := params.BeaconConfig().EffectiveBalanceIncrement + minSlashing := mathutil.Min(totalSlashing*params.BeaconConfig().ProportionalSlashingMultiplier, totalBalance) err = state.ApplyToEveryValidator(func(idx int, val *ethpb.Validator) (bool, error) { correctEpoch := (currentEpoch + exitLength/2) == val.WithdrawableEpoch if val.Slashed && correctEpoch { - minSlashing := mathutil.Min(totalSlashing*3, totalBalance) penaltyNumerator := val.EffectiveBalance / increment * minSlashing penalty := penaltyNumerator / totalBalance * increment if err := helpers.DecreaseBalance(state, uint64(idx), penalty); err != nil { diff --git a/shared/params/config.go b/shared/params/config.go index b68811dc59..2eb0274c12 100644 --- a/shared/params/config.go +++ b/shared/params/config.go @@ -64,11 +64,12 @@ type BeaconChainConfig struct { ValidatorRegistryLimit uint64 `yaml:"VALIDATOR_REGISTRY_LIMIT"` // ValidatorRegistryLimit defines the upper bound of validators can participate in eth2. // Reward and penalty quotients constants. - BaseRewardFactor uint64 `yaml:"BASE_REWARD_FACTOR"` // BaseRewardFactor is used to calculate validator per-slot interest rate. - WhistleBlowerRewardQuotient uint64 `yaml:"WHISTLEBLOWER_REWARD_QUOTIENT"` // WhistleBlowerRewardQuotient is used to calculate whistle blower reward. - ProposerRewardQuotient uint64 `yaml:"PROPOSER_REWARD_QUOTIENT"` // ProposerRewardQuotient is used to calculate the reward for proposers. - InactivityPenaltyQuotient uint64 `yaml:"INACTIVITY_PENALTY_QUOTIENT"` // InactivityPenaltyQuotient is used to calculate the penalty for a validator that is offline. - MinSlashingPenaltyQuotient uint64 `yaml:"MIN_SLASHING_PENALTY_QUOTIENT"` // MinSlashingPenaltyQuotient is used to calculate the minimum penalty to prevent DoS attacks. + BaseRewardFactor uint64 `yaml:"BASE_REWARD_FACTOR"` // BaseRewardFactor is used to calculate validator per-slot interest rate. + WhistleBlowerRewardQuotient uint64 `yaml:"WHISTLEBLOWER_REWARD_QUOTIENT"` // WhistleBlowerRewardQuotient is used to calculate whistle blower reward. + ProposerRewardQuotient uint64 `yaml:"PROPOSER_REWARD_QUOTIENT"` // ProposerRewardQuotient is used to calculate the reward for proposers. + InactivityPenaltyQuotient uint64 `yaml:"INACTIVITY_PENALTY_QUOTIENT"` // InactivityPenaltyQuotient is used to calculate the penalty for a validator that is offline. + MinSlashingPenaltyQuotient uint64 `yaml:"MIN_SLASHING_PENALTY_QUOTIENT"` // MinSlashingPenaltyQuotient is used to calculate the minimum penalty to prevent DoS attacks. + ProportionalSlashingMultiplier uint64 `yaml:"PROPORTIONAL_SLASHING_MULTIPLIER"` // ProportionalSlashingMultiplier is used as a multiplier on slashed penalties. // Max operations per block constants. MaxProposerSlashings uint64 `yaml:"MAX_PROPOSER_SLASHINGS"` // MaxProposerSlashings defines the maximum number of slashings of proposers possible in a block. diff --git a/shared/params/mainnet_config.go b/shared/params/mainnet_config.go index 0c7e23db11..2e447216b9 100644 --- a/shared/params/mainnet_config.go +++ b/shared/params/mainnet_config.go @@ -89,11 +89,12 @@ var mainnetBeaconConfig = &BeaconChainConfig{ ValidatorRegistryLimit: 1099511627776, // Reward and penalty quotients constants. - BaseRewardFactor: 64, - WhistleBlowerRewardQuotient: 512, - ProposerRewardQuotient: 8, - InactivityPenaltyQuotient: 1 << 24, - MinSlashingPenaltyQuotient: 32, + BaseRewardFactor: 64, + WhistleBlowerRewardQuotient: 512, + ProposerRewardQuotient: 8, + InactivityPenaltyQuotient: 1 << 24, + MinSlashingPenaltyQuotient: 32, + ProportionalSlashingMultiplier: 3, // Max operations per block constants. MaxProposerSlashings: 16, diff --git a/shared/params/minimal_config.go b/shared/params/minimal_config.go index 7672345658..2bd3473b98 100644 --- a/shared/params/minimal_config.go +++ b/shared/params/minimal_config.go @@ -58,6 +58,7 @@ func MinimalSpecConfig() *BeaconChainConfig { minimalConfig.ProposerRewardQuotient = 8 minimalConfig.InactivityPenaltyQuotient = 1 << 24 minimalConfig.MinSlashingPenaltyQuotient = 32 + minimalConfig.ProportionalSlashingMultiplier = 3 // Max operations per block minimalConfig.MaxProposerSlashings = 16