Merge remote-tracking branch 'sigp/epoch-single-pass' into tree-states

This commit is contained in:
dapplion
2024-02-23 11:36:02 +08:00
parent 20f53e7769
commit a5d3408c59
21 changed files with 127 additions and 112 deletions

View File

@@ -24,7 +24,7 @@ impl<E: EthSpec> AllCaches for BeaconState<E> {
fn build_all_caches(&mut self, spec: &ChainSpec) -> Result<(), EpochCacheError> {
self.build_caches(spec)?;
initialize_epoch_cache(self, spec)?;
initialize_progressive_balances_cache(self, None, spec)?;
initialize_progressive_balances_cache(self, spec)?;
Ok(())
}

View File

@@ -3,21 +3,16 @@ use crate::metrics::{
PARTICIPATION_CURR_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 lighthouse_metrics::set_gauge;
use std::borrow::Cow;
use types::{
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
/// `ParticipationCache`. If the optional `&ParticipationCache` is not supplied, it will be computed
/// from the `BeaconState`.
/// Initializes the `ProgressiveBalancesCache` if it is unbuilt.
pub fn initialize_progressive_balances_cache<E: EthSpec>(
state: &mut BeaconState<E>,
maybe_participation_cache: Option<&ParticipationCache>,
spec: &ChainSpec,
) -> Result<(), BeaconStateError> {
if !is_progressive_balances_enabled(state)
@@ -26,29 +21,37 @@ pub fn initialize_progressive_balances_cache<E: EthSpec>(
return Ok(());
}
// FIXME(sproul): simplify the participation cache
let participation_cache = match maybe_participation_cache {
Some(cache) => Cow::Borrowed(cache),
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:?}")))?,
)
}
};
// Calculate the total flag balances for previous & current epoch in a single iteration.
// This calculates `get_total_balance(unslashed_participating_indices(..))` for each flag in
// the current and previous epoch.
let current_epoch = state.current_epoch();
let previous_epoch_cache = EpochTotalBalances {
total_flag_balances: participation_cache
.previous_epoch_participation
.total_flag_balances,
};
let current_epoch_cache = EpochTotalBalances {
total_flag_balances: participation_cache
.current_epoch_participation
.total_flag_balances,
};
let previous_epoch = state.previous_epoch();
let mut previous_epoch_cache = EpochTotalBalances::new(spec);
let mut current_epoch_cache = EpochTotalBalances::new(spec);
for ((validator, current_epoch_flags), previous_epoch_flags) in state
.validators()
.iter()
.zip(state.current_epoch_participation()?)
.zip(state.previous_epoch_participation()?)
{
// 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(
current_epoch,
@@ -61,6 +64,26 @@ pub fn initialize_progressive_balances_cache<E: EthSpec>(
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.
pub fn update_progressive_balances_on_attestation<T: EthSpec>(
state: &mut BeaconState<T>,

View File

@@ -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
initialize_epoch_cache(state, spec)?;
initialize_progressive_balances_cache(state, None, spec)?;
initialize_progressive_balances_cache(state, spec)?;
state.build_slashings_cache()?;
let verify_signatures = match block_signature_strategy {

View File

@@ -4,7 +4,9 @@ use crate::{signature_sets::sync_aggregate_signature_set, VerifySignatures};
use safe_arith::SafeArith;
use std::borrow::Cow;
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>(
state: &mut BeaconState<T>,
@@ -47,20 +49,34 @@ pub fn process_sync_aggregate<T: EthSpec>(
// Apply participant and proposer rewards
let committee_indices = state.get_sync_committee_indices(&current_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
.into_iter()
.zip(aggregate.sync_committee_bits.iter())
{
// FIXME(sproul): double-check this for Capella, proposer shouldn't have 0 effective balance
if participation_bit {
increase_balance(state, participant_index, participant_reward)?;
total_proposer_reward.safe_add_assign(proposer_reward)?;
// Accumulate proposer rewards in a temp var in case the proposer has very low balance, is
// 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 {
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(())
}

View File

@@ -1,8 +1,6 @@
use super::signature_sets::Error as SignatureSetError;
use crate::per_epoch_processing::altair::participation_cache;
use crate::{ContextError, EpochCacheError};
use merkle_proof::MerkleTreeError;
use participation_cache::Error as ParticipationCacheError;
use safe_arith::ArithError;
use ssz::DecodeError;
use types::*;
@@ -91,7 +89,6 @@ pub enum BlockProcessingError {
found: Hash256,
},
WithdrawalCredentialsInvalid,
ParticipationCacheError(ParticipationCacheError),
}
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.
///
/// Used here to allow converting an error into an upstream error that points to the object that

View File

@@ -11,7 +11,6 @@ use crate::per_epoch_processing::{
};
pub use inactivity_updates::process_inactivity_updates_slow;
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 rewards_and_penalties::process_rewards_and_penalties_slow;
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 justification_and_finalization;
pub mod participation_cache;
pub mod participation_flag_updates;
pub mod rewards_and_penalties;
pub mod sync_committee_updates;
@@ -34,7 +32,7 @@ pub fn process_epoch<T: EthSpec>(
state.build_committee_cache(RelativeEpoch::Next, spec)?;
state.build_total_active_balance_cache_at(state.current_epoch(), 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();

View File

@@ -100,10 +100,6 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
&metrics::PARTICIPATION_PREV_EPOCH_SOURCE_ATTESTING_GWEI_TOTAL,
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(())
}
@@ -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
/// epoch *and* the validator is not slashed.
///

View File

@@ -1,4 +1,3 @@
use crate::per_epoch_processing::altair::participation_cache::Error as ParticipationCacheError;
use types::{milhouse, BeaconStateError, EpochCacheError, InconsistentFork};
#[derive(Debug, PartialEq)]
@@ -24,7 +23,6 @@ pub enum EpochProcessingError {
InconsistentStateFork(InconsistentFork),
InvalidJustificationBit(ssz_types::Error),
InvalidFlagIndex(usize),
ParticipationCache(ParticipationCacheError),
MilhouseError(milhouse::Error),
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 {
fn from(e: milhouse::Error) -> Self {
Self::MilhouseError(e)

View File

@@ -111,7 +111,7 @@ pub fn process_epoch_single_pass<E: EthSpec>(
conf: SinglePassConfig,
) -> Result<ParticipationEpochSummary<E>, Error> {
initialize_epoch_cache(state, spec)?;
initialize_progressive_balances_cache(state, None, spec)?;
initialize_progressive_balances_cache(state, spec)?;
state.build_exit_cache(spec)?;
let previous_epoch = state.previous_epoch();

View File

@@ -113,7 +113,7 @@ pub fn upgrade_to_altair<E: EthSpec>(
// Fill in previous epoch participation from the pre state's pending attestations.
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
// Note: A duplicate committee is assigned for the current and next committee at the fork