And ranking and simplify

This commit is contained in:
Greg Fitzgerald
2019-02-20 09:21:29 -07:00
parent 6ce2c06fd6
commit 88d6db8537
2 changed files with 24 additions and 14 deletions

View File

@ -1,5 +1,4 @@
use crate::leader_schedule::LeaderSchedule; use crate::leader_schedule::LeaderSchedule;
use hashbrown::{HashMap, HashSet};
use solana_runtime::bank::Bank; use solana_runtime::bank::Bank;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::vote_program::VoteState; use solana_sdk::vote_program::VoteState;
@ -13,14 +12,30 @@ fn is_active_staker(vote_state: &VoteState, lower_bound: u64, upper_bound: u64)
.is_some() .is_some()
} }
fn rank_stakes(stakes: &mut Vec<(Pubkey, u64)>) {
// Rank first by stake. If stakes are the same we rank by pubkey to ensure a
// deterministic result.
// Note: Use unstable sort, because we dedup right after to remove the equal elements.
stakes.sort_unstable_by(|(pubkey0, stake0), (pubkey1, stake1)| {
if stake0 == stake1 {
pubkey0.cmp(&pubkey1)
} else {
stake0.cmp(&stake1)
}
});
// Now that it's sorted, we can do an O(n) dedup.
stakes.dedup();
}
/// The set of stakers that have voted near the time of construction /// The set of stakers that have voted near the time of construction
pub struct ActiveStakers { pub struct ActiveStakers {
stakes: HashMap<Pubkey, u64>, stakes: Vec<(Pubkey, u64)>,
} }
impl ActiveStakers { impl ActiveStakers {
pub fn new_with_upper_bound(bank: &Bank, lower_bound: u64, upper_bound: u64) -> Self { pub fn new_with_upper_bound(bank: &Bank, lower_bound: u64, upper_bound: u64) -> Self {
let stakes = bank let mut stakes: Vec<_> = bank
.vote_states(|vote_state| is_active_staker(vote_state, lower_bound, upper_bound)) .vote_states(|vote_state| is_active_staker(vote_state, lower_bound, upper_bound))
.iter() .iter()
.filter_map(|vote_state| { .filter_map(|vote_state| {
@ -33,6 +48,7 @@ impl ActiveStakers {
} }
}) })
.collect(); .collect();
rank_stakes(&mut stakes);
Self { stakes } Self { stakes }
} }
@ -40,19 +56,12 @@ impl ActiveStakers {
Self::new_with_upper_bound(bank, lower_bound, bank.tick_height()) Self::new_with_upper_bound(bank, lower_bound, bank.tick_height())
} }
/// Return a map from staker pubkeys to their respective stakes.
pub fn stakes(&self) -> HashMap<Pubkey, u64> {
self.stakes.clone()
}
/// Return the pubkeys of each staker. /// Return the pubkeys of each staker.
pub fn stakers(&self) -> HashSet<Pubkey> { pub fn pubkeys(&self) -> Vec<Pubkey> {
self.stakes.keys().cloned().collect() self.stakes.iter().map(|(pubkey, _stake)| *pubkey).collect()
} }
pub fn leader_schedule(&self) -> LeaderSchedule { pub fn leader_schedule(&self) -> LeaderSchedule {
let mut stakers: Vec<_> = self.stakes.keys().cloned().collect(); LeaderSchedule::new(self.pubkeys())
stakers.sort();
LeaderSchedule::new(stakers)
} }
} }

View File

@ -214,7 +214,8 @@ impl LeaderScheduler {
upper_bound upper_bound
); );
ActiveStakers::new_with_upper_bound(&bank, lower_bound, upper_bound).stakers() let active_stakers = ActiveStakers::new_with_upper_bound(&bank, lower_bound, upper_bound);
active_stakers.pubkeys().into_iter().collect()
} }
// Updates the leader schedule to include ticks from tick_height to the first tick of the next epoch // Updates the leader schedule to include ticks from tick_height to the first tick of the next epoch