diff --git a/eth2/types/src/beacon_state.rs b/eth2/types/src/beacon_state.rs index 362460c0c..b7f869c8d 100644 --- a/eth2/types/src/beacon_state.rs +++ b/eth2/types/src/beacon_state.rs @@ -1,7 +1,7 @@ use crate::test_utils::TestRandom; use crate::{ 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, }; use bls::bls_verify_aggregate; @@ -28,7 +28,7 @@ const DOMAIN_ATTESTATION: u64 = 1; pub enum Error { InsufficientValidators, BadBlockSignature, - InvalidEpoch(u64, Range), + InvalidEpoch(Slot, Range), CommitteesError(CommitteesError), } @@ -81,7 +81,7 @@ pub enum WinningRootError { #[derive(Debug, PartialEq)] pub enum CommitteesError { - InvalidEpoch(u64, Range), + InvalidEpoch, InsufficientNumberOfValidators, } @@ -198,20 +198,20 @@ impl BeaconState { Hash256::from(&self.hash_tree_root()[..]) } - pub fn current_epoch(&self, spec: &ChainSpec) -> u64 { - self.slot / spec.epoch_length + pub fn current_epoch(&self, spec: &ChainSpec) -> Epoch { + self.slot.epoch(spec.epoch_length) } - pub fn previous_epoch(&self, spec: &ChainSpec) -> u64 { - self.current_epoch(spec).saturating_sub(1) + pub fn previous_epoch(&self, spec: &ChainSpec) -> Epoch { + self.current_epoch(spec).saturating_sub(1_u64) } - pub fn current_epoch_start_slot(&self, spec: &ChainSpec) -> u64 { - self.current_epoch(spec) * spec.epoch_length + pub fn current_epoch_start_slot(&self, spec: &ChainSpec) -> Slot { + self.current_epoch(spec).start_slot(spec.epoch_length) } - pub fn previous_epoch_start_slot(&self, spec: &ChainSpec) -> u64 { - self.previous_epoch(spec) * spec.epoch_length + pub fn previous_epoch_start_slot(&self, spec: &ChainSpec) -> Slot { + self.previous_epoch(spec).start_slot(spec.epoch_length) } /// 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 { - 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 { - 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 { let previous_active_validators = get_active_validator_indices( &self.validator_registry, @@ -266,24 +249,24 @@ impl BeaconState { pub fn get_crosslink_committees_at_slot( &self, - slot: u64, + slot: Slot, spec: &ChainSpec, ) -> Result, u64)>, CommitteesError> { - let epoch = slot / spec.epoch_length; - let current_epoch = self.slot / spec.epoch_length; - let previous_epoch = if current_epoch == spec.genesis_slot { + let epoch = slot.epoch(spec.epoch_length); + let current_epoch = self.current_epoch(spec); + let previous_epoch = if current_epoch == spec.genesis_slot.epoch(spec.epoch_length) { current_epoch } else { - current_epoch.saturating_sub(1) + current_epoch.saturating_sub(1_u64) }; let next_epoch = current_epoch + 1; ensure!( (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 = 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)?; 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 - 1) % spec.latest_randao_mixes_length) as usize]; + self.latest_randao_mixes[(self.slot % spec.latest_randao_mixes_length).as_usize()] = self + .latest_randao_mixes[((self.slot - 1) % spec.latest_randao_mixes_length).as_usize()]; // 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; if self.slot % spec.latest_block_roots_length == 0 { @@ -350,9 +333,9 @@ impl BeaconState { &self, validator_index: usize, spec: &ChainSpec, - ) -> Result, CommitteesError> { + ) -> Result, CommitteesError> { 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)? { if let Some(committee_index) = committee.iter().position(|&i| i == validator_index) { @@ -426,13 +409,14 @@ impl BeaconState { // TODO: check this is correct. let new_mix = { let mut mix = self.latest_randao_mixes - [(self.slot % spec.latest_randao_mixes_length) as usize] - .to_vec(); + [(self.slot % spec.latest_randao_mixes_length).as_usize()] + .to_vec(); mix.append(&mut ssz_encode(&block.randao_reveal)); 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 @@ -593,7 +577,7 @@ impl BeaconState { Ok(()) } - pub fn get_shuffling(&self, seed: Hash256, slot: u64, spec: &ChainSpec) -> Vec> { + pub fn get_shuffling(&self, seed: Hash256, slot: Slot, spec: &ChainSpec) -> Vec> { let slot = slot - (slot % spec.epoch_length); 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); // 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 = 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. pub fn get_beacon_proposer_index( &self, - slot: u64, + slot: Slot, spec: &ChainSpec, ) -> Result { let committees = self.get_crosslink_committees_at_slot(slot, spec)?; @@ -624,7 +608,7 @@ impl BeaconState { .first() .ok_or(CommitteesError::InsufficientNumberOfValidators) .and_then(|(first_committee, _)| { - let index = (slot as usize) + let index = (slot.as_usize()) .checked_rem(first_committee.len()) .ok_or(CommitteesError::InsufficientNumberOfValidators)?; // 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 .latest_attestations .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(); debug!( @@ -708,7 +695,8 @@ impl BeaconState { .par_iter() .filter(|a| { //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(); @@ -864,7 +852,7 @@ impl BeaconState { HashMap::new(); // 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)?; for (crosslink_committee, shard) in crosslink_committees_at_slot { @@ -909,7 +897,7 @@ impl BeaconState { * Justification and finalization */ 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 let previous_epoch_justified_attester_indices_hashset: HashSet = @@ -1028,7 +1016,7 @@ impl BeaconState { /* * 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)?; 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) % spec.shard_count; self.current_epoch_seed = self.get_randao_mix( - self.current_epoch_calculation_slot - .saturating_sub(spec.seed_lookahead), + self.current_epoch_calculation_slot - spec.seed_lookahead, spec, ); } else { @@ -1107,8 +1094,7 @@ impl BeaconState { if epochs_since_last_registry_change.is_power_of_two() { self.current_epoch_calculation_slot = self.slot; self.current_epoch_seed = self.get_randao_mix( - self.current_epoch_calculation_slot - .saturating_sub(spec.seed_lookahead), + self.current_epoch_calculation_slot - spec.seed_lookahead, spec, ); } @@ -1117,13 +1103,16 @@ impl BeaconState { self.process_penalties_and_exits(spec); 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 % 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_attestations = self .latest_attestations .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() .collect(); @@ -1146,8 +1135,8 @@ impl BeaconState { { let e = (self.slot / spec.epoch_length) % spec.latest_penalized_exit_length; let total_at_start = self.latest_penalized_balances - [((e + 1) % spec.latest_penalized_exit_length) as usize]; - let total_at_end = self.latest_penalized_balances[e as usize]; + [((e + 1) % spec.latest_penalized_exit_length).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 penalty = self.get_effective_balance(index, spec) * std::cmp::min(total_penalities * 3, total_balance) @@ -1187,10 +1176,10 @@ impl BeaconState { 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!(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) { @@ -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 } @@ -1288,9 +1277,7 @@ impl BeaconState { ) -> Result { let attestation = self.earliest_included_attestation(attestations, validator_index, spec)?; - Ok(attestation - .slot_included - .saturating_sub(attestation.data.slot)) + Ok((attestation.slot_included - attestation.data.slot).as_u64()) } fn inclusion_slot( @@ -1298,7 +1285,7 @@ impl BeaconState { attestations: &[&PendingAttestation], validator_index: usize, spec: &ChainSpec, - ) -> Result { + ) -> Result { let attestation = self.earliest_included_attestation(attestations, validator_index, spec)?; Ok(attestation.slot_included) @@ -1350,10 +1337,10 @@ impl BeaconState { 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 { self.latest_block_roots - .get((slot % spec.latest_block_roots_length) as usize) + .get((slot % spec.latest_block_roots_length).as_usize()) } else { None } @@ -1589,7 +1576,7 @@ fn penalize_validator(_state: &BeaconState, _proposer_index: usize) { // 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. 0 } diff --git a/eth2/types/src/readers/block_reader.rs b/eth2/types/src/readers/block_reader.rs index d87bc5caf..bcb2d0e63 100644 --- a/eth2/types/src/readers/block_reader.rs +++ b/eth2/types/src/readers/block_reader.rs @@ -1,5 +1,4 @@ -use super::state_reader::BeaconStateReader; -use crate::{BeaconBlock, Hash256}; +use crate::{BeaconBlock, Hash256, Slot}; use std::fmt::Debug; /// 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 /// "future proofing". pub trait BeaconBlockReader: Debug + PartialEq { - fn slot(&self) -> u64; + fn slot(&self) -> Slot; fn parent_root(&self) -> Hash256; fn state_root(&self) -> Hash256; fn canonical_root(&self) -> Hash256; @@ -19,7 +18,7 @@ pub trait BeaconBlockReader: Debug + PartialEq { } impl BeaconBlockReader for BeaconBlock { - fn slot(&self) -> u64 { + fn slot(&self) -> Slot { self.slot } diff --git a/eth2/types/src/readers/state_reader.rs b/eth2/types/src/readers/state_reader.rs index 47266bd36..92a870855 100644 --- a/eth2/types/src/readers/state_reader.rs +++ b/eth2/types/src/readers/state_reader.rs @@ -1,4 +1,4 @@ -use crate::{BeaconState, Hash256}; +use crate::{BeaconState, Hash256, Slot}; use std::fmt::Debug; /// 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 /// "future proofing". pub trait BeaconStateReader: Debug + PartialEq { - fn slot(&self) -> u64; + fn slot(&self) -> Slot; fn canonical_root(&self) -> Hash256; fn into_beacon_state(self) -> Option; } impl BeaconStateReader for BeaconState { - fn slot(&self) -> u64 { + fn slot(&self) -> Slot { self.slot } diff --git a/eth2/types/src/slot_epoch.rs b/eth2/types/src/slot_epoch.rs index 4996722e4..40b0c5e95 100644 --- a/eth2/types/src/slot_epoch.rs +++ b/eth2/types/src/slot_epoch.rs @@ -10,13 +10,13 @@ /// implement `Into`, however this would allow operations between `Slots` and `Epochs` which /// may lead to programming errors which are not detected by the compiler. use crate::test_utils::TestRandom; -use crate::ChainSpec; use rand::RngCore; use serde_derive::Serialize; use ssz::{hash, Decodable, DecodeError, Encodable, SszStream, TreeHash}; use std::cmp::{Ord, Ordering}; 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 { ($main: ident) => { @@ -88,7 +88,7 @@ macro_rules! impl_math_between { impl AddAssign<$other> for $main { 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 { 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>(&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 { ($type: ident) => { impl fmt::Display for $type { @@ -169,6 +228,7 @@ impl_from_into_u64!(Slot); impl_from_into_usize!(Slot); impl_math_between!(Slot, Slot); impl_math_between!(Slot, u64); +impl_math!(Slot); impl_display!(Slot); impl_ssz!(Slot); @@ -176,33 +236,59 @@ impl_from_into_u64!(Epoch); impl_from_into_usize!(Epoch); impl_math_between!(Epoch, Epoch); impl_math_between!(Epoch, u64); +impl_math!(Epoch); impl_display!(Epoch); impl_ssz!(Epoch); impl Slot { - pub fn epoch(&self, spec: &ChainSpec) -> Epoch { - Epoch::from(self.0 / spec.epoch_length) + pub fn epoch(&self, epoch_length: u64) -> Epoch { + Epoch::from(self.0 / epoch_length) + } + + pub fn max_value() -> Slot { + Slot(u64::max_value()) } } impl Epoch { - pub fn start_slot(&self, spec: &ChainSpec) -> Slot { - Slot::from(self.0.saturating_mul(spec.epoch_length)) + pub fn start_slot(&self, epoch_length: u64) -> Slot { + 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( self.0 .saturating_add(1) - .saturating_mul(spec.epoch_length) + .saturating_mul(epoch_length) .saturating_sub(1), ) } - pub fn slots(&self, spec: &ChainSpec) -> Vec { - (self.start_slot(spec).as_u64()..self.end_slot(spec).as_u64()) - .into_iter() - .map(|i| Slot::from(i)) - .collect() + pub fn slot_iter(&self, epoch_length: u64) -> SlotIter { + SlotIter { + current: self.start_slot(epoch_length), + epoch: self, + 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 { + if self.current == self.epoch.end_slot(self.epoch_length) { + None + } else { + let previous = self.current; + self.current += 1; + Some(previous) + } } } diff --git a/eth2/types/src/spec/foundation.rs b/eth2/types/src/spec/foundation.rs index f24a55b2a..46f16ecd9 100644 --- a/eth2/types/src/spec/foundation.rs +++ b/eth2/types/src/spec/foundation.rs @@ -1,7 +1,7 @@ use super::ChainSpec; 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. pub const DEPOSIT_GWEI: u64 = 32_000_000_000; @@ -37,9 +37,9 @@ impl ChainSpec { * Initial Values */ genesis_fork_version: 0, - genesis_slot: 0, + genesis_slot: Slot::from(0_u64), genesis_start_shard: 0, - far_future_slot: u64::max_value(), + far_future_slot: Slot::from(u64::max_value()), zero_hash: Hash256::zero(), empty_signature: Signature::empty_signature(), bls_withdrawal_prefix_byte: 0x00, @@ -109,15 +109,15 @@ fn initial_validators_for_testing() -> Vec { let validator = Validator { pubkey: keypair.pk.clone(), withdrawal_credentials: Hash256::zero(), - proposer_slots: 0, - activation_slot: u64::max_value(), - exit_slot: u64::max_value(), - withdrawal_slot: u64::max_value(), - penalized_slot: u64::max_value(), + proposer_slots: Slot::from(0_u64), + activation_slot: Slot::max_value(), + exit_slot: Slot::max_value(), + withdrawal_slot: Slot::max_value(), + penalized_slot: Slot::max_value(), exit_count: 0, status_flags: None, - latest_custody_reseed_slot: 0, - penultimate_custody_reseed_slot: 0, + latest_custody_reseed_slot: Slot::from(0_u64), + penultimate_custody_reseed_slot: Slot::from(0_u64), }; initial_validators.push(validator); } diff --git a/eth2/types/src/spec/mod.rs b/eth2/types/src/spec/mod.rs index 077b6bef5..5007a26b0 100644 --- a/eth2/types/src/spec/mod.rs +++ b/eth2/types/src/spec/mod.rs @@ -1,6 +1,6 @@ mod foundation; -use crate::{Address, Eth1Data, Hash256, Validator}; +use crate::{Address, Eth1Data, Hash256, Slot, Validator}; use bls::Signature; #[derive(PartialEq, Debug, Clone)] @@ -29,9 +29,9 @@ pub struct ChainSpec { * Initial Values */ pub genesis_fork_version: u64, - pub genesis_slot: u64, + pub genesis_slot: Slot, pub genesis_start_shard: u64, - pub far_future_slot: u64, + pub far_future_slot: Slot, pub zero_hash: Hash256, pub empty_signature: Signature, pub bls_withdrawal_prefix_byte: u8, diff --git a/eth2/types/src/validator_registry.rs b/eth2/types/src/validator_registry.rs index 509ab7c7b..236d512b6 100644 --- a/eth2/types/src/validator_registry.rs +++ b/eth2/types/src/validator_registry.rs @@ -1,9 +1,10 @@ /// Contains logic to manipulate a `&[Validator]`. /// For now, we avoid defining a newtype and just have flat functions here. use super::validator::*; +use crate::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 { +pub fn get_active_validator_indices(validators: &[Validator], slot: Slot) -> Vec { validators .iter() .enumerate() @@ -27,7 +28,7 @@ mod tests { let mut rng = XorShiftRng::from_seed([42; 16]); 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); assert_eq!(indices, vec![]); } @@ -41,7 +42,7 @@ mod tests { 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); assert_eq!(indices, vec![]); } @@ -50,7 +51,7 @@ mod tests { fn can_get_all_active_validator_indices() { let mut rng = XorShiftRng::from_seed([42; 16]); 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) .into_iter() @@ -60,8 +61,8 @@ mod tests { let activation_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.exit_slot = some_slot.checked_add(exit_offset).unwrap_or(std::u64::MAX); + validator.activation_slot = some_slot - activation_offset; + validator.exit_slot = some_slot + exit_offset; validator }) @@ -81,13 +82,13 @@ mod tests { fn set_validators_to_default_entry_exit(validators: &mut [Validator]) { for validator in validators.iter_mut() { - validator.activation_slot = std::u64::MAX; - validator.exit_slot = std::u64::MAX; + validator.activation_slot = Slot::max_value(); + validator.exit_slot = Slot::max_value(); } } // 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; for validator in validators.iter_mut() { validator.activation_slot = activation_slot; @@ -96,7 +97,7 @@ mod tests { } // 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); let mut exit_slot = activation_slot + 10; while exit_slot >= slot { @@ -114,18 +115,18 @@ mod tests { let mut rng = XorShiftRng::from_seed([42; 16]); const COUNT_PARTITIONS: usize = 3; 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) .into_iter() .map(|_| { let mut validator = Validator::default(); - let activation_offset = u64::random_for_test(&mut rng); - let exit_offset = u64::random_for_test(&mut rng); + let activation_offset = Slot::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.exit_slot = some_slot.checked_add(exit_offset).unwrap_or(std::u64::MAX); + validator.activation_slot = some_slot - activation_offset; + validator.exit_slot = some_slot + exit_offset; validator })