diff --git a/eth2/types/Cargo.toml b/eth2/types/Cargo.toml index a553e42404..3da5a1d26d 100644 --- a/eth2/types/Cargo.toml +++ b/eth2/types/Cargo.toml @@ -9,9 +9,11 @@ bls = { path = "../utils/bls" } boolean-bitfield = { path = "../utils/boolean-bitfield" } ethereum-types = "0.4.0" hashing = { path = "../utils/hashing" } +honey-badger-split = { path = "../utils/honey-badger-split" } integer-sqrt = "0.1" rand = "0.5.5" serde = "1.0" serde_derive = "1.0" serde_json = "1.0" ssz = { path = "../utils/ssz" } +vec_shuffle = { path = "../utils/vec_shuffle" } diff --git a/eth2/types/src/beacon_state/epoch_processing.rs b/eth2/types/src/beacon_state/epoch_processing.rs index ac6ccbb04d..948da15d7e 100644 --- a/eth2/types/src/beacon_state/epoch_processing.rs +++ b/eth2/types/src/beacon_state/epoch_processing.rs @@ -717,22 +717,6 @@ impl BeaconState { self.get_committee_count_per_slot(current_active_validators.len(), spec) } - fn get_committee_count_per_slot( - &self, - active_validator_count: usize, - spec: &ChainSpec, - ) -> usize { - std::cmp::max( - 1, - std::cmp::min( - spec.shard_count as usize / spec.epoch_length as usize, - active_validator_count - / spec.epoch_length as usize - / spec.target_committee_size as usize, - ), - ) - } - fn process_ejections(&self) { //TODO: stubbed out. } @@ -784,10 +768,6 @@ impl BeaconState { self.get_effective_balance(validator_index, spec) / base_reward_quotient / 5 } - pub fn get_crosslink_committees_at_slot(&self, _slot: u64) -> Option { - Some(vec![(vec![0], 0)]) - } - pub fn get_effective_balance(&self, validator_index: usize, spec: &ChainSpec) -> u64 { std::cmp::min(self.validator_balances[validator_index], spec.max_deposit) } @@ -810,6 +790,3 @@ impl BeaconState { vec![0, 1] } } - -type CrosslinkCommittee = (Vec, usize); -type CrosslinkCommittees = Vec; diff --git a/eth2/types/src/beacon_state/mod.rs b/eth2/types/src/beacon_state/mod.rs index b287c0c7f1..0032f275f4 100644 --- a/eth2/types/src/beacon_state/mod.rs +++ b/eth2/types/src/beacon_state/mod.rs @@ -12,6 +12,7 @@ use ssz::{hash, Decodable, DecodeError, Encodable, SszStream, TreeHash}; mod attestation_validation; mod epoch_processing; +mod shuffling; mod slot_processing; mod winning_root; diff --git a/eth2/types/src/beacon_state/shuffling.rs b/eth2/types/src/beacon_state/shuffling.rs new file mode 100644 index 0000000000..eb93947f3e --- /dev/null +++ b/eth2/types/src/beacon_state/shuffling.rs @@ -0,0 +1,47 @@ +use crate::{validator_registry::get_active_validator_indices, BeaconState, ChainSpec, Hash256}; +use honey_badger_split::SplitExt; +use vec_shuffle::shuffle; + +type CrosslinkCommittee = (Vec, usize); +type CrosslinkCommittees = Vec; + +impl BeaconState { + pub fn get_shuffling(&self, seed: Hash256, slot: u64, spec: &ChainSpec) -> Vec> { + let slot = slot - (slot % spec.epoch_length); + + let active_validator_indices = get_active_validator_indices(&self.validator_registry, slot); + + let committees_per_slot = + 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 shuffled_active_validator_indices = + shuffle(&seed, active_validator_indices).expect("Max validator count exceed!"); + + shuffled_active_validator_indices + .honey_badger_split(committees_per_slot * spec.epoch_length as usize) + .filter_map(|slice: &[usize]| Some(slice.to_vec())) + .collect() + } + + pub fn get_committee_count_per_slot( + &self, + active_validator_count: usize, + spec: &ChainSpec, + ) -> usize { + std::cmp::max( + 1, + std::cmp::min( + spec.shard_count as usize / spec.epoch_length as usize, + active_validator_count + / spec.epoch_length as usize + / spec.target_committee_size as usize, + ), + ) + } + + pub fn get_crosslink_committees_at_slot(&self, _slot: u64) -> Option { + Some(vec![(vec![0], 0)]) + } +}