Convert beacon_state to Slot/Epoch newtypes

This commit is contained in:
Paul Hauner 2019-02-06 13:17:10 +11:00
parent 2aa7d80a5f
commit bd71304d73
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
7 changed files with 194 additions and 121 deletions

View File

@ -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<u64>),
InvalidEpoch(Slot, Range<Epoch>),
CommitteesError(CommitteesError),
}
@ -81,7 +81,7 @@ pub enum WinningRootError {
#[derive(Debug, PartialEq)]
pub enum CommitteesError {
InvalidEpoch(u64, Range<u64>),
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<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 {
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<Vec<(Vec<usize>, 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<Option<(u64, u64, u64)>, CommitteesError> {
) -> Result<Option<(Slot, u64, u64)>, 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<Vec<usize>> {
pub fn get_shuffling(&self, seed: Hash256, slot: Slot, spec: &ChainSpec) -> Vec<Vec<usize>> {
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<usize, CommitteesError> {
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<usize> =
@ -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<u64, InclusionError> {
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<u64, InclusionError> {
) -> Result<Slot, InclusionError> {
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
}

View File

@ -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
}

View File

@ -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<BeaconState>;
}
impl BeaconStateReader for BeaconState {
fn slot(&self) -> u64 {
fn slot(&self) -> Slot {
self.slot
}

View File

@ -10,13 +10,13 @@
/// 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.
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<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 {
($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<Slot> {
(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<Slot> {
if self.current == self.epoch.end_slot(self.epoch_length) {
None
} else {
let previous = self.current;
self.current += 1;
Some(previous)
}
}
}

View File

@ -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<Validator> {
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);
}

View File

@ -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,

View File

@ -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<usize> {
pub fn get_active_validator_indices(validators: &[Validator], slot: Slot) -> Vec<usize> {
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
})