mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-04 13:24:39 +00:00
Use CoW
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2886,6 +2886,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"state_processing",
|
"state_processing",
|
||||||
|
"store",
|
||||||
"tree_hash",
|
"tree_hash",
|
||||||
"types",
|
"types",
|
||||||
"validator_dir",
|
"validator_dir",
|
||||||
@@ -3657,6 +3658,7 @@ dependencies = [
|
|||||||
"eth2_ssz",
|
"eth2_ssz",
|
||||||
"itertools",
|
"itertools",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
"rayon",
|
||||||
"serde",
|
"serde",
|
||||||
"tree_hash",
|
"tree_hash",
|
||||||
"triomphe",
|
"triomphe",
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ use tree_hash::TreeHash;
|
|||||||
use typenum::Unsigned;
|
use typenum::Unsigned;
|
||||||
use types::VList;
|
use types::VList;
|
||||||
|
|
||||||
#[cfg(feature = "milhouse")]
|
|
||||||
use types::milhouse::ImmList;
|
|
||||||
|
|
||||||
/// Description of how a `BeaconState` field is updated during state processing.
|
/// Description of how a `BeaconState` field is updated during state processing.
|
||||||
///
|
///
|
||||||
/// When storing a state, this allows us to efficiently store only those entries
|
/// When storing a state, this allows us to efficiently store only those entries
|
||||||
@@ -301,7 +298,7 @@ field!(
|
|||||||
T::SlotsPerHistoricalRoot,
|
T::SlotsPerHistoricalRoot,
|
||||||
DBColumn::BeaconBlockRoots,
|
DBColumn::BeaconBlockRoots,
|
||||||
|_| OncePerNSlots { n: 1 },
|
|_| OncePerNSlots { n: 1 },
|
||||||
|state: &BeaconState<_>, index, _| safe_modulo_index(state.block_roots(), index)
|
|state: &BeaconState<_>, index, _| safe_modulo_index_vect(state.block_roots(), index)
|
||||||
);
|
);
|
||||||
|
|
||||||
field!(
|
field!(
|
||||||
@@ -311,7 +308,7 @@ field!(
|
|||||||
T::SlotsPerHistoricalRoot,
|
T::SlotsPerHistoricalRoot,
|
||||||
DBColumn::BeaconStateRoots,
|
DBColumn::BeaconStateRoots,
|
||||||
|_| OncePerNSlots { n: 1 },
|
|_| OncePerNSlots { n: 1 },
|
||||||
|state: &BeaconState<_>, index, _| safe_modulo_index(state.state_roots(), index)
|
|state: &BeaconState<_>, index, _| safe_modulo_index_vect(state.state_roots(), index)
|
||||||
);
|
);
|
||||||
|
|
||||||
field!(
|
field!(
|
||||||
@@ -323,7 +320,7 @@ field!(
|
|||||||
|_| OncePerNSlots {
|
|_| OncePerNSlots {
|
||||||
n: T::SlotsPerHistoricalRoot::to_u64()
|
n: T::SlotsPerHistoricalRoot::to_u64()
|
||||||
},
|
},
|
||||||
|state: &BeaconState<_>, index, _| safe_modulo_index(state.historical_roots(), index)
|
|state: &BeaconState<_>, index, _| safe_modulo_index_list(state.historical_roots(), index)
|
||||||
);
|
);
|
||||||
|
|
||||||
field!(
|
field!(
|
||||||
@@ -333,7 +330,7 @@ field!(
|
|||||||
T::EpochsPerHistoricalVector,
|
T::EpochsPerHistoricalVector,
|
||||||
DBColumn::BeaconRandaoMixes,
|
DBColumn::BeaconRandaoMixes,
|
||||||
|_| OncePerEpoch { lag: 1 },
|
|_| OncePerEpoch { lag: 1 },
|
||||||
|state: &BeaconState<_>, index, _| safe_modulo_index(state.randao_mixes(), index)
|
|state: &BeaconState<_>, index, _| safe_modulo_index_vect(state.randao_mixes(), index)
|
||||||
);
|
);
|
||||||
|
|
||||||
pub fn store_updated_vector<F: Field<E>, E: EthSpec, S: KeyValueStore<E>>(
|
pub fn store_updated_vector<F: Field<E>, E: EthSpec, S: KeyValueStore<E>>(
|
||||||
@@ -572,7 +569,25 @@ fn safe_modulo_index<T: Copy>(values: &[T], index: u64) -> Result<T, ChunkError>
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "milhouse")]
|
#[cfg(feature = "milhouse")]
|
||||||
fn safe_modulo_index<V: ImmList<T>, T: Copy>(values: &V, index: u64) -> Result<T, ChunkError> {
|
fn safe_modulo_index_list<T: TreeHash + Copy, N: Unsigned>(
|
||||||
|
values: &VList<T, N>,
|
||||||
|
index: u64,
|
||||||
|
) -> Result<T, ChunkError> {
|
||||||
|
if values.is_empty() {
|
||||||
|
Err(ChunkError::ZeroLengthVector)
|
||||||
|
} else {
|
||||||
|
values
|
||||||
|
.get(index as usize % values.len())
|
||||||
|
.copied()
|
||||||
|
.ok_or(ChunkError::OutOfBounds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "milhouse")]
|
||||||
|
fn safe_modulo_index_vect<T: TreeHash + Copy, N: Unsigned>(
|
||||||
|
values: &FixedVector<T, N>,
|
||||||
|
index: u64,
|
||||||
|
) -> Result<T, ChunkError> {
|
||||||
if values.is_empty() {
|
if values.is_empty() {
|
||||||
Err(ChunkError::ZeroLengthVector)
|
Err(ChunkError::ZeroLengthVector)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ where
|
|||||||
|
|
||||||
// Inactivity
|
// Inactivity
|
||||||
#[superstruct(only(Altair, Merge))]
|
#[superstruct(only(Altair, Merge))]
|
||||||
pub inactivity_scores: VariableList<u64, T::ValidatorRegistryLimit>,
|
pub inactivity_scores: VList<u64, T::ValidatorRegistryLimit>,
|
||||||
|
|
||||||
// Light-client sync committees
|
// Light-client sync committees
|
||||||
#[superstruct(only(Altair, Merge))]
|
#[superstruct(only(Altair, Merge))]
|
||||||
@@ -266,17 +266,9 @@ impl<T: EthSpec> PartialBeaconState<T> {
|
|||||||
let current_epoch = self.slot().epoch(T::slots_per_epoch());
|
let current_epoch = self.slot().epoch(T::slots_per_epoch());
|
||||||
let len = randao_mixes.len();
|
let len = randao_mixes.len();
|
||||||
|
|
||||||
#[cfg(feature = "milhouse")]
|
*randao_mixes
|
||||||
{
|
.get_mut(current_epoch.as_usize() % len)
|
||||||
use milhouse::interface::MutList;
|
.unwrap() = *self.latest_randao_value();
|
||||||
randao_mixes
|
|
||||||
.replace(current_epoch.as_usize() % len, *self.latest_randao_value())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "milhouse"))]
|
|
||||||
{
|
|
||||||
randao_mixes[current_epoch.as_usize() % len] = *self.latest_randao_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
*self.randao_mixes_mut() = Some(randao_mixes)
|
*self.randao_mixes_mut() = Some(randao_mixes)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,13 +32,11 @@ pub fn initiate_validator_exit<T: EthSpec>(
|
|||||||
.exit_cache_mut()
|
.exit_cache_mut()
|
||||||
.record_validator_exit(exit_queue_epoch)?;
|
.record_validator_exit(exit_queue_epoch)?;
|
||||||
|
|
||||||
let mut validators = state.validators_mut();
|
// FIXME(sproul): could avoid this second lookup with some clever borrowing
|
||||||
let validator = validators.get_validator_mut(index)?;
|
let mut validator = state.get_validator_mut(index)?;
|
||||||
|
|
||||||
validator.exit_epoch = exit_queue_epoch;
|
validator.exit_epoch = exit_queue_epoch;
|
||||||
validator.withdrawable_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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub use initiate_validator_exit::initiate_validator_exit;
|
|||||||
pub use slash_validator::slash_validator;
|
pub use slash_validator::slash_validator;
|
||||||
|
|
||||||
use safe_arith::SafeArith;
|
use safe_arith::SafeArith;
|
||||||
use types::{BeaconState, BeaconStateError, EthSpec, GetBalanceMut};
|
use types::{BeaconState, BeaconStateError, EthSpec};
|
||||||
|
|
||||||
/// Increase the balance of a validator, erroring upon overflow, as per the spec.
|
/// Increase the balance of a validator, erroring upon overflow, as per the spec.
|
||||||
pub fn increase_balance<E: EthSpec>(
|
pub fn increase_balance<E: EthSpec>(
|
||||||
@@ -24,10 +24,7 @@ pub fn increase_balance<E: EthSpec>(
|
|||||||
index: usize,
|
index: usize,
|
||||||
delta: u64,
|
delta: u64,
|
||||||
) -> Result<(), BeaconStateError> {
|
) -> Result<(), BeaconStateError> {
|
||||||
state
|
state.get_balance_mut(index)?.safe_add_assign(delta)?;
|
||||||
.balances_mut()
|
|
||||||
.get_balance_mut(index)?
|
|
||||||
.safe_add_assign(delta)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,8 +34,7 @@ pub fn decrease_balance<E: EthSpec>(
|
|||||||
index: usize,
|
index: usize,
|
||||||
delta: u64,
|
delta: u64,
|
||||||
) -> Result<(), BeaconStateError> {
|
) -> Result<(), BeaconStateError> {
|
||||||
let mut balances = state.balances_mut();
|
let balance = state.get_balance_mut(index)?;
|
||||||
let balance = balances.get_balance_mut(index)?;
|
|
||||||
*balance = balance.saturating_sub(delta);
|
*balance = balance.saturating_sub(delta);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,13 @@ pub fn slash_validator<T: EthSpec>(
|
|||||||
|
|
||||||
initiate_validator_exit(state, slashed_index, spec)?;
|
initiate_validator_exit(state, slashed_index, spec)?;
|
||||||
|
|
||||||
let mut validators = state.validators_mut();
|
let validator = state.get_validator_mut(slashed_index)?;
|
||||||
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
|
||||||
|
|||||||
@@ -96,9 +96,10 @@ pub fn process_activations<T: EthSpec>(
|
|||||||
state: &mut BeaconState<T>,
|
state: &mut BeaconState<T>,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let (mut validators, balances) = state.validators_and_balances_mut();
|
let (validators, balances) = state.validators_and_balances_mut();
|
||||||
for index in 0..validators.len() {
|
let mut validators_iter = validators.iter_cow();
|
||||||
let validator = validators.get_validator_mut(index)?;
|
while let Some((index, validator)) = validators_iter.next_cow() {
|
||||||
|
let validator = validator.to_mut();
|
||||||
let balance = balances
|
let balance = balances
|
||||||
.get(index)
|
.get(index)
|
||||||
.copied()
|
.copied()
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use types::{
|
|||||||
TIMELY_TARGET_FLAG_INDEX,
|
TIMELY_TARGET_FLAG_INDEX,
|
||||||
},
|
},
|
||||||
BeaconState, BeaconStateError, ChainSpec, Epoch, EthSpec, ParticipationFlags, RelativeEpoch,
|
BeaconState, BeaconStateError, ChainSpec, Epoch, EthSpec, ParticipationFlags, RelativeEpoch,
|
||||||
|
Validator,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@@ -120,12 +121,10 @@ impl SingleEpochParticipationCache {
|
|||||||
fn process_active_validator<T: EthSpec>(
|
fn process_active_validator<T: EthSpec>(
|
||||||
&mut self,
|
&mut self,
|
||||||
val_index: usize,
|
val_index: usize,
|
||||||
|
validator: &Validator,
|
||||||
state: &BeaconState<T>,
|
state: &BeaconState<T>,
|
||||||
relative_epoch: RelativeEpoch,
|
relative_epoch: RelativeEpoch,
|
||||||
) -> Result<(), BeaconStateError> {
|
) -> Result<(), BeaconStateError> {
|
||||||
let val_balance = state.get_effective_balance(val_index)?;
|
|
||||||
let validator = state.get_validator(val_index)?;
|
|
||||||
|
|
||||||
// Sanity check to ensure the validator is active.
|
// Sanity check to ensure the validator is active.
|
||||||
let epoch = relative_epoch.into_epoch(state.current_epoch());
|
let epoch = relative_epoch.into_epoch(state.current_epoch());
|
||||||
if !validator.is_active_at(epoch) {
|
if !validator.is_active_at(epoch) {
|
||||||
@@ -141,7 +140,8 @@ impl SingleEpochParticipationCache {
|
|||||||
.ok_or(BeaconStateError::ParticipationOutOfBounds(val_index))?;
|
.ok_or(BeaconStateError::ParticipationOutOfBounds(val_index))?;
|
||||||
|
|
||||||
// All active validators increase the total active balance.
|
// All active validators increase the total active balance.
|
||||||
self.total_active_balance.safe_add_assign(val_balance)?;
|
self.total_active_balance
|
||||||
|
.safe_add_assign(validator.effective_balance)?;
|
||||||
|
|
||||||
// Only unslashed validators may proceed.
|
// Only unslashed validators may proceed.
|
||||||
if validator.slashed {
|
if validator.slashed {
|
||||||
@@ -156,7 +156,7 @@ impl SingleEpochParticipationCache {
|
|||||||
// are set for `val_index`.
|
// are set for `val_index`.
|
||||||
for (flag, balance) in self.total_flag_balances.iter_mut().enumerate() {
|
for (flag, balance) in self.total_flag_balances.iter_mut().enumerate() {
|
||||||
if epoch_participation.has_flag(flag)? {
|
if epoch_participation.has_flag(flag)? {
|
||||||
balance.safe_add_assign(val_balance)?;
|
balance.safe_add_assign(validator.effective_balance)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,6 +223,7 @@ impl ParticipationCache {
|
|||||||
if val.is_active_at(current_epoch) {
|
if val.is_active_at(current_epoch) {
|
||||||
current_epoch_participation.process_active_validator(
|
current_epoch_participation.process_active_validator(
|
||||||
val_index,
|
val_index,
|
||||||
|
val,
|
||||||
state,
|
state,
|
||||||
RelativeEpoch::Current,
|
RelativeEpoch::Current,
|
||||||
)?;
|
)?;
|
||||||
@@ -231,6 +232,7 @@ impl ParticipationCache {
|
|||||||
if val.is_active_at(previous_epoch) {
|
if val.is_active_at(previous_epoch) {
|
||||||
previous_epoch_participation.process_active_validator(
|
previous_epoch_participation.process_active_validator(
|
||||||
val_index,
|
val_index,
|
||||||
|
val,
|
||||||
state,
|
state,
|
||||||
RelativeEpoch::Previous,
|
RelativeEpoch::Previous,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ pub fn get_flag_index_deltas<T: EthSpec>(
|
|||||||
let active_increments = total_active_balance.safe_div(spec.effective_balance_increment)?;
|
let active_increments = total_active_balance.safe_div(spec.effective_balance_increment)?;
|
||||||
|
|
||||||
for &index in participation_cache.eligible_validator_indices() {
|
for &index in participation_cache.eligible_validator_indices() {
|
||||||
|
// FIXME(sproul): compute base reward in participation cache
|
||||||
let base_reward = get_base_reward(state, index, total_active_balance, spec)?;
|
let base_reward = get_base_reward(state, index, total_active_balance, spec)?;
|
||||||
let mut delta = Delta::default();
|
let mut delta = Delta::default();
|
||||||
|
|
||||||
|
|||||||
@@ -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, GetValidatorMut};
|
use types::{BeaconStateError, EthSpec};
|
||||||
|
|
||||||
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,9 +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 (mut validators, balances) = state.validators_and_balances_mut();
|
let (validators, balances) = state.validators_and_balances_mut();
|
||||||
for index in 0..validators.len() {
|
let mut validators_iter = validators.iter_cow();
|
||||||
let validator = validators.get_validator_mut(index)?;
|
while let Some((index, validator)) = validators_iter.next_cow() {
|
||||||
let balance = balances
|
let balance = balances
|
||||||
.get(index)
|
.get(index)
|
||||||
.copied()
|
.copied()
|
||||||
@@ -24,7 +24,7 @@ pub fn process_effective_balance_updates<T: EthSpec>(
|
|||||||
if balance.safe_add(downward_threshold)? < validator.effective_balance
|
if balance.safe_add(downward_threshold)? < validator.effective_balance
|
||||||
|| validator.effective_balance.safe_add(upward_threshold)? < balance
|
|| validator.effective_balance.safe_add(upward_threshold)? < balance
|
||||||
{
|
{
|
||||||
validator.effective_balance = std::cmp::min(
|
validator.to_mut().effective_balance = std::cmp::min(
|
||||||
balance.safe_sub(balance.safe_rem(spec.effective_balance_increment)?)?,
|
balance.safe_sub(balance.safe_rem(spec.effective_balance_increment)?)?,
|
||||||
spec.max_effective_balance,
|
spec.max_effective_balance,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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, GetValidatorMut, Validator};
|
use types::{BeaconState, ChainSpec, EthSpec, Validator};
|
||||||
|
|
||||||
/// Performs a validator registry update, if required.
|
/// Performs a validator registry update, if required.
|
||||||
///
|
///
|
||||||
@@ -30,13 +30,11 @@ pub fn process_registry_updates<T: EthSpec>(
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for index in indices_to_update {
|
for index in indices_to_update {
|
||||||
let mut validators = state.validators_mut();
|
let validator = state.get_validator_mut(index)?;
|
||||||
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)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,9 +52,8 @@ 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) {
|
||||||
validators.get_validator_mut(index)?.activation_epoch = delayed_activation_epoch;
|
state.get_validator_mut(index)?.activation_epoch = delayed_activation_epoch;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -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, ChainSpec, EthSpec, GetBalanceMut, GetValidatorMut, Unsigned};
|
use types::{BeaconState, BeaconStateError, ChainSpec, EthSpec, Unsigned};
|
||||||
|
|
||||||
/// Process slashings.
|
/// Process slashings.
|
||||||
pub fn process_slashings<T: EthSpec>(
|
pub fn process_slashings<T: EthSpec>(
|
||||||
@@ -16,9 +16,9 @@ pub fn process_slashings<T: EthSpec>(
|
|||||||
total_balance,
|
total_balance,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (validators, mut balances) = state.validators_and_balances_mut();
|
let (validators, balances) = state.validators_and_balances_mut();
|
||||||
for index in 0..validators.len() {
|
let mut validators_iter = validators.iter_cow();
|
||||||
let validator = validators.get_validator(index)?;
|
while let Some((index, validator)) = validators_iter.next_cow() {
|
||||||
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
|
||||||
@@ -33,7 +33,9 @@ pub fn process_slashings<T: EthSpec>(
|
|||||||
.safe_mul(increment)?;
|
.safe_mul(increment)?;
|
||||||
|
|
||||||
// Equivalent to `decrease_balance(state, index, penalty)`, but avoids borrowing `state`.
|
// Equivalent to `decrease_balance(state, index, penalty)`, but avoids borrowing `state`.
|
||||||
let balance = balances.get_balance_mut(index)?;
|
let balance = balances
|
||||||
|
.get_mut(index)
|
||||||
|
.ok_or(BeaconStateError::BalancesOutOfBounds(index))?;
|
||||||
*balance = balance.saturating_sub(penalty);
|
*balance = balance.saturating_sub(penalty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ pub fn upgrade_to_altair<E: EthSpec>(
|
|||||||
|
|
||||||
let default_epoch_participation =
|
let default_epoch_participation =
|
||||||
VariableList::new(vec![ParticipationFlags::default(); pre.validators.len()])?;
|
VariableList::new(vec![ParticipationFlags::default(); pre.validators.len()])?;
|
||||||
let inactivity_scores = VariableList::new(vec![0; pre.validators.len()])?;
|
let inactivity_scores = VList::new(vec![0; pre.validators.len()])?;
|
||||||
|
|
||||||
let temp_sync_committee = Arc::new(SyncCommittee::temporary()?);
|
let temp_sync_committee = Arc::new(SyncCommittee::temporary()?);
|
||||||
|
|
||||||
|
|||||||
@@ -47,28 +47,6 @@ mod tests;
|
|||||||
#[cfg(not(feature = "milhouse"))]
|
#[cfg(not(feature = "milhouse"))]
|
||||||
mod tree_hash_cache;
|
mod tree_hash_cache;
|
||||||
|
|
||||||
#[cfg(feature = "milhouse")]
|
|
||||||
mod type_aliases {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub type ListMut<'a, T, N> = Interface<'a, T, List<T, N>>;
|
|
||||||
pub type VectMut<'a, T, N> = Interface<'a, T, FixedVector<T, N>>;
|
|
||||||
pub type ValidatorsMut<'a, N> = ListMut<'a, Validator, N>;
|
|
||||||
pub type BalancesMut<'a, N> = ListMut<'a, u64, N>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "milhouse"))]
|
|
||||||
mod type_aliases {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub type ListMut<'a, T, N> = &'a mut VList<T, N>;
|
|
||||||
pub type VectMut<'a, T, N> = &'a mut FixedVector<T, N>;
|
|
||||||
pub type ValidatorsMut<'a, N> = &'a mut VList<Validator, N>;
|
|
||||||
pub type BalancesMut<'a, N> = ListMut<'a, u64, N>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use type_aliases::*;
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@@ -248,10 +226,8 @@ where
|
|||||||
|
|
||||||
// History
|
// History
|
||||||
pub latest_block_header: BeaconBlockHeader,
|
pub latest_block_header: BeaconBlockHeader,
|
||||||
#[superstruct(getter(rename = "block_roots_raw"))]
|
|
||||||
#[test_random(default)]
|
#[test_random(default)]
|
||||||
pub block_roots: FixedVector<Hash256, T::SlotsPerHistoricalRoot>,
|
pub block_roots: FixedVector<Hash256, T::SlotsPerHistoricalRoot>,
|
||||||
#[superstruct(getter(rename = "state_roots_raw"))]
|
|
||||||
#[test_random(default)]
|
#[test_random(default)]
|
||||||
pub state_roots: FixedVector<Hash256, T::SlotsPerHistoricalRoot>,
|
pub state_roots: FixedVector<Hash256, T::SlotsPerHistoricalRoot>,
|
||||||
#[test_random(default)]
|
#[test_random(default)]
|
||||||
@@ -266,22 +242,18 @@ 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>,
|
||||||
// FIXME(sproul): serde quoting
|
// FIXME(sproul): serde quoting
|
||||||
// #[serde(with = "ssz_types::serde_utils::quoted_u64_var_list")]
|
// #[serde(with = "ssz_types::serde_utils::quoted_u64_var_list")]
|
||||||
#[superstruct(getter(rename = "balances_raw"))]
|
|
||||||
#[test_random(default)]
|
#[test_random(default)]
|
||||||
pub balances: VList<u64, T::ValidatorRegistryLimit>,
|
pub balances: VList<u64, T::ValidatorRegistryLimit>,
|
||||||
|
|
||||||
// Randomness
|
// Randomness
|
||||||
#[superstruct(getter(rename = "randao_mixes_raw"))]
|
|
||||||
#[test_random(default)]
|
#[test_random(default)]
|
||||||
pub randao_mixes: FixedVector<Hash256, T::EpochsPerHistoricalVector>,
|
pub randao_mixes: FixedVector<Hash256, T::EpochsPerHistoricalVector>,
|
||||||
|
|
||||||
// Slashings
|
// Slashings
|
||||||
#[superstruct(getter(rename = "slashings_raw"))]
|
|
||||||
#[test_random(default)]
|
#[test_random(default)]
|
||||||
// FIXME(sproul): serde quoting
|
// FIXME(sproul): serde quoting
|
||||||
// #[serde(with = "ssz_types::serde_utils::quoted_u64_fixed_vec")]
|
// #[serde(with = "ssz_types::serde_utils::quoted_u64_fixed_vec")]
|
||||||
@@ -312,9 +284,11 @@ where
|
|||||||
pub finalized_checkpoint: Checkpoint,
|
pub finalized_checkpoint: Checkpoint,
|
||||||
|
|
||||||
// Inactivity
|
// Inactivity
|
||||||
#[serde(with = "ssz_types::serde_utils::quoted_u64_var_list")]
|
// FIXME(sproul): quoting
|
||||||
|
// #[serde(with = "ssz_types::serde_utils::quoted_u64_var_list")]
|
||||||
#[superstruct(only(Altair, Merge))]
|
#[superstruct(only(Altair, Merge))]
|
||||||
pub inactivity_scores: VariableList<u64, T::ValidatorRegistryLimit>,
|
#[test_random(default)]
|
||||||
|
pub inactivity_scores: VList<u64, T::ValidatorRegistryLimit>,
|
||||||
|
|
||||||
// Light-client sync committees
|
// Light-client sync committees
|
||||||
#[superstruct(only(Altair, Merge))]
|
#[superstruct(only(Altair, Merge))]
|
||||||
@@ -990,7 +964,7 @@ impl<T: EthSpec> BeaconState<T> {
|
|||||||
|
|
||||||
/// Fill `randao_mixes` with
|
/// Fill `randao_mixes` with
|
||||||
pub fn fill_randao_mixes_with(&mut self, index_root: Hash256) {
|
pub fn fill_randao_mixes_with(&mut self, index_root: Hash256) {
|
||||||
*self.randao_mixes_raw_mut() = FixedVector::from_elem(index_root);
|
*self.randao_mixes_mut() = FixedVector::from_elem(index_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Safely obtains the index for `randao_mixes`
|
/// Safely obtains the index for `randao_mixes`
|
||||||
@@ -1139,116 +1113,25 @@ 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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn balances(&self) -> &VList<u64, T::ValidatorRegistryLimit> {
|
|
||||||
self.balances_raw()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn balances_mut(&mut self) -> BalancesMut<T::ValidatorRegistryLimit> {
|
|
||||||
#[cfg(not(feature = "milhouse"))]
|
|
||||||
{
|
|
||||||
self.balances_raw_mut()
|
|
||||||
}
|
|
||||||
#[cfg(feature = "milhouse")]
|
|
||||||
{
|
|
||||||
self.balances_raw_mut().as_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convenience accessor for validators and balances simultaneously.
|
/// Convenience accessor for validators and balances simultaneously.
|
||||||
pub fn validators_and_balances_mut(
|
pub fn validators_and_balances_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> (
|
) -> (
|
||||||
ValidatorsMut<T::ValidatorRegistryLimit>,
|
&mut VList<Validator, T::ValidatorRegistryLimit>,
|
||||||
BalancesMut<T::ValidatorRegistryLimit>,
|
&mut VList<u64, T::ValidatorRegistryLimit>,
|
||||||
) {
|
) {
|
||||||
#[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),
|
||||||
BeaconState::Merge(state) => (&mut state.validators, &mut state.balances),
|
BeaconState::Merge(state) => (&mut state.validators, &mut state.balances),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "milhouse")]
|
|
||||||
match self {
|
|
||||||
BeaconState::Base(state) => (state.validators.as_mut(), state.balances.as_mut()),
|
|
||||||
BeaconState::Altair(state) => (state.validators.as_mut(), state.balances.as_mut()),
|
|
||||||
BeaconState::Merge(state) => (state.validators.as_mut(), state.balances.as_mut()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn block_roots(&self) -> &FixedVector<Hash256, T::SlotsPerHistoricalRoot> {
|
/// Get a mutable reference to the balance of a single validator.
|
||||||
self.block_roots_raw()
|
pub fn get_balance_mut(&mut self, validator_index: usize) -> Result<&mut u64, Error> {
|
||||||
}
|
self.balances_mut()
|
||||||
|
.get_mut(validator_index)
|
||||||
pub fn block_roots_mut(&mut self) -> VectMut<Hash256, T::SlotsPerHistoricalRoot> {
|
.ok_or(Error::BalancesOutOfBounds(validator_index))
|
||||||
#[cfg(not(feature = "milhouse"))]
|
|
||||||
{
|
|
||||||
self.block_roots_raw_mut()
|
|
||||||
}
|
|
||||||
#[cfg(feature = "milhouse")]
|
|
||||||
{
|
|
||||||
self.block_roots_raw_mut().as_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn state_roots(&self) -> &FixedVector<Hash256, T::SlotsPerHistoricalRoot> {
|
|
||||||
self.state_roots_raw()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn state_roots_mut(&mut self) -> VectMut<Hash256, T::SlotsPerHistoricalRoot> {
|
|
||||||
#[cfg(not(feature = "milhouse"))]
|
|
||||||
{
|
|
||||||
self.state_roots_raw_mut()
|
|
||||||
}
|
|
||||||
#[cfg(feature = "milhouse")]
|
|
||||||
{
|
|
||||||
self.state_roots_raw_mut().as_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn randao_mixes(&self) -> &FixedVector<Hash256, T::EpochsPerHistoricalVector> {
|
|
||||||
self.randao_mixes_raw()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn randao_mixes_mut(&mut self) -> VectMut<Hash256, T::EpochsPerHistoricalVector> {
|
|
||||||
#[cfg(not(feature = "milhouse"))]
|
|
||||||
{
|
|
||||||
self.randao_mixes_raw_mut()
|
|
||||||
}
|
|
||||||
#[cfg(feature = "milhouse")]
|
|
||||||
{
|
|
||||||
self.randao_mixes_raw_mut().as_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn slashings(&self) -> &FixedVector<u64, T::EpochsPerSlashingsVector> {
|
|
||||||
self.slashings_raw()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn slashings_mut(&mut self) -> VectMut<u64, T::EpochsPerSlashingsVector> {
|
|
||||||
#[cfg(not(feature = "milhouse"))]
|
|
||||||
{
|
|
||||||
self.slashings_raw_mut()
|
|
||||||
}
|
|
||||||
#[cfg(feature = "milhouse")]
|
|
||||||
{
|
|
||||||
self.slashings_raw_mut().as_mut()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a seed for the given `epoch`.
|
/// Generate a seed for the given `epoch`.
|
||||||
@@ -1293,14 +1176,22 @@ impl<T: EthSpec> BeaconState<T> {
|
|||||||
.ok_or(Error::UnknownValidator(validator_index))
|
.ok_or(Error::UnknownValidator(validator_index))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME(sproul): lens?
|
|
||||||
/// Safe mutator for the `validators` list.
|
/// Safe mutator for the `validators` list.
|
||||||
pub fn get_validator_mut(&mut self, validator_index: usize) -> Result<&mut Validator, Error> {
|
pub fn get_validator_mut(&mut self, validator_index: usize) -> Result<&mut Validator, Error> {
|
||||||
self.validators_mut()
|
self.validators_mut()
|
||||||
.get_mut(validator_index)
|
.get_mut(validator_index)
|
||||||
.ok_or(Error::UnknownValidator(validator_index))
|
.ok_or(Error::UnknownValidator(validator_index))
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
/// Safe copy-on-write accessor for the `validators` list.
|
||||||
|
pub fn get_validator_cow(
|
||||||
|
&mut self,
|
||||||
|
validator_index: usize,
|
||||||
|
) -> Result<milhouse::Cow<Validator>, Error> {
|
||||||
|
self.validators_mut()
|
||||||
|
.get_cow(validator_index)
|
||||||
|
.ok_or(Error::UnknownValidator(validator_index))
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the effective balance for a validator with the given `validator_index`.
|
/// Return the effective balance for a validator with the given `validator_index`.
|
||||||
pub fn get_effective_balance(&self, validator_index: usize) -> Result<u64, Error> {
|
pub fn get_effective_balance(&self, validator_index: usize) -> Result<u64, Error> {
|
||||||
@@ -1387,6 +1278,28 @@ impl<T: EthSpec> BeaconState<T> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn compute_total_active_balance(
|
||||||
|
&self,
|
||||||
|
epoch: Epoch,
|
||||||
|
spec: &ChainSpec,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
|
if epoch != self.current_epoch() && epoch != self.next_epoch()? {
|
||||||
|
return Err(Error::EpochOutOfBounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut total_active_balance = 0;
|
||||||
|
|
||||||
|
for validator in self.validators() {
|
||||||
|
if validator.is_active_at(epoch) {
|
||||||
|
total_active_balance.safe_add_assign(validator.effective_balance)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(std::cmp::max(
|
||||||
|
total_active_balance,
|
||||||
|
spec.effective_balance_increment,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
/// Implementation of `get_total_active_balance`, matching the spec.
|
/// Implementation of `get_total_active_balance`, matching the spec.
|
||||||
///
|
///
|
||||||
/// Requires the total active balance cache to be initialised, which is initialised whenever
|
/// Requires the total active balance cache to be initialised, which is initialised whenever
|
||||||
@@ -1410,16 +1323,9 @@ impl<T: EthSpec> BeaconState<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Build the total active balance cache.
|
/// Build the total active balance cache.
|
||||||
///
|
|
||||||
/// This function requires the current committee cache to be already built. It is called
|
|
||||||
/// automatically when `build_committee_cache` is called for the current epoch.
|
|
||||||
fn build_total_active_balance_cache(&mut self, spec: &ChainSpec) -> Result<(), Error> {
|
fn build_total_active_balance_cache(&mut self, spec: &ChainSpec) -> Result<(), Error> {
|
||||||
// Order is irrelevant, so use the cached indices.
|
|
||||||
let current_epoch = self.current_epoch();
|
let current_epoch = self.current_epoch();
|
||||||
let total_active_balance = self.get_total_balance(
|
let total_active_balance = self.compute_total_active_balance(current_epoch, spec)?;
|
||||||
self.get_cached_active_validator_indices(RelativeEpoch::Current)?,
|
|
||||||
spec,
|
|
||||||
)?;
|
|
||||||
*self.total_active_balance_mut() = Some((current_epoch, total_active_balance));
|
*self.total_active_balance_mut() = Some((current_epoch, total_active_balance));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1578,10 +1484,9 @@ impl<T: EthSpec> BeaconState<T> {
|
|||||||
// not yet been advanced.
|
// not yet been advanced.
|
||||||
let new_current_epoch = self.next_epoch()?;
|
let new_current_epoch = self.next_epoch()?;
|
||||||
if curr_cache.is_initialized_at(new_current_epoch) {
|
if curr_cache.is_initialized_at(new_current_epoch) {
|
||||||
*self.total_active_balance_mut() = Some((
|
let total_active_balance =
|
||||||
new_current_epoch,
|
self.compute_total_active_balance(new_current_epoch, spec)?;
|
||||||
self.get_total_balance(curr_cache.active_validator_indices(), spec)?,
|
*self.total_active_balance_mut() = Some((new_current_epoch, total_active_balance));
|
||||||
));
|
|
||||||
}
|
}
|
||||||
// If the cache is not initialized, then the previous cached value for the total balance is
|
// If the cache is not initialized, then the previous cached value for the total balance is
|
||||||
// wrong, so delete it.
|
// wrong, so delete it.
|
||||||
@@ -1671,6 +1576,38 @@ impl<T: EthSpec> BeaconState<T> {
|
|||||||
*self.pubkey_cache_mut() = PubkeyCache::default()
|
*self.pubkey_cache_mut() = PubkeyCache::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the `BeaconState` has any pending mutations.
|
||||||
|
pub fn has_pending_mutations(&self) -> bool {
|
||||||
|
// FIXME(sproul): check this more thoroughly
|
||||||
|
self.block_roots().has_pending_updates()
|
||||||
|
|| self.state_roots().has_pending_updates()
|
||||||
|
|| self.historical_roots().has_pending_updates()
|
||||||
|
|| self.eth1_data_votes().has_pending_updates()
|
||||||
|
|| self.validators().has_pending_updates()
|
||||||
|
|| self.balances().has_pending_updates()
|
||||||
|
|| self.randao_mixes().has_pending_updates()
|
||||||
|
|| self.slashings().has_pending_updates()
|
||||||
|
|| self
|
||||||
|
.inactivity_scores()
|
||||||
|
.map_or(false, VList::has_pending_updates)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apply_pending_mutations(&mut self) -> Result<(), Error> {
|
||||||
|
self.block_roots_mut().apply_updates()?;
|
||||||
|
self.state_roots_mut().apply_updates()?;
|
||||||
|
self.historical_roots_mut().apply_updates()?;
|
||||||
|
self.eth1_data_votes_mut().apply_updates()?;
|
||||||
|
self.validators_mut().apply_updates()?;
|
||||||
|
self.balances_mut().apply_updates()?;
|
||||||
|
self.randao_mixes_mut().apply_updates()?;
|
||||||
|
self.slashings_mut().apply_updates()?;
|
||||||
|
|
||||||
|
if let Ok(inactivity_scores) = self.inactivity_scores_mut() {
|
||||||
|
inactivity_scores.apply_updates()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialize but don't fill the tree hash cache, if it isn't already initialized.
|
/// Initialize but don't fill the tree hash cache, if it isn't already initialized.
|
||||||
pub fn initialize_tree_hash_cache(&mut self) {
|
pub fn initialize_tree_hash_cache(&mut self) {
|
||||||
#[cfg(not(feature = "milhouse"))]
|
#[cfg(not(feature = "milhouse"))]
|
||||||
@@ -1700,8 +1637,11 @@ impl<T: EthSpec> BeaconState<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "milhouse")]
|
#[cfg(feature = "milhouse")]
|
||||||
|
{
|
||||||
|
self.apply_pending_mutations()?;
|
||||||
Ok(self.tree_hash_root())
|
Ok(self.tree_hash_root())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Compute the tree hash root of the validators using the tree hash cache.
|
/// Compute the tree hash root of the validators using the tree hash cache.
|
||||||
///
|
///
|
||||||
@@ -1724,8 +1664,11 @@ impl<T: EthSpec> BeaconState<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "milhouse")]
|
#[cfg(feature = "milhouse")]
|
||||||
|
{
|
||||||
|
self.validators_mut().apply_updates()?;
|
||||||
Ok(self.validators().tree_hash_root())
|
Ok(self.validators().tree_hash_root())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Completely drops the tree hash cache, replacing it with a new, empty cache.
|
/// Completely drops the tree hash cache, replacing it with a new, empty cache.
|
||||||
pub fn drop_tree_hash_cache(&mut self) {
|
pub fn drop_tree_hash_cache(&mut self) {
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ 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;
|
||||||
@@ -123,7 +122,6 @@ 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::{GetBalanceMut, 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;
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
use crate::beacon_state::{BalancesMut, 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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait GetBalanceMut {
|
|
||||||
fn get_balance(&self, index: usize) -> Result<u64, Error>;
|
|
||||||
|
|
||||||
fn get_balance_mut(&mut self, index: usize) -> Result<&mut u64, Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, N: Unsigned> GetBalanceMut for BalancesMut<'a, N> {
|
|
||||||
fn get_balance(&self, index: usize) -> Result<u64, Error> {
|
|
||||||
self.get(index)
|
|
||||||
.copied()
|
|
||||||
.ok_or(Error::BalancesOutOfBounds(index))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_balance_mut(&mut self, index: usize) -> Result<&mut u64, Error> {
|
|
||||||
self.get_mut(index).ok_or(Error::BalancesOutOfBounds(index))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -42,7 +42,7 @@ pub fn run<T: EthSpec>(testnet_dir: PathBuf, matches: &ArgMatches) -> Result<(),
|
|||||||
|
|
||||||
let mut deposit_tree = DepositDataTree::create(&[], 0, DEPOSIT_TREE_DEPTH);
|
let mut deposit_tree = DepositDataTree::create(&[], 0, DEPOSIT_TREE_DEPTH);
|
||||||
let mut deposit_root = Hash256::zero();
|
let mut deposit_root = Hash256::zero();
|
||||||
let mut validators = state.validators_mut();
|
let validators = state.validators_mut();
|
||||||
for index in 0..validators.len() {
|
for index in 0..validators.len() {
|
||||||
let (secret, _) =
|
let (secret, _) =
|
||||||
recover_validator_secret_from_mnemonic(seed.as_bytes(), index as u32, KeyType::Voting)
|
recover_validator_secret_from_mnemonic(seed.as_bytes(), index as u32, KeyType::Voting)
|
||||||
|
|||||||
Reference in New Issue
Block a user