Update state_processing

This commit is contained in:
Michael Sproul
2021-11-25 17:32:18 +11:00
parent 1b4dad0d76
commit 238ac98d7c
18 changed files with 107 additions and 20 deletions

View File

@@ -31,6 +31,7 @@ default = ["legacy-arith", "metrics"]
fake_crypto = ["bls/fake_crypto"] fake_crypto = ["bls/fake_crypto"]
legacy-arith = ["types/legacy-arith"] legacy-arith = ["types/legacy-arith"]
metrics = ["lighthouse_metrics", "lazy_static"] metrics = ["lighthouse_metrics", "lazy_static"]
milhouse = ["types/milhouse"]
arbitrary-fuzz = [ arbitrary-fuzz = [
"arbitrary", "arbitrary",
"types/arbitrary-fuzz", "types/arbitrary-fuzz",

View File

@@ -31,9 +31,14 @@ pub fn initiate_validator_exit<T: EthSpec>(
state state
.exit_cache_mut() .exit_cache_mut()
.record_validator_exit(exit_queue_epoch)?; .record_validator_exit(exit_queue_epoch)?;
state.get_validator_mut(index)?.exit_epoch = exit_queue_epoch;
state.get_validator_mut(index)?.withdrawable_epoch = let mut validators = state.validators_mut();
let validator = validators.get_validator_mut(index)?;
validator.exit_epoch = exit_queue_epoch;
validator.withdrawable_epoch =
exit_queue_epoch.safe_add(spec.min_validator_withdrawability_delay)?; exit_queue_epoch.safe_add(spec.min_validator_withdrawability_delay)?;
drop(validators);
Ok(()) Ok(())
} }

View File

@@ -17,13 +17,16 @@ pub fn slash_validator<T: EthSpec>(
initiate_validator_exit(state, slashed_index, spec)?; initiate_validator_exit(state, slashed_index, spec)?;
let validator = state.get_validator_mut(slashed_index)?; let mut validators = state.validators_mut();
let validator = validators.get_validator_mut(slashed_index)?;
validator.slashed = true; validator.slashed = true;
validator.withdrawable_epoch = cmp::max( validator.withdrawable_epoch = cmp::max(
validator.withdrawable_epoch, validator.withdrawable_epoch,
epoch.safe_add(T::EpochsPerSlashingsVector::to_u64())?, epoch.safe_add(T::EpochsPerSlashingsVector::to_u64())?,
); );
let validator_effective_balance = validator.effective_balance; let validator_effective_balance = validator.effective_balance;
drop(validators);
state.set_slashings( state.set_slashings(
epoch, epoch,
state state

View File

@@ -76,8 +76,9 @@ pub fn process_activations<T: EthSpec>(
state: &mut BeaconState<T>, state: &mut BeaconState<T>,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<(), Error> { ) -> Result<(), Error> {
let (validators, balances) = state.validators_and_balances_mut(); let (mut validators, balances) = state.validators_and_balances_mut();
for (index, validator) in validators.iter_mut().enumerate() { for index in 0..validators.len() {
let validator = validators.get_validator_mut(index)?;
let balance = balances let balance = balances
.get(index) .get(index)
.copied() .copied()

View File

@@ -57,6 +57,8 @@ pub enum BlockProcessingError {
ArithError(ArithError), ArithError(ArithError),
InconsistentBlockFork(InconsistentFork), InconsistentBlockFork(InconsistentFork),
InconsistentStateFork(InconsistentFork), InconsistentStateFork(InconsistentFork),
#[cfg(feature = "milhouse")]
MilhouseError(milhouse::Error),
} }
impl From<BeaconStateError> for BlockProcessingError { impl From<BeaconStateError> for BlockProcessingError {
@@ -89,6 +91,13 @@ impl From<SyncAggregateInvalid> for BlockProcessingError {
} }
} }
#[cfg(feature = "milhouse")]
impl From<milhouse::Error> for BlockProcessingError {
fn from(e: milhouse::Error) -> Self {
Self::MilhouseError(e)
}
}
impl From<BlockOperationError<HeaderInvalid>> for BlockProcessingError { impl From<BlockOperationError<HeaderInvalid>> for BlockProcessingError {
fn from(e: BlockOperationError<HeaderInvalid>) -> BlockProcessingError { fn from(e: BlockOperationError<HeaderInvalid>) -> BlockProcessingError {
match e { match e {

View File

@@ -14,6 +14,9 @@ use types::{
SignedVoluntaryExit, SigningData, Slot, SyncAggregate, SyncAggregatorSelectionData, Unsigned, SignedVoluntaryExit, SigningData, Slot, SyncAggregate, SyncAggregatorSelectionData, Unsigned,
}; };
#[cfg(feature = "milhouse")]
use types::milhouse::prelude::*;
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]

View File

@@ -21,6 +21,9 @@ use types::{
BeaconState, BeaconStateError, ChainSpec, Epoch, EthSpec, ParticipationFlags, RelativeEpoch, BeaconState, BeaconStateError, ChainSpec, Epoch, EthSpec, ParticipationFlags, RelativeEpoch,
}; };
#[cfg(feature = "milhouse")]
use types::milhouse::prelude::*;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Error { pub enum Error {
InvalidFlagIndex(usize), InvalidFlagIndex(usize),

View File

@@ -6,6 +6,9 @@ use types::eth_spec::EthSpec;
use types::participation_flags::ParticipationFlags; use types::participation_flags::ParticipationFlags;
use types::VariableList; use types::VariableList;
#[cfg(feature = "milhouse")]
use types::milhouse::prelude::*;
pub fn process_participation_flag_updates<T: EthSpec>( pub fn process_participation_flag_updates<T: EthSpec>(
state: &mut BeaconState<T>, state: &mut BeaconState<T>,
) -> Result<(), EpochProcessingError> { ) -> Result<(), EpochProcessingError> {

View File

@@ -6,6 +6,9 @@ use types::consts::altair::{
}; };
use types::{BeaconState, ChainSpec, EthSpec}; use types::{BeaconState, ChainSpec, EthSpec};
#[cfg(feature = "milhouse")]
use types::milhouse::prelude::*;
use crate::common::{altair::get_base_reward, decrease_balance, increase_balance}; use crate::common::{altair::get_base_reward, decrease_balance, increase_balance};
use crate::per_epoch_processing::{Delta, Error}; use crate::per_epoch_processing::{Delta, Error};

View File

@@ -7,6 +7,9 @@ use safe_arith::SafeArith;
use std::array::IntoIter as ArrayIter; use std::array::IntoIter as ArrayIter;
use types::{BeaconState, ChainSpec, EthSpec}; use types::{BeaconState, ChainSpec, EthSpec};
#[cfg(feature = "milhouse")]
use types::milhouse::prelude::*;
/// Combination of several deltas for different components of an attestation reward. /// Combination of several deltas for different components of an attestation reward.
/// ///
/// Exists only for compatibility with EF rewards tests. /// Exists only for compatibility with EF rewards tests.

View File

@@ -2,6 +2,9 @@ use crate::common::get_attesting_indices;
use safe_arith::SafeArith; use safe_arith::SafeArith;
use types::{BeaconState, BeaconStateError, ChainSpec, Epoch, EthSpec, PendingAttestation}; use types::{BeaconState, BeaconStateError, ChainSpec, Epoch, EthSpec, PendingAttestation};
#[cfg(feature = "milhouse")]
use types::milhouse::prelude::*;
#[cfg(feature = "arbitrary-fuzz")] #[cfg(feature = "arbitrary-fuzz")]
use arbitrary::Arbitrary; use arbitrary::Arbitrary;

View File

@@ -2,7 +2,7 @@ use super::errors::EpochProcessingError;
use safe_arith::SafeArith; use safe_arith::SafeArith;
use types::beacon_state::BeaconState; use types::beacon_state::BeaconState;
use types::chain_spec::ChainSpec; use types::chain_spec::ChainSpec;
use types::{BeaconStateError, EthSpec}; use types::{BeaconStateError, EthSpec, GetValidatorMut};
pub fn process_effective_balance_updates<T: EthSpec>( pub fn process_effective_balance_updates<T: EthSpec>(
state: &mut BeaconState<T>, state: &mut BeaconState<T>,
@@ -13,8 +13,9 @@ pub fn process_effective_balance_updates<T: EthSpec>(
.safe_div(spec.hysteresis_quotient)?; .safe_div(spec.hysteresis_quotient)?;
let downward_threshold = hysteresis_increment.safe_mul(spec.hysteresis_downward_multiplier)?; let downward_threshold = hysteresis_increment.safe_mul(spec.hysteresis_downward_multiplier)?;
let upward_threshold = hysteresis_increment.safe_mul(spec.hysteresis_upward_multiplier)?; let upward_threshold = hysteresis_increment.safe_mul(spec.hysteresis_upward_multiplier)?;
let (validators, balances) = state.validators_and_balances_mut(); let (mut validators, balances) = state.validators_and_balances_mut();
for (index, validator) in validators.iter_mut().enumerate() { for index in 0..validators.len() {
let validator = validators.get_validator_mut(index)?;
let balance = balances let balance = balances
.get(index) .get(index)
.copied() .copied()

View File

@@ -1,7 +1,7 @@
use crate::{common::initiate_validator_exit, per_epoch_processing::Error}; use crate::{common::initiate_validator_exit, per_epoch_processing::Error};
use itertools::Itertools; use itertools::Itertools;
use safe_arith::SafeArith; use safe_arith::SafeArith;
use types::{BeaconState, ChainSpec, EthSpec, Validator}; use types::{BeaconState, ChainSpec, EthSpec, GetValidatorMut, Validator};
/// Performs a validator registry update, if required. /// Performs a validator registry update, if required.
/// ///
@@ -30,11 +30,13 @@ pub fn process_registry_updates<T: EthSpec>(
.collect(); .collect();
for index in indices_to_update { for index in indices_to_update {
let validator = state.get_validator_mut(index)?; let mut validators = state.validators_mut();
let validator = validators.get_validator_mut(index)?;
if validator.is_eligible_for_activation_queue(spec) { if validator.is_eligible_for_activation_queue(spec) {
validator.activation_eligibility_epoch = current_epoch.safe_add(1)?; validator.activation_eligibility_epoch = current_epoch.safe_add(1)?;
} }
if is_ejectable(validator) { if is_ejectable(validator) {
drop(validators);
initiate_validator_exit(state, index, spec)?; initiate_validator_exit(state, index, spec)?;
} }
} }
@@ -52,8 +54,9 @@ pub fn process_registry_updates<T: EthSpec>(
// Dequeue validators for activation up to churn limit // Dequeue validators for activation up to churn limit
let churn_limit = state.get_churn_limit(spec)? as usize; let churn_limit = state.get_churn_limit(spec)? as usize;
let delayed_activation_epoch = state.compute_activation_exit_epoch(current_epoch, spec)?; let delayed_activation_epoch = state.compute_activation_exit_epoch(current_epoch, spec)?;
let mut validators = state.validators_mut();
for index in activation_queue.into_iter().take(churn_limit) { for index in activation_queue.into_iter().take(churn_limit) {
state.get_validator_mut(index)?.activation_epoch = delayed_activation_epoch; validators.get_validator_mut(index)?.activation_epoch = delayed_activation_epoch;
} }
Ok(()) Ok(())

View File

@@ -1,6 +1,6 @@
use crate::per_epoch_processing::Error; use crate::per_epoch_processing::Error;
use safe_arith::{SafeArith, SafeArithIter}; use safe_arith::{SafeArith, SafeArithIter};
use types::{BeaconState, BeaconStateError, ChainSpec, EthSpec, Unsigned}; use types::{BeaconState, BeaconStateError, ChainSpec, EthSpec, GetValidatorMut, Unsigned};
/// Process slashings. /// Process slashings.
pub fn process_slashings<T: EthSpec>( pub fn process_slashings<T: EthSpec>(
@@ -16,7 +16,8 @@ pub fn process_slashings<T: EthSpec>(
std::cmp::min(sum_slashings.safe_mul(slashing_multiplier)?, total_balance); std::cmp::min(sum_slashings.safe_mul(slashing_multiplier)?, total_balance);
let (validators, balances) = state.validators_and_balances_mut(); let (validators, balances) = state.validators_and_balances_mut();
for (index, validator) in validators.iter().enumerate() { for index in 0..validators.len() {
let validator = validators.get_validator(index)?;
if validator.slashed if validator.slashed
&& epoch.safe_add(T::EpochsPerSlashingsVector::to_u64().safe_div(2)?)? && epoch.safe_add(T::EpochsPerSlashingsVector::to_u64().safe_div(2)?)?
== validator.withdrawable_epoch == validator.withdrawable_epoch

View File

@@ -6,6 +6,9 @@ use types::{
ParticipationFlags, PendingAttestation, RelativeEpoch, SyncCommittee, VariableList, ParticipationFlags, PendingAttestation, RelativeEpoch, SyncCommittee, VariableList,
}; };
#[cfg(feature = "milhouse")]
use types::milhouse::prelude::*;
/// Translate the participation information from the epoch prior to the fork into Altair's format. /// Translate the participation information from the epoch prior to the fork into Altair's format.
pub fn translate_participation<E: EthSpec>( pub fn translate_participation<E: EthSpec>(
state: &mut BeaconState<E>, state: &mut BeaconState<E>,
@@ -104,6 +107,7 @@ pub fn upgrade_to_altair<E: EthSpec>(
committee_caches: mem::take(&mut pre.committee_caches), committee_caches: mem::take(&mut pre.committee_caches),
pubkey_cache: mem::take(&mut pre.pubkey_cache), pubkey_cache: mem::take(&mut pre.pubkey_cache),
exit_cache: mem::take(&mut pre.exit_cache), exit_cache: mem::take(&mut pre.exit_cache),
#[cfg(not(feature = "milhouse"))]
tree_hash_cache: mem::take(&mut pre.tree_hash_cache), tree_hash_cache: mem::take(&mut pre.tree_hash_cache),
}); });

View File

@@ -47,7 +47,11 @@ mod tree_hash_cache;
#[cfg(feature = "milhouse")] #[cfg(feature = "milhouse")]
pub type ListMut<'a, T, N> = Interface<T, &'a mut List<T, N>>; pub type ListMut<'a, T, N> = Interface<T, &'a mut List<T, N>>;
#[cfg(feature = "milhouse")]
pub type ValidatorsMut<'a, N> = ListMut<'a, Validator, N>; pub type ValidatorsMut<'a, N> = ListMut<'a, Validator, N>;
#[cfg(not(feature = "milhouse"))]
pub type ValidatorsMut<'a, N> = &'a mut VList<Validator, N>;
pub const CACHED_EPOCHS: usize = 3; pub const CACHED_EPOCHS: usize = 3;
const MAX_RANDOM_BYTE: u64 = (1 << 8) - 1; const MAX_RANDOM_BYTE: u64 = (1 << 8) - 1;
@@ -240,6 +244,7 @@ where
pub eth1_deposit_index: u64, pub eth1_deposit_index: u64,
// Registry // Registry
#[superstruct(getter(rename = "validators_raw"))]
#[test_random(default)] #[test_random(default)]
pub validators: VList<Validator, T::ValidatorRegistryLimit>, pub validators: VList<Validator, T::ValidatorRegistryLimit>,
#[compare_fields(as_slice)] #[compare_fields(as_slice)]
@@ -1096,19 +1101,32 @@ impl<T: EthSpec> BeaconState<T> {
Ok(()) Ok(())
} }
pub fn validators(&self) -> &VList<Validator, T::ValidatorRegistryLimit> {
self.validators_raw()
}
pub fn validators_mut(&mut self) -> ValidatorsMut<T::ValidatorRegistryLimit> {
#[cfg(not(feature = "milhouse"))]
{
self.validators_raw_mut()
}
#[cfg(feature = "milhouse")]
{
self.validators_raw_mut().as_mut()
}
}
/// Convenience accessor for validators and balances simultaneously. /// Convenience accessor for validators and balances simultaneously.
#[cfg(not(feature = "milhouse"))] pub fn validators_and_balances_mut(
pub fn validators_and_balances_mut(&mut self) -> (&mut [Validator], &mut [u64]) { &mut self,
) -> (ValidatorsMut<T::ValidatorRegistryLimit>, &mut [u64]) {
#[cfg(not(feature = "milhouse"))]
match self { match self {
BeaconState::Base(state) => (&mut state.validators, &mut state.balances), BeaconState::Base(state) => (&mut state.validators, &mut state.balances),
BeaconState::Altair(state) => (&mut state.validators, &mut state.balances), BeaconState::Altair(state) => (&mut state.validators, &mut state.balances),
} }
}
#[cfg(feature = "milhouse")] #[cfg(feature = "milhouse")]
pub fn validators_and_balances_mut(
&mut self,
) -> (ValidatorsMut<T::ValidatorRegistryLimit>, &mut [u64]) {
match self { match self {
BeaconState::Base(state) => (state.validators.as_mut(), &mut state.balances), BeaconState::Base(state) => (state.validators.as_mut(), &mut state.balances),
BeaconState::Altair(state) => (state.validators.as_mut(), &mut state.balances), BeaconState::Altair(state) => (state.validators.as_mut(), &mut state.balances),

View File

@@ -64,6 +64,7 @@ pub mod voluntary_exit;
pub mod slot_epoch_macros; pub mod slot_epoch_macros;
pub mod config_and_preset; pub mod config_and_preset;
pub mod fork_context; pub mod fork_context;
pub mod mixin;
pub mod participation_flags; pub mod participation_flags;
pub mod participation_list; pub mod participation_list;
pub mod preset; pub mod preset;
@@ -117,6 +118,7 @@ pub use crate::free_attestation::FreeAttestation;
pub use crate::graffiti::{Graffiti, GRAFFITI_BYTES_LEN}; pub use crate::graffiti::{Graffiti, GRAFFITI_BYTES_LEN};
pub use crate::historical_batch::HistoricalBatch; pub use crate::historical_batch::HistoricalBatch;
pub use crate::indexed_attestation::IndexedAttestation; pub use crate::indexed_attestation::IndexedAttestation;
pub use crate::mixin::GetValidatorMut;
pub use crate::participation_flags::ParticipationFlags; pub use crate::participation_flags::ParticipationFlags;
pub use crate::participation_list::ParticipationList; pub use crate::participation_list::ParticipationList;
pub use crate::pending_attestation::PendingAttestation; pub use crate::pending_attestation::PendingAttestation;
@@ -159,3 +161,6 @@ pub use bls::{
}; };
pub use ssz_types::{typenum, typenum::Unsigned, BitList, BitVector, FixedVector, VariableList}; pub use ssz_types::{typenum, typenum::Unsigned, BitList, BitVector, FixedVector, VariableList};
pub use superstruct::superstruct; pub use superstruct::superstruct;
#[cfg(feature = "milhouse")]
pub use milhouse::{self, prelude::*};

View File

@@ -0,0 +1,18 @@
use crate::beacon_state::{Error, ValidatorsMut};
use crate::{Unsigned, Validator};
pub trait GetValidatorMut {
fn get_validator(&self, index: usize) -> Result<&Validator, Error>;
fn get_validator_mut(&mut self, index: usize) -> Result<&mut Validator, Error>;
}
impl<'a, N: Unsigned> GetValidatorMut for ValidatorsMut<'a, N> {
fn get_validator(&self, index: usize) -> Result<&Validator, Error> {
self.get(index).ok_or(Error::UnknownValidator(index))
}
fn get_validator_mut(&mut self, index: usize) -> Result<&mut Validator, Error> {
self.get_mut(index).ok_or(Error::UnknownValidator(index))
}
}