mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-22 14:24:44 +00:00
Merge remote-tracking branch 'origin/unstable' into tree-states
This commit is contained in:
@@ -33,7 +33,9 @@ pub fn process_epoch<T: EthSpec>(
|
||||
let sync_committee = state.current_sync_committee()?.clone();
|
||||
|
||||
// Justification and finalization.
|
||||
process_justification_and_finalization(state, &participation_cache)?;
|
||||
let justification_and_finalization_state =
|
||||
process_justification_and_finalization(state, &participation_cache)?;
|
||||
justification_and_finalization_state.apply_changes_to_state(state);
|
||||
|
||||
process_inactivity_updates(state, &mut participation_cache, spec)?;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ pub fn process_inactivity_updates<T: EthSpec>(
|
||||
participation_cache: &mut ParticipationCache,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), EpochProcessingError> {
|
||||
let previous_epoch = state.previous_epoch();
|
||||
// Score updates based on previous epoch participation, skip genesis epoch
|
||||
if state.current_epoch() == T::genesis_epoch() {
|
||||
return Ok(());
|
||||
@@ -25,7 +26,7 @@ pub fn process_inactivity_updates<T: EthSpec>(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let is_in_inactivity_leak = state.is_in_inactivity_leak(spec);
|
||||
let is_in_inactivity_leak = state.is_in_inactivity_leak(previous_epoch, spec);
|
||||
|
||||
let mut inactivity_scores = state.inactivity_scores_mut()?.iter_cow();
|
||||
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
use super::ParticipationCache;
|
||||
use crate::per_epoch_processing::weigh_justification_and_finalization;
|
||||
use crate::per_epoch_processing::Error;
|
||||
use crate::per_epoch_processing::{
|
||||
weigh_justification_and_finalization, JustificationAndFinalizationState,
|
||||
};
|
||||
use safe_arith::SafeArith;
|
||||
use types::{BeaconState, EthSpec};
|
||||
|
||||
/// Update the justified and finalized checkpoints for matching target attestations.
|
||||
pub fn process_justification_and_finalization<T: EthSpec>(
|
||||
state: &mut BeaconState<T>,
|
||||
state: &BeaconState<T>,
|
||||
participation_cache: &ParticipationCache,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<JustificationAndFinalizationState<T>, Error> {
|
||||
let justification_and_finalization_state = JustificationAndFinalizationState::new(state);
|
||||
|
||||
if state.current_epoch() <= T::genesis_epoch().safe_add(1)? {
|
||||
return Ok(());
|
||||
return Ok(justification_and_finalization_state);
|
||||
}
|
||||
|
||||
let total_active_balance = participation_cache.current_epoch_total_active_balance();
|
||||
let previous_target_balance = participation_cache.previous_epoch_target_attesting_balance()?;
|
||||
let current_target_balance = participation_cache.current_epoch_target_attesting_balance()?;
|
||||
weigh_justification_and_finalization(
|
||||
state,
|
||||
justification_and_finalization_state,
|
||||
total_active_balance,
|
||||
previous_target_balance,
|
||||
current_target_balance,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
//! Additionally, this cache is returned from the `altair::process_epoch` function and can be used
|
||||
//! to get useful summaries about the validator participation in an epoch.
|
||||
|
||||
use crate::common::altair::get_base_reward;
|
||||
use crate::common::altair::{get_base_reward, BaseRewardPerIncrement};
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use types::milhouse::update_map::{MaxMap, UpdateMap};
|
||||
use types::{
|
||||
@@ -31,6 +31,7 @@ pub enum Error {
|
||||
MissingValidator(usize),
|
||||
BeaconState(BeaconStateError),
|
||||
Arith(ArithError),
|
||||
InvalidValidatorIndex(usize),
|
||||
}
|
||||
|
||||
impl From<BeaconStateError> for Error {
|
||||
@@ -115,11 +116,13 @@ impl SingleEpochParticipationCache {
|
||||
val_index: usize,
|
||||
validator: &Validator,
|
||||
epoch_participation: &ParticipationFlags,
|
||||
state: &BeaconState<T>,
|
||||
// FIXME(sproul): remove state argument
|
||||
_state: &BeaconState<T>,
|
||||
current_epoch: Epoch,
|
||||
relative_epoch: RelativeEpoch,
|
||||
) -> Result<(), BeaconStateError> {
|
||||
// Sanity check to ensure the validator is active.
|
||||
let epoch = relative_epoch.into_epoch(state.current_epoch());
|
||||
let epoch = relative_epoch.into_epoch(current_epoch);
|
||||
if !validator.is_active_at(epoch) {
|
||||
return Err(BeaconStateError::ValidatorIsInactive { val_index });
|
||||
}
|
||||
@@ -220,6 +223,8 @@ impl ParticipationCache {
|
||||
let mut validators = ValidatorInfoCache::new(state.validators().len());
|
||||
|
||||
let current_epoch_total_active_balance = state.get_total_active_balance()?;
|
||||
let base_reward_per_increment =
|
||||
BaseRewardPerIncrement::new(current_epoch_total_active_balance, spec)?;
|
||||
|
||||
// Contains the set of validators which are either:
|
||||
//
|
||||
@@ -257,7 +262,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(val);
|
||||
let is_eligible = state.is_eligible_validator(previous_epoch, val);
|
||||
|
||||
if is_active_current_epoch {
|
||||
current_epoch_participation.process_active_validator(
|
||||
@@ -265,6 +270,7 @@ impl ParticipationCache {
|
||||
val,
|
||||
curr_epoch_flags,
|
||||
state,
|
||||
current_epoch,
|
||||
RelativeEpoch::Current,
|
||||
)?;
|
||||
}
|
||||
@@ -277,6 +283,7 @@ impl ParticipationCache {
|
||||
val,
|
||||
prev_epoch_flags,
|
||||
state,
|
||||
current_epoch,
|
||||
RelativeEpoch::Previous,
|
||||
)?;
|
||||
}
|
||||
@@ -326,7 +333,7 @@ impl ParticipationCache {
|
||||
if is_eligible || is_active_current_epoch {
|
||||
let effective_balance = val.effective_balance;
|
||||
let base_reward =
|
||||
get_base_reward(effective_balance, current_epoch_total_active_balance, spec)?;
|
||||
get_base_reward(effective_balance, base_reward_per_increment, spec)?;
|
||||
validator_info.base_reward = base_reward;
|
||||
validators.info[val_index] = Some(validator_info);
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ pub fn get_flag_index_deltas<T: EthSpec>(
|
||||
let unslashed_participating_increments =
|
||||
unslashed_participating_balance.safe_div(spec.effective_balance_increment)?;
|
||||
let active_increments = total_active_balance.safe_div(spec.effective_balance_increment)?;
|
||||
let previous_epoch = state.previous_epoch();
|
||||
|
||||
for &index in participation_cache.eligible_validator_indices() {
|
||||
let validator = participation_cache.get_validator(index)?;
|
||||
@@ -84,7 +85,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(spec) {
|
||||
if !state.is_in_inactivity_leak(previous_epoch, spec) {
|
||||
let reward_numerator = base_reward
|
||||
.safe_mul(weight)?
|
||||
.safe_mul(unslashed_participating_increments)?;
|
||||
|
||||
@@ -31,7 +31,9 @@ pub fn process_epoch<T: EthSpec>(
|
||||
validator_statuses.process_attestations(state)?;
|
||||
|
||||
// Justification and finalization.
|
||||
process_justification_and_finalization(state, &validator_statuses.total_balances, spec)?;
|
||||
let justification_and_finalization_state =
|
||||
process_justification_and_finalization(state, &validator_statuses.total_balances, spec)?;
|
||||
justification_and_finalization_state.apply_changes_to_state(state);
|
||||
|
||||
// Rewards and Penalties.
|
||||
process_rewards_and_penalties(state, &mut validator_statuses, spec)?;
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
use crate::per_epoch_processing::base::TotalBalances;
|
||||
use crate::per_epoch_processing::weigh_justification_and_finalization;
|
||||
use crate::per_epoch_processing::Error;
|
||||
use crate::per_epoch_processing::{
|
||||
weigh_justification_and_finalization, JustificationAndFinalizationState,
|
||||
};
|
||||
use safe_arith::SafeArith;
|
||||
use types::{BeaconState, ChainSpec, EthSpec};
|
||||
|
||||
/// Update the justified and finalized checkpoints for matching target attestations.
|
||||
pub fn process_justification_and_finalization<T: EthSpec>(
|
||||
state: &mut BeaconState<T>,
|
||||
state: &BeaconState<T>,
|
||||
total_balances: &TotalBalances,
|
||||
_spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<JustificationAndFinalizationState<T>, Error> {
|
||||
let justification_and_finalization_state = JustificationAndFinalizationState::new(state);
|
||||
|
||||
if state.current_epoch() <= T::genesis_epoch().safe_add(1)? {
|
||||
return Ok(());
|
||||
return Ok(justification_and_finalization_state);
|
||||
}
|
||||
|
||||
weigh_justification_and_finalization(
|
||||
state,
|
||||
justification_and_finalization_state,
|
||||
total_balances.current_epoch(),
|
||||
total_balances.previous_epoch_target_attesters(),
|
||||
total_balances.current_epoch_target_attesters(),
|
||||
|
||||
@@ -78,6 +78,7 @@ pub fn get_attestation_deltas<T: EthSpec>(
|
||||
validator_statuses: &ValidatorStatuses,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Vec<AttestationDelta>, Error> {
|
||||
let previous_epoch = state.previous_epoch();
|
||||
let finality_delay = state
|
||||
.previous_epoch()
|
||||
.safe_sub(state.finalized_checkpoint().epoch)?
|
||||
@@ -94,7 +95,7 @@ pub fn get_attestation_deltas<T: EthSpec>(
|
||||
// eligible.
|
||||
// FIXME(sproul): this is inefficient
|
||||
let full_validator = state.get_validator(index)?;
|
||||
if !state.is_eligible_validator(full_validator) {
|
||||
if !state.is_eligible_validator(previous_epoch, full_validator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -278,8 +278,8 @@ impl ValidatorStatuses {
|
||||
// Loop through the participating validator indices and update the status vec.
|
||||
for validator_index in attesting_indices {
|
||||
self.statuses
|
||||
.get_mut(validator_index)
|
||||
.ok_or(BeaconStateError::UnknownValidator(validator_index))?
|
||||
.get_mut(validator_index as usize)
|
||||
.ok_or(BeaconStateError::UnknownValidator(validator_index as usize))?
|
||||
.update(&status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,12 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
|
||||
EpochProcessingSummary::Altair {
|
||||
participation_cache,
|
||||
..
|
||||
} => participation_cache.is_current_epoch_timely_target_attester(val_index),
|
||||
} => participation_cache
|
||||
.is_current_epoch_timely_target_attester(val_index)
|
||||
.or_else(|e| match e {
|
||||
ParticipationCacheError::InvalidValidatorIndex(_) => Ok(false),
|
||||
e => Err(e),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +223,12 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
|
||||
EpochProcessingSummary::Altair {
|
||||
participation_cache,
|
||||
..
|
||||
} => participation_cache.is_previous_epoch_timely_target_attester(val_index),
|
||||
} => participation_cache
|
||||
.is_previous_epoch_timely_target_attester(val_index)
|
||||
.or_else(|e| match e {
|
||||
ParticipationCacheError::InvalidValidatorIndex(_) => Ok(false),
|
||||
e => Err(e),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +254,12 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
|
||||
EpochProcessingSummary::Altair {
|
||||
participation_cache,
|
||||
..
|
||||
} => participation_cache.is_previous_epoch_timely_head_attester(val_index),
|
||||
} => participation_cache
|
||||
.is_previous_epoch_timely_head_attester(val_index)
|
||||
.or_else(|e| match e {
|
||||
ParticipationCacheError::InvalidValidatorIndex(_) => Ok(false),
|
||||
e => Err(e),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,7 +285,12 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
|
||||
EpochProcessingSummary::Altair {
|
||||
participation_cache,
|
||||
..
|
||||
} => participation_cache.is_previous_epoch_timely_source_attester(val_index),
|
||||
} => participation_cache
|
||||
.is_previous_epoch_timely_source_attester(val_index)
|
||||
.or_else(|e| match e {
|
||||
ParticipationCacheError::InvalidValidatorIndex(_) => Ok(false),
|
||||
e => Err(e),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
use types::{BeaconState, BeaconStateError, BitVector, Checkpoint, Epoch, EthSpec, Hash256};
|
||||
|
||||
/// This is a subset of the `BeaconState` which is used to compute justification and finality
|
||||
/// without modifying the `BeaconState`.
|
||||
///
|
||||
/// A `JustificationAndFinalizationState` can be created from a `BeaconState` to compute
|
||||
/// justification/finality changes and then applied to a `BeaconState` to enshrine those changes.
|
||||
#[must_use = "this value must be applied to a state or explicitly dropped"]
|
||||
pub struct JustificationAndFinalizationState<T: EthSpec> {
|
||||
/*
|
||||
* Immutable fields.
|
||||
*/
|
||||
previous_epoch: Epoch,
|
||||
previous_epoch_target_root: Result<Hash256, BeaconStateError>,
|
||||
current_epoch: Epoch,
|
||||
current_epoch_target_root: Result<Hash256, BeaconStateError>,
|
||||
/*
|
||||
* Mutable fields.
|
||||
*/
|
||||
previous_justified_checkpoint: Checkpoint,
|
||||
current_justified_checkpoint: Checkpoint,
|
||||
finalized_checkpoint: Checkpoint,
|
||||
justification_bits: BitVector<T::JustificationBitsLength>,
|
||||
}
|
||||
|
||||
impl<T: EthSpec> JustificationAndFinalizationState<T> {
|
||||
pub fn new(state: &BeaconState<T>) -> Self {
|
||||
let previous_epoch = state.previous_epoch();
|
||||
let current_epoch = state.current_epoch();
|
||||
Self {
|
||||
previous_epoch,
|
||||
previous_epoch_target_root: state.get_block_root_at_epoch(previous_epoch).copied(),
|
||||
current_epoch,
|
||||
current_epoch_target_root: state.get_block_root_at_epoch(current_epoch).copied(),
|
||||
previous_justified_checkpoint: state.previous_justified_checkpoint(),
|
||||
current_justified_checkpoint: state.current_justified_checkpoint(),
|
||||
finalized_checkpoint: state.finalized_checkpoint(),
|
||||
justification_bits: state.justification_bits().clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_changes_to_state(self, state: &mut BeaconState<T>) {
|
||||
let Self {
|
||||
/*
|
||||
* Immutable fields do not need to be used.
|
||||
*/
|
||||
previous_epoch: _,
|
||||
previous_epoch_target_root: _,
|
||||
current_epoch: _,
|
||||
current_epoch_target_root: _,
|
||||
/*
|
||||
* Mutable fields *must* be used.
|
||||
*/
|
||||
previous_justified_checkpoint,
|
||||
current_justified_checkpoint,
|
||||
finalized_checkpoint,
|
||||
justification_bits,
|
||||
} = self;
|
||||
|
||||
*state.previous_justified_checkpoint_mut() = previous_justified_checkpoint;
|
||||
*state.current_justified_checkpoint_mut() = current_justified_checkpoint;
|
||||
*state.finalized_checkpoint_mut() = finalized_checkpoint;
|
||||
*state.justification_bits_mut() = justification_bits;
|
||||
}
|
||||
|
||||
pub fn previous_epoch(&self) -> Epoch {
|
||||
self.previous_epoch
|
||||
}
|
||||
|
||||
pub fn current_epoch(&self) -> Epoch {
|
||||
self.current_epoch
|
||||
}
|
||||
|
||||
pub fn get_block_root_at_epoch(&self, epoch: Epoch) -> Result<Hash256, BeaconStateError> {
|
||||
if epoch == self.previous_epoch {
|
||||
self.previous_epoch_target_root.clone()
|
||||
} else if epoch == self.current_epoch {
|
||||
self.current_epoch_target_root.clone()
|
||||
} else {
|
||||
Err(BeaconStateError::SlotOutOfBounds)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn previous_justified_checkpoint(&self) -> Checkpoint {
|
||||
self.previous_justified_checkpoint
|
||||
}
|
||||
|
||||
pub fn previous_justified_checkpoint_mut(&mut self) -> &mut Checkpoint {
|
||||
&mut self.previous_justified_checkpoint
|
||||
}
|
||||
|
||||
pub fn current_justified_checkpoint_mut(&mut self) -> &mut Checkpoint {
|
||||
&mut self.current_justified_checkpoint
|
||||
}
|
||||
|
||||
pub fn current_justified_checkpoint(&self) -> Checkpoint {
|
||||
self.current_justified_checkpoint
|
||||
}
|
||||
|
||||
pub fn finalized_checkpoint(&self) -> Checkpoint {
|
||||
self.finalized_checkpoint
|
||||
}
|
||||
|
||||
pub fn finalized_checkpoint_mut(&mut self) -> &mut Checkpoint {
|
||||
&mut self.finalized_checkpoint
|
||||
}
|
||||
|
||||
pub fn justification_bits(&self) -> &BitVector<T::JustificationBitsLength> {
|
||||
&self.justification_bits
|
||||
}
|
||||
|
||||
pub fn justification_bits_mut(&mut self) -> &mut BitVector<T::JustificationBitsLength> {
|
||||
&mut self.justification_bits
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,8 @@ use bls::Hash256;
|
||||
use env_logger::{Builder, Env};
|
||||
use types::Slot;
|
||||
|
||||
#[test]
|
||||
fn runs_without_error() {
|
||||
#[tokio::test]
|
||||
async fn runs_without_error() {
|
||||
Builder::from_env(Env::default().default_filter_or("error")).init();
|
||||
|
||||
let harness = BeaconChainHarness::builder(MinimalEthSpec)
|
||||
@@ -22,15 +22,17 @@ fn runs_without_error() {
|
||||
(MinimalEthSpec::genesis_epoch() + 4).end_slot(MinimalEthSpec::slots_per_epoch());
|
||||
|
||||
let state = harness.get_current_state();
|
||||
harness.add_attested_blocks_at_slots(
|
||||
state,
|
||||
Hash256::zero(),
|
||||
(1..target_slot.as_u64())
|
||||
.map(Slot::new)
|
||||
.collect::<Vec<_>>()
|
||||
.as_slice(),
|
||||
(0..8).collect::<Vec<_>>().as_slice(),
|
||||
);
|
||||
harness
|
||||
.add_attested_blocks_at_slots(
|
||||
state,
|
||||
Hash256::zero(),
|
||||
(1..target_slot.as_u64())
|
||||
.map(Slot::new)
|
||||
.collect::<Vec<_>>()
|
||||
.as_slice(),
|
||||
(0..8).collect::<Vec<_>>().as_slice(),
|
||||
)
|
||||
.await;
|
||||
let mut new_head_state = harness.get_current_state();
|
||||
|
||||
process_epoch(&mut new_head_state, &spec).unwrap();
|
||||
@@ -45,8 +47,8 @@ mod release_tests {
|
||||
use beacon_chain::test_utils::{AttestationStrategy, BlockStrategy};
|
||||
use types::{Epoch, ForkName, InconsistentFork, MainnetEthSpec};
|
||||
|
||||
#[test]
|
||||
fn altair_state_on_base_fork() {
|
||||
#[tokio::test]
|
||||
async fn altair_state_on_base_fork() {
|
||||
let mut spec = MainnetEthSpec::default_spec();
|
||||
let slots_per_epoch = MainnetEthSpec::slots_per_epoch();
|
||||
// The Altair fork happens at epoch 1.
|
||||
@@ -61,12 +63,14 @@ mod release_tests {
|
||||
|
||||
harness.advance_slot();
|
||||
|
||||
harness.extend_chain(
|
||||
// Build out enough blocks so we get an Altair block at the very end of an epoch.
|
||||
(slots_per_epoch * 2 - 1) as usize,
|
||||
BlockStrategy::OnCanonicalHead,
|
||||
AttestationStrategy::AllValidators,
|
||||
);
|
||||
harness
|
||||
.extend_chain(
|
||||
// Build out enough blocks so we get an Altair block at the very end of an epoch.
|
||||
(slots_per_epoch * 2 - 1) as usize,
|
||||
BlockStrategy::OnCanonicalHead,
|
||||
AttestationStrategy::AllValidators,
|
||||
)
|
||||
.await;
|
||||
|
||||
harness.get_current_state()
|
||||
};
|
||||
@@ -103,8 +107,8 @@ mod release_tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn base_state_on_altair_fork() {
|
||||
#[tokio::test]
|
||||
async fn base_state_on_altair_fork() {
|
||||
let mut spec = MainnetEthSpec::default_spec();
|
||||
let slots_per_epoch = MainnetEthSpec::slots_per_epoch();
|
||||
// The Altair fork never happens.
|
||||
@@ -119,12 +123,14 @@ mod release_tests {
|
||||
|
||||
harness.advance_slot();
|
||||
|
||||
harness.extend_chain(
|
||||
// Build out enough blocks so we get a block at the very end of an epoch.
|
||||
(slots_per_epoch * 2 - 1) as usize,
|
||||
BlockStrategy::OnCanonicalHead,
|
||||
AttestationStrategy::AllValidators,
|
||||
);
|
||||
harness
|
||||
.extend_chain(
|
||||
// Build out enough blocks so we get a block at the very end of an epoch.
|
||||
(slots_per_epoch * 2 - 1) as usize,
|
||||
BlockStrategy::OnCanonicalHead,
|
||||
AttestationStrategy::AllValidators,
|
||||
)
|
||||
.await;
|
||||
|
||||
harness.get_current_state()
|
||||
};
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
use crate::per_epoch_processing::Error;
|
||||
use crate::per_epoch_processing::{Error, JustificationAndFinalizationState};
|
||||
use safe_arith::SafeArith;
|
||||
use std::ops::Range;
|
||||
use types::{BeaconState, Checkpoint, EthSpec};
|
||||
use types::{Checkpoint, EthSpec};
|
||||
|
||||
/// Update the justified and finalized checkpoints for matching target attestations.
|
||||
#[allow(clippy::if_same_then_else)] // For readability and consistency with spec.
|
||||
pub fn weigh_justification_and_finalization<T: EthSpec>(
|
||||
state: &mut BeaconState<T>,
|
||||
mut state: JustificationAndFinalizationState<T>,
|
||||
total_active_balance: u64,
|
||||
previous_target_balance: u64,
|
||||
current_target_balance: u64,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<JustificationAndFinalizationState<T>, Error> {
|
||||
let previous_epoch = state.previous_epoch();
|
||||
let current_epoch = state.current_epoch();
|
||||
|
||||
@@ -24,7 +24,7 @@ pub fn weigh_justification_and_finalization<T: EthSpec>(
|
||||
if previous_target_balance.safe_mul(3)? >= total_active_balance.safe_mul(2)? {
|
||||
*state.current_justified_checkpoint_mut() = Checkpoint {
|
||||
epoch: previous_epoch,
|
||||
root: *state.get_block_root_at_epoch(previous_epoch)?,
|
||||
root: state.get_block_root_at_epoch(previous_epoch)?,
|
||||
};
|
||||
state.justification_bits_mut().set(1, true)?;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ pub fn weigh_justification_and_finalization<T: EthSpec>(
|
||||
if current_target_balance.safe_mul(3)? >= total_active_balance.safe_mul(2)? {
|
||||
*state.current_justified_checkpoint_mut() = Checkpoint {
|
||||
epoch: current_epoch,
|
||||
root: *state.get_block_root_at_epoch(current_epoch)?,
|
||||
root: state.get_block_root_at_epoch(current_epoch)?,
|
||||
};
|
||||
state.justification_bits_mut().set(0, true)?;
|
||||
}
|
||||
@@ -66,5 +66,5 @@ pub fn weigh_justification_and_finalization<T: EthSpec>(
|
||||
*state.finalized_checkpoint_mut() = old_current_justified_checkpoint;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(state)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user