mirror of
https://gitlab.com/pulsechaincom/lighthouse-pulse.git
synced 2024-12-25 04:57:17 +00:00
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:
parent
dd370b2e33
commit
a488c4dccd
@ -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| {
|
||||
|
@ -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)
|
||||
);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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`
|
||||
|
@ -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()))?;
|
||||
|
Loading…
Reference in New Issue
Block a user