Absorb LeaderScheduler's rank_active_set()
Delete overly-complicated tests
This commit is contained in:
parent
1c2169aec7
commit
e9daf57d7f
@ -60,6 +60,10 @@ impl ActiveStakers {
|
|||||||
Self::new_with_bounds(bank, DEFAULT_ACTIVE_WINDOW_TICK_LENGTH, bank.tick_height())
|
Self::new_with_bounds(bank, DEFAULT_ACTIVE_WINDOW_TICK_LENGTH, bank.tick_height())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ranked_stakes(&self) -> Vec<(Pubkey, u64)> {
|
||||||
|
self.stakes.clone()
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the pubkeys of each staker.
|
/// Return the pubkeys of each staker.
|
||||||
pub fn pubkeys(&self) -> Vec<Pubkey> {
|
pub fn pubkeys(&self) -> Vec<Pubkey> {
|
||||||
self.stakes.iter().map(|(pubkey, _stake)| *pubkey).collect()
|
self.stakes.iter().map(|(pubkey, _stake)| *pubkey).collect()
|
||||||
@ -77,6 +81,7 @@ impl ActiveStakers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
@ -294,4 +299,31 @@ pub mod tests {
|
|||||||
assert_eq!(result.len(), 0);
|
assert_eq!(result.len(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rank_stakes_basic() {
|
||||||
|
let pubkey0 = Keypair::new().pubkey();
|
||||||
|
let pubkey1 = Keypair::new().pubkey();
|
||||||
|
let mut stakes = vec![(pubkey0, 2), (pubkey1, 1)];
|
||||||
|
rank_stakes(&mut stakes);
|
||||||
|
assert_eq!(stakes, vec![(pubkey1, 1), (pubkey0, 2)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rank_stakes_with_dup() {
|
||||||
|
let pubkey0 = Keypair::new().pubkey();
|
||||||
|
let pubkey1 = Keypair::new().pubkey();
|
||||||
|
let mut stakes = vec![(pubkey0, 1), (pubkey1, 2), (pubkey0, 1)];
|
||||||
|
rank_stakes(&mut stakes);
|
||||||
|
assert_eq!(stakes, vec![(pubkey0, 1), (pubkey1, 2)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rank_stakes_with_equal_stakes() {
|
||||||
|
let pubkey0 = Pubkey::default();
|
||||||
|
let pubkey1 = Keypair::new().pubkey();
|
||||||
|
let mut stakes = vec![(pubkey0, 1), (pubkey1, 1)];
|
||||||
|
rank_stakes(&mut stakes);
|
||||||
|
assert_eq!(stakes, vec![(pubkey0, 1), (pubkey1, 1)]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! The `leader_scheduler` module implements a structure and functions for tracking and
|
//! The `leader_scheduler` module implements a structure and functions for tracking and
|
||||||
//! managing the schedule for leader rotation
|
//! managing the schedule for leader rotation
|
||||||
|
|
||||||
use crate::active_stakers::{self, ActiveStakers, DEFAULT_ACTIVE_WINDOW_TICK_LENGTH};
|
use crate::active_stakers::{ActiveStakers, DEFAULT_ACTIVE_WINDOW_TICK_LENGTH};
|
||||||
use crate::entry::{create_ticks, next_entry_mut, Entry};
|
use crate::entry::{create_ticks, next_entry_mut, Entry};
|
||||||
use crate::voting_keypair::VotingKeypair;
|
use crate::voting_keypair::VotingKeypair;
|
||||||
use bincode::serialize;
|
use bincode::serialize;
|
||||||
@ -228,10 +228,9 @@ impl LeaderScheduler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.seed = Self::calculate_seed(tick_height);
|
self.seed = Self::calculate_seed(tick_height);
|
||||||
let active_set =
|
let ranked_active_set =
|
||||||
ActiveStakers::new_with_bounds(&bank, self.active_window_tick_length, tick_height)
|
ActiveStakers::new_with_bounds(&bank, self.active_window_tick_length, tick_height)
|
||||||
.pubkeys();
|
.ranked_stakes();
|
||||||
let ranked_active_set = Self::rank_active_set(bank, active_set);
|
|
||||||
|
|
||||||
if ranked_active_set.is_empty() {
|
if ranked_active_set.is_empty() {
|
||||||
info!(
|
info!(
|
||||||
@ -288,22 +287,6 @@ impl LeaderScheduler {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rank_active_set(bank: &Bank, active: Vec<Pubkey>) -> Vec<(Pubkey, u64)> {
|
|
||||||
let mut active_accounts: Vec<_> = active
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|pubkey| {
|
|
||||||
let stake = bank.get_balance(&pubkey);
|
|
||||||
if stake > 0 {
|
|
||||||
Some((pubkey, stake as u64))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
active_stakers::rank_stakes(&mut active_accounts);
|
|
||||||
active_accounts
|
|
||||||
}
|
|
||||||
|
|
||||||
fn calculate_seed(tick_height: u64) -> u64 {
|
fn calculate_seed(tick_height: u64) -> u64 {
|
||||||
let hash = hash(&serialize(&tick_height).unwrap());
|
let hash = hash(&serialize(&tick_height).unwrap());
|
||||||
let bytes = hash.as_ref();
|
let bytes = hash.as_ref();
|
||||||
@ -578,93 +561,6 @@ pub mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_rank_active_set() {
|
|
||||||
let num_validators: usize = 101;
|
|
||||||
// Give genesis_block sum(1..num_validators) tokens
|
|
||||||
let (genesis_block, mint_keypair) =
|
|
||||||
GenesisBlock::new((((num_validators + 1) / 2) * (num_validators + 1)) as u64);
|
|
||||||
let bank = Bank::new(&genesis_block);
|
|
||||||
let mut validators = vec![];
|
|
||||||
let last_id = genesis_block.last_id();
|
|
||||||
for i in 0..num_validators {
|
|
||||||
let new_validator = Keypair::new();
|
|
||||||
let new_pubkey = new_validator.pubkey();
|
|
||||||
validators.push(new_validator);
|
|
||||||
bank.transfer(
|
|
||||||
(num_validators - i) as u64,
|
|
||||||
&mint_keypair,
|
|
||||||
new_pubkey,
|
|
||||||
last_id,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let validator_pubkeys: Vec<_> = validators.iter().map(Keypair::pubkey).collect();
|
|
||||||
let result = LeaderScheduler::rank_active_set(&bank, validator_pubkeys);
|
|
||||||
|
|
||||||
assert_eq!(result.len(), validators.len());
|
|
||||||
|
|
||||||
// Expect the result to be the reverse of the list we passed into the rank_active_set()
|
|
||||||
for (i, (pubkey, stake)) in result.into_iter().enumerate() {
|
|
||||||
assert_eq!(stake, i as u64 + 1);
|
|
||||||
assert_eq!(pubkey, validators[num_validators - i - 1].pubkey());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transfer all the tokens to a new set of validators, old validators should now
|
|
||||||
// have balance of zero and get filtered out of the rankings
|
|
||||||
let mut new_validators = vec![];
|
|
||||||
for i in 0..num_validators {
|
|
||||||
let new_validator = Keypair::new();
|
|
||||||
let new_pubkey = new_validator.pubkey();
|
|
||||||
new_validators.push(new_validator);
|
|
||||||
bank.transfer(
|
|
||||||
(num_validators - i) as u64,
|
|
||||||
&validators[i],
|
|
||||||
new_pubkey,
|
|
||||||
last_id,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let all_validators: Vec<Pubkey> = validators
|
|
||||||
.iter()
|
|
||||||
.chain(new_validators.iter())
|
|
||||||
.map(Keypair::pubkey)
|
|
||||||
.collect();
|
|
||||||
let result = LeaderScheduler::rank_active_set(&bank, all_validators);
|
|
||||||
assert_eq!(result.len(), new_validators.len());
|
|
||||||
|
|
||||||
for (i, (pubkey, balance)) in result.into_iter().enumerate() {
|
|
||||||
assert_eq!(balance, i as u64 + 1);
|
|
||||||
assert_eq!(pubkey, new_validators[num_validators - i - 1].pubkey());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Break ties between validators with the same balances using public key
|
|
||||||
let (genesis_block, mint_keypair) = GenesisBlock::new((num_validators + 1) as u64);
|
|
||||||
let bank = Bank::new(&genesis_block);
|
|
||||||
let mut tied_validators_pk = vec![];
|
|
||||||
let last_id = genesis_block.last_id();
|
|
||||||
|
|
||||||
for _i in 0..num_validators {
|
|
||||||
let new_validator = Keypair::new();
|
|
||||||
let new_pubkey = new_validator.pubkey();
|
|
||||||
tied_validators_pk.push(new_pubkey);
|
|
||||||
assert!(bank.get_balance(&mint_keypair.pubkey()) > 1);
|
|
||||||
bank.transfer(1, &mint_keypair, new_pubkey, last_id)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut sorted = tied_validators_pk.clone();
|
|
||||||
sorted.sort_by(|pk1, pk2| pk1.cmp(pk2));
|
|
||||||
let result = LeaderScheduler::rank_active_set(&bank, tied_validators_pk);
|
|
||||||
assert_eq!(result.len(), sorted.len());
|
|
||||||
for (i, (pk, s)) in result.into_iter().enumerate() {
|
|
||||||
assert_eq!(s, 1);
|
|
||||||
assert_eq!(pk, sorted[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_choose_account() {
|
fn test_choose_account() {
|
||||||
let tokens = vec![10, 30, 50, 5, 1];
|
let tokens = vec![10, 30, 50, 5, 1];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user