From da1498fc45867673ed382a94013db4e409da5675 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 5 Feb 2019 12:48:07 +1100 Subject: [PATCH] Remove validator_shuffling crate. It has been replaced by the `beacon_state.get_shuffling` function. --- Cargo.toml | 1 - eth2/genesis/Cargo.toml | 1 - eth2/validator_shuffling/Cargo.toml | 10 - eth2/validator_shuffling/src/lib.rs | 3 - eth2/validator_shuffling/src/shuffle.rs | 278 ------------------------ 5 files changed, 293 deletions(-) delete mode 100644 eth2/validator_shuffling/Cargo.toml delete mode 100644 eth2/validator_shuffling/src/lib.rs delete mode 100644 eth2/validator_shuffling/src/shuffle.rs diff --git a/Cargo.toml b/Cargo.toml index 59dfce953..b2efe55ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,6 @@ members = [ "eth2/utils/ssz", "eth2/utils/vec_shuffle", "eth2/validator_induction", - "eth2/validator_shuffling", "beacon_node", "beacon_node/db", "beacon_node/beacon_chain", diff --git a/eth2/genesis/Cargo.toml b/eth2/genesis/Cargo.toml index d56b3f929..09e5d1e88 100644 --- a/eth2/genesis/Cargo.toml +++ b/eth2/genesis/Cargo.toml @@ -9,4 +9,3 @@ bls = { path = "../utils/bls" } ssz = { path = "../utils/ssz" } types = { path = "../types" } validator_induction = { path = "../validator_induction" } -validator_shuffling = { path = "../validator_shuffling" } diff --git a/eth2/validator_shuffling/Cargo.toml b/eth2/validator_shuffling/Cargo.toml deleted file mode 100644 index ae2babf1a..000000000 --- a/eth2/validator_shuffling/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "validator_shuffling" -version = "0.1.0" -authors = ["Paul Hauner "] -edition = "2018" - -[dependencies] -honey-badger-split = { path = "../utils/honey-badger-split" } -types = { path = "../types" } -vec_shuffle = { path = "../utils/vec_shuffle" } diff --git a/eth2/validator_shuffling/src/lib.rs b/eth2/validator_shuffling/src/lib.rs deleted file mode 100644 index 2307dd301..000000000 --- a/eth2/validator_shuffling/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod shuffle; - -pub use crate::shuffle::{shard_and_committees_for_cycle, ValidatorAssignmentError}; diff --git a/eth2/validator_shuffling/src/shuffle.rs b/eth2/validator_shuffling/src/shuffle.rs deleted file mode 100644 index 48d16fddc..000000000 --- a/eth2/validator_shuffling/src/shuffle.rs +++ /dev/null @@ -1,278 +0,0 @@ -use std::cmp::min; - -use honey_badger_split::SplitExt; -use types::validator_registry::get_active_validator_indices; -use types::{ChainSpec, ShardCommittee, Validator}; -use vec_shuffle::{shuffle, ShuffleErr}; - -type DelegatedCycle = Vec>; - -#[derive(Debug, PartialEq)] -pub enum ValidatorAssignmentError { - TooManyValidators, - TooFewShards, -} - -/// Delegates active validators into slots for a given cycle, given a random seed. -/// Returns a vector or ShardAndComitte vectors representing the shards and committiees for -/// each slot. -/// References get_new_shuffling (ethereum 2.1 specification) -pub fn shard_and_committees_for_cycle( - seed: &[u8], - validators: &[Validator], - crosslinking_shard_start: u16, - spec: &ChainSpec, -) -> Result { - let shuffled_validator_indices = { - let validator_indices = get_active_validator_indices(validators, 0); - shuffle(seed, validator_indices)? - }; - let shard_indices: Vec = (0_usize..spec.shard_count as usize).into_iter().collect(); - let crosslinking_shard_start = crosslinking_shard_start as usize; - let epoch_length = spec.epoch_length as usize; - let min_committee_size = spec.target_committee_size as usize; - generate_cycle( - &shuffled_validator_indices, - &shard_indices, - crosslinking_shard_start, - epoch_length, - min_committee_size, - ) -} - -/// Given the validator list, delegates the validators into slots and comittees for a given cycle. -fn generate_cycle( - validator_indices: &[usize], - shard_indices: &[usize], - crosslinking_shard_start: usize, - epoch_length: usize, - min_committee_size: usize, -) -> Result { - let validator_count = validator_indices.len(); - let shard_count = shard_indices.len(); - - if shard_count / epoch_length == 0 { - return Err(ValidatorAssignmentError::TooFewShards); - } - - let (committees_per_slot, slots_per_committee) = { - if validator_count >= epoch_length * min_committee_size { - let committees_per_slot = min( - validator_count / epoch_length / (min_committee_size * 2) + 1, - shard_count / epoch_length, - ); - let slots_per_committee = 1; - (committees_per_slot, slots_per_committee) - } else { - let committees_per_slot = 1; - let mut slots_per_committee = 1; - while (validator_count * slots_per_committee < epoch_length * min_committee_size) - & (slots_per_committee < epoch_length) - { - slots_per_committee *= 2; - } - (committees_per_slot, slots_per_committee) - } - }; - - let cycle = validator_indices - .honey_badger_split(epoch_length) - .enumerate() - .map(|(i, slot_indices)| { - let shard_start = - crosslinking_shard_start + i * committees_per_slot / slots_per_committee; - slot_indices - .honey_badger_split(committees_per_slot) - .enumerate() - .map(|(j, shard_indices)| ShardCommittee { - shard: ((shard_start + j) % shard_count) as u64, - committee: shard_indices.to_vec(), - }) - .collect() - }) - .collect(); - Ok(cycle) -} - -impl From for ValidatorAssignmentError { - fn from(e: ShuffleErr) -> ValidatorAssignmentError { - match e { - ShuffleErr::ExceedsListLength => ValidatorAssignmentError::TooManyValidators, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - fn generate_cycle_helper( - validator_count: &usize, - shard_count: &usize, - crosslinking_shard_start: usize, - epoch_length: usize, - min_committee_size: usize, - ) -> ( - Vec, - Vec, - Result, - ) { - let validator_indices: Vec = (0_usize..*validator_count).into_iter().collect(); - let shard_indices: Vec = (0_usize..*shard_count).into_iter().collect(); - let result = generate_cycle( - &validator_indices, - &shard_indices, - crosslinking_shard_start, - epoch_length, - min_committee_size, - ); - (validator_indices, shard_indices, result) - } - - #[allow(dead_code)] - fn print_cycle(cycle: &DelegatedCycle) { - cycle.iter().enumerate().for_each(|(i, slot)| { - println!("slot {:?}", &i); - slot.iter().enumerate().for_each(|(i, sac)| { - println!( - "#{:?}\tshard={}\tcommittee.len()={}", - &i, - &sac.shard, - &sac.committee.len() - ) - }) - }); - } - - fn flatten_validators(cycle: &DelegatedCycle) -> Vec { - let mut flattened = vec![]; - for slot in cycle.iter() { - for sac in slot.iter() { - for validator in sac.committee.iter() { - flattened.push(*validator); - } - } - } - flattened - } - - fn flatten_and_dedup_shards(cycle: &DelegatedCycle) -> Vec { - let mut flattened = vec![]; - for slot in cycle.iter() { - for sac in slot.iter() { - flattened.push(sac.shard as usize); - } - } - flattened.dedup(); - flattened - } - - fn flatten_shards_in_slots(cycle: &DelegatedCycle) -> Vec> { - let mut shards_in_slots: Vec> = vec![]; - for slot in cycle.iter() { - let mut shards: Vec = vec![]; - for sac in slot.iter() { - shards.push(sac.shard as usize); - } - shards_in_slots.push(shards); - } - shards_in_slots - } - - // TODO: Improve these tests to check committee lengths - #[test] - fn test_generate_cycle() { - let validator_count: usize = 100; - let shard_count: usize = 20; - let crosslinking_shard_start: usize = 0; - let epoch_length: usize = 20; - let min_committee_size: usize = 10; - let (validators, shards, result) = generate_cycle_helper( - &validator_count, - &shard_count, - crosslinking_shard_start, - epoch_length, - min_committee_size, - ); - let cycle = result.unwrap(); - - let assigned_validators = flatten_validators(&cycle); - let assigned_shards = flatten_and_dedup_shards(&cycle); - let shards_in_slots = flatten_shards_in_slots(&cycle); - let expected_shards = shards.get(0..10).unwrap(); - assert_eq!( - assigned_validators, validators, - "Validator assignment incorrect" - ); - assert_eq!( - assigned_shards, expected_shards, - "Shard assignment incorrect" - ); - - let expected_shards_in_slots: Vec> = vec![ - vec![0], - vec![0], // Each line is 2 slots.. - vec![1], - vec![1], - vec![2], - vec![2], - vec![3], - vec![3], - vec![4], - vec![4], - vec![5], - vec![5], - vec![6], - vec![6], - vec![7], - vec![7], - vec![8], - vec![8], - vec![9], - vec![9], - ]; - // assert!(compare_shards_in_slots(&cycle, &expected_shards_in_slots)); - assert_eq!( - expected_shards_in_slots, shards_in_slots, - "Shard assignment incorrect." - ) - } - - #[test] - // Check that the committees per slot is upper bounded by shard count - fn test_generate_cycle_committees_bounded() { - let validator_count: usize = 523; - let shard_count: usize = 31; - let crosslinking_shard_start: usize = 0; - let epoch_length: usize = 11; - let min_committee_size: usize = 5; - let (validators, shards, result) = generate_cycle_helper( - &validator_count, - &shard_count, - crosslinking_shard_start, - epoch_length, - min_committee_size, - ); - let cycle = result.unwrap(); - let assigned_validators = flatten_validators(&cycle); - let assigned_shards = flatten_and_dedup_shards(&cycle); - let shards_in_slots = flatten_shards_in_slots(&cycle); - let expected_shards = shards.get(0..22).unwrap(); - let expected_shards_in_slots: Vec> = (0_usize..11_usize) - .map(|x| vec![2 * x, 2 * x + 1]) - .collect(); - assert_eq!( - assigned_validators, validators, - "Validator assignment incorrect" - ); - assert_eq!( - assigned_shards, expected_shards, - "Shard assignment incorrect" - ); - // assert!(compare_shards_in_slots(&cycle, &expected_shards_in_slots)); - assert_eq!( - expected_shards_in_slots, shards_in_slots, - "Shard assignment incorrect." - ) - } -}