mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 19:51:47 +00:00
Realized unrealized experimentation (#3322)
## Issue Addressed Add a flag that optionally enables unrealized vote tracking. Would like to test out on testnets and benchmark differences in methods of vote tracking. This PR includes a DB schema upgrade to enable to new vote tracking style. Co-authored-by: realbigsean <sean@sigmaprime.io> Co-authored-by: Paul Hauner <paul@paulhauner.com> Co-authored-by: sean <seananderson33@gmail.com> Co-authored-by: Mac L <mjladson@pm.me>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
pub use epoch_processing_summary::EpochProcessingSummary;
|
||||
use errors::EpochProcessingError as Error;
|
||||
pub use justification_and_finalization_state::JustificationAndFinalizationState;
|
||||
pub use registry_updates::process_registry_updates;
|
||||
use safe_arith::SafeArith;
|
||||
pub use slashings::process_slashings;
|
||||
@@ -14,6 +15,7 @@ pub mod effective_balance_updates;
|
||||
pub mod epoch_processing_summary;
|
||||
pub mod errors;
|
||||
pub mod historical_roots_update;
|
||||
pub mod justification_and_finalization_state;
|
||||
pub mod registry_updates;
|
||||
pub mod resets;
|
||||
pub mod slashings;
|
||||
|
||||
@@ -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, &participation_cache, spec)?;
|
||||
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
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::consts::altair::TIMELY_TARGET_FLAG_INDEX;
|
||||
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 previous_epoch = state.previous_epoch();
|
||||
@@ -24,7 +28,7 @@ pub fn process_justification_and_finalization<T: EthSpec>(
|
||||
let previous_target_balance = previous_indices.total_balance()?;
|
||||
let current_target_balance = current_indices.total_balance()?;
|
||||
weigh_justification_and_finalization(
|
||||
state,
|
||||
justification_and_finalization_state,
|
||||
total_active_balance,
|
||||
previous_target_balance,
|
||||
current_target_balance,
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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