From 9e51a04139d72a0668bdd626acac3f13f6a8e521 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Wed, 12 Jun 2019 16:55:01 +1000 Subject: [PATCH] Delete unused fished_yates_shuffle crate --- Cargo.toml | 1 - eth2/utils/fisher_yates_shuffle/Cargo.toml | 16 --- .../fisher_yates_shuffle/benches/benches.rs | 55 -------- eth2/utils/fisher_yates_shuffle/src/lib.rs | 81 ----------- eth2/utils/fisher_yates_shuffle/src/rng.rs | 90 ------------ .../src/specs/shuffle_test_vectors.yaml | 131 ------------------ 6 files changed, 374 deletions(-) delete mode 100644 eth2/utils/fisher_yates_shuffle/Cargo.toml delete mode 100644 eth2/utils/fisher_yates_shuffle/benches/benches.rs delete mode 100644 eth2/utils/fisher_yates_shuffle/src/lib.rs delete mode 100644 eth2/utils/fisher_yates_shuffle/src/rng.rs delete mode 100644 eth2/utils/fisher_yates_shuffle/src/specs/shuffle_test_vectors.yaml diff --git a/Cargo.toml b/Cargo.toml index e9acb2be47..3b89c51243 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,6 @@ members = [ "eth2/utils/swap_or_not_shuffle", "eth2/utils/tree_hash", "eth2/utils/tree_hash_derive", - "eth2/utils/fisher_yates_shuffle", "eth2/utils/test_random_derive", "beacon_node", "beacon_node/store", diff --git a/eth2/utils/fisher_yates_shuffle/Cargo.toml b/eth2/utils/fisher_yates_shuffle/Cargo.toml deleted file mode 100644 index ff1f646082..0000000000 --- a/eth2/utils/fisher_yates_shuffle/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "fisher_yates_shuffle" -version = "0.1.0" -authors = ["Paul Hauner "] -edition = "2018" - -[[bench]] -name = "benches" -harness = false - -[dev-dependencies] -criterion = "0.2" -yaml-rust = "0.4.2" - -[dependencies] -hashing = { path = "../hashing" } diff --git a/eth2/utils/fisher_yates_shuffle/benches/benches.rs b/eth2/utils/fisher_yates_shuffle/benches/benches.rs deleted file mode 100644 index 9aa1885abd..0000000000 --- a/eth2/utils/fisher_yates_shuffle/benches/benches.rs +++ /dev/null @@ -1,55 +0,0 @@ -use criterion::Criterion; -use criterion::{black_box, criterion_group, criterion_main, Benchmark}; -use fisher_yates_shuffle::shuffle; - -fn get_list(n: usize) -> Vec { - let mut list = Vec::with_capacity(n); - for i in 0..n { - list.push(i) - } - assert_eq!(list.len(), n); - list -} - -fn shuffles(c: &mut Criterion) { - c.bench( - "whole list shuffle", - Benchmark::new("8 elements", move |b| { - let seed = vec![42; 32]; - let list = get_list(8); - b.iter_with_setup(|| list.clone(), |list| black_box(shuffle(&seed, list))) - }), - ); - - c.bench( - "whole list shuffle", - Benchmark::new("16 elements", move |b| { - let seed = vec![42; 32]; - let list = get_list(16); - b.iter_with_setup(|| list.clone(), |list| black_box(shuffle(&seed, list))) - }), - ); - - c.bench( - "whole list shuffle", - Benchmark::new("512 elements", move |b| { - let seed = vec![42; 32]; - let list = get_list(512); - b.iter_with_setup(|| list.clone(), |list| black_box(shuffle(&seed, list))) - }) - .sample_size(10), - ); - - c.bench( - "whole list shuffle", - Benchmark::new("16384 elements", move |b| { - let seed = vec![42; 32]; - let list = get_list(16_384); - b.iter_with_setup(|| list.clone(), |list| black_box(shuffle(&seed, list))) - }) - .sample_size(10), - ); -} - -criterion_group!(benches, shuffles); -criterion_main!(benches); diff --git a/eth2/utils/fisher_yates_shuffle/src/lib.rs b/eth2/utils/fisher_yates_shuffle/src/lib.rs deleted file mode 100644 index 78bb8aa105..0000000000 --- a/eth2/utils/fisher_yates_shuffle/src/lib.rs +++ /dev/null @@ -1,81 +0,0 @@ -/// A library for performing deterministic, pseudo-random shuffling on a vector. -/// -/// This library is designed to confirm to the Ethereum 2.0 specification. -extern crate hashing; - -mod rng; - -use self::rng::ShuffleRng; - -#[derive(Debug)] -pub enum ShuffleErr { - ExceedsListLength, -} - -/// Performs a deterministic, in-place shuffle of a vector. -/// -/// The final order of the shuffle is determined by successive hashes -/// of the supplied `seed`. -/// -/// This is a Fisher-Yates-Durtstenfeld shuffle. -pub fn shuffle(seed: &[u8], mut list: Vec) -> Result, ShuffleErr> { - let mut rng = ShuffleRng::new(seed); - - if list.len() > rng.rand_max as usize { - return Err(ShuffleErr::ExceedsListLength); - } - - if list.is_empty() { - return Ok(list); - } - - for i in 0..(list.len() - 1) { - let n = list.len() - i; - let j = rng.rand_range(n as u32) as usize + i; - list.swap(i, j); - } - Ok(list) -} - -#[cfg(test)] -mod tests { - extern crate yaml_rust; - - use self::yaml_rust::yaml; - - use std::{fs::File, io::prelude::*, path::PathBuf}; - - use super::{hashing::hash, *}; - - #[test] - fn test_shuffling() { - let mut file = { - let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - file_path_buf.push("src/specs/shuffle_test_vectors.yaml"); - - File::open(file_path_buf).unwrap() - }; - - let mut yaml_str = String::new(); - - file.read_to_string(&mut yaml_str).unwrap(); - - let docs = yaml::YamlLoader::load_from_str(&yaml_str).unwrap(); - let doc = &docs[0]; - let test_cases = doc["test_cases"].as_vec().unwrap(); - - for test_case in test_cases { - let input = test_case["input"].clone().into_vec().unwrap(); - let output = test_case["output"].clone().into_vec().unwrap(); - let seed_bytes = test_case["seed"].as_str().unwrap().as_bytes(); - - let seed = if seed_bytes.len() > 0 { - hash(seed_bytes) - } else { - vec![] - }; - - assert_eq!(shuffle(&seed, input).unwrap(), output); - } - } -} diff --git a/eth2/utils/fisher_yates_shuffle/src/rng.rs b/eth2/utils/fisher_yates_shuffle/src/rng.rs deleted file mode 100644 index 7a4a785ff4..0000000000 --- a/eth2/utils/fisher_yates_shuffle/src/rng.rs +++ /dev/null @@ -1,90 +0,0 @@ -use super::hashing::hash; - -const SEED_SIZE_BYTES: usize = 32; -const RAND_BYTES: usize = 3; // 24 / 8 -const RAND_MAX: u32 = 16_777_215; // 2 ** (rand_bytes * 8) - 1 - -/// A pseudo-random number generator which given a seed -/// uses successive blake2s hashing to generate "entropy". -pub struct ShuffleRng { - seed: Vec, - idx: usize, - pub rand_max: u32, -} - -impl ShuffleRng { - /// Create a new instance given some "seed" bytes. - pub fn new(initial_seed: &[u8]) -> Self { - Self { - seed: hash(initial_seed), - idx: 0, - rand_max: RAND_MAX, - } - } - - /// "Regenerates" the seed by hashing it. - fn rehash_seed(&mut self) { - self.seed = hash(&self.seed); - self.idx = 0; - } - - /// Extracts 3 bytes from the `seed`. Rehashes seed if required. - fn rand(&mut self) -> u32 { - self.idx += RAND_BYTES; - if self.idx >= SEED_SIZE_BYTES { - self.rehash_seed(); - self.rand() - } else { - int_from_byte_slice(&self.seed, self.idx - RAND_BYTES) - } - } - - /// Generate a random u32 below the specified maximum `n`. - /// - /// Provides a filtered result from a higher-level rng, by discarding - /// results which may bias the output. Because of this, execution time is - /// not linear and may potentially be infinite. - pub fn rand_range(&mut self, n: u32) -> u32 { - assert!(n < RAND_MAX, "RAND_MAX exceed"); - let mut x = self.rand(); - while x >= self.rand_max - (self.rand_max % n) { - x = self.rand(); - } - x % n - } -} - -/// Reads the next three bytes of `source`, starting from `offset` and -/// interprets those bytes as a 24 bit big-endian integer. -/// Returns that integer. -fn int_from_byte_slice(source: &[u8], offset: usize) -> u32 { - (u32::from(source[offset + 2])) - | (u32::from(source[offset + 1]) << 8) - | (u32::from(source[offset]) << 16) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_shuffling_int_from_slice() { - let mut x = int_from_byte_slice(&[0, 0, 1], 0); - assert_eq!((x as u32), 1); - - x = int_from_byte_slice(&[0, 1, 1], 0); - assert_eq!(x, 257); - - x = int_from_byte_slice(&[1, 1, 1], 0); - assert_eq!(x, 65793); - - x = int_from_byte_slice(&[255, 1, 1], 0); - assert_eq!(x, 16711937); - - x = int_from_byte_slice(&[255, 255, 255], 0); - assert_eq!(x, 16777215); - - x = int_from_byte_slice(&[0x8f, 0xbb, 0xc7], 0); - assert_eq!(x, 9419719); - } -} diff --git a/eth2/utils/fisher_yates_shuffle/src/specs/shuffle_test_vectors.yaml b/eth2/utils/fisher_yates_shuffle/src/specs/shuffle_test_vectors.yaml deleted file mode 100644 index 2571f08042..0000000000 --- a/eth2/utils/fisher_yates_shuffle/src/specs/shuffle_test_vectors.yaml +++ /dev/null @@ -1,131 +0,0 @@ -title: Shuffling Algorithm Tests -summary: Test vectors for shuffling a list based upon a seed. -test_suite: Shuffling - -test_cases: -- input: [] - output: [] - seed: '' -- input: [0] - output: [0] - seed: '' -- input: [255] - output: [255] - seed: '' -- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [2, 1, 1, 5, 6, 6, 6, 2, 4, 4] - seed: '' -- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] - output: [4, 9, 6, 8, 13, 3, 2, 11, 5, 1, 12, 7, 10] - seed: '' -- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [2, 1, 1, 5, 6, 6, 6, 2, 4, 65] - seed: '' -- input: [] - output: [] - seed: 4kn4driuctg8 -- input: [0] - output: [0] - seed: 4kn4driuctg8 -- input: [255] - output: [255] - seed: 4kn4driuctg8 -- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [2, 4, 4, 2, 1, 1, 6, 5, 6, 6] - seed: 4kn4driuctg8 -- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] - output: [7, 6, 3, 12, 11, 1, 8, 13, 10, 5, 9, 4, 2] - seed: 4kn4driuctg8 -- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [2, 4, 65, 2, 1, 1, 6, 5, 6, 6] - seed: 4kn4driuctg8 -- input: [] - output: [] - seed: ytre1p -- input: [0] - output: [0] - seed: ytre1p -- input: [255] - output: [255] - seed: ytre1p -- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [6, 1, 1, 5, 6, 2, 6, 2, 4, 4] - seed: ytre1p -- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] - output: [6, 2, 3, 4, 8, 5, 12, 9, 7, 11, 10, 1, 13] - seed: ytre1p -- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [6, 1, 1, 5, 6, 2, 6, 2, 4, 65] - seed: ytre1p -- input: [] - output: [] - seed: mytobcffnkvj -- input: [0] - output: [0] - seed: mytobcffnkvj -- input: [255] - output: [255] - seed: mytobcffnkvj -- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [2, 4, 1, 1, 6, 4, 6, 5, 6, 2] - seed: mytobcffnkvj -- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] - output: [11, 5, 9, 7, 2, 4, 12, 10, 8, 1, 6, 3, 13] - seed: mytobcffnkvj -- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [2, 65, 1, 1, 6, 4, 6, 5, 6, 2] - seed: mytobcffnkvj -- input: [] - output: [] - seed: myzu3g7evxp5nkvj -- input: [0] - output: [0] - seed: myzu3g7evxp5nkvj -- input: [255] - output: [255] - seed: myzu3g7evxp5nkvj -- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [6, 2, 1, 4, 2, 6, 5, 6, 4, 1] - seed: myzu3g7evxp5nkvj -- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] - output: [2, 1, 11, 3, 9, 7, 8, 13, 4, 10, 5, 6, 12] - seed: myzu3g7evxp5nkvj -- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [6, 2, 1, 4, 2, 6, 5, 6, 65, 1] - seed: myzu3g7evxp5nkvj -- input: [] - output: [] - seed: xdpli1jsx5xb -- input: [0] - output: [0] - seed: xdpli1jsx5xb -- input: [255] - output: [255] - seed: xdpli1jsx5xb -- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [2, 1, 2, 4, 6, 6, 5, 6, 1, 4] - seed: xdpli1jsx5xb -- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] - output: [5, 8, 12, 9, 11, 4, 7, 13, 1, 3, 2, 10, 6] - seed: xdpli1jsx5xb -- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [2, 1, 2, 65, 6, 6, 5, 6, 1, 4] - seed: xdpli1jsx5xb -- input: [] - output: [] - seed: oab3mbb3xe8qsx5xb -- input: [0] - output: [0] - seed: oab3mbb3xe8qsx5xb -- input: [255] - output: [255] - seed: oab3mbb3xe8qsx5xb -- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [6, 2, 1, 1, 6, 2, 4, 4, 6, 5] - seed: oab3mbb3xe8qsx5xb -- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] - output: [1, 8, 5, 13, 2, 10, 7, 11, 12, 6, 3, 4, 9] - seed: oab3mbb3xe8qsx5xb -- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5] - output: [6, 2, 1, 1, 6, 2, 4, 65, 6, 5] - seed: oab3mbb3xe8qsx5xb