mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 00:42:42 +00:00
Merge remote-tracking branch 'sigp/epoch-single-pass' into tree-states
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
use crate::{BeaconChain, BeaconChainError, BeaconChainTypes};
|
use crate::{BeaconChain, BeaconChainError, BeaconChainTypes};
|
||||||
use eth2::lighthouse::attestation_rewards::{IdealAttestationRewards, TotalAttestationRewards};
|
use eth2::lighthouse::attestation_rewards::{IdealAttestationRewards, TotalAttestationRewards};
|
||||||
use eth2::lighthouse::StandardAttestationRewards;
|
use eth2::lighthouse::StandardAttestationRewards;
|
||||||
use participation_cache::ParticipationCache;
|
|
||||||
use safe_arith::SafeArith;
|
use safe_arith::SafeArith;
|
||||||
use serde_utils::quoted_u64::Quoted;
|
use serde_utils::quoted_u64::Quoted;
|
||||||
use slog::debug;
|
use slog::debug;
|
||||||
@@ -10,7 +9,7 @@ use state_processing::per_epoch_processing::altair::{
|
|||||||
};
|
};
|
||||||
use state_processing::{
|
use state_processing::{
|
||||||
common::altair::BaseRewardPerIncrement,
|
common::altair::BaseRewardPerIncrement,
|
||||||
per_epoch_processing::altair::{participation_cache, rewards_and_penalties::get_flag_weight},
|
per_epoch_processing::altair::rewards_and_penalties::get_flag_weight,
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use store::consts::altair::{
|
use store::consts::altair::{
|
||||||
@@ -134,8 +133,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
let spec = &self.spec;
|
let spec = &self.spec;
|
||||||
|
|
||||||
// Calculate ideal_rewards
|
// Calculate ideal_rewards
|
||||||
let participation_cache = ParticipationCache::new(&state, spec)
|
|
||||||
.map_err(|_| BeaconChainError::AttestationRewardsError)?;
|
|
||||||
process_justification_and_finalization(&state)?.apply_changes_to_state(&mut state);
|
process_justification_and_finalization(&state)?.apply_changes_to_state(&mut state);
|
||||||
process_inactivity_updates_slow(&mut state, spec)?;
|
process_inactivity_updates_slow(&mut state, spec)?;
|
||||||
|
|
||||||
@@ -147,14 +144,14 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
let weight = get_flag_weight(flag_index)
|
let weight = get_flag_weight(flag_index)
|
||||||
.map_err(|_| BeaconChainError::AttestationRewardsError)?;
|
.map_err(|_| BeaconChainError::AttestationRewardsError)?;
|
||||||
|
|
||||||
let unslashed_participating_balance = participation_cache
|
let unslashed_participating_balance = state
|
||||||
.previous_epoch_flag_attesting_balance(flag_index)
|
.progressive_balances_cache()
|
||||||
.map_err(|_| BeaconChainError::AttestationRewardsError)?;
|
.previous_epoch_flag_attesting_balance(flag_index)?;
|
||||||
|
|
||||||
let unslashed_participating_increments =
|
let unslashed_participating_increments =
|
||||||
unslashed_participating_balance.safe_div(spec.effective_balance_increment)?;
|
unslashed_participating_balance.safe_div(spec.effective_balance_increment)?;
|
||||||
|
|
||||||
let total_active_balance = participation_cache.current_epoch_total_active_balance();
|
let total_active_balance = state.get_total_active_balance()?;
|
||||||
|
|
||||||
let active_increments =
|
let active_increments =
|
||||||
total_active_balance.safe_div(spec.effective_balance_increment)?;
|
total_active_balance.safe_div(spec.effective_balance_increment)?;
|
||||||
@@ -190,7 +187,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
let mut total_rewards: Vec<TotalAttestationRewards> = Vec::new();
|
let mut total_rewards: Vec<TotalAttestationRewards> = Vec::new();
|
||||||
|
|
||||||
let validators = if validators.is_empty() {
|
let validators = if validators.is_empty() {
|
||||||
participation_cache.eligible_validator_indices().to_vec()
|
Self::all_eligible_validator_indices(&state, previous_epoch)?
|
||||||
} else {
|
} else {
|
||||||
Self::validators_ids_to_indices(&mut state, validators)?
|
Self::validators_ids_to_indices(&mut state, validators)?
|
||||||
};
|
};
|
||||||
@@ -198,7 +195,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
for &validator_index in &validators {
|
for &validator_index in &validators {
|
||||||
// Return 0s for unknown/inactive validator indices. This is a bit different from stable
|
// Return 0s for unknown/inactive validator indices. This is a bit different from stable
|
||||||
// where we error for unknown pubkeys.
|
// where we error for unknown pubkeys.
|
||||||
let Ok(validator) = participation_cache.get_validator(validator_index) else {
|
let Ok(validator) = state.get_validator(validator_index) else {
|
||||||
debug!(
|
debug!(
|
||||||
self.log,
|
self.log,
|
||||||
"No rewards for inactive/unknown validator";
|
"No rewards for inactive/unknown validator";
|
||||||
@@ -215,22 +212,25 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let eligible = validator.is_eligible;
|
let previous_epoch_participation_flags = state
|
||||||
|
.previous_epoch_participation()?
|
||||||
|
.get(validator_index)
|
||||||
|
.ok_or(BeaconChainError::AttestationRewardsError)?;
|
||||||
|
let eligible = state.is_eligible_validator(previous_epoch, validator)?;
|
||||||
let mut head_reward = 0i64;
|
let mut head_reward = 0i64;
|
||||||
let mut target_reward = 0i64;
|
let mut target_reward = 0i64;
|
||||||
let mut source_reward = 0i64;
|
let mut source_reward = 0i64;
|
||||||
let mut inactivity_penalty = 0i64;
|
let mut inactivity_penalty = 0i64;
|
||||||
|
|
||||||
if eligible {
|
if eligible {
|
||||||
let effective_balance = validator.effective_balance;
|
let effective_balance = validator.effective_balance();
|
||||||
|
|
||||||
for flag_index in 0..PARTICIPATION_FLAG_WEIGHTS.len() {
|
for flag_index in 0..PARTICIPATION_FLAG_WEIGHTS.len() {
|
||||||
let (ideal_reward, penalty) = ideal_rewards_hashmap
|
let (ideal_reward, penalty) = ideal_rewards_hashmap
|
||||||
.get(&(flag_index, effective_balance))
|
.get(&(flag_index, effective_balance))
|
||||||
.ok_or(BeaconChainError::AttestationRewardsError)?;
|
.ok_or(BeaconChainError::AttestationRewardsError)?;
|
||||||
let voted_correctly = validator
|
let voted_correctly = !validator.slashed()
|
||||||
.is_unslashed_participating_index(flag_index)
|
&& previous_epoch_participation_flags.has_flag(flag_index)?;
|
||||||
.map_err(|_| BeaconChainError::AttestationRewardsError)?;
|
|
||||||
if voted_correctly {
|
if voted_correctly {
|
||||||
if flag_index == TIMELY_HEAD_FLAG_INDEX {
|
if flag_index == TIMELY_HEAD_FLAG_INDEX {
|
||||||
head_reward += *ideal_reward as i64;
|
head_reward += *ideal_reward as i64;
|
||||||
@@ -246,9 +246,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
|
|
||||||
let penalty_numerator = effective_balance
|
let penalty_numerator = effective_balance
|
||||||
.safe_mul(state.get_inactivity_score(validator_index)?)?;
|
.safe_mul(state.get_inactivity_score(validator_index)?)?;
|
||||||
let penalty_denominator = spec
|
let penalty_denominator = spec.inactivity_score_bias.safe_mul(
|
||||||
.inactivity_score_bias
|
spec.inactivity_penalty_quotient_for_fork(state.fork_name_unchecked()),
|
||||||
.safe_mul(spec.inactivity_penalty_quotient_for_state(&state))?;
|
)?;
|
||||||
inactivity_penalty =
|
inactivity_penalty =
|
||||||
-(penalty_numerator.safe_div(penalty_denominator)? as i64);
|
-(penalty_numerator.safe_div(penalty_denominator)? as i64);
|
||||||
} else if flag_index == TIMELY_SOURCE_FLAG_INDEX {
|
} else if flag_index == TIMELY_SOURCE_FLAG_INDEX {
|
||||||
@@ -314,6 +314,24 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
Ok(max_steps)
|
Ok(max_steps)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn all_eligible_validator_indices(
|
||||||
|
state: &BeaconState<T::EthSpec>,
|
||||||
|
previous_epoch: Epoch,
|
||||||
|
) -> Result<Vec<usize>, BeaconChainError> {
|
||||||
|
state
|
||||||
|
.validators()
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(i, validator)| {
|
||||||
|
state
|
||||||
|
.is_eligible_validator(previous_epoch, validator)
|
||||||
|
.map(|eligible| eligible.then_some(i))
|
||||||
|
.map_err(BeaconChainError::BeaconStateError)
|
||||||
|
.transpose()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn validators_ids_to_indices(
|
fn validators_ids_to_indices(
|
||||||
state: &mut BeaconState<T::EthSpec>,
|
state: &mut BeaconState<T::EthSpec>,
|
||||||
validators: Vec<ValidatorId>,
|
validators: Vec<ValidatorId>,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use eth2::lighthouse::{
|
|||||||
AttestationPerformance, AttestationPerformanceQuery, AttestationPerformanceStatistics,
|
AttestationPerformance, AttestationPerformanceQuery, AttestationPerformanceStatistics,
|
||||||
};
|
};
|
||||||
use state_processing::{
|
use state_processing::{
|
||||||
per_epoch_processing::altair::participation_cache::Error as ParticipationCacheError,
|
|
||||||
per_epoch_processing::EpochProcessingSummary, BlockReplayError, BlockReplayer,
|
per_epoch_processing::EpochProcessingSummary, BlockReplayError, BlockReplayer,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -18,7 +17,6 @@ const BLOCK_ROOT_CHUNK_SIZE: usize = 100;
|
|||||||
enum AttestationPerformanceError {
|
enum AttestationPerformanceError {
|
||||||
BlockReplay(#[allow(dead_code)] BlockReplayError),
|
BlockReplay(#[allow(dead_code)] BlockReplayError),
|
||||||
BeaconState(#[allow(dead_code)] BeaconStateError),
|
BeaconState(#[allow(dead_code)] BeaconStateError),
|
||||||
ParticipationCache(#[allow(dead_code)] ParticipationCacheError),
|
|
||||||
UnableToFindValidator(#[allow(dead_code)] usize),
|
UnableToFindValidator(#[allow(dead_code)] usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,12 +32,6 @@ impl From<BeaconStateError> for AttestationPerformanceError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ParticipationCacheError> for AttestationPerformanceError {
|
|
||||||
fn from(e: ParticipationCacheError) -> Self {
|
|
||||||
Self::ParticipationCache(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_attestation_performance<T: BeaconChainTypes>(
|
pub fn get_attestation_performance<T: BeaconChainTypes>(
|
||||||
target: String,
|
target: String,
|
||||||
query: AttestationPerformanceQuery,
|
query: AttestationPerformanceQuery,
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ pub fn global_validator_inclusion_data<T: BeaconChainTypes>(
|
|||||||
|
|
||||||
Ok(GlobalValidatorInclusionData {
|
Ok(GlobalValidatorInclusionData {
|
||||||
current_epoch_active_gwei: summary.current_epoch_total_active_balance(),
|
current_epoch_active_gwei: summary.current_epoch_total_active_balance(),
|
||||||
previous_epoch_active_gwei: summary.previous_epoch_total_active_balance(),
|
|
||||||
current_epoch_target_attesting_gwei: summary
|
current_epoch_target_attesting_gwei: summary
|
||||||
.current_epoch_target_attesting_balance()
|
.current_epoch_target_attesting_balance()
|
||||||
.map_err(convert_cache_error)?,
|
.map_err(convert_cache_error)?,
|
||||||
|
|||||||
@@ -54,8 +54,6 @@ pub struct Peer<T: EthSpec> {
|
|||||||
pub struct GlobalValidatorInclusionData {
|
pub struct GlobalValidatorInclusionData {
|
||||||
/// The total effective balance of all active validators during the _current_ epoch.
|
/// The total effective balance of all active validators during the _current_ epoch.
|
||||||
pub current_epoch_active_gwei: u64,
|
pub current_epoch_active_gwei: u64,
|
||||||
/// The total effective balance of all active validators during the _previous_ epoch.
|
|
||||||
pub previous_epoch_active_gwei: u64,
|
|
||||||
/// The total effective balance of all validators who attested during the _current_ epoch and
|
/// The total effective balance of all validators who attested during the _current_ epoch and
|
||||||
/// agreed with the state about the beacon block at the first slot of the _current_ epoch.
|
/// agreed with the state about the beacon block at the first slot of the _current_ epoch.
|
||||||
pub current_epoch_target_attesting_gwei: u64,
|
pub current_epoch_target_attesting_gwei: u64,
|
||||||
|
|||||||
@@ -747,7 +747,11 @@ where
|
|||||||
| BeaconBlockRef::Capella(_)
|
| BeaconBlockRef::Capella(_)
|
||||||
| BeaconBlockRef::Merge(_)
|
| BeaconBlockRef::Merge(_)
|
||||||
| BeaconBlockRef::Altair(_) => {
|
| BeaconBlockRef::Altair(_) => {
|
||||||
// FIXME(sproul): initialize progressive balances
|
// NOTE: Processing justification & finalization requires the progressive
|
||||||
|
// balances cache, but we cannot initialize it here as we only have an
|
||||||
|
// immutable reference. The state *should* have come straight from block
|
||||||
|
// processing, which initialises the cache, but if we add other `on_block`
|
||||||
|
// calls in future it could be worth passing a mutable reference.
|
||||||
per_epoch_processing::altair::process_justification_and_finalization(state)?
|
per_epoch_processing::altair::process_justification_and_finalization(state)?
|
||||||
}
|
}
|
||||||
BeaconBlockRef::Base(_) => {
|
BeaconBlockRef::Base(_) => {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ impl<E: EthSpec> AllCaches for BeaconState<E> {
|
|||||||
fn build_all_caches(&mut self, spec: &ChainSpec) -> Result<(), EpochCacheError> {
|
fn build_all_caches(&mut self, spec: &ChainSpec) -> Result<(), EpochCacheError> {
|
||||||
self.build_caches(spec)?;
|
self.build_caches(spec)?;
|
||||||
initialize_epoch_cache(self, spec)?;
|
initialize_epoch_cache(self, spec)?;
|
||||||
initialize_progressive_balances_cache(self, None, spec)?;
|
initialize_progressive_balances_cache(self, spec)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,21 +3,16 @@ use crate::metrics::{
|
|||||||
PARTICIPATION_CURR_EPOCH_TARGET_ATTESTING_GWEI_PROGRESSIVE_TOTAL,
|
PARTICIPATION_CURR_EPOCH_TARGET_ATTESTING_GWEI_PROGRESSIVE_TOTAL,
|
||||||
PARTICIPATION_PREV_EPOCH_TARGET_ATTESTING_GWEI_PROGRESSIVE_TOTAL,
|
PARTICIPATION_PREV_EPOCH_TARGET_ATTESTING_GWEI_PROGRESSIVE_TOTAL,
|
||||||
};
|
};
|
||||||
use crate::per_epoch_processing::altair::ParticipationCache;
|
|
||||||
use crate::{BlockProcessingError, EpochProcessingError};
|
use crate::{BlockProcessingError, EpochProcessingError};
|
||||||
use lighthouse_metrics::set_gauge;
|
use lighthouse_metrics::set_gauge;
|
||||||
use std::borrow::Cow;
|
|
||||||
use types::{
|
use types::{
|
||||||
is_progressive_balances_enabled, BeaconState, BeaconStateError, ChainSpec, Epoch,
|
is_progressive_balances_enabled, BeaconState, BeaconStateError, ChainSpec, Epoch,
|
||||||
EpochTotalBalances, EthSpec, ProgressiveBalancesCache,
|
EpochTotalBalances, EthSpec, ParticipationFlags, ProgressiveBalancesCache, Validator,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Initializes the `ProgressiveBalancesCache` cache using balance values from the
|
/// Initializes the `ProgressiveBalancesCache` if it is unbuilt.
|
||||||
/// `ParticipationCache`. If the optional `&ParticipationCache` is not supplied, it will be computed
|
|
||||||
/// from the `BeaconState`.
|
|
||||||
pub fn initialize_progressive_balances_cache<E: EthSpec>(
|
pub fn initialize_progressive_balances_cache<E: EthSpec>(
|
||||||
state: &mut BeaconState<E>,
|
state: &mut BeaconState<E>,
|
||||||
maybe_participation_cache: Option<&ParticipationCache>,
|
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<(), BeaconStateError> {
|
) -> Result<(), BeaconStateError> {
|
||||||
if !is_progressive_balances_enabled(state)
|
if !is_progressive_balances_enabled(state)
|
||||||
@@ -26,29 +21,37 @@ pub fn initialize_progressive_balances_cache<E: EthSpec>(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(sproul): simplify the participation cache
|
// Calculate the total flag balances for previous & current epoch in a single iteration.
|
||||||
let participation_cache = match maybe_participation_cache {
|
// This calculates `get_total_balance(unslashed_participating_indices(..))` for each flag in
|
||||||
Some(cache) => Cow::Borrowed(cache),
|
// the current and previous epoch.
|
||||||
None => {
|
|
||||||
state.build_total_active_balance_cache_at(state.current_epoch(), spec)?;
|
|
||||||
Cow::Owned(
|
|
||||||
ParticipationCache::new(state, spec)
|
|
||||||
.map_err(|e| BeaconStateError::ParticipationCacheError(format!("{e:?}")))?,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let current_epoch = state.current_epoch();
|
let current_epoch = state.current_epoch();
|
||||||
let previous_epoch_cache = EpochTotalBalances {
|
let previous_epoch = state.previous_epoch();
|
||||||
total_flag_balances: participation_cache
|
let mut previous_epoch_cache = EpochTotalBalances::new(spec);
|
||||||
.previous_epoch_participation
|
let mut current_epoch_cache = EpochTotalBalances::new(spec);
|
||||||
.total_flag_balances,
|
for ((validator, current_epoch_flags), previous_epoch_flags) in state
|
||||||
};
|
.validators()
|
||||||
let current_epoch_cache = EpochTotalBalances {
|
.iter()
|
||||||
total_flag_balances: participation_cache
|
.zip(state.current_epoch_participation()?)
|
||||||
.current_epoch_participation
|
.zip(state.previous_epoch_participation()?)
|
||||||
.total_flag_balances,
|
{
|
||||||
};
|
// Exclude slashed validators. We are calculating *unslashed* participating totals.
|
||||||
|
if validator.slashed() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update current epoch flag balances.
|
||||||
|
if validator.is_active_at(current_epoch) {
|
||||||
|
update_flag_total_balances(&mut current_epoch_cache, *current_epoch_flags, validator)?;
|
||||||
|
}
|
||||||
|
// Update previous epoch flag balances.
|
||||||
|
if validator.is_active_at(previous_epoch) {
|
||||||
|
update_flag_total_balances(
|
||||||
|
&mut previous_epoch_cache,
|
||||||
|
*previous_epoch_flags,
|
||||||
|
validator,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state.progressive_balances_cache_mut().initialize(
|
state.progressive_balances_cache_mut().initialize(
|
||||||
current_epoch,
|
current_epoch,
|
||||||
@@ -61,6 +64,26 @@ pub fn initialize_progressive_balances_cache<E: EthSpec>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// During the initialization of the progressive balances for a single epoch, add
|
||||||
|
/// `validator.effective_balance` to the flag total, for each flag present in `participation_flags`.
|
||||||
|
///
|
||||||
|
/// Pre-conditions:
|
||||||
|
///
|
||||||
|
/// - `validator` must not be slashed
|
||||||
|
/// - the `participation_flags` must be for `validator` in the same epoch as the `total_balances`
|
||||||
|
fn update_flag_total_balances(
|
||||||
|
total_balances: &mut EpochTotalBalances,
|
||||||
|
participation_flags: ParticipationFlags,
|
||||||
|
validator: &Validator,
|
||||||
|
) -> Result<(), BeaconStateError> {
|
||||||
|
for (flag, balance) in total_balances.total_flag_balances.iter_mut().enumerate() {
|
||||||
|
if participation_flags.has_flag(flag)? {
|
||||||
|
balance.safe_add_assign(validator.effective_balance())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates the `ProgressiveBalancesCache` when a new target attestation has been processed.
|
/// Updates the `ProgressiveBalancesCache` when a new target attestation has been processed.
|
||||||
pub fn update_progressive_balances_on_attestation<T: EthSpec>(
|
pub fn update_progressive_balances_on_attestation<T: EthSpec>(
|
||||||
state: &mut BeaconState<T>,
|
state: &mut BeaconState<T>,
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ pub fn per_block_processing<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
|||||||
|
|
||||||
// Build epoch cache if it hasn't already been built, or if it is no longer valid
|
// Build epoch cache if it hasn't already been built, or if it is no longer valid
|
||||||
initialize_epoch_cache(state, spec)?;
|
initialize_epoch_cache(state, spec)?;
|
||||||
initialize_progressive_balances_cache(state, None, spec)?;
|
initialize_progressive_balances_cache(state, spec)?;
|
||||||
state.build_slashings_cache()?;
|
state.build_slashings_cache()?;
|
||||||
|
|
||||||
let verify_signatures = match block_signature_strategy {
|
let verify_signatures = match block_signature_strategy {
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ use crate::{signature_sets::sync_aggregate_signature_set, VerifySignatures};
|
|||||||
use safe_arith::SafeArith;
|
use safe_arith::SafeArith;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use types::consts::altair::{PROPOSER_WEIGHT, SYNC_REWARD_WEIGHT, WEIGHT_DENOMINATOR};
|
use types::consts::altair::{PROPOSER_WEIGHT, SYNC_REWARD_WEIGHT, WEIGHT_DENOMINATOR};
|
||||||
use types::{BeaconState, ChainSpec, EthSpec, PublicKeyBytes, SyncAggregate, Unsigned};
|
use types::{
|
||||||
|
BeaconState, BeaconStateError, ChainSpec, EthSpec, PublicKeyBytes, SyncAggregate, Unsigned,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn process_sync_aggregate<T: EthSpec>(
|
pub fn process_sync_aggregate<T: EthSpec>(
|
||||||
state: &mut BeaconState<T>,
|
state: &mut BeaconState<T>,
|
||||||
@@ -47,20 +49,34 @@ pub fn process_sync_aggregate<T: EthSpec>(
|
|||||||
// Apply participant and proposer rewards
|
// Apply participant and proposer rewards
|
||||||
let committee_indices = state.get_sync_committee_indices(¤t_sync_committee)?;
|
let committee_indices = state.get_sync_committee_indices(¤t_sync_committee)?;
|
||||||
|
|
||||||
let mut total_proposer_reward = 0;
|
let proposer_index = proposer_index as usize;
|
||||||
|
let mut proposer_balance = *state
|
||||||
|
.balances()
|
||||||
|
.get(proposer_index)
|
||||||
|
.ok_or(BeaconStateError::BalancesOutOfBounds(proposer_index))?;
|
||||||
|
|
||||||
for (participant_index, participation_bit) in committee_indices
|
for (participant_index, participation_bit) in committee_indices
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(aggregate.sync_committee_bits.iter())
|
.zip(aggregate.sync_committee_bits.iter())
|
||||||
{
|
{
|
||||||
// FIXME(sproul): double-check this for Capella, proposer shouldn't have 0 effective balance
|
// FIXME(sproul): double-check this for Capella, proposer shouldn't have 0 effective balance
|
||||||
if participation_bit {
|
if participation_bit {
|
||||||
increase_balance(state, participant_index, participant_reward)?;
|
// Accumulate proposer rewards in a temp var in case the proposer has very low balance, is
|
||||||
total_proposer_reward.safe_add_assign(proposer_reward)?;
|
// part of the sync committee, does not participate and its penalties saturate.
|
||||||
|
if participant_index == proposer_index {
|
||||||
|
proposer_balance.safe_add_assign(participant_reward)?;
|
||||||
|
} else {
|
||||||
|
increase_balance(state, participant_index, participant_reward)?;
|
||||||
|
}
|
||||||
|
proposer_balance.safe_add_assign(proposer_reward)?;
|
||||||
|
} else if participant_index == proposer_index {
|
||||||
|
proposer_balance = proposer_balance.saturating_sub(participant_reward);
|
||||||
} else {
|
} else {
|
||||||
decrease_balance(state, participant_index, participant_reward)?;
|
decrease_balance(state, participant_index, participant_reward)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
increase_balance(state, proposer_index as usize, total_proposer_reward)?;
|
|
||||||
|
*state.get_balance_mut(proposer_index)? = proposer_balance;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
use super::signature_sets::Error as SignatureSetError;
|
use super::signature_sets::Error as SignatureSetError;
|
||||||
use crate::per_epoch_processing::altair::participation_cache;
|
|
||||||
use crate::{ContextError, EpochCacheError};
|
use crate::{ContextError, EpochCacheError};
|
||||||
use merkle_proof::MerkleTreeError;
|
use merkle_proof::MerkleTreeError;
|
||||||
use participation_cache::Error as ParticipationCacheError;
|
|
||||||
use safe_arith::ArithError;
|
use safe_arith::ArithError;
|
||||||
use ssz::DecodeError;
|
use ssz::DecodeError;
|
||||||
use types::*;
|
use types::*;
|
||||||
@@ -91,7 +89,6 @@ pub enum BlockProcessingError {
|
|||||||
found: Hash256,
|
found: Hash256,
|
||||||
},
|
},
|
||||||
WithdrawalCredentialsInvalid,
|
WithdrawalCredentialsInvalid,
|
||||||
ParticipationCacheError(ParticipationCacheError),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BeaconStateError> for BlockProcessingError {
|
impl From<BeaconStateError> for BlockProcessingError {
|
||||||
@@ -161,12 +158,6 @@ impl From<BlockOperationError<HeaderInvalid>> for BlockProcessingError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ParticipationCacheError> for BlockProcessingError {
|
|
||||||
fn from(e: ParticipationCacheError) -> Self {
|
|
||||||
BlockProcessingError::ParticipationCacheError(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A conversion that consumes `self` and adds an `index` variable to resulting struct.
|
/// A conversion that consumes `self` and adds an `index` variable to resulting struct.
|
||||||
///
|
///
|
||||||
/// Used here to allow converting an error into an upstream error that points to the object that
|
/// Used here to allow converting an error into an upstream error that points to the object that
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use crate::per_epoch_processing::{
|
|||||||
};
|
};
|
||||||
pub use inactivity_updates::process_inactivity_updates_slow;
|
pub use inactivity_updates::process_inactivity_updates_slow;
|
||||||
pub use justification_and_finalization::process_justification_and_finalization;
|
pub use justification_and_finalization::process_justification_and_finalization;
|
||||||
pub use participation_cache::ParticipationCache;
|
|
||||||
pub use participation_flag_updates::process_participation_flag_updates;
|
pub use participation_flag_updates::process_participation_flag_updates;
|
||||||
pub use rewards_and_penalties::process_rewards_and_penalties_slow;
|
pub use rewards_and_penalties::process_rewards_and_penalties_slow;
|
||||||
pub use sync_committee_updates::process_sync_committee_updates;
|
pub use sync_committee_updates::process_sync_committee_updates;
|
||||||
@@ -19,7 +18,6 @@ use types::{BeaconState, ChainSpec, EthSpec, RelativeEpoch};
|
|||||||
|
|
||||||
pub mod inactivity_updates;
|
pub mod inactivity_updates;
|
||||||
pub mod justification_and_finalization;
|
pub mod justification_and_finalization;
|
||||||
pub mod participation_cache;
|
|
||||||
pub mod participation_flag_updates;
|
pub mod participation_flag_updates;
|
||||||
pub mod rewards_and_penalties;
|
pub mod rewards_and_penalties;
|
||||||
pub mod sync_committee_updates;
|
pub mod sync_committee_updates;
|
||||||
@@ -34,7 +32,7 @@ pub fn process_epoch<T: EthSpec>(
|
|||||||
state.build_committee_cache(RelativeEpoch::Next, spec)?;
|
state.build_committee_cache(RelativeEpoch::Next, spec)?;
|
||||||
state.build_total_active_balance_cache_at(state.current_epoch(), spec)?;
|
state.build_total_active_balance_cache_at(state.current_epoch(), spec)?;
|
||||||
initialize_epoch_cache(state, spec)?;
|
initialize_epoch_cache(state, spec)?;
|
||||||
initialize_progressive_balances_cache::<T>(state, None, spec)?;
|
initialize_progressive_balances_cache::<T>(state, spec)?;
|
||||||
|
|
||||||
let sync_committee = state.current_sync_committee()?.clone();
|
let sync_committee = state.current_sync_committee()?.clone();
|
||||||
|
|
||||||
|
|||||||
@@ -100,10 +100,6 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
|
|||||||
&metrics::PARTICIPATION_PREV_EPOCH_SOURCE_ATTESTING_GWEI_TOTAL,
|
&metrics::PARTICIPATION_PREV_EPOCH_SOURCE_ATTESTING_GWEI_TOTAL,
|
||||||
self.previous_epoch_source_attesting_balance()? as i64,
|
self.previous_epoch_source_attesting_balance()? as i64,
|
||||||
);
|
);
|
||||||
metrics::set_gauge(
|
|
||||||
&metrics::PARTICIPATION_PREV_EPOCH_ACTIVE_GWEI_TOTAL,
|
|
||||||
self.previous_epoch_total_active_balance() as i64,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -141,12 +137,6 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the sum of the effective balance of all validators in the previous epoch.
|
|
||||||
pub fn previous_epoch_total_active_balance(&self) -> u64 {
|
|
||||||
// FIXME(sproul): this is not a useful concept and should be deleted
|
|
||||||
self.current_epoch_total_active_balance()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `true` if `val_index` was included in the active validator indices in the current
|
/// Returns `true` if `val_index` was included in the active validator indices in the current
|
||||||
/// epoch *and* the validator is not slashed.
|
/// epoch *and* the validator is not slashed.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use crate::per_epoch_processing::altair::participation_cache::Error as ParticipationCacheError;
|
|
||||||
use types::{milhouse, BeaconStateError, EpochCacheError, InconsistentFork};
|
use types::{milhouse, BeaconStateError, EpochCacheError, InconsistentFork};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@@ -24,7 +23,6 @@ pub enum EpochProcessingError {
|
|||||||
InconsistentStateFork(InconsistentFork),
|
InconsistentStateFork(InconsistentFork),
|
||||||
InvalidJustificationBit(ssz_types::Error),
|
InvalidJustificationBit(ssz_types::Error),
|
||||||
InvalidFlagIndex(usize),
|
InvalidFlagIndex(usize),
|
||||||
ParticipationCache(ParticipationCacheError),
|
|
||||||
MilhouseError(milhouse::Error),
|
MilhouseError(milhouse::Error),
|
||||||
EpochCache(EpochCacheError),
|
EpochCache(EpochCacheError),
|
||||||
}
|
}
|
||||||
@@ -53,12 +51,6 @@ impl From<safe_arith::ArithError> for EpochProcessingError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ParticipationCacheError> for EpochProcessingError {
|
|
||||||
fn from(e: ParticipationCacheError) -> EpochProcessingError {
|
|
||||||
EpochProcessingError::ParticipationCache(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<milhouse::Error> for EpochProcessingError {
|
impl From<milhouse::Error> for EpochProcessingError {
|
||||||
fn from(e: milhouse::Error) -> Self {
|
fn from(e: milhouse::Error) -> Self {
|
||||||
Self::MilhouseError(e)
|
Self::MilhouseError(e)
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ pub fn process_epoch_single_pass<E: EthSpec>(
|
|||||||
conf: SinglePassConfig,
|
conf: SinglePassConfig,
|
||||||
) -> Result<ParticipationEpochSummary<E>, Error> {
|
) -> Result<ParticipationEpochSummary<E>, Error> {
|
||||||
initialize_epoch_cache(state, spec)?;
|
initialize_epoch_cache(state, spec)?;
|
||||||
initialize_progressive_balances_cache(state, None, spec)?;
|
initialize_progressive_balances_cache(state, spec)?;
|
||||||
state.build_exit_cache(spec)?;
|
state.build_exit_cache(spec)?;
|
||||||
|
|
||||||
let previous_epoch = state.previous_epoch();
|
let previous_epoch = state.previous_epoch();
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ pub fn upgrade_to_altair<E: EthSpec>(
|
|||||||
// Fill in previous epoch participation from the pre state's pending attestations.
|
// Fill in previous epoch participation from the pre state's pending attestations.
|
||||||
translate_participation(&mut post, &pre.previous_epoch_attestations, spec)?;
|
translate_participation(&mut post, &pre.previous_epoch_attestations, spec)?;
|
||||||
|
|
||||||
initialize_progressive_balances_cache(&mut post, None, spec)?;
|
initialize_progressive_balances_cache(&mut post, spec)?;
|
||||||
|
|
||||||
// Fill in sync committees
|
// Fill in sync committees
|
||||||
// Note: A duplicate committee is assigned for the current and next committee at the fork
|
// Note: A duplicate committee is assigned for the current and next committee at the fork
|
||||||
|
|||||||
@@ -115,7 +115,6 @@ pub enum Error {
|
|||||||
SszTypesError(ssz_types::Error),
|
SszTypesError(ssz_types::Error),
|
||||||
TreeHashCacheNotInitialized,
|
TreeHashCacheNotInitialized,
|
||||||
NonLinearTreeHashCacheHistory,
|
NonLinearTreeHashCacheHistory,
|
||||||
ParticipationCacheError(String),
|
|
||||||
ProgressiveBalancesCacheNotInitialized,
|
ProgressiveBalancesCacheNotInitialized,
|
||||||
ProgressiveBalancesCacheInconsistent,
|
ProgressiveBalancesCacheInconsistent,
|
||||||
TreeHashCacheSkippedSlot {
|
TreeHashCacheSkippedSlot {
|
||||||
@@ -1593,7 +1592,7 @@ impl<T: EthSpec> BeaconState<T> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_total_active_balance(
|
pub fn compute_total_active_balance_slow(
|
||||||
&self,
|
&self,
|
||||||
epoch: Epoch,
|
epoch: Epoch,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
@@ -1661,7 +1660,7 @@ impl<T: EthSpec> BeaconState<T> {
|
|||||||
epoch: Epoch,
|
epoch: Epoch,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let total_active_balance = self.compute_total_active_balance(epoch, spec)?;
|
let total_active_balance = self.compute_total_active_balance_slow(epoch, spec)?;
|
||||||
*self.total_active_balance_mut() = Some((epoch, total_active_balance));
|
*self.total_active_balance_mut() = Some((epoch, total_active_balance));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ impl ProgressiveBalancesCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `ProgressiveBalancesCache` is only enabled from `Altair` as it requires `ParticipationCache`.
|
/// `ProgressiveBalancesCache` is only enabled from `Altair` as it uses Altair-specific logic.
|
||||||
pub fn is_progressive_balances_enabled<E: EthSpec>(state: &BeaconState<E>) -> bool {
|
pub fn is_progressive_balances_enabled<E: EthSpec>(state: &BeaconState<E>) -> bool {
|
||||||
match state {
|
match state {
|
||||||
BeaconState::Base(_) => false,
|
BeaconState::Base(_) => false,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use rpds::HashTrieMapSync as HashTrieMap;
|
|||||||
|
|
||||||
type ValidatorIndex = usize;
|
type ValidatorIndex = usize;
|
||||||
|
|
||||||
|
#[allow(clippy::len_without_is_empty)]
|
||||||
#[derive(Debug, PartialEq, Clone, Default)]
|
#[derive(Debug, PartialEq, Clone, Default)]
|
||||||
pub struct PubkeyCache {
|
pub struct PubkeyCache {
|
||||||
/// Maintain the number of keys added to the map. It is not sufficient to just use the
|
/// Maintain the number of keys added to the map. It is not sufficient to just use the
|
||||||
|
|||||||
@@ -326,12 +326,6 @@ impl ChainSpec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For a given `BeaconState`, return the inactivity penalty quotient associated with its variant.
|
|
||||||
// FIXME(sproul): delete once unused
|
|
||||||
pub fn inactivity_penalty_quotient_for_state<T: EthSpec>(&self, state: &BeaconState<T>) -> u64 {
|
|
||||||
self.inactivity_penalty_quotient_for_fork(state.fork_name_unchecked())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn inactivity_penalty_quotient_for_fork(&self, fork_name: ForkName) -> u64 {
|
pub fn inactivity_penalty_quotient_for_fork(&self, fork_name: ForkName) -> u64 {
|
||||||
match fork_name {
|
match fork_name {
|
||||||
ForkName::Base => self.inactivity_penalty_quotient,
|
ForkName::Base => self.inactivity_penalty_quotient,
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ impl<E: EthSpec> EpochTransition<E> for JustificationAndFinalization {
|
|||||||
| BeaconState::Merge(_)
|
| BeaconState::Merge(_)
|
||||||
| BeaconState::Capella(_)
|
| BeaconState::Capella(_)
|
||||||
| BeaconState::Deneb(_) => {
|
| BeaconState::Deneb(_) => {
|
||||||
initialize_progressive_balances_cache(state, None, spec)?;
|
initialize_progressive_balances_cache(state, spec)?;
|
||||||
let justification_and_finalization_state =
|
let justification_and_finalization_state =
|
||||||
altair::process_justification_and_finalization(state)?;
|
altair::process_justification_and_finalization(state)?;
|
||||||
justification_and_finalization_state.apply_changes_to_state(state);
|
justification_and_finalization_state.apply_changes_to_state(state);
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ impl<E: EthSpec> Operation<E> for Attestation<E> {
|
|||||||
| BeaconState::Merge(_)
|
| BeaconState::Merge(_)
|
||||||
| BeaconState::Capella(_)
|
| BeaconState::Capella(_)
|
||||||
| BeaconState::Deneb(_) => {
|
| BeaconState::Deneb(_) => {
|
||||||
initialize_progressive_balances_cache(state, None, spec)?;
|
initialize_progressive_balances_cache(state, spec)?;
|
||||||
altair_deneb::process_attestation(
|
altair_deneb::process_attestation(
|
||||||
state,
|
state,
|
||||||
self,
|
self,
|
||||||
@@ -134,7 +134,7 @@ impl<E: EthSpec> Operation<E> for AttesterSlashing<E> {
|
|||||||
_: &Operations<E, Self>,
|
_: &Operations<E, Self>,
|
||||||
) -> Result<(), BlockProcessingError> {
|
) -> Result<(), BlockProcessingError> {
|
||||||
let mut ctxt = ConsensusContext::new(state.slot());
|
let mut ctxt = ConsensusContext::new(state.slot());
|
||||||
initialize_progressive_balances_cache(state, None, spec)?;
|
initialize_progressive_balances_cache(state, spec)?;
|
||||||
process_attester_slashings(
|
process_attester_slashings(
|
||||||
state,
|
state,
|
||||||
&[self.clone()],
|
&[self.clone()],
|
||||||
@@ -185,7 +185,7 @@ impl<E: EthSpec> Operation<E> for ProposerSlashing {
|
|||||||
_: &Operations<E, Self>,
|
_: &Operations<E, Self>,
|
||||||
) -> Result<(), BlockProcessingError> {
|
) -> Result<(), BlockProcessingError> {
|
||||||
let mut ctxt = ConsensusContext::new(state.slot());
|
let mut ctxt = ConsensusContext::new(state.slot());
|
||||||
initialize_progressive_balances_cache(state, None, spec)?;
|
initialize_progressive_balances_cache(state, spec)?;
|
||||||
process_proposer_slashings(
|
process_proposer_slashings(
|
||||||
state,
|
state,
|
||||||
&[self.clone()],
|
&[self.clone()],
|
||||||
|
|||||||
Reference in New Issue
Block a user