Rename get_permutated_index to compute_shuffled_index. (#564)

To match name of equivalent function in v0.8.3 spec.
This commit is contained in:
gnattishness 2019-10-29 01:07:12 +00:00 committed by Paul Hauner
parent dd370b2e33
commit a488c4dccd
5 changed files with 24 additions and 23 deletions

View File

@ -1,13 +1,13 @@
use criterion::Criterion; use criterion::Criterion;
use criterion::{black_box, criterion_group, criterion_main, Benchmark}; use criterion::{black_box, criterion_group, criterion_main, Benchmark};
use swap_or_not_shuffle::{get_permutated_index, shuffle_list as fast_shuffle}; use swap_or_not_shuffle::{compute_shuffled_index, shuffle_list as fast_shuffle};
const SHUFFLE_ROUND_COUNT: u8 = 90; const SHUFFLE_ROUND_COUNT: u8 = 90;
fn shuffle_list(seed: &[u8], list_size: usize) -> Vec<usize> { fn shuffle_list(seed: &[u8], list_size: usize) -> Vec<usize> {
let mut output = Vec::with_capacity(list_size); let mut output = Vec::with_capacity(list_size);
for i in 0..list_size { for i in 0..list_size {
output.push(get_permutated_index(i, list_size, seed, SHUFFLE_ROUND_COUNT).unwrap()); output.push(compute_shuffled_index(i, list_size, seed, SHUFFLE_ROUND_COUNT).unwrap());
} }
output output
} }
@ -15,7 +15,7 @@ fn shuffle_list(seed: &[u8], list_size: usize) -> Vec<usize> {
fn shuffles(c: &mut Criterion) { fn shuffles(c: &mut Criterion) {
c.bench_function("single swap", move |b| { c.bench_function("single swap", move |b| {
let seed = vec![42; 32]; let seed = vec![42; 32];
b.iter(|| black_box(get_permutated_index(0, 10, &seed, SHUFFLE_ROUND_COUNT))) b.iter(|| black_box(compute_shuffled_index(0, 10, &seed, SHUFFLE_ROUND_COUNT)))
}); });
c.bench_function("whole list of size 8", move |b| { c.bench_function("whole list of size 8", move |b| {

View File

@ -9,7 +9,7 @@ use std::cmp::max;
/// See the 'generalized domain' algorithm on page 3. /// See the 'generalized domain' algorithm on page 3.
/// ///
/// Note: this function is significantly slower than the `shuffle_list` function in this crate. /// Note: this function is significantly slower than the `shuffle_list` function in this crate.
/// Using `get_permutated_list` to shuffle an entire list, index by index, has been observed to be /// Using `compute_shuffled_index` to shuffle an entire list, index by index, has been observed to be
/// 250x slower than `shuffle_list`. Therefore, this function is only useful when shuffling a small /// 250x slower than `shuffle_list`. Therefore, this function is only useful when shuffling a small
/// portion of a much larger list. /// portion of a much larger list.
/// ///
@ -18,7 +18,7 @@ use std::cmp::max;
/// - `index >= list_size` /// - `index >= list_size`
/// - `list_size > 2**24` /// - `list_size > 2**24`
/// - `list_size > usize::max_value() / 2` /// - `list_size > usize::max_value() / 2`
pub fn get_permutated_index( pub fn compute_shuffled_index(
index: usize, index: usize,
list_size: usize, list_size: usize,
seed: &[u8], seed: &[u8],
@ -54,7 +54,7 @@ fn hash_with_round_and_position(seed: &[u8], round: u8, position: usize) -> Opti
seed.append(&mut int_to_bytes1(round)); seed.append(&mut int_to_bytes1(round));
/* /*
* Note: the specification has an implicit assertion in `int_to_bytes4` that `position / 256 < * Note: the specification has an implicit assertion in `int_to_bytes4` that `position / 256 <
* 2**24`. For efficiency, we do not check for that here as it is checked in `get_permutated_index`. * 2**24`. For efficiency, we do not check for that here as it is checked in `compute_shuffled_index`.
*/ */
seed.append(&mut int_to_bytes4((position / 256) as u32)); seed.append(&mut int_to_bytes4((position / 256) as u32));
Some(hash(&seed[..])) Some(hash(&seed[..]))
@ -90,7 +90,7 @@ mod tests {
let seed = Hash256::random(); let seed = Hash256::random();
let shuffle_rounds = 90; let shuffle_rounds = 90;
assert!(get_permutated_index(index, list_size, &seed[..], shuffle_rounds).is_some()); assert!(compute_shuffled_index(index, list_size, &seed[..], shuffle_rounds).is_some());
} }
// Test at max list_size low indices. // Test at max list_size low indices.
@ -100,7 +100,7 @@ mod tests {
let seed = Hash256::random(); let seed = Hash256::random();
let shuffle_rounds = 90; let shuffle_rounds = 90;
assert!(get_permutated_index(index, list_size, &seed[..], shuffle_rounds).is_some()); assert!(compute_shuffled_index(index, list_size, &seed[..], shuffle_rounds).is_some());
} }
// Test at max list_size high indices. // Test at max list_size high indices.
@ -110,25 +110,25 @@ mod tests {
let seed = Hash256::random(); let seed = Hash256::random();
let shuffle_rounds = 90; let shuffle_rounds = 90;
assert!(get_permutated_index(index, list_size, &seed[..], shuffle_rounds).is_some()); assert!(compute_shuffled_index(index, list_size, &seed[..], shuffle_rounds).is_some());
} }
} }
#[test] #[test]
fn returns_none_for_zero_length_list() { fn returns_none_for_zero_length_list() {
assert_eq!(None, get_permutated_index(100, 0, &[42, 42], 90)); assert_eq!(None, compute_shuffled_index(100, 0, &[42, 42], 90));
} }
#[test] #[test]
fn returns_none_for_out_of_bounds_index() { fn returns_none_for_out_of_bounds_index() {
assert_eq!(None, get_permutated_index(100, 100, &[42, 42], 90)); assert_eq!(None, compute_shuffled_index(100, 100, &[42, 42], 90));
} }
#[test] #[test]
fn returns_none_for_too_large_list() { fn returns_none_for_too_large_list() {
assert_eq!( assert_eq!(
None, None,
get_permutated_index(100, usize::max_value() / 2, &[42, 42], 90) compute_shuffled_index(100, usize::max_value() / 2, &[42, 42], 90)
); );
} }
} }

View File

@ -1,21 +1,21 @@
//! Provides list-shuffling functions matching the Ethereum 2.0 specification. //! Provides list-shuffling functions matching the Ethereum 2.0 specification.
//! //!
//! See //! See
//! [get_permutated_index](https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_permuted_index) //! [compute_shuffled_index](https://github.com/ethereum/eth2.0-specs/blob/v0.8.3/specs/core/0_beacon-chain.md#compute_shuffled_index)
//! for specifications. //! for specifications.
//! //!
//! There are two functions exported by this crate: //! There are two functions exported by this crate:
//! //!
//! - `get_permutated_index`: given a single index, computes the index resulting from a shuffle. //! - `compute_shuffled_index`: given a single index, computes the index resulting from a shuffle.
//! Runs in less time than it takes to run `shuffle_list`. //! Runs in less time than it takes to run `shuffle_list`.
//! - `shuffle_list`: shuffles an entire list in-place. Runs in less time than it takes to run //! - `shuffle_list`: shuffles an entire list in-place. Runs in less time than it takes to run
//! `get_permutated_index` on each index. //! `compute_shuffled_index` on each index.
//! //!
//! In general, use `get_permutated_list` to calculate the shuffling of a small subset of a much //! In general, use `compute_shuffled_index` to calculate the shuffling of a small subset of a much
//! larger list (~250x larger is a good guide, but solid figures yet to be calculated). //! larger list (~250x larger is a good guide, but solid figures yet to be calculated).
mod get_permutated_index; mod compute_shuffled_index;
mod shuffle_list; mod shuffle_list;
pub use get_permutated_index::get_permutated_index; pub use compute_shuffled_index::compute_shuffled_index;
pub use shuffle_list::shuffle_list; pub use shuffle_list::shuffle_list;

View File

@ -9,9 +9,9 @@ const TOTAL_SIZE: usize = SEED_SIZE + ROUND_SIZE + POSITION_WINDOW_SIZE;
/// Shuffles an entire list in-place. /// Shuffles an entire list in-place.
/// ///
/// Note: this is equivalent to the `get_permutated_index` function, except it shuffles an entire /// Note: this is equivalent to the `compute_shuffled_index` function, except it shuffles an entire
/// list not just a single index. With large lists this function has been observed to be 250x /// list not just a single index. With large lists this function has been observed to be 250x
/// faster than running `get_permutated_index` across an entire list. /// faster than running `compute_shuffled_index` across an entire list.
/// ///
/// Credits to [@protolambda](https://github.com/protolambda) for defining this algorithm. /// Credits to [@protolambda](https://github.com/protolambda) for defining this algorithm.
/// ///
@ -19,6 +19,7 @@ const TOTAL_SIZE: usize = SEED_SIZE + ROUND_SIZE + POSITION_WINDOW_SIZE;
/// It holds that: shuffle_list(shuffle_list(l, r, s, true), r, s, false) == l /// It holds that: shuffle_list(shuffle_list(l, r, s, true), r, s, false) == l
/// and: shuffle_list(shuffle_list(l, r, s, false), r, s, true) == l /// and: shuffle_list(shuffle_list(l, r, s, false), r, s, true) == l
/// ///
/// TODO forwards is around the wrong way - denote?
/// Returns `None` under any of the following conditions: /// Returns `None` under any of the following conditions:
/// - `list_size == 0` /// - `list_size == 0`
/// - `list_size > 2**24` /// - `list_size > 2**24`

View File

@ -3,7 +3,7 @@ use crate::case_result::compare_result;
use crate::decode::yaml_decode_file; use crate::decode::yaml_decode_file;
use serde_derive::Deserialize; use serde_derive::Deserialize;
use std::marker::PhantomData; use std::marker::PhantomData;
use swap_or_not_shuffle::{get_permutated_index, shuffle_list}; use swap_or_not_shuffle::{compute_shuffled_index, shuffle_list};
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize)]
pub struct Shuffling<T> { pub struct Shuffling<T> {
@ -29,10 +29,10 @@ impl<T: EthSpec> Case for Shuffling<T> {
let seed = hex::decode(&self.seed[2..]) let seed = hex::decode(&self.seed[2..])
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?; .map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
// Test get_permuted_index // Test compute_shuffled_index
let shuffling = (0..self.count) let shuffling = (0..self.count)
.map(|i| { .map(|i| {
get_permutated_index(i, self.count, &seed, spec.shuffle_round_count).unwrap() compute_shuffled_index(i, self.count, &seed, spec.shuffle_round_count).unwrap()
}) })
.collect(); .collect();
compare_result::<_, Error>(&Ok(shuffling), &Some(self.mapping.clone()))?; compare_result::<_, Error>(&Ok(shuffling), &Some(self.mapping.clone()))?;