Skip to content

Instantly share code, notes, and snippets.

@aeyakovenko
Created January 26, 2019 02:39
Show Gist options
  • Save aeyakovenko/f10aa07ce00905fabaeb9ce832c97138 to your computer and use it in GitHub Desktop.
Save aeyakovenko/f10aa07ce00905fabaeb9ce832c97138 to your computer and use it in GitHub Desktop.
use fnv::FnvHasher;
pub const REFRESH_RATE: u64 = 1000;
struct Sched {
seed: u64,
ranks: Vec<(Pubkey, u64)>,
}
impl Sched {
fn should_regenerate(prev_root: u64, new_root: u64) -> bool {
prev_root/REFRESH_RATE != new_root/REFRESH_RATE
}
/// ranked leaders
fn new_schedule(root: &BankCheckpoint) -> Sched {
let accounts = root.accounts.accounts_db.read().unwrap();
let mut leaders = accounts
.accounts
.iter()
.flat_map(|(_, account)| {
if vote_program::check_id(&account.owner) {
if let Ok(vote_state) = VoteProgram::deserialize(&account.userdata) {
return (vote_state.node_id, account.tokens)
}
}
None
})
.collect();
leaders.sort_by_key(|l| l.1);
Sched { ranks: leaders.into_iter().fold(|x,z| (x.0, z + x.1)).collect(), seed: root.fork_id() }
}
fn compute_node(&self, slot: usize) -> Pubkey {
let total = leaders.last().1;
// use a stable known hasher because this MUST be the same across the entire network
let mut hasher = FnvHasher::with_key(self.seed);
hasher.write(slot);
let random = hasher.finish();
let val = random % total;
self.leaders.drop_while(|l| val < l.1).first().unwrap().0
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment