2021-07-09 06:15:32 +00:00
|
|
|
use integer_sqrt::IntegerSquareRoot;
|
|
|
|
use safe_arith::{ArithError, SafeArith};
|
|
|
|
use types::*;
|
|
|
|
|
2022-06-10 04:29:28 +00:00
|
|
|
/// This type exists to avoid confusing `total_active_balance` with `base_reward_per_increment`,
|
|
|
|
/// since they are used in close proximity and the same type (`u64`).
|
|
|
|
#[derive(Copy, Clone)]
|
|
|
|
pub struct BaseRewardPerIncrement(u64);
|
|
|
|
|
|
|
|
impl BaseRewardPerIncrement {
|
|
|
|
pub fn new(total_active_balance: u64, spec: &ChainSpec) -> Result<Self, ArithError> {
|
|
|
|
get_base_reward_per_increment(total_active_balance, spec).map(Self)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_u64(&self) -> u64 {
|
|
|
|
self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-09 06:15:32 +00:00
|
|
|
/// Returns the base reward for some validator.
|
|
|
|
///
|
2022-06-10 04:29:28 +00:00
|
|
|
/// The function has a different interface to the spec since it accepts the
|
|
|
|
/// `base_reward_per_increment` without computing it each time. Avoiding the re computation has
|
|
|
|
/// shown to be a significant optimisation.
|
|
|
|
///
|
2021-07-09 06:15:32 +00:00
|
|
|
/// Spec v1.1.0
|
|
|
|
pub fn get_base_reward<T: EthSpec>(
|
|
|
|
state: &BeaconState<T>,
|
|
|
|
index: usize,
|
2022-06-10 04:29:28 +00:00
|
|
|
base_reward_per_increment: BaseRewardPerIncrement,
|
2021-07-09 06:15:32 +00:00
|
|
|
spec: &ChainSpec,
|
|
|
|
) -> Result<u64, Error> {
|
|
|
|
state
|
|
|
|
.get_effective_balance(index)?
|
|
|
|
.safe_div(spec.effective_balance_increment)?
|
2022-06-10 04:29:28 +00:00
|
|
|
.safe_mul(base_reward_per_increment.as_u64())
|
2021-07-09 06:15:32 +00:00
|
|
|
.map_err(Into::into)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the base reward for some validator.
|
|
|
|
///
|
|
|
|
/// Spec v1.1.0
|
2022-06-10 04:29:28 +00:00
|
|
|
fn get_base_reward_per_increment(
|
2021-07-09 06:15:32 +00:00
|
|
|
total_active_balance: u64,
|
|
|
|
spec: &ChainSpec,
|
|
|
|
) -> Result<u64, ArithError> {
|
|
|
|
spec.effective_balance_increment
|
|
|
|
.safe_mul(spec.base_reward_factor)?
|
|
|
|
.safe_div(total_active_balance.integer_sqrt())
|
|
|
|
}
|