mirror of
https://gitlab.com/pulsechaincom/lighthouse-pulse.git
synced 2024-12-24 12:37:17 +00:00
Fix epoch cache, add tests
This commit is contained in:
parent
86c3dad3e7
commit
089febb944
@ -362,6 +362,21 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
unimplemented!("FIXME(sproul)")
|
||||
}
|
||||
|
||||
/// Returns the crosslink committees for some shard in some cached epoch.
|
||||
///
|
||||
/// Note: Utilizes the cache and will fail if the appropriate cache is not initialized.
|
||||
///
|
||||
/// Spec v0.6.1
|
||||
pub fn get_crosslink_committee_for_shard(
|
||||
&self,
|
||||
shard: u64,
|
||||
epoch: Epoch,
|
||||
) -> Result<Option<&CrosslinkCommittee>, Error> {
|
||||
let cache = self.cache(epoch)?;
|
||||
|
||||
Ok(cache.get_crosslink_committee_for_shard(shard))
|
||||
}
|
||||
|
||||
/// Return the crosslink committeee for `shard` in `epoch`.
|
||||
///
|
||||
/// Note: Utilizes the cache and will fail if the appropriate cache is not initialized.
|
||||
@ -457,7 +472,7 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
let current_epoch = self.current_epoch();
|
||||
let len = T::LatestRandaoMixesLength::to_u64();
|
||||
|
||||
if (current_epoch - len < epoch) & (epoch <= current_epoch) {
|
||||
if (epoch + len > current_epoch) & (epoch <= current_epoch) {
|
||||
Ok(epoch.as_usize() % len as usize)
|
||||
} else {
|
||||
Err(Error::EpochOutOfBounds)
|
||||
@ -504,10 +519,10 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
fn get_active_index_root_index(&self, epoch: Epoch, spec: &ChainSpec) -> Result<usize, Error> {
|
||||
let current_epoch = self.current_epoch();
|
||||
|
||||
if current_epoch - self.latest_active_index_roots.len() as u64 + spec.activation_exit_delay
|
||||
< epoch
|
||||
&& epoch <= current_epoch + spec.activation_exit_delay
|
||||
{
|
||||
let lookahead = spec.activation_exit_delay;
|
||||
let lookback = self.latest_active_index_roots.len() as u64 - lookahead;
|
||||
|
||||
if (epoch + lookback > current_epoch) && (current_epoch + lookahead >= epoch) {
|
||||
Ok(epoch.as_usize() % self.latest_active_index_roots.len())
|
||||
} else {
|
||||
Err(Error::EpochOutOfBounds)
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::BeaconState;
|
||||
use crate::*;
|
||||
use honey_badger_split::SplitExt;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use swap_or_not_shuffle::shuffle_list;
|
||||
|
||||
@ -35,7 +36,7 @@ impl EpochCache {
|
||||
epoch: Epoch,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<EpochCache, BeaconStateError> {
|
||||
if epoch != state.previous_epoch() && epoch != state.current_epoch() {
|
||||
if (epoch < state.previous_epoch()) || (epoch > state.next_epoch()) {
|
||||
return Err(BeaconStateError::EpochOutOfBounds);
|
||||
}
|
||||
|
||||
@ -44,7 +45,7 @@ impl EpochCache {
|
||||
|
||||
let epoch_committee_count = state.get_epoch_committee_count(epoch, spec);
|
||||
|
||||
let crosslink_committees = compute_epoch_commitees(
|
||||
let crosslink_committees = compute_epoch_committees(
|
||||
epoch,
|
||||
state,
|
||||
active_validator_indices.clone(),
|
||||
@ -58,7 +59,11 @@ impl EpochCache {
|
||||
|
||||
for (i, crosslink_committee) in crosslink_committees.iter().enumerate() {
|
||||
shard_crosslink_committees[crosslink_committee.shard as usize] = Some(i);
|
||||
slot_crosslink_committees[crosslink_committee.slot.as_usize()] = Some(i);
|
||||
|
||||
let slot_index = epoch
|
||||
.position(crosslink_committee.slot, spec.slots_per_epoch)
|
||||
.ok_or_else(|| BeaconStateError::SlotOutOfBounds)?;
|
||||
slot_crosslink_committees[slot_index] = Some(i);
|
||||
|
||||
// Loop through each validator in the committee and store its attestation duties.
|
||||
for (committee_index, validator_index) in
|
||||
@ -74,6 +79,8 @@ impl EpochCache {
|
||||
}
|
||||
}
|
||||
|
||||
dbg!(&shard_crosslink_committees);
|
||||
|
||||
Ok(EpochCache {
|
||||
initialized_epoch: Some(epoch),
|
||||
crosslink_committees,
|
||||
@ -118,7 +125,7 @@ pub fn get_active_validator_indices(validators: &[Validator], epoch: Epoch) -> V
|
||||
active
|
||||
}
|
||||
|
||||
pub fn compute_epoch_commitees<T: EthSpec>(
|
||||
pub fn compute_epoch_committees<T: EthSpec>(
|
||||
epoch: Epoch,
|
||||
state: &BeaconState<T>,
|
||||
active_validator_indices: Vec<usize>,
|
||||
@ -141,15 +148,17 @@ pub fn compute_epoch_commitees<T: EthSpec>(
|
||||
.ok_or_else(|| Error::UnableToShuffle)?
|
||||
};
|
||||
|
||||
let committee_size = shuffled_active_validator_indices.len() / epoch_committee_count as usize;
|
||||
|
||||
let epoch_start_shard = state.get_epoch_start_shard(epoch, spec)?;
|
||||
|
||||
Ok(shuffled_active_validator_indices
|
||||
.chunks(committee_size)
|
||||
.honey_badger_split(epoch_committee_count as usize)
|
||||
.enumerate()
|
||||
.map(|(index, committee)| {
|
||||
let shard = (epoch_start_shard + index as u64) % spec.shard_count;
|
||||
|
||||
dbg!(index);
|
||||
dbg!(shard);
|
||||
|
||||
let slot = crosslink_committee_slot(
|
||||
shard,
|
||||
epoch,
|
||||
|
@ -5,16 +5,15 @@ use crate::beacon_state::FewValidatorsEthSpec;
|
||||
use crate::test_utils::*;
|
||||
use swap_or_not_shuffle::shuffle_list;
|
||||
|
||||
fn do_sane_cache_test<T: EthSpec>(
|
||||
fn execute_sane_cache_test<T: EthSpec>(
|
||||
state: BeaconState<T>,
|
||||
epoch: Epoch,
|
||||
relative_epoch: RelativeEpoch,
|
||||
validator_count: usize,
|
||||
spec: &ChainSpec,
|
||||
) {
|
||||
let active_indices: Vec<usize> = (0..validator_count).collect();
|
||||
let seed = state.generate_seed(epoch, spec).unwrap();
|
||||
let expected_shuffling_start = state.get_epoch_start_shard(epoch, spec).unwrap();
|
||||
let start_shard = state.get_epoch_start_shard(epoch, spec).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
&active_indices[..],
|
||||
@ -25,48 +24,43 @@ fn do_sane_cache_test<T: EthSpec>(
|
||||
let shuffling =
|
||||
shuffle_list(active_indices, spec.shuffle_round_count, &seed[..], false).unwrap();
|
||||
|
||||
let committees_per_epoch = spec.get_epoch_committee_count(shuffling.len());
|
||||
let committees_per_slot = committees_per_epoch / spec.slots_per_epoch;
|
||||
|
||||
let mut expected_indices_iter = shuffling.iter();
|
||||
let mut shard_counter = expected_shuffling_start;
|
||||
|
||||
for (i, slot) in epoch.slot_iter(spec.slots_per_epoch).enumerate() {
|
||||
let crosslink_committees_at_slot =
|
||||
state.get_crosslink_committees_at_slot(slot, &spec).unwrap();
|
||||
for i in 0..T::shard_count() {
|
||||
let shard = (i + start_shard as usize) % T::shard_count();
|
||||
|
||||
assert_eq!(
|
||||
crosslink_committees_at_slot.len(),
|
||||
committees_per_slot as usize,
|
||||
"Bad committees per slot ({})",
|
||||
i
|
||||
);
|
||||
dbg!(shard);
|
||||
dbg!(start_shard);
|
||||
|
||||
for c in crosslink_committees_at_slot {
|
||||
assert_eq!(c.shard, shard_counter, "Bad shard");
|
||||
shard_counter += 1;
|
||||
shard_counter %= spec.shard_count;
|
||||
let c = state
|
||||
.get_crosslink_committee_for_shard(shard as u64, epoch)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
for &i in &c.committee {
|
||||
assert_eq!(
|
||||
i,
|
||||
*expected_indices_iter.next().unwrap(),
|
||||
"Non-sequential validators."
|
||||
);
|
||||
}
|
||||
for &i in &c.committee {
|
||||
assert_eq!(
|
||||
i,
|
||||
*expected_indices_iter.next().unwrap(),
|
||||
"Non-sequential validators."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_sane_cache_test<T: EthSpec>(validator_count: usize, spec: &ChainSpec) -> BeaconState<T> {
|
||||
let mut builder =
|
||||
TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(validator_count, spec);
|
||||
fn sane_cache_test<T: EthSpec>(
|
||||
validator_count: usize,
|
||||
state_epoch: Epoch,
|
||||
cache_epoch: RelativeEpoch,
|
||||
) {
|
||||
let spec = &T::spec();
|
||||
|
||||
let epoch = spec.genesis_epoch + 4;
|
||||
let slot = epoch.start_slot(spec.slots_per_epoch);
|
||||
let mut builder =
|
||||
TestingBeaconStateBuilder::from_single_keypair(validator_count, &Keypair::random(), spec);
|
||||
|
||||
let slot = state_epoch.start_slot(spec.slots_per_epoch);
|
||||
builder.teleport_to_slot(slot, spec);
|
||||
|
||||
let (mut state, _keypairs) = builder.build();
|
||||
let (mut state, _keypairs): (BeaconState<T>, _) = builder.build();
|
||||
|
||||
state
|
||||
.build_epoch_cache(RelativeEpoch::Previous, spec)
|
||||
@ -76,88 +70,42 @@ fn setup_sane_cache_test<T: EthSpec>(validator_count: usize, spec: &ChainSpec) -
|
||||
.unwrap();
|
||||
state.build_epoch_cache(RelativeEpoch::Next, spec).unwrap();
|
||||
|
||||
state
|
||||
let cache_epoch = cache_epoch.into_epoch(state_epoch);
|
||||
|
||||
execute_sane_cache_test(state, cache_epoch, validator_count as usize, &spec);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builds_sane_current_epoch_cache() {
|
||||
let mut spec = FewValidatorsEthSpec::spec();
|
||||
fn sane_cache_test_suite<T: EthSpec>(cached_epoch: RelativeEpoch) {
|
||||
let spec = T::spec();
|
||||
|
||||
let validator_count = (spec.shard_count * spec.target_committee_size) + 1;
|
||||
|
||||
let state: BeaconState<FewValidatorsEthSpec> =
|
||||
setup_sane_cache_test(validator_count as usize, &spec);
|
||||
sane_cache_test::<T>(validator_count as usize, Epoch::new(0), cached_epoch);
|
||||
|
||||
let epoch = state.current_epoch();
|
||||
|
||||
do_sane_cache_test(
|
||||
state,
|
||||
epoch,
|
||||
RelativeEpoch::Current,
|
||||
sane_cache_test::<T>(
|
||||
validator_count as usize,
|
||||
&spec,
|
||||
spec.genesis_epoch + 4,
|
||||
cached_epoch,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
#[test]
|
||||
fn builds_sane_current_epoch_cache() {
|
||||
let mut spec = FewValidatorsEthSpec::spec();
|
||||
spec.shard_count = 4;
|
||||
let validator_count = (spec.shard_count * spec.target_committee_size) + 1;
|
||||
|
||||
let state: BeaconState<FewValidatorsEthSpec> =
|
||||
setup_sane_cache_test(validator_count as usize, &spec);
|
||||
|
||||
do_sane_cache_test(
|
||||
state.clone(),
|
||||
state.current_epoch(&spec),
|
||||
RelativeEpoch::Current,
|
||||
sane_cache_test::<T>(
|
||||
validator_count as usize,
|
||||
state.current_shuffling_seed,
|
||||
state.current_shuffling_start_shard,
|
||||
&spec,
|
||||
spec.genesis_epoch + T::slots_per_historical_root() as u64 * T::slots_per_epoch() * 4,
|
||||
cached_epoch,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builds_sane_previous_epoch_cache() {
|
||||
let mut spec = FewValidatorsEthSpec::spec();
|
||||
spec.shard_count = 2;
|
||||
let validator_count = (spec.shard_count * spec.target_committee_size) + 1;
|
||||
|
||||
let state: BeaconState<FewValidatorsEthSpec> =
|
||||
setup_sane_cache_test(validator_count as usize, &spec);
|
||||
|
||||
do_sane_cache_test(
|
||||
state.clone(),
|
||||
state.previous_epoch(&spec),
|
||||
RelativeEpoch::Previous,
|
||||
validator_count as usize,
|
||||
state.previous_shuffling_seed,
|
||||
state.previous_shuffling_start_shard,
|
||||
&spec,
|
||||
);
|
||||
fn current_epoch_suite() {
|
||||
sane_cache_test_suite::<FewValidatorsEthSpec>(RelativeEpoch::Current);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builds_sane_next_without_update_epoch_cache() {
|
||||
let mut spec = FewValidatorsEthSpec::spec();
|
||||
spec.shard_count = 2;
|
||||
let validator_count = (spec.shard_count * spec.target_committee_size) + 1;
|
||||
|
||||
let mut state: BeaconState<FewValidatorsEthSpec> =
|
||||
setup_sane_cache_test(validator_count as usize, &spec);
|
||||
|
||||
state.validator_registry_update_epoch = state.slot.epoch(spec.slots_per_epoch);
|
||||
do_sane_cache_test(
|
||||
state.clone(),
|
||||
state.next_epoch(&spec),
|
||||
RelativeEpoch::NextWithoutRegistryChange,
|
||||
validator_count as usize,
|
||||
state.current_shuffling_seed,
|
||||
state.current_shuffling_start_shard,
|
||||
&spec,
|
||||
);
|
||||
fn previous_epoch_suite() {
|
||||
sane_cache_test_suite::<FewValidatorsEthSpec>(RelativeEpoch::Previous);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn next_epoch_suite() {
|
||||
sane_cache_test_suite::<FewValidatorsEthSpec>(RelativeEpoch::Next);
|
||||
}
|
||||
*/
|
||||
|
@ -2,10 +2,77 @@
|
||||
use super::*;
|
||||
use crate::beacon_state::FewValidatorsEthSpec;
|
||||
use crate::test_utils::*;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
ssz_tests!(FoundationBeaconState);
|
||||
cached_tree_hash_tests!(FoundationBeaconState);
|
||||
|
||||
/// Should produce (note the set notation brackets):
|
||||
///
|
||||
/// (current_epoch - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_EXIT_DELAY, current_epoch +
|
||||
/// ACTIVATION_EXIT_DELAY]
|
||||
fn active_index_range<T: EthSpec>(current_epoch: Epoch) -> RangeInclusive<Epoch> {
|
||||
let delay = T::spec().activation_exit_delay;
|
||||
|
||||
let start: i32 =
|
||||
current_epoch.as_u64() as i32 - T::latest_active_index_roots() as i32 + delay as i32;
|
||||
let end = current_epoch + delay;
|
||||
|
||||
let start: Epoch = if start < 0 {
|
||||
Epoch::new(0)
|
||||
} else {
|
||||
Epoch::from(start as u64 + 1)
|
||||
};
|
||||
|
||||
start..=end
|
||||
}
|
||||
|
||||
/// Test getting an active index root at the start and end of the valid range, and one either side
|
||||
/// of that range.
|
||||
fn test_active_index<T: EthSpec>(state_slot: Slot) {
|
||||
let spec = T::spec();
|
||||
let builder: TestingBeaconStateBuilder<T> =
|
||||
TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec);
|
||||
let (mut state, _keypairs) = builder.build();
|
||||
state.slot = state_slot;
|
||||
|
||||
let range = active_index_range::<T>(state.current_epoch());
|
||||
|
||||
let modulo = |epoch: Epoch| epoch.as_usize() % T::latest_active_index_roots();
|
||||
|
||||
// Test the start and end of the range.
|
||||
assert_eq!(
|
||||
state.get_active_index_root_index(*range.start(), &spec),
|
||||
Ok(modulo(*range.start()))
|
||||
);
|
||||
assert_eq!(
|
||||
state.get_active_index_root_index(*range.end(), &spec),
|
||||
Ok(modulo(*range.end()))
|
||||
);
|
||||
|
||||
// One either side of the range.
|
||||
if state.current_epoch() > 0 {
|
||||
// Test is invalid on epoch zero, cannot subtract from zero.
|
||||
assert_eq!(
|
||||
state.get_active_index_root_index(*range.start() - 1, &spec),
|
||||
Err(Error::EpochOutOfBounds)
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
state.get_active_index_root_index(*range.end() + 1, &spec),
|
||||
Err(Error::EpochOutOfBounds)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_active_index_root_index() {
|
||||
test_active_index::<FoundationEthSpec>(Slot::new(0));
|
||||
|
||||
let epoch = Epoch::from(FoundationEthSpec::latest_active_index_roots() * 4);
|
||||
let slot = epoch.start_slot(FoundationEthSpec::slots_per_epoch());
|
||||
test_active_index::<FoundationEthSpec>(slot);
|
||||
}
|
||||
|
||||
/*
|
||||
/// Test that
|
||||
///
|
||||
|
@ -258,7 +258,7 @@ impl ChainSpec {
|
||||
|
||||
/// Returns a `ChainSpec` compatible with the specification suitable for 8 validators.
|
||||
pub(crate) fn few_validators() -> Self {
|
||||
let genesis_slot = Slot::new(2_u64.pow(32));
|
||||
let genesis_slot = Slot::new(0);
|
||||
let slots_per_epoch = 8;
|
||||
let genesis_epoch = genesis_slot.epoch(slots_per_epoch);
|
||||
|
||||
|
@ -26,8 +26,9 @@ impl RelativeEpoch {
|
||||
/// Spec v0.6.1
|
||||
pub fn into_epoch(self, base: Epoch) -> Epoch {
|
||||
match self {
|
||||
RelativeEpoch::Previous => base - 1,
|
||||
// Due to saturating nature of epoch, check for current first.
|
||||
RelativeEpoch::Current => base,
|
||||
RelativeEpoch::Previous => base - 1,
|
||||
RelativeEpoch::Next => base + 1,
|
||||
}
|
||||
}
|
||||
@ -41,10 +42,11 @@ impl RelativeEpoch {
|
||||
///
|
||||
/// Spec v0.6.1
|
||||
pub fn from_epoch(base: Epoch, other: Epoch) -> Result<Self, Error> {
|
||||
if other == base - 1 {
|
||||
Ok(RelativeEpoch::Previous)
|
||||
} else if other == base {
|
||||
// Due to saturating nature of epoch, check for current first.
|
||||
if other == base {
|
||||
Ok(RelativeEpoch::Current)
|
||||
} else if other == base - 1 {
|
||||
Ok(RelativeEpoch::Previous)
|
||||
} else if other == base + 1 {
|
||||
Ok(RelativeEpoch::Next)
|
||||
} else if other < base {
|
||||
|
@ -58,10 +58,12 @@ impl Epoch {
|
||||
Epoch(u64::max_value())
|
||||
}
|
||||
|
||||
/// The first slot in the epoch.
|
||||
pub fn start_slot(self, slots_per_epoch: u64) -> Slot {
|
||||
Slot::from(self.0.saturating_mul(slots_per_epoch))
|
||||
}
|
||||
|
||||
/// The last slot in the epoch.
|
||||
pub fn end_slot(self, slots_per_epoch: u64) -> Slot {
|
||||
Slot::from(
|
||||
self.0
|
||||
@ -71,6 +73,20 @@ impl Epoch {
|
||||
)
|
||||
}
|
||||
|
||||
/// Position of some slot inside an epoch, if any.
|
||||
///
|
||||
/// E.g., the first `slot` in `epoch` is at position `0`.
|
||||
pub fn position(&self, slot: Slot, slots_per_epoch: u64) -> Option<usize> {
|
||||
let start = self.start_slot(slots_per_epoch);
|
||||
let end = self.end_slot(slots_per_epoch);
|
||||
|
||||
if (slot >= start) && (slot <= end) {
|
||||
Some(slot.as_usize() - start.as_usize())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn slot_iter(&self, slots_per_epoch: u64) -> SlotIter {
|
||||
SlotIter {
|
||||
current_iteration: 0,
|
||||
@ -124,6 +140,26 @@ mod epoch_tests {
|
||||
assert_eq!(epoch.end_slot(slots_per_epoch), Slot::new(7));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn position() {
|
||||
let slots_per_epoch = 8;
|
||||
|
||||
let epoch = Epoch::new(0);
|
||||
assert_eq!(epoch.position(Slot::new(0), slots_per_epoch), Some(0));
|
||||
assert_eq!(epoch.position(Slot::new(1), slots_per_epoch), Some(1));
|
||||
assert_eq!(epoch.position(Slot::new(2), slots_per_epoch), Some(2));
|
||||
assert_eq!(epoch.position(Slot::new(3), slots_per_epoch), Some(3));
|
||||
assert_eq!(epoch.position(Slot::new(4), slots_per_epoch), Some(4));
|
||||
assert_eq!(epoch.position(Slot::new(5), slots_per_epoch), Some(5));
|
||||
assert_eq!(epoch.position(Slot::new(6), slots_per_epoch), Some(6));
|
||||
assert_eq!(epoch.position(Slot::new(7), slots_per_epoch), Some(7));
|
||||
assert_eq!(epoch.position(Slot::new(8), slots_per_epoch), None);
|
||||
|
||||
let epoch = Epoch::new(1);
|
||||
assert_eq!(epoch.position(Slot::new(7), slots_per_epoch), None);
|
||||
assert_eq!(epoch.position(Slot::new(8), slots_per_epoch), Some(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slot_iter() {
|
||||
let slots_per_epoch = 8;
|
||||
|
@ -52,6 +52,38 @@ impl<T> SplitExt<T> for [T] {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn alternative_split_at_index<T>(indices: &[T], index: usize, count: usize) -> &[T] {
|
||||
let start = (indices.len() * index) / count;
|
||||
let end = (indices.len() * (index + 1)) / count;
|
||||
|
||||
&indices[start..end]
|
||||
}
|
||||
|
||||
fn alternative_split<T: Clone>(input: &[T], n: usize) -> Vec<&[T]> {
|
||||
(0..n)
|
||||
.into_iter()
|
||||
.map(|i| alternative_split_at_index(&input, i, n))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn honey_badger_vs_alternative_fn(num_items: usize, num_chunks: usize) {
|
||||
let input: Vec<usize> = (0..num_items).collect();
|
||||
|
||||
let hb: Vec<&[usize]> = input.honey_badger_split(num_chunks).collect();
|
||||
let spec: Vec<&[usize]> = alternative_split(&input, num_chunks);
|
||||
|
||||
assert_eq!(hb, spec);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vs_eth_spec_fn() {
|
||||
for i in 0..10 {
|
||||
for j in 0..10 {
|
||||
honey_badger_vs_alternative_fn(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_honey_badger_split() {
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user