Convert beacon_state
to Slot/Epoch newtypes
This commit is contained in:
parent
2aa7d80a5f
commit
bd71304d73
@ -1,7 +1,7 @@
|
|||||||
use crate::test_utils::TestRandom;
|
use crate::test_utils::TestRandom;
|
||||||
use crate::{
|
use crate::{
|
||||||
validator::StatusFlags, validator_registry::get_active_validator_indices, AggregatePublicKey,
|
validator::StatusFlags, validator_registry::get_active_validator_indices, AggregatePublicKey,
|
||||||
Attestation, AttestationData, BeaconBlock, Bitfield, ChainSpec, Crosslink, Eth1Data,
|
Attestation, AttestationData, BeaconBlock, Bitfield, ChainSpec, Crosslink, Epoch, Eth1Data,
|
||||||
Eth1DataVote, Exit, Fork, Hash256, PendingAttestation, PublicKey, Signature, Slot, Validator,
|
Eth1DataVote, Exit, Fork, Hash256, PendingAttestation, PublicKey, Signature, Slot, Validator,
|
||||||
};
|
};
|
||||||
use bls::bls_verify_aggregate;
|
use bls::bls_verify_aggregate;
|
||||||
@ -28,7 +28,7 @@ const DOMAIN_ATTESTATION: u64 = 1;
|
|||||||
pub enum Error {
|
pub enum Error {
|
||||||
InsufficientValidators,
|
InsufficientValidators,
|
||||||
BadBlockSignature,
|
BadBlockSignature,
|
||||||
InvalidEpoch(u64, Range<u64>),
|
InvalidEpoch(Slot, Range<Epoch>),
|
||||||
CommitteesError(CommitteesError),
|
CommitteesError(CommitteesError),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ pub enum WinningRootError {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum CommitteesError {
|
pub enum CommitteesError {
|
||||||
InvalidEpoch(u64, Range<u64>),
|
InvalidEpoch,
|
||||||
InsufficientNumberOfValidators,
|
InsufficientNumberOfValidators,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,20 +198,20 @@ impl BeaconState {
|
|||||||
Hash256::from(&self.hash_tree_root()[..])
|
Hash256::from(&self.hash_tree_root()[..])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_epoch(&self, spec: &ChainSpec) -> u64 {
|
pub fn current_epoch(&self, spec: &ChainSpec) -> Epoch {
|
||||||
self.slot / spec.epoch_length
|
self.slot.epoch(spec.epoch_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn previous_epoch(&self, spec: &ChainSpec) -> u64 {
|
pub fn previous_epoch(&self, spec: &ChainSpec) -> Epoch {
|
||||||
self.current_epoch(spec).saturating_sub(1)
|
self.current_epoch(spec).saturating_sub(1_u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_epoch_start_slot(&self, spec: &ChainSpec) -> u64 {
|
pub fn current_epoch_start_slot(&self, spec: &ChainSpec) -> Slot {
|
||||||
self.current_epoch(spec) * spec.epoch_length
|
self.current_epoch(spec).start_slot(spec.epoch_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn previous_epoch_start_slot(&self, spec: &ChainSpec) -> u64 {
|
pub fn previous_epoch_start_slot(&self, spec: &ChainSpec) -> Slot {
|
||||||
self.previous_epoch(spec) * spec.epoch_length
|
self.previous_epoch(spec).start_slot(spec.epoch_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of committees per slot.
|
/// Returns the number of committees per slot.
|
||||||
@ -231,23 +231,6 @@ impl BeaconState {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the start slot and end slot of the current epoch containing `self.slot`.
|
|
||||||
pub fn get_current_epoch_boundaries(&self, epoch_length: u64) -> Range<u64> {
|
|
||||||
let slot_in_epoch = self.slot % epoch_length;
|
|
||||||
let start = self.slot - slot_in_epoch;
|
|
||||||
let end = self.slot + (epoch_length - slot_in_epoch);
|
|
||||||
start..end
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the start slot and end slot of the current epoch containing `self.slot`.
|
|
||||||
pub fn get_previous_epoch_boundaries(&self, spec: &ChainSpec) -> Range<u64> {
|
|
||||||
let current_epoch = self.slot / spec.epoch_length;
|
|
||||||
let previous_epoch = current_epoch.saturating_sub(1);
|
|
||||||
let start = previous_epoch * spec.epoch_length;
|
|
||||||
let end = start + spec.epoch_length;
|
|
||||||
start..end
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_previous_epoch_committee_count_per_slot(&self, spec: &ChainSpec) -> u64 {
|
fn get_previous_epoch_committee_count_per_slot(&self, spec: &ChainSpec) -> u64 {
|
||||||
let previous_active_validators = get_active_validator_indices(
|
let previous_active_validators = get_active_validator_indices(
|
||||||
&self.validator_registry,
|
&self.validator_registry,
|
||||||
@ -266,24 +249,24 @@ impl BeaconState {
|
|||||||
|
|
||||||
pub fn get_crosslink_committees_at_slot(
|
pub fn get_crosslink_committees_at_slot(
|
||||||
&self,
|
&self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<Vec<(Vec<usize>, u64)>, CommitteesError> {
|
) -> Result<Vec<(Vec<usize>, u64)>, CommitteesError> {
|
||||||
let epoch = slot / spec.epoch_length;
|
let epoch = slot.epoch(spec.epoch_length);
|
||||||
let current_epoch = self.slot / spec.epoch_length;
|
let current_epoch = self.current_epoch(spec);
|
||||||
let previous_epoch = if current_epoch == spec.genesis_slot {
|
let previous_epoch = if current_epoch == spec.genesis_slot.epoch(spec.epoch_length) {
|
||||||
current_epoch
|
current_epoch
|
||||||
} else {
|
} else {
|
||||||
current_epoch.saturating_sub(1)
|
current_epoch.saturating_sub(1_u64)
|
||||||
};
|
};
|
||||||
let next_epoch = current_epoch + 1;
|
let next_epoch = current_epoch + 1;
|
||||||
|
|
||||||
ensure!(
|
ensure!(
|
||||||
(previous_epoch <= epoch) & (epoch < next_epoch),
|
(previous_epoch <= epoch) & (epoch < next_epoch),
|
||||||
CommitteesError::InvalidEpoch(slot, previous_epoch..current_epoch)
|
CommitteesError::InvalidEpoch
|
||||||
);
|
);
|
||||||
|
|
||||||
let offset = slot % spec.epoch_length;
|
let offset = slot.as_u64() % spec.epoch_length;
|
||||||
|
|
||||||
let (committees_per_slot, shuffling, slot_start_shard) = if epoch < current_epoch {
|
let (committees_per_slot, shuffling, slot_start_shard) = if epoch < current_epoch {
|
||||||
let committees_per_slot = self.get_previous_epoch_committee_count_per_slot(spec);
|
let committees_per_slot = self.get_previous_epoch_committee_count_per_slot(spec);
|
||||||
@ -332,11 +315,11 @@ impl BeaconState {
|
|||||||
let block_proposer = self.get_beacon_proposer_index(self.slot, spec)?;
|
let block_proposer = self.get_beacon_proposer_index(self.slot, spec)?;
|
||||||
|
|
||||||
self.validator_registry[block_proposer].proposer_slots += 1;
|
self.validator_registry[block_proposer].proposer_slots += 1;
|
||||||
self.latest_randao_mixes[(self.slot % spec.latest_randao_mixes_length) as usize] =
|
self.latest_randao_mixes[(self.slot % spec.latest_randao_mixes_length).as_usize()] = self
|
||||||
self.latest_randao_mixes[((self.slot - 1) % spec.latest_randao_mixes_length) as usize];
|
.latest_randao_mixes[((self.slot - 1) % spec.latest_randao_mixes_length).as_usize()];
|
||||||
|
|
||||||
// Block roots.
|
// Block roots.
|
||||||
self.latest_block_roots[((self.slot - 1) % spec.latest_block_roots_length) as usize] =
|
self.latest_block_roots[((self.slot - 1) % spec.latest_block_roots_length).as_usize()] =
|
||||||
previous_block_root;
|
previous_block_root;
|
||||||
|
|
||||||
if self.slot % spec.latest_block_roots_length == 0 {
|
if self.slot % spec.latest_block_roots_length == 0 {
|
||||||
@ -350,9 +333,9 @@ impl BeaconState {
|
|||||||
&self,
|
&self,
|
||||||
validator_index: usize,
|
validator_index: usize,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<Option<(u64, u64, u64)>, CommitteesError> {
|
) -> Result<Option<(Slot, u64, u64)>, CommitteesError> {
|
||||||
let mut result = None;
|
let mut result = None;
|
||||||
for slot in self.get_current_epoch_boundaries(spec.epoch_length) {
|
for slot in self.current_epoch(spec).slot_iter(spec.epoch_length) {
|
||||||
for (committee, shard) in self.get_crosslink_committees_at_slot(slot, spec)? {
|
for (committee, shard) in self.get_crosslink_committees_at_slot(slot, spec)? {
|
||||||
if let Some(committee_index) = committee.iter().position(|&i| i == validator_index)
|
if let Some(committee_index) = committee.iter().position(|&i| i == validator_index)
|
||||||
{
|
{
|
||||||
@ -426,13 +409,14 @@ impl BeaconState {
|
|||||||
// TODO: check this is correct.
|
// TODO: check this is correct.
|
||||||
let new_mix = {
|
let new_mix = {
|
||||||
let mut mix = self.latest_randao_mixes
|
let mut mix = self.latest_randao_mixes
|
||||||
[(self.slot % spec.latest_randao_mixes_length) as usize]
|
[(self.slot % spec.latest_randao_mixes_length).as_usize()]
|
||||||
.to_vec();
|
.to_vec();
|
||||||
mix.append(&mut ssz_encode(&block.randao_reveal));
|
mix.append(&mut ssz_encode(&block.randao_reveal));
|
||||||
Hash256::from(&hash(&mix)[..])
|
Hash256::from(&hash(&mix)[..])
|
||||||
};
|
};
|
||||||
|
|
||||||
self.latest_randao_mixes[(self.slot % spec.latest_randao_mixes_length) as usize] = new_mix;
|
self.latest_randao_mixes[(self.slot % spec.latest_randao_mixes_length).as_usize()] =
|
||||||
|
new_mix;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Eth1 data
|
* Eth1 data
|
||||||
@ -593,7 +577,7 @@ impl BeaconState {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_shuffling(&self, seed: Hash256, slot: u64, spec: &ChainSpec) -> Vec<Vec<usize>> {
|
pub fn get_shuffling(&self, seed: Hash256, slot: Slot, spec: &ChainSpec) -> Vec<Vec<usize>> {
|
||||||
let slot = slot - (slot % spec.epoch_length);
|
let slot = slot - (slot % spec.epoch_length);
|
||||||
|
|
||||||
let active_validator_indices = get_active_validator_indices(&self.validator_registry, slot);
|
let active_validator_indices = get_active_validator_indices(&self.validator_registry, slot);
|
||||||
@ -602,7 +586,7 @@ impl BeaconState {
|
|||||||
self.get_committee_count_per_slot(active_validator_indices.len(), spec);
|
self.get_committee_count_per_slot(active_validator_indices.len(), spec);
|
||||||
|
|
||||||
// TODO: check that Hash256 matches 'int_to_bytes32'.
|
// TODO: check that Hash256 matches 'int_to_bytes32'.
|
||||||
let seed = seed ^ Hash256::from(slot);
|
let seed = seed ^ Hash256::from(slot.as_u64());
|
||||||
let shuffled_active_validator_indices =
|
let shuffled_active_validator_indices =
|
||||||
shuffle(&seed, active_validator_indices).expect("Max validator count exceed!");
|
shuffle(&seed, active_validator_indices).expect("Max validator count exceed!");
|
||||||
|
|
||||||
@ -616,7 +600,7 @@ impl BeaconState {
|
|||||||
/// If the state does not contain an index for a beacon proposer at the requested `slot`, then `None` is returned.
|
/// If the state does not contain an index for a beacon proposer at the requested `slot`, then `None` is returned.
|
||||||
pub fn get_beacon_proposer_index(
|
pub fn get_beacon_proposer_index(
|
||||||
&self,
|
&self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<usize, CommitteesError> {
|
) -> Result<usize, CommitteesError> {
|
||||||
let committees = self.get_crosslink_committees_at_slot(slot, spec)?;
|
let committees = self.get_crosslink_committees_at_slot(slot, spec)?;
|
||||||
@ -624,7 +608,7 @@ impl BeaconState {
|
|||||||
.first()
|
.first()
|
||||||
.ok_or(CommitteesError::InsufficientNumberOfValidators)
|
.ok_or(CommitteesError::InsufficientNumberOfValidators)
|
||||||
.and_then(|(first_committee, _)| {
|
.and_then(|(first_committee, _)| {
|
||||||
let index = (slot as usize)
|
let index = (slot.as_usize())
|
||||||
.checked_rem(first_committee.len())
|
.checked_rem(first_committee.len())
|
||||||
.ok_or(CommitteesError::InsufficientNumberOfValidators)?;
|
.ok_or(CommitteesError::InsufficientNumberOfValidators)?;
|
||||||
// NOTE: next index will not panic as we have already returned if this is the case
|
// NOTE: next index will not panic as we have already returned if this is the case
|
||||||
@ -653,7 +637,10 @@ impl BeaconState {
|
|||||||
let current_epoch_attestations: Vec<&PendingAttestation> = self
|
let current_epoch_attestations: Vec<&PendingAttestation> = self
|
||||||
.latest_attestations
|
.latest_attestations
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.filter(|a| a.data.slot / spec.epoch_length == self.current_epoch(spec))
|
.filter(|a| {
|
||||||
|
(a.data.slot / spec.epoch_length).epoch(spec.epoch_length)
|
||||||
|
== self.current_epoch(spec)
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
@ -708,7 +695,8 @@ impl BeaconState {
|
|||||||
.par_iter()
|
.par_iter()
|
||||||
.filter(|a| {
|
.filter(|a| {
|
||||||
//TODO: ensure these saturating subs are correct.
|
//TODO: ensure these saturating subs are correct.
|
||||||
a.data.slot / spec.epoch_length == self.previous_epoch(spec)
|
(a.data.slot / spec.epoch_length).epoch(spec.epoch_length)
|
||||||
|
== self.previous_epoch(spec)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -864,7 +852,7 @@ impl BeaconState {
|
|||||||
HashMap::new();
|
HashMap::new();
|
||||||
|
|
||||||
// for slot in self.slot.saturating_sub(2 * spec.epoch_length)..self.slot {
|
// for slot in self.slot.saturating_sub(2 * spec.epoch_length)..self.slot {
|
||||||
for slot in self.get_previous_epoch_boundaries(spec) {
|
for slot in self.previous_epoch(spec).slot_iter(spec.epoch_length) {
|
||||||
let crosslink_committees_at_slot = self.get_crosslink_committees_at_slot(slot, spec)?;
|
let crosslink_committees_at_slot = self.get_crosslink_committees_at_slot(slot, spec)?;
|
||||||
|
|
||||||
for (crosslink_committee, shard) in crosslink_committees_at_slot {
|
for (crosslink_committee, shard) in crosslink_committees_at_slot {
|
||||||
@ -909,7 +897,7 @@ impl BeaconState {
|
|||||||
* Justification and finalization
|
* Justification and finalization
|
||||||
*/
|
*/
|
||||||
let epochs_since_finality =
|
let epochs_since_finality =
|
||||||
self.slot.saturating_sub(self.finalized_slot) / spec.epoch_length;
|
(self.slot.saturating_sub(self.finalized_slot) / spec.epoch_length).as_u64();
|
||||||
|
|
||||||
// TODO: fix this extra map
|
// TODO: fix this extra map
|
||||||
let previous_epoch_justified_attester_indices_hashset: HashSet<usize> =
|
let previous_epoch_justified_attester_indices_hashset: HashSet<usize> =
|
||||||
@ -1028,7 +1016,7 @@ impl BeaconState {
|
|||||||
/*
|
/*
|
||||||
* Crosslinks
|
* Crosslinks
|
||||||
*/
|
*/
|
||||||
for slot in self.get_previous_epoch_boundaries(spec) {
|
for slot in self.previous_epoch(spec).slot_iter(spec.epoch_length) {
|
||||||
let crosslink_committees_at_slot = self.get_crosslink_committees_at_slot(slot, spec)?;
|
let crosslink_committees_at_slot = self.get_crosslink_committees_at_slot(slot, spec)?;
|
||||||
|
|
||||||
for (_crosslink_committee, shard) in crosslink_committees_at_slot {
|
for (_crosslink_committee, shard) in crosslink_committees_at_slot {
|
||||||
@ -1097,8 +1085,7 @@ impl BeaconState {
|
|||||||
+ self.get_current_epoch_committee_count_per_slot(spec) as u64 * spec.epoch_length)
|
+ self.get_current_epoch_committee_count_per_slot(spec) as u64 * spec.epoch_length)
|
||||||
% spec.shard_count;
|
% spec.shard_count;
|
||||||
self.current_epoch_seed = self.get_randao_mix(
|
self.current_epoch_seed = self.get_randao_mix(
|
||||||
self.current_epoch_calculation_slot
|
self.current_epoch_calculation_slot - spec.seed_lookahead,
|
||||||
.saturating_sub(spec.seed_lookahead),
|
|
||||||
spec,
|
spec,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -1107,8 +1094,7 @@ impl BeaconState {
|
|||||||
if epochs_since_last_registry_change.is_power_of_two() {
|
if epochs_since_last_registry_change.is_power_of_two() {
|
||||||
self.current_epoch_calculation_slot = self.slot;
|
self.current_epoch_calculation_slot = self.slot;
|
||||||
self.current_epoch_seed = self.get_randao_mix(
|
self.current_epoch_seed = self.get_randao_mix(
|
||||||
self.current_epoch_calculation_slot
|
self.current_epoch_calculation_slot - spec.seed_lookahead,
|
||||||
.saturating_sub(spec.seed_lookahead),
|
|
||||||
spec,
|
spec,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1117,13 +1103,16 @@ impl BeaconState {
|
|||||||
self.process_penalties_and_exits(spec);
|
self.process_penalties_and_exits(spec);
|
||||||
|
|
||||||
let e = self.slot / spec.epoch_length;
|
let e = self.slot / spec.epoch_length;
|
||||||
self.latest_penalized_balances[((e + 1) % spec.latest_penalized_exit_length) as usize] =
|
self.latest_penalized_balances[((e + 1) % spec.latest_penalized_exit_length).as_usize()] =
|
||||||
self.latest_penalized_balances[(e % spec.latest_penalized_exit_length) as usize];
|
self.latest_penalized_balances[(e % spec.latest_penalized_exit_length).as_usize()];
|
||||||
|
|
||||||
self.latest_attestations = self
|
self.latest_attestations = self
|
||||||
.latest_attestations
|
.latest_attestations
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|a| a.data.slot / spec.epoch_length >= self.current_epoch(spec))
|
.filter(|a| {
|
||||||
|
(a.data.slot / spec.epoch_length).epoch(spec.epoch_length)
|
||||||
|
>= self.current_epoch(spec)
|
||||||
|
})
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -1146,8 +1135,8 @@ impl BeaconState {
|
|||||||
{
|
{
|
||||||
let e = (self.slot / spec.epoch_length) % spec.latest_penalized_exit_length;
|
let e = (self.slot / spec.epoch_length) % spec.latest_penalized_exit_length;
|
||||||
let total_at_start = self.latest_penalized_balances
|
let total_at_start = self.latest_penalized_balances
|
||||||
[((e + 1) % spec.latest_penalized_exit_length) as usize];
|
[((e + 1) % spec.latest_penalized_exit_length).as_usize()];
|
||||||
let total_at_end = self.latest_penalized_balances[e as usize];
|
let total_at_end = self.latest_penalized_balances[e.as_usize()];
|
||||||
let total_penalities = total_at_end.saturating_sub(total_at_start);
|
let total_penalities = total_at_end.saturating_sub(total_at_start);
|
||||||
let penalty = self.get_effective_balance(index, spec)
|
let penalty = self.get_effective_balance(index, spec)
|
||||||
* std::cmp::min(total_penalities * 3, total_balance)
|
* std::cmp::min(total_penalities * 3, total_balance)
|
||||||
@ -1187,10 +1176,10 @@ impl BeaconState {
|
|||||||
self.validator_registry[index].status_flags = Some(StatusFlags::Withdrawable);
|
self.validator_registry[index].status_flags = Some(StatusFlags::Withdrawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_randao_mix(&mut self, slot: u64, spec: &ChainSpec) -> Hash256 {
|
fn get_randao_mix(&mut self, slot: Slot, spec: &ChainSpec) -> Hash256 {
|
||||||
assert!(self.slot < slot + spec.latest_randao_mixes_length);
|
assert!(self.slot < slot + spec.latest_randao_mixes_length);
|
||||||
assert!(slot <= self.slot);
|
assert!(slot <= self.slot);
|
||||||
self.latest_randao_mixes[(slot & spec.latest_randao_mixes_length) as usize]
|
self.latest_randao_mixes[(slot % spec.latest_randao_mixes_length).as_usize()]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_validator_registry(&mut self, spec: &ChainSpec) {
|
fn update_validator_registry(&mut self, spec: &ChainSpec) {
|
||||||
@ -1260,7 +1249,7 @@ impl BeaconState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn entry_exit_effect_slot(&self, slot: u64, spec: &ChainSpec) -> u64 {
|
fn entry_exit_effect_slot(&self, slot: Slot, spec: &ChainSpec) -> Slot {
|
||||||
(slot - slot % spec.epoch_length) + spec.epoch_length + spec.entry_exit_delay
|
(slot - slot % spec.epoch_length) + spec.epoch_length + spec.entry_exit_delay
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1288,9 +1277,7 @@ impl BeaconState {
|
|||||||
) -> Result<u64, InclusionError> {
|
) -> Result<u64, InclusionError> {
|
||||||
let attestation =
|
let attestation =
|
||||||
self.earliest_included_attestation(attestations, validator_index, spec)?;
|
self.earliest_included_attestation(attestations, validator_index, spec)?;
|
||||||
Ok(attestation
|
Ok((attestation.slot_included - attestation.data.slot).as_u64())
|
||||||
.slot_included
|
|
||||||
.saturating_sub(attestation.data.slot))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inclusion_slot(
|
fn inclusion_slot(
|
||||||
@ -1298,7 +1285,7 @@ impl BeaconState {
|
|||||||
attestations: &[&PendingAttestation],
|
attestations: &[&PendingAttestation],
|
||||||
validator_index: usize,
|
validator_index: usize,
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<u64, InclusionError> {
|
) -> Result<Slot, InclusionError> {
|
||||||
let attestation =
|
let attestation =
|
||||||
self.earliest_included_attestation(attestations, validator_index, spec)?;
|
self.earliest_included_attestation(attestations, validator_index, spec)?;
|
||||||
Ok(attestation.slot_included)
|
Ok(attestation.slot_included)
|
||||||
@ -1350,10 +1337,10 @@ impl BeaconState {
|
|||||||
std::cmp::min(self.validator_balances[validator_index], spec.max_deposit)
|
std::cmp::min(self.validator_balances[validator_index], spec.max_deposit)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_block_root(&self, slot: u64, spec: &ChainSpec) -> Option<&Hash256> {
|
pub fn get_block_root(&self, slot: Slot, spec: &ChainSpec) -> Option<&Hash256> {
|
||||||
if self.slot <= slot + spec.latest_block_roots_length && slot <= self.slot {
|
if self.slot <= slot + spec.latest_block_roots_length && slot <= self.slot {
|
||||||
self.latest_block_roots
|
self.latest_block_roots
|
||||||
.get((slot % spec.latest_block_roots_length) as usize)
|
.get((slot % spec.latest_block_roots_length).as_usize())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -1589,7 +1576,7 @@ fn penalize_validator(_state: &BeaconState, _proposer_index: usize) {
|
|||||||
// TODO: stubbed out.
|
// TODO: stubbed out.
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_domain(_fork: &Fork, _slot: u64, _domain_type: u64) -> u64 {
|
fn get_domain(_fork: &Fork, _slot: Slot, _domain_type: u64) -> u64 {
|
||||||
// TODO: stubbed out.
|
// TODO: stubbed out.
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use super::state_reader::BeaconStateReader;
|
use crate::{BeaconBlock, Hash256, Slot};
|
||||||
use crate::{BeaconBlock, Hash256};
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
/// The `BeaconBlockReader` provides interfaces for reading a subset of fields of a `BeaconBlock`.
|
/// The `BeaconBlockReader` provides interfaces for reading a subset of fields of a `BeaconBlock`.
|
||||||
@ -11,7 +10,7 @@ use std::fmt::Debug;
|
|||||||
/// Note: presently, direct SSZ reading has not been implemented so this trait is being used for
|
/// Note: presently, direct SSZ reading has not been implemented so this trait is being used for
|
||||||
/// "future proofing".
|
/// "future proofing".
|
||||||
pub trait BeaconBlockReader: Debug + PartialEq {
|
pub trait BeaconBlockReader: Debug + PartialEq {
|
||||||
fn slot(&self) -> u64;
|
fn slot(&self) -> Slot;
|
||||||
fn parent_root(&self) -> Hash256;
|
fn parent_root(&self) -> Hash256;
|
||||||
fn state_root(&self) -> Hash256;
|
fn state_root(&self) -> Hash256;
|
||||||
fn canonical_root(&self) -> Hash256;
|
fn canonical_root(&self) -> Hash256;
|
||||||
@ -19,7 +18,7 @@ pub trait BeaconBlockReader: Debug + PartialEq {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BeaconBlockReader for BeaconBlock {
|
impl BeaconBlockReader for BeaconBlock {
|
||||||
fn slot(&self) -> u64 {
|
fn slot(&self) -> Slot {
|
||||||
self.slot
|
self.slot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{BeaconState, Hash256};
|
use crate::{BeaconState, Hash256, Slot};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
/// The `BeaconStateReader` provides interfaces for reading a subset of fields of a `BeaconState`.
|
/// The `BeaconStateReader` provides interfaces for reading a subset of fields of a `BeaconState`.
|
||||||
@ -10,13 +10,13 @@ use std::fmt::Debug;
|
|||||||
/// Note: presently, direct SSZ reading has not been implemented so this trait is being used for
|
/// Note: presently, direct SSZ reading has not been implemented so this trait is being used for
|
||||||
/// "future proofing".
|
/// "future proofing".
|
||||||
pub trait BeaconStateReader: Debug + PartialEq {
|
pub trait BeaconStateReader: Debug + PartialEq {
|
||||||
fn slot(&self) -> u64;
|
fn slot(&self) -> Slot;
|
||||||
fn canonical_root(&self) -> Hash256;
|
fn canonical_root(&self) -> Hash256;
|
||||||
fn into_beacon_state(self) -> Option<BeaconState>;
|
fn into_beacon_state(self) -> Option<BeaconState>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BeaconStateReader for BeaconState {
|
impl BeaconStateReader for BeaconState {
|
||||||
fn slot(&self) -> u64 {
|
fn slot(&self) -> Slot {
|
||||||
self.slot
|
self.slot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,13 +10,13 @@
|
|||||||
/// implement `Into<u64>`, however this would allow operations between `Slots` and `Epochs` which
|
/// implement `Into<u64>`, however this would allow operations between `Slots` and `Epochs` which
|
||||||
/// may lead to programming errors which are not detected by the compiler.
|
/// may lead to programming errors which are not detected by the compiler.
|
||||||
use crate::test_utils::TestRandom;
|
use crate::test_utils::TestRandom;
|
||||||
use crate::ChainSpec;
|
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
use serde_derive::Serialize;
|
use serde_derive::Serialize;
|
||||||
use ssz::{hash, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
use ssz::{hash, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
||||||
use std::cmp::{Ord, Ordering};
|
use std::cmp::{Ord, Ordering};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Add, AddAssign, Rem, Sub, SubAssign};
|
use std::iter::Iterator;
|
||||||
|
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, Sub, SubAssign};
|
||||||
|
|
||||||
macro_rules! impl_from_into_u64 {
|
macro_rules! impl_from_into_u64 {
|
||||||
($main: ident) => {
|
($main: ident) => {
|
||||||
@ -88,7 +88,7 @@ macro_rules! impl_math_between {
|
|||||||
|
|
||||||
impl AddAssign<$other> for $main {
|
impl AddAssign<$other> for $main {
|
||||||
fn add_assign(&mut self, other: $other) {
|
fn add_assign(&mut self, other: $other) {
|
||||||
self.0.saturating_add(other.into());
|
self.0 = self.0.saturating_add(other.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +102,45 @@ macro_rules! impl_math_between {
|
|||||||
|
|
||||||
impl SubAssign<$other> for $main {
|
impl SubAssign<$other> for $main {
|
||||||
fn sub_assign(&mut self, other: $other) {
|
fn sub_assign(&mut self, other: $other) {
|
||||||
self.0.saturating_sub(other.into());
|
self.0 = self.0.saturating_sub(other.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<$other> for $main {
|
||||||
|
type Output = $main;
|
||||||
|
|
||||||
|
fn mul(self, rhs: $other) -> $main {
|
||||||
|
let rhs: u64 = rhs.into();
|
||||||
|
$main::from(self.0.saturating_mul(rhs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MulAssign<$other> for $main {
|
||||||
|
fn mul_assign(&mut self, rhs: $other) {
|
||||||
|
let rhs: u64 = rhs.into();
|
||||||
|
self.0 = self.0.saturating_mul(rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Div<$other> for $main {
|
||||||
|
type Output = $main;
|
||||||
|
|
||||||
|
fn div(self, rhs: $other) -> $main {
|
||||||
|
let rhs: u64 = rhs.into();
|
||||||
|
if rhs == 0 {
|
||||||
|
panic!("Cannot divide by zero-valued Slot/Epoch")
|
||||||
|
}
|
||||||
|
$main::from(self.0 / rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DivAssign<$other> for $main {
|
||||||
|
fn div_assign(&mut self, rhs: $other) {
|
||||||
|
let rhs: u64 = rhs.into();
|
||||||
|
if rhs == 0 {
|
||||||
|
panic!("Cannot divide by zero-valued Slot/Epoch")
|
||||||
|
}
|
||||||
|
self.0 = self.0 / rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +155,27 @@ macro_rules! impl_math_between {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_math {
|
||||||
|
($type: ident) => {
|
||||||
|
impl $type {
|
||||||
|
pub fn saturating_sub<T: Into<$type>>(&self, other: T) -> $type {
|
||||||
|
*self - other.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_power_of_two(&self) -> bool {
|
||||||
|
self.0.is_power_of_two()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for $type {
|
||||||
|
fn cmp(&self, other: &$type) -> Ordering {
|
||||||
|
let other: u64 = (*other).into();
|
||||||
|
self.0.cmp(&other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! impl_display {
|
macro_rules! impl_display {
|
||||||
($type: ident) => {
|
($type: ident) => {
|
||||||
impl fmt::Display for $type {
|
impl fmt::Display for $type {
|
||||||
@ -169,6 +228,7 @@ impl_from_into_u64!(Slot);
|
|||||||
impl_from_into_usize!(Slot);
|
impl_from_into_usize!(Slot);
|
||||||
impl_math_between!(Slot, Slot);
|
impl_math_between!(Slot, Slot);
|
||||||
impl_math_between!(Slot, u64);
|
impl_math_between!(Slot, u64);
|
||||||
|
impl_math!(Slot);
|
||||||
impl_display!(Slot);
|
impl_display!(Slot);
|
||||||
impl_ssz!(Slot);
|
impl_ssz!(Slot);
|
||||||
|
|
||||||
@ -176,33 +236,59 @@ impl_from_into_u64!(Epoch);
|
|||||||
impl_from_into_usize!(Epoch);
|
impl_from_into_usize!(Epoch);
|
||||||
impl_math_between!(Epoch, Epoch);
|
impl_math_between!(Epoch, Epoch);
|
||||||
impl_math_between!(Epoch, u64);
|
impl_math_between!(Epoch, u64);
|
||||||
|
impl_math!(Epoch);
|
||||||
impl_display!(Epoch);
|
impl_display!(Epoch);
|
||||||
impl_ssz!(Epoch);
|
impl_ssz!(Epoch);
|
||||||
|
|
||||||
impl Slot {
|
impl Slot {
|
||||||
pub fn epoch(&self, spec: &ChainSpec) -> Epoch {
|
pub fn epoch(&self, epoch_length: u64) -> Epoch {
|
||||||
Epoch::from(self.0 / spec.epoch_length)
|
Epoch::from(self.0 / epoch_length)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max_value() -> Slot {
|
||||||
|
Slot(u64::max_value())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Epoch {
|
impl Epoch {
|
||||||
pub fn start_slot(&self, spec: &ChainSpec) -> Slot {
|
pub fn start_slot(&self, epoch_length: u64) -> Slot {
|
||||||
Slot::from(self.0.saturating_mul(spec.epoch_length))
|
Slot::from(self.0.saturating_mul(epoch_length))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn end_slot(&self, spec: &ChainSpec) -> Slot {
|
pub fn end_slot(&self, epoch_length: u64) -> Slot {
|
||||||
Slot::from(
|
Slot::from(
|
||||||
self.0
|
self.0
|
||||||
.saturating_add(1)
|
.saturating_add(1)
|
||||||
.saturating_mul(spec.epoch_length)
|
.saturating_mul(epoch_length)
|
||||||
.saturating_sub(1),
|
.saturating_sub(1),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slots(&self, spec: &ChainSpec) -> Vec<Slot> {
|
pub fn slot_iter(&self, epoch_length: u64) -> SlotIter {
|
||||||
(self.start_slot(spec).as_u64()..self.end_slot(spec).as_u64())
|
SlotIter {
|
||||||
.into_iter()
|
current: self.start_slot(epoch_length),
|
||||||
.map(|i| Slot::from(i))
|
epoch: self,
|
||||||
.collect()
|
epoch_length,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SlotIter<'a> {
|
||||||
|
current: Slot,
|
||||||
|
epoch: &'a Epoch,
|
||||||
|
epoch_length: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for SlotIter<'a> {
|
||||||
|
type Item = Slot;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Slot> {
|
||||||
|
if self.current == self.epoch.end_slot(self.epoch_length) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let previous = self.current;
|
||||||
|
self.current += 1;
|
||||||
|
Some(previous)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::ChainSpec;
|
use super::ChainSpec;
|
||||||
use bls::{Keypair, PublicKey, SecretKey, Signature};
|
use bls::{Keypair, PublicKey, SecretKey, Signature};
|
||||||
|
|
||||||
use crate::{Address, Eth1Data, Hash256, Validator};
|
use crate::{Address, Eth1Data, Hash256, Slot, Validator};
|
||||||
|
|
||||||
/// The size of a validators deposit in GWei.
|
/// The size of a validators deposit in GWei.
|
||||||
pub const DEPOSIT_GWEI: u64 = 32_000_000_000;
|
pub const DEPOSIT_GWEI: u64 = 32_000_000_000;
|
||||||
@ -37,9 +37,9 @@ impl ChainSpec {
|
|||||||
* Initial Values
|
* Initial Values
|
||||||
*/
|
*/
|
||||||
genesis_fork_version: 0,
|
genesis_fork_version: 0,
|
||||||
genesis_slot: 0,
|
genesis_slot: Slot::from(0_u64),
|
||||||
genesis_start_shard: 0,
|
genesis_start_shard: 0,
|
||||||
far_future_slot: u64::max_value(),
|
far_future_slot: Slot::from(u64::max_value()),
|
||||||
zero_hash: Hash256::zero(),
|
zero_hash: Hash256::zero(),
|
||||||
empty_signature: Signature::empty_signature(),
|
empty_signature: Signature::empty_signature(),
|
||||||
bls_withdrawal_prefix_byte: 0x00,
|
bls_withdrawal_prefix_byte: 0x00,
|
||||||
@ -109,15 +109,15 @@ fn initial_validators_for_testing() -> Vec<Validator> {
|
|||||||
let validator = Validator {
|
let validator = Validator {
|
||||||
pubkey: keypair.pk.clone(),
|
pubkey: keypair.pk.clone(),
|
||||||
withdrawal_credentials: Hash256::zero(),
|
withdrawal_credentials: Hash256::zero(),
|
||||||
proposer_slots: 0,
|
proposer_slots: Slot::from(0_u64),
|
||||||
activation_slot: u64::max_value(),
|
activation_slot: Slot::max_value(),
|
||||||
exit_slot: u64::max_value(),
|
exit_slot: Slot::max_value(),
|
||||||
withdrawal_slot: u64::max_value(),
|
withdrawal_slot: Slot::max_value(),
|
||||||
penalized_slot: u64::max_value(),
|
penalized_slot: Slot::max_value(),
|
||||||
exit_count: 0,
|
exit_count: 0,
|
||||||
status_flags: None,
|
status_flags: None,
|
||||||
latest_custody_reseed_slot: 0,
|
latest_custody_reseed_slot: Slot::from(0_u64),
|
||||||
penultimate_custody_reseed_slot: 0,
|
penultimate_custody_reseed_slot: Slot::from(0_u64),
|
||||||
};
|
};
|
||||||
initial_validators.push(validator);
|
initial_validators.push(validator);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
mod foundation;
|
mod foundation;
|
||||||
|
|
||||||
use crate::{Address, Eth1Data, Hash256, Validator};
|
use crate::{Address, Eth1Data, Hash256, Slot, Validator};
|
||||||
use bls::Signature;
|
use bls::Signature;
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
@ -29,9 +29,9 @@ pub struct ChainSpec {
|
|||||||
* Initial Values
|
* Initial Values
|
||||||
*/
|
*/
|
||||||
pub genesis_fork_version: u64,
|
pub genesis_fork_version: u64,
|
||||||
pub genesis_slot: u64,
|
pub genesis_slot: Slot,
|
||||||
pub genesis_start_shard: u64,
|
pub genesis_start_shard: u64,
|
||||||
pub far_future_slot: u64,
|
pub far_future_slot: Slot,
|
||||||
pub zero_hash: Hash256,
|
pub zero_hash: Hash256,
|
||||||
pub empty_signature: Signature,
|
pub empty_signature: Signature,
|
||||||
pub bls_withdrawal_prefix_byte: u8,
|
pub bls_withdrawal_prefix_byte: u8,
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
/// Contains logic to manipulate a `&[Validator]`.
|
/// Contains logic to manipulate a `&[Validator]`.
|
||||||
/// For now, we avoid defining a newtype and just have flat functions here.
|
/// For now, we avoid defining a newtype and just have flat functions here.
|
||||||
use super::validator::*;
|
use super::validator::*;
|
||||||
|
use crate::Slot;
|
||||||
|
|
||||||
/// Given an indexed sequence of `validators`, return the indices corresponding to validators that are active at `slot`.
|
/// Given an indexed sequence of `validators`, return the indices corresponding to validators that are active at `slot`.
|
||||||
pub fn get_active_validator_indices(validators: &[Validator], slot: u64) -> Vec<usize> {
|
pub fn get_active_validator_indices(validators: &[Validator], slot: Slot) -> Vec<usize> {
|
||||||
validators
|
validators
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
@ -27,7 +28,7 @@ mod tests {
|
|||||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
|
|
||||||
let validators = vec![];
|
let validators = vec![];
|
||||||
let some_slot = u64::random_for_test(&mut rng);
|
let some_slot = Slot::random_for_test(&mut rng);
|
||||||
let indices = get_active_validator_indices(&validators, some_slot);
|
let indices = get_active_validator_indices(&validators, some_slot);
|
||||||
assert_eq!(indices, vec![]);
|
assert_eq!(indices, vec![]);
|
||||||
}
|
}
|
||||||
@ -41,7 +42,7 @@ mod tests {
|
|||||||
validators.push(Validator::default())
|
validators.push(Validator::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
let some_slot = u64::random_for_test(&mut rng);
|
let some_slot = Slot::random_for_test(&mut rng);
|
||||||
let indices = get_active_validator_indices(&validators, some_slot);
|
let indices = get_active_validator_indices(&validators, some_slot);
|
||||||
assert_eq!(indices, vec![]);
|
assert_eq!(indices, vec![]);
|
||||||
}
|
}
|
||||||
@ -50,7 +51,7 @@ mod tests {
|
|||||||
fn can_get_all_active_validator_indices() {
|
fn can_get_all_active_validator_indices() {
|
||||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
let count_validators = 10;
|
let count_validators = 10;
|
||||||
let some_slot = u64::random_for_test(&mut rng);
|
let some_slot = Slot::random_for_test(&mut rng);
|
||||||
|
|
||||||
let mut validators = (0..count_validators)
|
let mut validators = (0..count_validators)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -60,8 +61,8 @@ mod tests {
|
|||||||
let activation_offset = u64::random_for_test(&mut rng);
|
let activation_offset = u64::random_for_test(&mut rng);
|
||||||
let exit_offset = u64::random_for_test(&mut rng);
|
let exit_offset = u64::random_for_test(&mut rng);
|
||||||
|
|
||||||
validator.activation_slot = some_slot.checked_sub(activation_offset).unwrap_or(0);
|
validator.activation_slot = some_slot - activation_offset;
|
||||||
validator.exit_slot = some_slot.checked_add(exit_offset).unwrap_or(std::u64::MAX);
|
validator.exit_slot = some_slot + exit_offset;
|
||||||
|
|
||||||
validator
|
validator
|
||||||
})
|
})
|
||||||
@ -81,13 +82,13 @@ mod tests {
|
|||||||
|
|
||||||
fn set_validators_to_default_entry_exit(validators: &mut [Validator]) {
|
fn set_validators_to_default_entry_exit(validators: &mut [Validator]) {
|
||||||
for validator in validators.iter_mut() {
|
for validator in validators.iter_mut() {
|
||||||
validator.activation_slot = std::u64::MAX;
|
validator.activation_slot = Slot::max_value();
|
||||||
validator.exit_slot = std::u64::MAX;
|
validator.exit_slot = Slot::max_value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets all `validators` to be active as of some slot prior to `slot`. returns the activation slot.
|
// sets all `validators` to be active as of some slot prior to `slot`. returns the activation slot.
|
||||||
fn set_validators_to_activated(validators: &mut [Validator], slot: u64) -> u64 {
|
fn set_validators_to_activated(validators: &mut [Validator], slot: Slot) -> Slot {
|
||||||
let activation_slot = slot - 10;
|
let activation_slot = slot - 10;
|
||||||
for validator in validators.iter_mut() {
|
for validator in validators.iter_mut() {
|
||||||
validator.activation_slot = activation_slot;
|
validator.activation_slot = activation_slot;
|
||||||
@ -96,7 +97,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sets all `validators` to be exited as of some slot before `slot`.
|
// sets all `validators` to be exited as of some slot before `slot`.
|
||||||
fn set_validators_to_exited(validators: &mut [Validator], slot: u64, activation_slot: u64) {
|
fn set_validators_to_exited(validators: &mut [Validator], slot: Slot, activation_slot: Slot) {
|
||||||
assert!(activation_slot < slot);
|
assert!(activation_slot < slot);
|
||||||
let mut exit_slot = activation_slot + 10;
|
let mut exit_slot = activation_slot + 10;
|
||||||
while exit_slot >= slot {
|
while exit_slot >= slot {
|
||||||
@ -114,18 +115,18 @@ mod tests {
|
|||||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
const COUNT_PARTITIONS: usize = 3;
|
const COUNT_PARTITIONS: usize = 3;
|
||||||
const COUNT_VALIDATORS: usize = 3 * COUNT_PARTITIONS;
|
const COUNT_VALIDATORS: usize = 3 * COUNT_PARTITIONS;
|
||||||
let some_slot: u64 = u64::random_for_test(&mut rng);
|
let some_slot: Slot = Slot::random_for_test(&mut rng);
|
||||||
|
|
||||||
let mut validators = (0..COUNT_VALIDATORS)
|
let mut validators = (0..COUNT_VALIDATORS)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|_| {
|
.map(|_| {
|
||||||
let mut validator = Validator::default();
|
let mut validator = Validator::default();
|
||||||
|
|
||||||
let activation_offset = u64::random_for_test(&mut rng);
|
let activation_offset = Slot::random_for_test(&mut rng);
|
||||||
let exit_offset = u64::random_for_test(&mut rng);
|
let exit_offset = Slot::random_for_test(&mut rng);
|
||||||
|
|
||||||
validator.activation_slot = some_slot.checked_sub(activation_offset).unwrap_or(0);
|
validator.activation_slot = some_slot - activation_offset;
|
||||||
validator.exit_slot = some_slot.checked_add(exit_offset).unwrap_or(std::u64::MAX);
|
validator.exit_slot = some_slot + exit_offset;
|
||||||
|
|
||||||
validator
|
validator
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user