mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 01:05:47 +00:00
@@ -1,11 +1,8 @@
|
||||
extern crate active_validators;
|
||||
extern crate honey_badger_split;
|
||||
extern crate vec_shuffle;
|
||||
extern crate types;
|
||||
extern crate vec_shuffle;
|
||||
|
||||
mod shuffle;
|
||||
|
||||
pub use shuffle::{
|
||||
shard_and_committees_for_cycle,
|
||||
ValidatorAssignmentError,
|
||||
};
|
||||
pub use shuffle::{shard_and_committees_for_cycle, ValidatorAssignmentError};
|
||||
|
||||
@@ -2,16 +2,8 @@ use std::cmp::min;
|
||||
|
||||
use active_validators::active_validator_indices;
|
||||
use honey_badger_split::SplitExt;
|
||||
use vec_shuffle::{
|
||||
shuffle,
|
||||
ShuffleErr,
|
||||
};
|
||||
use types::{
|
||||
ShardAndCommittee,
|
||||
ValidatorRecord,
|
||||
ChainConfig,
|
||||
};
|
||||
|
||||
use types::{ChainConfig, ShardAndCommittee, ValidatorRecord};
|
||||
use vec_shuffle::{shuffle, ShuffleErr};
|
||||
|
||||
type DelegatedCycle = Vec<Vec<ShardAndCommittee>>;
|
||||
|
||||
@@ -29,9 +21,8 @@ pub fn shard_and_committees_for_cycle(
|
||||
seed: &[u8],
|
||||
validators: &[ValidatorRecord],
|
||||
crosslinking_shard_start: u16,
|
||||
config: &ChainConfig)
|
||||
-> Result<DelegatedCycle, ValidatorAssignmentError>
|
||||
{
|
||||
config: &ChainConfig,
|
||||
) -> Result<DelegatedCycle, ValidatorAssignmentError> {
|
||||
let shuffled_validator_indices = {
|
||||
let mut validator_indices = active_validator_indices(validators);
|
||||
shuffle(seed, validator_indices)?
|
||||
@@ -45,7 +36,8 @@ pub fn shard_and_committees_for_cycle(
|
||||
&shard_indices,
|
||||
crosslinking_shard_start,
|
||||
cycle_length,
|
||||
min_committee_size)
|
||||
min_committee_size,
|
||||
)
|
||||
}
|
||||
|
||||
/// Given the validator list, delegates the validators into slots and comittees for a given cycle.
|
||||
@@ -54,50 +46,49 @@ fn generate_cycle(
|
||||
shard_indices: &[usize],
|
||||
crosslinking_shard_start: usize,
|
||||
cycle_length: usize,
|
||||
min_committee_size: usize)
|
||||
-> Result<DelegatedCycle, ValidatorAssignmentError>
|
||||
{
|
||||
|
||||
min_committee_size: usize,
|
||||
) -> Result<DelegatedCycle, ValidatorAssignmentError> {
|
||||
let validator_count = validator_indices.len();
|
||||
let shard_count = shard_indices.len();
|
||||
|
||||
if shard_count / cycle_length == 0 {
|
||||
return Err(ValidatorAssignmentError::TooFewShards)
|
||||
return Err(ValidatorAssignmentError::TooFewShards);
|
||||
}
|
||||
|
||||
let (committees_per_slot, slots_per_committee) = {
|
||||
if validator_count >= cycle_length * min_committee_size {
|
||||
let committees_per_slot = min(validator_count / cycle_length /
|
||||
(min_committee_size * 2) + 1, shard_count /
|
||||
cycle_length);
|
||||
let committees_per_slot = min(
|
||||
validator_count / cycle_length / (min_committee_size * 2) + 1,
|
||||
shard_count / cycle_length,
|
||||
);
|
||||
let slots_per_committee = 1;
|
||||
(committees_per_slot, slots_per_committee)
|
||||
} else {
|
||||
let committees_per_slot = 1;
|
||||
let mut slots_per_committee = 1;
|
||||
while (validator_count * slots_per_committee < cycle_length * min_committee_size) &
|
||||
(slots_per_committee < cycle_length) {
|
||||
while (validator_count * slots_per_committee < cycle_length * min_committee_size)
|
||||
& (slots_per_committee < cycle_length)
|
||||
{
|
||||
slots_per_committee *= 2;
|
||||
}
|
||||
(committees_per_slot, slots_per_committee)
|
||||
}
|
||||
};
|
||||
|
||||
let cycle = validator_indices.honey_badger_split(cycle_length)
|
||||
let cycle = validator_indices
|
||||
.honey_badger_split(cycle_length)
|
||||
.enumerate()
|
||||
.map(|(i, slot_indices)| {
|
||||
let shard_start = crosslinking_shard_start + i * committees_per_slot / slots_per_committee;
|
||||
slot_indices.honey_badger_split(committees_per_slot)
|
||||
let shard_start =
|
||||
crosslinking_shard_start + i * committees_per_slot / slots_per_committee;
|
||||
slot_indices
|
||||
.honey_badger_split(committees_per_slot)
|
||||
.enumerate()
|
||||
.map(|(j, shard_indices)| {
|
||||
ShardAndCommittee{
|
||||
shard: ((shard_start + j) % shard_count) as u16,
|
||||
committee: shard_indices.to_vec(),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.collect();
|
||||
.map(|(j, shard_indices)| ShardAndCommittee {
|
||||
shard: ((shard_start + j) % shard_count) as u16,
|
||||
committee: shard_indices.to_vec(),
|
||||
}).collect()
|
||||
}).collect();
|
||||
Ok(cycle)
|
||||
}
|
||||
|
||||
@@ -118,9 +109,12 @@ mod tests {
|
||||
shard_count: &usize,
|
||||
crosslinking_shard_start: usize,
|
||||
cycle_length: usize,
|
||||
min_committee_size: usize)
|
||||
-> (Vec<usize>, Vec<usize>, Result<DelegatedCycle, ValidatorAssignmentError>)
|
||||
{
|
||||
min_committee_size: usize,
|
||||
) -> (
|
||||
Vec<usize>,
|
||||
Vec<usize>,
|
||||
Result<DelegatedCycle, ValidatorAssignmentError>,
|
||||
) {
|
||||
let validator_indices: Vec<usize> = (0_usize..*validator_count).into_iter().collect();
|
||||
let shard_indices: Vec<usize> = (0_usize..*shard_count).into_iter().collect();
|
||||
let result = generate_cycle(
|
||||
@@ -128,28 +122,27 @@ mod tests {
|
||||
&shard_indices,
|
||||
crosslinking_shard_start,
|
||||
cycle_length,
|
||||
min_committee_size);
|
||||
min_committee_size,
|
||||
);
|
||||
(validator_indices, shard_indices, result)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn print_cycle(cycle: &DelegatedCycle) {
|
||||
cycle.iter()
|
||||
.enumerate()
|
||||
.for_each(|(i, slot)| {
|
||||
println!("slot {:?}", &i);
|
||||
slot.iter()
|
||||
.enumerate()
|
||||
.for_each(|(i, sac)| {
|
||||
println!("#{:?}\tshard={}\tcommittee.len()={}",
|
||||
&i, &sac.shard, &sac.committee.len())
|
||||
})
|
||||
});
|
||||
cycle.iter().enumerate().for_each(|(i, slot)| {
|
||||
println!("slot {:?}", &i);
|
||||
slot.iter().enumerate().for_each(|(i, sac)| {
|
||||
println!(
|
||||
"#{:?}\tshard={}\tcommittee.len()={}",
|
||||
&i,
|
||||
&sac.shard,
|
||||
&sac.committee.len()
|
||||
)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn flatten_validators(cycle: &DelegatedCycle)
|
||||
-> Vec<usize>
|
||||
{
|
||||
fn flatten_validators(cycle: &DelegatedCycle) -> Vec<usize> {
|
||||
let mut flattened = vec![];
|
||||
for slot in cycle.iter() {
|
||||
for sac in slot.iter() {
|
||||
@@ -161,9 +154,7 @@ mod tests {
|
||||
flattened
|
||||
}
|
||||
|
||||
fn flatten_and_dedup_shards(cycle: &DelegatedCycle)
|
||||
-> Vec<usize>
|
||||
{
|
||||
fn flatten_and_dedup_shards(cycle: &DelegatedCycle) -> Vec<usize> {
|
||||
let mut flattened = vec![];
|
||||
for slot in cycle.iter() {
|
||||
for sac in slot.iter() {
|
||||
@@ -174,9 +165,7 @@ mod tests {
|
||||
flattened
|
||||
}
|
||||
|
||||
fn flatten_shards_in_slots(cycle: &DelegatedCycle)
|
||||
-> Vec<Vec<usize>>
|
||||
{
|
||||
fn flatten_shards_in_slots(cycle: &DelegatedCycle) -> Vec<Vec<usize>> {
|
||||
let mut shards_in_slots: Vec<Vec<usize>> = vec![];
|
||||
for slot in cycle.iter() {
|
||||
let mut shards: Vec<usize> = vec![];
|
||||
@@ -201,30 +190,50 @@ mod tests {
|
||||
&shard_count,
|
||||
crosslinking_shard_start,
|
||||
cycle_length,
|
||||
min_committee_size);
|
||||
min_committee_size,
|
||||
);
|
||||
let cycle = result.unwrap();
|
||||
|
||||
let assigned_validators = flatten_validators(&cycle);
|
||||
let assigned_shards = flatten_and_dedup_shards(&cycle);
|
||||
let shards_in_slots = flatten_shards_in_slots(&cycle);
|
||||
let expected_shards = shards.get(0..10).unwrap();
|
||||
assert_eq!(assigned_validators, validators, "Validator assignment incorrect");
|
||||
assert_eq!(assigned_shards, expected_shards, "Shard assignment incorrect");
|
||||
assert_eq!(
|
||||
assigned_validators, validators,
|
||||
"Validator assignment incorrect"
|
||||
);
|
||||
assert_eq!(
|
||||
assigned_shards, expected_shards,
|
||||
"Shard assignment incorrect"
|
||||
);
|
||||
|
||||
let expected_shards_in_slots: Vec<Vec<usize>> = vec![
|
||||
vec![0], vec![0], // Each line is 2 slots..
|
||||
vec![1], vec![1],
|
||||
vec![2], vec![2],
|
||||
vec![3], vec![3],
|
||||
vec![4], vec![4],
|
||||
vec![5], vec![5],
|
||||
vec![6], vec![6],
|
||||
vec![7], vec![7],
|
||||
vec![8], vec![8],
|
||||
vec![9], vec![9],
|
||||
vec![0],
|
||||
vec![0], // Each line is 2 slots..
|
||||
vec![1],
|
||||
vec![1],
|
||||
vec![2],
|
||||
vec![2],
|
||||
vec![3],
|
||||
vec![3],
|
||||
vec![4],
|
||||
vec![4],
|
||||
vec![5],
|
||||
vec![5],
|
||||
vec![6],
|
||||
vec![6],
|
||||
vec![7],
|
||||
vec![7],
|
||||
vec![8],
|
||||
vec![8],
|
||||
vec![9],
|
||||
vec![9],
|
||||
];
|
||||
// assert!(compare_shards_in_slots(&cycle, &expected_shards_in_slots));
|
||||
assert_eq!(expected_shards_in_slots, shards_in_slots, "Shard assignment incorrect.")
|
||||
assert_eq!(
|
||||
expected_shards_in_slots, shards_in_slots,
|
||||
"Shard assignment incorrect."
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -240,17 +249,28 @@ mod tests {
|
||||
&shard_count,
|
||||
crosslinking_shard_start,
|
||||
cycle_length,
|
||||
min_committee_size);
|
||||
min_committee_size,
|
||||
);
|
||||
let cycle = result.unwrap();
|
||||
let assigned_validators = flatten_validators(&cycle);
|
||||
let assigned_shards = flatten_and_dedup_shards(&cycle);
|
||||
let shards_in_slots = flatten_shards_in_slots(&cycle);
|
||||
let expected_shards = shards.get(0..22).unwrap();
|
||||
let expected_shards_in_slots: Vec<Vec<usize>> =
|
||||
(0_usize..11_usize) .map(|x| vec![2*x,2*x+1]).collect();
|
||||
assert_eq!(assigned_validators, validators, "Validator assignment incorrect");
|
||||
assert_eq!(assigned_shards, expected_shards, "Shard assignment incorrect");
|
||||
let expected_shards_in_slots: Vec<Vec<usize>> = (0_usize..11_usize)
|
||||
.map(|x| vec![2 * x, 2 * x + 1])
|
||||
.collect();
|
||||
assert_eq!(
|
||||
assigned_validators, validators,
|
||||
"Validator assignment incorrect"
|
||||
);
|
||||
assert_eq!(
|
||||
assigned_shards, expected_shards,
|
||||
"Shard assignment incorrect"
|
||||
);
|
||||
// assert!(compare_shards_in_slots(&cycle, &expected_shards_in_slots));
|
||||
assert_eq!(expected_shards_in_slots, shards_in_slots, "Shard assignment incorrect.")
|
||||
assert_eq!(
|
||||
expected_shards_in_slots, shards_in_slots,
|
||||
"Shard assignment incorrect."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user