mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-15 10:52:43 +00:00
Merge remote-tracking branch 'origin/unstable' into tree-states
This commit is contained in:
@@ -220,9 +220,12 @@ impl ParticipationCache {
|
||||
// Fast path for inactivity scores update when we are definitely not in an inactivity leak.
|
||||
// This breaks the dependence of `process_inactivity_updates` on the finalization
|
||||
// re-calculation.
|
||||
let definitely_not_in_inactivity_leak =
|
||||
state.finalized_checkpoint().epoch + spec.min_epochs_to_inactivity_penalty + 1
|
||||
>= state.current_epoch();
|
||||
let definitely_not_in_inactivity_leak = state
|
||||
.finalized_checkpoint()
|
||||
.epoch
|
||||
.safe_add(spec.min_epochs_to_inactivity_penalty)?
|
||||
.safe_add(1)?
|
||||
>= state.current_epoch();
|
||||
let mut inactivity_score_updates = MaxMap::default();
|
||||
|
||||
// Iterate through all validators, updating:
|
||||
@@ -242,7 +245,7 @@ impl ParticipationCache {
|
||||
for (val_index, (((val, curr_epoch_flags), prev_epoch_flags), inactivity_score)) in iter {
|
||||
let is_active_current_epoch = val.is_active_at(current_epoch);
|
||||
let is_active_previous_epoch = val.is_active_at(previous_epoch);
|
||||
let is_eligible = state.is_eligible_validator(previous_epoch, val);
|
||||
let is_eligible = state.is_eligible_validator(previous_epoch, val)?;
|
||||
|
||||
if is_active_current_epoch {
|
||||
current_epoch_participation.process_active_validator(
|
||||
|
||||
@@ -54,7 +54,7 @@ pub fn get_flag_index_deltas<T: EthSpec>(
|
||||
let mut delta = Delta::default();
|
||||
|
||||
if validator.is_unslashed_participating_index(flag_index)? {
|
||||
if !state.is_in_inactivity_leak(previous_epoch, spec) {
|
||||
if !state.is_in_inactivity_leak(previous_epoch, spec)? {
|
||||
let reward_numerator = base_reward
|
||||
.safe_mul(weight)?
|
||||
.safe_mul(unslashed_participating_increments)?;
|
||||
|
||||
@@ -39,7 +39,7 @@ pub fn process_epoch<T: EthSpec>(
|
||||
justification_and_finalization_state.apply_changes_to_state(state);
|
||||
|
||||
// Rewards and Penalties.
|
||||
process_rewards_and_penalties(state, &mut validator_statuses, spec)?;
|
||||
process_rewards_and_penalties(state, &validator_statuses, spec)?;
|
||||
|
||||
// Registry Updates.
|
||||
process_registry_updates(state, spec)?;
|
||||
|
||||
@@ -48,7 +48,7 @@ impl AttestationDelta {
|
||||
/// Apply attester and proposer rewards.
|
||||
pub fn process_rewards_and_penalties<T: EthSpec>(
|
||||
state: &mut BeaconState<T>,
|
||||
validator_statuses: &mut ValidatorStatuses,
|
||||
validator_statuses: &ValidatorStatuses,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
if state.current_epoch() == T::genesis_epoch() {
|
||||
@@ -62,7 +62,7 @@ pub fn process_rewards_and_penalties<T: EthSpec>(
|
||||
return Err(Error::ValidatorStatusesInconsistent);
|
||||
}
|
||||
|
||||
let deltas = get_attestation_deltas(state, validator_statuses, spec)?;
|
||||
let deltas = get_attestation_deltas_all(state, validator_statuses, spec)?;
|
||||
|
||||
// Apply the deltas, erroring on overflow above but not on overflow below (saturating at 0
|
||||
// instead).
|
||||
@@ -76,10 +76,41 @@ pub fn process_rewards_and_penalties<T: EthSpec>(
|
||||
}
|
||||
|
||||
/// Apply rewards for participation in attestations during the previous epoch.
|
||||
pub fn get_attestation_deltas<T: EthSpec>(
|
||||
pub fn get_attestation_deltas_all<T: EthSpec>(
|
||||
state: &BeaconState<T>,
|
||||
validator_statuses: &ValidatorStatuses,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Vec<AttestationDelta>, Error> {
|
||||
get_attestation_deltas(state, validator_statuses, None, spec)
|
||||
}
|
||||
|
||||
/// Apply rewards for participation in attestations during the previous epoch, and only compute
|
||||
/// rewards for a subset of validators.
|
||||
pub fn get_attestation_deltas_subset<T: EthSpec>(
|
||||
state: &BeaconState<T>,
|
||||
validator_statuses: &ValidatorStatuses,
|
||||
validators_subset: &Vec<usize>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Vec<(usize, AttestationDelta)>, Error> {
|
||||
get_attestation_deltas(state, validator_statuses, Some(validators_subset), spec).map(|deltas| {
|
||||
deltas
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.filter(|(index, _)| validators_subset.contains(index))
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
/// Apply rewards for participation in attestations during the previous epoch.
|
||||
/// If `maybe_validators_subset` specified, only the deltas for the specified validator subset is
|
||||
/// returned, otherwise deltas for all validators are returned.
|
||||
///
|
||||
/// Returns a vec of validator indices to `AttestationDelta`.
|
||||
fn get_attestation_deltas<T: EthSpec>(
|
||||
state: &BeaconState<T>,
|
||||
validator_statuses: &ValidatorStatuses,
|
||||
maybe_validators_subset: Option<&Vec<usize>>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Vec<AttestationDelta>, Error> {
|
||||
let finality_delay = state
|
||||
.previous_epoch()
|
||||
@@ -91,6 +122,13 @@ pub fn get_attestation_deltas<T: EthSpec>(
|
||||
let total_balances = &validator_statuses.total_balances;
|
||||
let sqrt_total_active_balance = SqrtTotalActiveBalance::new(total_balances.current_epoch());
|
||||
|
||||
// Ignore validator if a subset is specified and validator is not in the subset
|
||||
let include_validator_delta = |idx| match maybe_validators_subset.as_ref() {
|
||||
None => true,
|
||||
Some(validators_subset) if validators_subset.contains(&idx) => true,
|
||||
Some(_) => false,
|
||||
};
|
||||
|
||||
for (index, validator) in validator_statuses.statuses.iter().enumerate() {
|
||||
// Ignore ineligible validators. All sub-functions of the spec do this except for
|
||||
// `get_inclusion_delay_deltas`. It's safe to do so here because any validator that is in
|
||||
@@ -106,41 +144,46 @@ pub fn get_attestation_deltas<T: EthSpec>(
|
||||
spec,
|
||||
)?;
|
||||
|
||||
let source_delta =
|
||||
get_source_delta(validator, base_reward, total_balances, finality_delay, spec)?;
|
||||
let target_delta =
|
||||
get_target_delta(validator, base_reward, total_balances, finality_delay, spec)?;
|
||||
let head_delta =
|
||||
get_head_delta(validator, base_reward, total_balances, finality_delay, spec)?;
|
||||
let (inclusion_delay_delta, proposer_delta) =
|
||||
get_inclusion_delay_delta(validator, base_reward, spec)?;
|
||||
let inactivity_penalty_delta =
|
||||
get_inactivity_penalty_delta(validator, base_reward, finality_delay, spec)?;
|
||||
|
||||
let delta = deltas
|
||||
.get_mut(index)
|
||||
.ok_or(Error::DeltaOutOfBounds(index))?;
|
||||
delta.source_delta.combine(source_delta)?;
|
||||
delta.target_delta.combine(target_delta)?;
|
||||
delta.head_delta.combine(head_delta)?;
|
||||
delta.inclusion_delay_delta.combine(inclusion_delay_delta)?;
|
||||
delta
|
||||
.inactivity_penalty_delta
|
||||
.combine(inactivity_penalty_delta)?;
|
||||
if include_validator_delta(index) {
|
||||
let source_delta =
|
||||
get_source_delta(validator, base_reward, total_balances, finality_delay, spec)?;
|
||||
let target_delta =
|
||||
get_target_delta(validator, base_reward, total_balances, finality_delay, spec)?;
|
||||
let head_delta =
|
||||
get_head_delta(validator, base_reward, total_balances, finality_delay, spec)?;
|
||||
let inactivity_penalty_delta =
|
||||
get_inactivity_penalty_delta(validator, base_reward, finality_delay, spec)?;
|
||||
|
||||
let delta = deltas
|
||||
.get_mut(index)
|
||||
.ok_or(Error::DeltaOutOfBounds(index))?;
|
||||
delta.source_delta.combine(source_delta)?;
|
||||
delta.target_delta.combine(target_delta)?;
|
||||
delta.head_delta.combine(head_delta)?;
|
||||
delta.inclusion_delay_delta.combine(inclusion_delay_delta)?;
|
||||
delta
|
||||
.inactivity_penalty_delta
|
||||
.combine(inactivity_penalty_delta)?;
|
||||
}
|
||||
|
||||
if let Some((proposer_index, proposer_delta)) = proposer_delta {
|
||||
deltas
|
||||
.get_mut(proposer_index)
|
||||
.ok_or(Error::ValidatorStatusesInconsistent)?
|
||||
.inclusion_delay_delta
|
||||
.combine(proposer_delta)?;
|
||||
if include_validator_delta(proposer_index) {
|
||||
deltas
|
||||
.get_mut(proposer_index)
|
||||
.ok_or(Error::ValidatorStatusesInconsistent)?
|
||||
.inclusion_delay_delta
|
||||
.combine(proposer_delta)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(deltas)
|
||||
}
|
||||
|
||||
fn get_attestation_component_delta(
|
||||
pub fn get_attestation_component_delta(
|
||||
index_in_unslashed_attesting_indices: bool,
|
||||
attesting_balance: u64,
|
||||
total_balances: &TotalBalances,
|
||||
@@ -223,7 +266,7 @@ fn get_head_delta(
|
||||
)
|
||||
}
|
||||
|
||||
fn get_inclusion_delay_delta(
|
||||
pub fn get_inclusion_delay_delta(
|
||||
validator: &ValidatorStatus,
|
||||
base_reward: u64,
|
||||
spec: &ChainSpec,
|
||||
@@ -249,7 +292,7 @@ fn get_inclusion_delay_delta(
|
||||
}
|
||||
}
|
||||
|
||||
fn get_inactivity_penalty_delta(
|
||||
pub fn get_inactivity_penalty_delta(
|
||||
validator: &ValidatorStatus,
|
||||
base_reward: u64,
|
||||
finality_delay: u64,
|
||||
|
||||
@@ -205,7 +205,7 @@ impl ValidatorStatuses {
|
||||
let effective_balance = validator.effective_balance();
|
||||
let mut status = ValidatorStatus {
|
||||
is_slashed: validator.slashed(),
|
||||
is_eligible: state.is_eligible_validator(previous_epoch, validator),
|
||||
is_eligible: state.is_eligible_validator(previous_epoch, validator)?,
|
||||
is_withdrawable_in_current_epoch: validator.is_withdrawable_at(current_epoch),
|
||||
current_epoch_effective_balance: effective_balance,
|
||||
..ValidatorStatus::default()
|
||||
|
||||
@@ -116,7 +116,7 @@ pub fn process_epoch_single_pass<E: EthSpec>(
|
||||
let previous_epoch = state.previous_epoch();
|
||||
let current_epoch = state.current_epoch();
|
||||
let next_epoch = state.next_epoch()?;
|
||||
let is_in_inactivity_leak = state.is_in_inactivity_leak(previous_epoch, spec);
|
||||
let is_in_inactivity_leak = state.is_in_inactivity_leak(previous_epoch, spec)?;
|
||||
let total_active_balance = state.get_total_active_balance()?;
|
||||
let churn_limit = state.get_churn_limit(spec)?;
|
||||
let finalized_checkpoint = state.finalized_checkpoint();
|
||||
@@ -198,7 +198,7 @@ pub fn process_epoch_single_pass<E: EthSpec>(
|
||||
let is_active_previous_epoch = validator.is_active_at(previous_epoch);
|
||||
let is_eligible = is_active_previous_epoch
|
||||
|| (validator.slashed()
|
||||
&& previous_epoch + Epoch::new(1) < validator.withdrawable_epoch());
|
||||
&& previous_epoch.safe_add(1)? < validator.withdrawable_epoch());
|
||||
|
||||
let base_reward = if is_eligible {
|
||||
epoch_cache.get_base_reward(index)?
|
||||
|
||||
Reference in New Issue
Block a user