11d80a6a38
## Issue Addressed NA ## Proposed Changes - Uses a `Vec` in `SingleEpochParticipationCache` rather than `HashMap` to speed up processing times at the cost of memory usage. - Cache the result of `integer_sqrt` rather than recomputing for each validator. - Cache `state.previous_epoch` rather than recomputing it for each validator. ### Benchmarks Benchmarks on a recent mainnet state using #3252 to get timing. #### Without this PR ``` lcli skip-slots --state-path /tmp/state-0x3cdc.ssz --partial-state-advance --slots 32 --state-root 0x3cdc33cd02713d8d6cc33a6dbe2d3a5bf9af1d357de0d175a403496486ff845e --runs 10 [2022-06-09T08:21:02Z INFO lcli::skip_slots] Using mainnet spec [2022-06-09T08:21:02Z INFO lcli::skip_slots] Advancing 32 slots [2022-06-09T08:21:02Z INFO lcli::skip_slots] Doing 10 runs [2022-06-09T08:21:02Z INFO lcli::skip_slots] State path: "/tmp/state-0x3cdc.ssz" SSZ decoding /tmp/state-0x3cdc.ssz: 43ms [2022-06-09T08:21:03Z INFO lcli::skip_slots] Run 0: 245.718794ms [2022-06-09T08:21:03Z INFO lcli::skip_slots] Run 1: 245.364782ms [2022-06-09T08:21:03Z INFO lcli::skip_slots] Run 2: 255.866179ms [2022-06-09T08:21:04Z INFO lcli::skip_slots] Run 3: 243.838909ms [2022-06-09T08:21:04Z INFO lcli::skip_slots] Run 4: 250.431425ms [2022-06-09T08:21:04Z INFO lcli::skip_slots] Run 5: 248.68765ms [2022-06-09T08:21:04Z INFO lcli::skip_slots] Run 6: 262.051113ms [2022-06-09T08:21:05Z INFO lcli::skip_slots] Run 7: 264.293967ms [2022-06-09T08:21:05Z INFO lcli::skip_slots] Run 8: 293.202007ms [2022-06-09T08:21:05Z INFO lcli::skip_slots] Run 9: 264.552017ms ``` #### With this PR: ``` lcli skip-slots --state-path /tmp/state-0x3cdc.ssz --partial-state-advance --slots 32 --state-root 0x3cdc33cd02713d8d6cc33a6dbe2d3a5bf9af1d357de0d175a403496486ff845e --runs 10 [2022-06-09T08:57:59Z INFO lcli::skip_slots] Run 0: 73.898678ms [2022-06-09T08:57:59Z INFO lcli::skip_slots] Run 1: 75.536978ms [2022-06-09T08:57:59Z INFO lcli::skip_slots] Run 2: 75.176104ms [2022-06-09T08:57:59Z INFO lcli::skip_slots] Run 3: 76.460828ms [2022-06-09T08:57:59Z INFO lcli::skip_slots] Run 4: 75.904195ms [2022-06-09T08:58:00Z INFO lcli::skip_slots] Run 5: 75.53077ms [2022-06-09T08:58:00Z INFO lcli::skip_slots] Run 6: 74.745572ms [2022-06-09T08:58:00Z INFO lcli::skip_slots] Run 7: 75.823489ms [2022-06-09T08:58:00Z INFO lcli::skip_slots] Run 8: 74.892055ms [2022-06-09T08:58:00Z INFO lcli::skip_slots] Run 9: 76.333569ms ``` ## Additional Info NA
51 lines
1.5 KiB
Rust
51 lines
1.5 KiB
Rust
use integer_sqrt::IntegerSquareRoot;
|
|
use safe_arith::{ArithError, SafeArith};
|
|
use types::*;
|
|
|
|
/// 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
|
|
}
|
|
}
|
|
|
|
/// Returns the base reward for some validator.
|
|
///
|
|
/// 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.
|
|
///
|
|
/// Spec v1.1.0
|
|
pub fn get_base_reward<T: EthSpec>(
|
|
state: &BeaconState<T>,
|
|
index: usize,
|
|
base_reward_per_increment: BaseRewardPerIncrement,
|
|
spec: &ChainSpec,
|
|
) -> Result<u64, Error> {
|
|
state
|
|
.get_effective_balance(index)?
|
|
.safe_div(spec.effective_balance_increment)?
|
|
.safe_mul(base_reward_per_increment.as_u64())
|
|
.map_err(Into::into)
|
|
}
|
|
|
|
/// Returns the base reward for some validator.
|
|
///
|
|
/// Spec v1.1.0
|
|
fn get_base_reward_per_increment(
|
|
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())
|
|
}
|