Break split function into its own crate.
- Added tests - Remove it from the delegation dir - Added it as a crate in utils
This commit is contained in:
parent
ddc8037487
commit
9717698f7b
@ -37,6 +37,7 @@ members = [
|
|||||||
"beacon_chain/utils/bls",
|
"beacon_chain/utils/bls",
|
||||||
"beacon_chain/utils/boolean-bitfield",
|
"beacon_chain/utils/boolean-bitfield",
|
||||||
"beacon_chain/utils/hashing",
|
"beacon_chain/utils/hashing",
|
||||||
|
"beacon_chain/utils/honey-badger-split",
|
||||||
"beacon_chain/utils/shuffling",
|
"beacon_chain/utils/shuffling",
|
||||||
"beacon_chain/utils/ssz",
|
"beacon_chain/utils/ssz",
|
||||||
"beacon_chain/utils/ssz_helpers",
|
"beacon_chain/utils/ssz_helpers",
|
||||||
|
@ -4,5 +4,6 @@ version = "0.1.0"
|
|||||||
authors = ["Age Manning <Age@AgeManning.com>"]
|
authors = ["Age Manning <Age@AgeManning.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
honey-badger-split = { path = "../utils/honey-badger-split" }
|
||||||
types = { path = "../types" }
|
types = { path = "../types" }
|
||||||
shuffling = { path = "../utils/shuffling" }
|
shuffling = { path = "../utils/shuffling" }
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::honey_badger_split;
|
||||||
use super::types;
|
use super::types;
|
||||||
use super::TransitionError;
|
use super::TransitionError;
|
||||||
use super::shuffling::shuffle;
|
use super::shuffling::shuffle;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::honey_badger_split::SplitExt;
|
||||||
use super::types::{ShardAndCommittee, ValidatorRecord, ChainConfig};
|
use super::types::{ShardAndCommittee, ValidatorRecord, ChainConfig};
|
||||||
use super::TransitionError;
|
use super::TransitionError;
|
||||||
use super::shuffle;
|
use super::shuffle;
|
||||||
@ -5,52 +6,6 @@ use std::cmp::min;
|
|||||||
|
|
||||||
type DelegatedCycle = Vec<Vec<ShardAndCommittee>>;
|
type DelegatedCycle = Vec<Vec<ShardAndCommittee>>;
|
||||||
|
|
||||||
/// Iterator for the honey_badger_split function
|
|
||||||
struct Split<'a, T: 'a> {
|
|
||||||
n: usize,
|
|
||||||
current_pos: usize,
|
|
||||||
list: &'a [T],
|
|
||||||
list_length: usize
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a,T> Iterator for Split<'a, T> {
|
|
||||||
type Item = &'a [T];
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
self.current_pos +=1;
|
|
||||||
if self.current_pos <= self.n {
|
|
||||||
match self.list.get(self.list_length*(self.current_pos-1)/self.n..self.list_length*self.current_pos/self.n) {
|
|
||||||
Some(v) => Some(v),
|
|
||||||
None => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Splits a slice into chunks of size n. All postive n values are applicable,
|
|
||||||
/// hence the honey_badger prefix.
|
|
||||||
/// Returns an iterator over the original list.
|
|
||||||
trait SplitExt<T> {
|
|
||||||
fn honey_badger_split(&self, n: usize) -> Split<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> SplitExt<T> for [T] {
|
|
||||||
|
|
||||||
fn honey_badger_split(&self, n: usize) -> Split<T> {
|
|
||||||
Split {
|
|
||||||
n,
|
|
||||||
current_pos: 0,
|
|
||||||
list: &self,
|
|
||||||
list_length: self.len(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Produce a vector of validators indicies where those validators start and end
|
/// Produce a vector of validators indicies where those validators start and end
|
||||||
/// dynasties are within the supplied `dynasty`.
|
/// dynasties are within the supplied `dynasty`.
|
||||||
fn active_validator_indicies(
|
fn active_validator_indicies(
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
extern crate honey_badger_split;
|
||||||
extern crate types;
|
extern crate types;
|
||||||
extern crate shuffling;
|
extern crate shuffling;
|
||||||
|
|
||||||
|
6
beacon_chain/utils/honey-badger-split/Cargo.toml
Normal file
6
beacon_chain/utils/honey-badger-split/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "honey-badger-split"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Paul Hauner <paul@paulhauner.com>"]
|
||||||
|
|
||||||
|
[dependencies]
|
85
beacon_chain/utils/honey-badger-split/src/lib.rs
Normal file
85
beacon_chain/utils/honey-badger-split/src/lib.rs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/// A function for splitting a list into N pieces.
|
||||||
|
///
|
||||||
|
/// We have titled it the "honey badger split" because of its robustness. It don't care.
|
||||||
|
|
||||||
|
|
||||||
|
/// Iterator for the honey_badger_split function
|
||||||
|
pub struct Split<'a, T: 'a> {
|
||||||
|
n: usize,
|
||||||
|
current_pos: usize,
|
||||||
|
list: &'a [T],
|
||||||
|
list_length: usize
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a,T> Iterator for Split<'a, T> {
|
||||||
|
type Item = &'a [T];
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.current_pos +=1;
|
||||||
|
if self.current_pos <= self.n {
|
||||||
|
match self.list.get(self.list_length*(self.current_pos-1)/self.n..self.list_length*self.current_pos/self.n) {
|
||||||
|
Some(v) => Some(v),
|
||||||
|
None => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Splits a slice into chunks of size n. All postive n values are applicable,
|
||||||
|
/// hence the honey_badger prefix.
|
||||||
|
///
|
||||||
|
/// Returns an iterator over the original list.
|
||||||
|
pub trait SplitExt<T> {
|
||||||
|
fn honey_badger_split(&self, n: usize) -> Split<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> SplitExt<T> for [T] {
|
||||||
|
|
||||||
|
fn honey_badger_split(&self, n: usize) -> Split<T> {
|
||||||
|
Split {
|
||||||
|
n,
|
||||||
|
current_pos: 0,
|
||||||
|
list: &self,
|
||||||
|
list_length: self.len(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_honey_badger_split() {
|
||||||
|
/*
|
||||||
|
* These test cases are generated from the eth2.0 spec `split()`
|
||||||
|
* function at commit cbd254a.
|
||||||
|
*/
|
||||||
|
let input: Vec<usize> = vec![0, 1, 2, 3];
|
||||||
|
let output: Vec<&[usize]> = input.honey_badger_split(2).collect();
|
||||||
|
assert_eq!(output, vec![&[0, 1], &[2, 3]]);
|
||||||
|
|
||||||
|
let input: Vec<usize> = vec![0, 1, 2, 3];
|
||||||
|
let output: Vec<&[usize]> = input.honey_badger_split(6).collect();
|
||||||
|
let expected: Vec<&[usize]> = vec![&[], &[0], &[1], &[], &[2], &[3]];
|
||||||
|
assert_eq!(output, expected);
|
||||||
|
|
||||||
|
let input: Vec<usize> = vec![0, 1, 2, 3];
|
||||||
|
let output: Vec<&[usize]> = input.honey_badger_split(10).collect();
|
||||||
|
let expected: Vec<&[usize]> = vec![&[], &[], &[0], &[], &[1], &[], &[], &[2], &[], &[3]];
|
||||||
|
assert_eq!(output, expected);
|
||||||
|
|
||||||
|
let input: Vec<usize> = vec![0];
|
||||||
|
let output: Vec<&[usize]> = input.honey_badger_split(5).collect();
|
||||||
|
let expected: Vec<&[usize]> = vec![&[], &[], &[], &[], &[0]];
|
||||||
|
assert_eq!(output, expected);
|
||||||
|
|
||||||
|
let input: Vec<usize> = vec![0, 1, 2];
|
||||||
|
let output: Vec<&[usize]> = input.honey_badger_split(2).collect();
|
||||||
|
let expected: Vec<&[usize]> = vec![&[0], &[1, 2]];
|
||||||
|
assert_eq!(output, expected);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user