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::{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;
fn shuffle_list(seed: &[u8], list_size: usize) -> Vec<usize> {
let mut output = Vec::with_capacity(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
}
@ -15,7 +15,7 @@ fn shuffle_list(seed: &[u8], list_size: usize) -> Vec<usize> {
fn shuffles(c: &mut Criterion) {
c.bench_function("single swap", move |b| {
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| {

View File

@ -9,7 +9,7 @@ use std::cmp::max;
/// See the 'generalized domain' algorithm on page 3.
///
/// 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
/// portion of a much larger list.
///
@ -18,7 +18,7 @@ use std::cmp::max;
/// - `index >= list_size`
/// - `list_size > 2**24`
/// - `list_size > usize::max_value() / 2`
pub fn get_permutated_index(
pub fn compute_shuffled_index(
index: usize,
list_size: usize,
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));
/*
* 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));
Some(hash(&seed[..]))
@ -90,7 +90,7 @@ mod tests {
let seed = Hash256::random();
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.
@ -100,7 +100,7 @@ mod tests {
let seed = Hash256::random();
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.
@ -110,25 +110,25 @@ mod tests {
let seed = Hash256::random();
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]
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]
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]
fn returns_none_for_too_large_list() {
assert_eq!(
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.
//!
//! 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.
//!
//! 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`.
//! - `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).
mod get_permutated_index;
mod compute_shuffled_index;
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;

View File

@ -9,9 +9,9 @@ const TOTAL_SIZE: usize = SEED_SIZE + ROUND_SIZE + POSITION_WINDOW_SIZE;
/// 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
/// 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.
///
@ -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
/// 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:
/// - `list_size == 0`
/// - `list_size > 2**24`

View File

@ -3,7 +3,7 @@ use crate::case_result::compare_result;
use crate::decode::yaml_decode_file;
use serde_derive::Deserialize;
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)]
pub struct Shuffling<T> {
@ -29,10 +29,10 @@ impl<T: EthSpec> Case for Shuffling<T> {
let seed = hex::decode(&self.seed[2..])
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
// Test get_permuted_index
// Test compute_shuffled_index
let shuffling = (0..self.count)
.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();
compare_result::<_, Error>(&Ok(shuffling), &Some(self.mapping.clone()))?;