diff --git a/beacon_node/beacon_chain/src/beacon_block_reward.rs b/beacon_node/beacon_chain/src/beacon_block_reward.rs index ac4ed2ab67..88686696ed 100644 --- a/beacon_node/beacon_chain/src/beacon_block_reward.rs +++ b/beacon_node/beacon_chain/src/beacon_block_reward.rs @@ -135,7 +135,7 @@ impl BeaconChain { state .get_validator(proposer_slashing.proposer_index() as usize)? .effective_balance - .safe_div(self.spec.whistleblower_reward_quotient_for_state(state))?, + .safe_div(state.get_whistleblower_reward_quotient(&self.spec))?, )?; } @@ -157,7 +157,7 @@ impl BeaconChain { state .get_validator(attester_index as usize)? .effective_balance - .safe_div(self.spec.whistleblower_reward_quotient_for_state(state))?, + .safe_div(state.get_whistleblower_reward_quotient(&self.spec))?, )?; } } diff --git a/beacon_node/beacon_chain/tests/rewards.rs b/beacon_node/beacon_chain/tests/rewards.rs index ee9cf511ea..94ad97c963 100644 --- a/beacon_node/beacon_chain/tests/rewards.rs +++ b/beacon_node/beacon_chain/tests/rewards.rs @@ -269,16 +269,16 @@ async fn test_rewards_electra_slashings() { harness.add_attester_slashing(vec![0]).unwrap(); let slashed_balance_1 = initial_balances.get_mut(0).unwrap(); let validator_1_effective_balance = state.get_effective_balance(0).unwrap(); - let delta_1 = validator_1_effective_balance - / harness.spec.min_slashing_penalty_quotient_for_state(&state); + let delta_1 = + validator_1_effective_balance / state.get_min_slashing_penalty_quotient(&harness.spec); *slashed_balance_1 -= delta_1; // add a proposer slashing and calculating slashing penalties harness.add_proposer_slashing(1).unwrap(); let slashed_balance_2 = initial_balances.get_mut(1).unwrap(); let validator_2_effective_balance = state.get_effective_balance(1).unwrap(); - let delta_2 = validator_2_effective_balance - / harness.spec.min_slashing_penalty_quotient_for_state(&state); + let delta_2 = + validator_2_effective_balance / state.get_min_slashing_penalty_quotient(&harness.spec); *slashed_balance_2 -= delta_2; check_all_electra_rewards(&harness, initial_balances).await; diff --git a/consensus/state_processing/src/common/slash_validator.rs b/consensus/state_processing/src/common/slash_validator.rs index 01c1855fb1..ac7379abd9 100644 --- a/consensus/state_processing/src/common/slash_validator.rs +++ b/consensus/state_processing/src/common/slash_validator.rs @@ -42,8 +42,7 @@ pub fn slash_validator( decrease_balance( state, slashed_index, - validator_effective_balance - .safe_div(spec.min_slashing_penalty_quotient_for_state(state))?, + validator_effective_balance.safe_div(state.get_min_slashing_penalty_quotient(spec))?, )?; update_progressive_balances_on_slashing(state, slashed_index, validator_effective_balance)?; @@ -54,8 +53,8 @@ pub fn slash_validator( // Apply proposer and whistleblower rewards let proposer_index = ctxt.get_proposer_index(state, spec)? as usize; let whistleblower_index = opt_whistleblower_index.unwrap_or(proposer_index); - let whistleblower_reward = validator_effective_balance - .safe_div(spec.whistleblower_reward_quotient_for_state(state))?; + let whistleblower_reward = + validator_effective_balance.safe_div(state.get_whistleblower_reward_quotient(spec))?; let proposer_reward = if state.fork_name_unchecked().altair_enabled() { whistleblower_reward .safe_mul(PROPOSER_WEIGHT)? diff --git a/consensus/state_processing/src/per_epoch_processing/single_pass.rs b/consensus/state_processing/src/per_epoch_processing/single_pass.rs index 914e025f2f..3e07803aa6 100644 --- a/consensus/state_processing/src/per_epoch_processing/single_pass.rs +++ b/consensus/state_processing/src/per_epoch_processing/single_pass.rs @@ -886,7 +886,7 @@ impl SlashingsContext { ) -> Result { let sum_slashings = state.get_all_slashings().iter().copied().safe_sum()?; let adjusted_total_slashing_balance = min( - sum_slashings.safe_mul(spec.proportional_slashing_multiplier_for_state(state))?, + sum_slashings.safe_mul(state.get_proportional_slashing_multiplier(spec))?, state_ctxt.total_active_balance, ); diff --git a/consensus/state_processing/src/per_epoch_processing/slashings.rs b/consensus/state_processing/src/per_epoch_processing/slashings.rs index 6008276d15..cf5e82663c 100644 --- a/consensus/state_processing/src/per_epoch_processing/slashings.rs +++ b/consensus/state_processing/src/per_epoch_processing/slashings.rs @@ -17,7 +17,7 @@ pub fn process_slashings( let sum_slashings = state.get_all_slashings().iter().copied().safe_sum()?; let adjusted_total_slashing_balance = std::cmp::min( - sum_slashings.safe_mul(spec.proportional_slashing_multiplier_for_state(state))?, + sum_slashings.safe_mul(state.get_proportional_slashing_multiplier(spec))?, total_balance, ); diff --git a/consensus/types/src/core/chain_spec.rs b/consensus/types/src/core/chain_spec.rs index da3f9b90cc..f47b4b4c91 100644 --- a/consensus/types/src/core/chain_spec.rs +++ b/consensus/types/src/core/chain_spec.rs @@ -19,7 +19,6 @@ use crate::{ data::{BlobIdentifier, DataColumnSubnetId, DataColumnsByRootIdentifier}, execution::ExecutionBlockHash, fork::{Fork, ForkData, ForkName}, - state::BeaconState, }; /// Each of the BLS signature domains. @@ -418,51 +417,6 @@ impl ChainSpec { } } - /// For a given `BeaconState`, return the proportional slashing multiplier associated with its variant. - pub fn proportional_slashing_multiplier_for_state( - &self, - state: &BeaconState, - ) -> u64 { - let fork_name = state.fork_name_unchecked(); - if fork_name >= ForkName::Bellatrix { - self.proportional_slashing_multiplier_bellatrix - } else if fork_name >= ForkName::Altair { - self.proportional_slashing_multiplier_altair - } else { - self.proportional_slashing_multiplier - } - } - - /// For a given `BeaconState`, return the minimum slashing penalty quotient associated with its variant. - pub fn min_slashing_penalty_quotient_for_state( - &self, - state: &BeaconState, - ) -> u64 { - let fork_name = state.fork_name_unchecked(); - if fork_name.electra_enabled() { - self.min_slashing_penalty_quotient_electra - } else if fork_name >= ForkName::Bellatrix { - self.min_slashing_penalty_quotient_bellatrix - } else if fork_name >= ForkName::Altair { - self.min_slashing_penalty_quotient_altair - } else { - self.min_slashing_penalty_quotient - } - } - - /// For a given `BeaconState`, return the whistleblower reward quotient associated with its variant. - pub fn whistleblower_reward_quotient_for_state( - &self, - state: &BeaconState, - ) -> u64 { - let fork_name = state.fork_name_unchecked(); - if fork_name.electra_enabled() { - self.whistleblower_reward_quotient_electra - } else { - self.whistleblower_reward_quotient - } - } - pub fn max_effective_balance_for_fork(&self, fork_name: ForkName) -> u64 { if fork_name.electra_enabled() { self.max_effective_balance_electra diff --git a/consensus/types/src/core/eth_spec.rs b/consensus/types/src/core/eth_spec.rs index 74795fdfc3..2983fc2c62 100644 --- a/consensus/types/src/core/eth_spec.rs +++ b/consensus/types/src/core/eth_spec.rs @@ -3,7 +3,7 @@ use std::{ str::FromStr, }; -use safe_arith::SafeArith; +use safe_arith::{ArithError, SafeArith}; use serde::{Deserialize, Serialize}; use typenum::{ U0, U1, U2, U4, U8, U16, U17, U32, U64, U128, U256, U512, U625, U1024, U2048, U4096, U8192, @@ -11,10 +11,7 @@ use typenum::{ U1099511627776, UInt, Unsigned, bit::B0, }; -use crate::{ - core::{ChainSpec, Epoch}, - state::BeaconStateError, -}; +use crate::core::{ChainSpec, Epoch}; type U5000 = UInt, B0>, B0>; // 625 * 8 = 5000 @@ -196,7 +193,7 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + fn get_committee_count_per_slot( active_validator_count: usize, spec: &ChainSpec, - ) -> Result { + ) -> Result { Self::get_committee_count_per_slot_with( active_validator_count, spec.max_committees_per_slot, @@ -208,7 +205,7 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + active_validator_count: usize, max_committees_per_slot: usize, target_committee_size: usize, - ) -> Result { + ) -> Result { let slots_per_epoch = Self::SlotsPerEpoch::to_usize(); Ok(std::cmp::max( diff --git a/consensus/types/src/state/beacon_state.rs b/consensus/types/src/state/beacon_state.rs index c1b6f0dc0c..f3e5ae411b 100644 --- a/consensus/types/src/state/beacon_state.rs +++ b/consensus/types/src/state/beacon_state.rs @@ -2528,6 +2528,42 @@ impl BeaconState { self.epoch_cache().get_base_reward(validator_index) } + /// Get the proportional slashing multiplier for the current fork. + pub fn get_proportional_slashing_multiplier(&self, spec: &ChainSpec) -> u64 { + let fork_name = self.fork_name_unchecked(); + if fork_name >= ForkName::Bellatrix { + spec.proportional_slashing_multiplier_bellatrix + } else if fork_name >= ForkName::Altair { + spec.proportional_slashing_multiplier_altair + } else { + spec.proportional_slashing_multiplier + } + } + + /// Get the minimum slashing penalty quotient for the current fork. + pub fn get_min_slashing_penalty_quotient(&self, spec: &ChainSpec) -> u64 { + let fork_name = self.fork_name_unchecked(); + if fork_name.electra_enabled() { + spec.min_slashing_penalty_quotient_electra + } else if fork_name >= ForkName::Bellatrix { + spec.min_slashing_penalty_quotient_bellatrix + } else if fork_name >= ForkName::Altair { + spec.min_slashing_penalty_quotient_altair + } else { + spec.min_slashing_penalty_quotient + } + } + + /// Get the whistleblower reward quotient for the current fork. + pub fn get_whistleblower_reward_quotient(&self, spec: &ChainSpec) -> u64 { + let fork_name = self.fork_name_unchecked(); + if fork_name.electra_enabled() { + spec.whistleblower_reward_quotient_electra + } else { + spec.whistleblower_reward_quotient + } + } + // ******* Electra accessors ******* /// Return the churn limit for the current epoch. diff --git a/consensus/types/src/state/committee_cache.rs b/consensus/types/src/state/committee_cache.rs index 15f6a4cd37..39e9011ef4 100644 --- a/consensus/types/src/state/committee_cache.rs +++ b/consensus/types/src/state/committee_cache.rs @@ -100,7 +100,8 @@ impl CommitteeCache { } let committees_per_slot = - E::get_committee_count_per_slot(active_validator_indices.len(), spec)? as u64; + E::get_committee_count_per_slot(active_validator_indices.len(), spec) + .map_err(BeaconStateError::ArithError)? as u64; let seed = state.get_seed(epoch, Domain::BeaconAttester, spec)?;