Update shuffling function
This commit is contained in:
parent
911eda7a2a
commit
ff3795dbf0
@ -1,13 +1,13 @@
|
|||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub attester_count: u32,
|
pub attester_count: u64,
|
||||||
pub max_validators: u32
|
pub max_validators: u64
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn standard() -> Self {
|
pub fn standard() -> Self {
|
||||||
Self {
|
Self {
|
||||||
attester_count: 32,
|
attester_count: 32,
|
||||||
max_validators: 2u32.pow(24)
|
max_validators: 2u64.pow(24)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,52 +8,57 @@ use super::config::Config;
|
|||||||
const AGG_VOTE_MSG_SIZE: i32 = 2 + 32 + 32 + 8 + 8;
|
const AGG_VOTE_MSG_SIZE: i32 = 2 + 32 + 32 + 8 + 8;
|
||||||
|
|
||||||
// Interprets a 3-byte slice from a [u8] as an integer.
|
// Interprets a 3-byte slice from a [u8] as an integer.
|
||||||
fn get_shift_from_source(source: &[u8], offset: usize) -> u32 {
|
fn get_shift_from_source(source: &[u8], offset: usize) -> usize {
|
||||||
(source[offset + 2] as u32) |
|
(source[offset + 2] as usize) |
|
||||||
((source[offset + 1] as u32) << 8) |
|
((source[offset + 1] as usize) << 8) |
|
||||||
((source[offset ] as u32) << 16)
|
((source[offset ] as usize) << 16)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given entropy in the form of `seed`, return a shuffled list of validators
|
// Given entropy in the form of `seed`, return a shuffled list of validators
|
||||||
// of size `validator_count` or `sample`.
|
// indicies of size `validator_count` or `sample`.
|
||||||
pub fn get_shuffling(
|
pub fn get_shuffling(
|
||||||
seed: &Sha256Digest,
|
seed: &Sha256Digest,
|
||||||
validator_count: &u32,
|
validator_count: &usize,
|
||||||
sample: &Option<u32>,
|
sample_size: &Option<usize>,
|
||||||
config: &Config)
|
config: &Config)
|
||||||
-> Vec<u32>
|
-> Vec<usize>
|
||||||
{
|
{
|
||||||
let max_validators = config.max_validators;
|
assert!(*validator_count > 0);
|
||||||
assert!(*validator_count <= max_validators);
|
let mut output: Vec<usize> = (0..*validator_count).collect();
|
||||||
|
|
||||||
|
assert!(*validator_count <= (config.max_validators as usize));
|
||||||
|
|
||||||
// TODO: figure out why the Python implementation uses
|
// Use a reduced "sample_size" output range if specified
|
||||||
// this `rand_max` var.
|
let output_range: &usize = match sample_size {
|
||||||
// let rand_max = max_validators - (max_validators % validator_count);
|
Some(x) => {
|
||||||
let validator_range = match sample {
|
assert!(x <= validator_count,
|
||||||
Some(x) => x,
|
"sample_size should be <= validator_count");
|
||||||
|
x
|
||||||
|
},
|
||||||
None => validator_count
|
None => validator_count
|
||||||
};
|
};
|
||||||
let mut output: Vec<u32> = (0..*validator_range).collect();
|
|
||||||
|
// Do the first blake hash round
|
||||||
let mut source = Blake2s::new();
|
let mut source = Blake2s::new();
|
||||||
source.input(&seed);
|
source.input(&seed);
|
||||||
|
|
||||||
let mut v = 0;
|
let mut v = 0;
|
||||||
while v < *validator_range {
|
while v < *output_range {
|
||||||
let current_source = source.result();
|
let current_source = source.result();
|
||||||
let mut source_offset = 0;
|
let mut source_offset = 0;
|
||||||
while source_offset < 30 {
|
while source_offset < 30 {
|
||||||
let m = get_shift_from_source(¤t_source, source_offset);
|
let m = get_shift_from_source(¤t_source, source_offset);
|
||||||
let shuffled_position = (m % (validator_count - v)) + v;
|
let shuffled_position: usize = (m % (validator_count - v)) + v;
|
||||||
output.swap(v as usize, shuffled_position as usize);
|
output.swap(v as usize, shuffled_position as usize);
|
||||||
v += 1;
|
v += 1;
|
||||||
if v >= *validator_count { break; }
|
if v >= *validator_count { break; }
|
||||||
source_offset += 3;
|
source_offset += 3;
|
||||||
}
|
}
|
||||||
// Re-hash the source
|
// Re-hash the source (TODO: this does one extra hash, can be optimised)
|
||||||
source = Blake2s::new();
|
source = Blake2s::new();
|
||||||
source.input(¤t_source);
|
source.input(¤t_source);
|
||||||
}
|
}
|
||||||
output
|
output[0..*output_range].to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given an aggregate_vote and a crystallized_state,
|
// Given an aggregate_vote and a crystallized_state,
|
||||||
|
Loading…
Reference in New Issue
Block a user