Skip to content

Commit

Permalink
feat: new leader schedule by vote delegation
Browse files Browse the repository at this point in the history
  • Loading branch information
jstarry committed Jan 28, 2025
1 parent 1fe4440 commit 9f16cee
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 10 deletions.
28 changes: 26 additions & 2 deletions ledger/src/leader_schedule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use {
rand_chacha::{rand_core::SeedableRng, ChaChaRng},
solana_pubkey::Pubkey,
solana_sdk::clock::Epoch,
solana_vote::vote_account::VoteAccountsHashMap,
std::{collections::HashMap, convert::identity, ops::Index, sync::Arc},
};

Expand All @@ -22,6 +23,27 @@ pub struct LeaderSchedule {
}

impl LeaderSchedule {
// Note: passing in zero vote accounts will cause a panic.
pub fn new_by_vote_delegation(
vote_accounts_map: &VoteAccountsHashMap,
epoch: Epoch,
len: u64,
repeat: u64,
) -> Self {
let stakes: Vec<_> = vote_accounts_map
.iter()
.map(|(vote_pubkey, (stake, _account))| (*vote_pubkey, *stake))
.collect();
let slot_leaders = Self::stake_weighted_slot_leaders(
stakes,
|vote_key| *vote_accounts_map.get(vote_key).unwrap().1.node_pubkey(),
epoch,
len,
repeat,
);
Self::new_from_schedule(slot_leaders)
}

// Note: passing in zero stakers will cause a panic.
pub fn new_by_node_total_stake(
stakes: &HashMap<Pubkey, u64>,
Expand All @@ -33,13 +55,15 @@ impl LeaderSchedule {
.iter()
.map(|(pubkey, stake)| (*pubkey, *stake))
.collect();
let slot_leaders = Self::stake_weighted_slot_leaders(stakes, epoch, len, repeat);
let slot_leaders =
Self::stake_weighted_slot_leaders(stakes, |leader| *leader, epoch, len, repeat);
Self::new_from_schedule(slot_leaders)
}

// Note: passing in zero stakers will cause a panic.
fn stake_weighted_slot_leaders(
mut stakes: Vec<(Pubkey, u64)>,
get_leader_node: impl Fn(&Pubkey) -> Pubkey,
epoch: Epoch,
len: u64,
repeat: u64,
Expand All @@ -54,7 +78,7 @@ impl LeaderSchedule {
(0..len)
.map(|i| {
if i % repeat == 0 {
current_node = ids[weighted_index.sample(rng)];
current_node = get_leader_node(&ids[weighted_index.sample(rng)]);
}
current_node
})
Expand Down
35 changes: 27 additions & 8 deletions ledger/src/leader_schedule_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,33 @@ use {

/// Return the leader schedule for the given epoch.
pub fn leader_schedule(epoch: Epoch, bank: &Bank) -> Option<LeaderSchedule> {
bank.epoch_staked_nodes(epoch).map(|stakes| {
LeaderSchedule::new_by_node_total_stake(
&stakes,
epoch,
bank.get_slots_in_epoch(epoch),
NUM_CONSECUTIVE_LEADER_SLOTS,
)
})
let use_new_leader_schedule = match bank
.feature_set
.new_leader_schedule_epoch(bank.epoch_schedule())
{
Some(new_leader_schedule_epoch) => epoch >= new_leader_schedule_epoch,
None => false,
};

if use_new_leader_schedule {
bank.epoch_vote_accounts(epoch).map(|vote_accounts_map| {
LeaderSchedule::new_by_vote_delegation(
vote_accounts_map,
epoch,
bank.get_slots_in_epoch(epoch),
NUM_CONSECUTIVE_LEADER_SLOTS,
)
})
} else {
bank.epoch_staked_nodes(epoch).map(|stakes| {
LeaderSchedule::new_by_node_total_stake(
&stakes,
epoch,
bank.get_slots_in_epoch(epoch),
NUM_CONSECUTIVE_LEADER_SLOTS,
)
})
}
}

/// Map of leader base58 identity pubkeys to the slot indices relative to the first epoch slot
Expand Down
18 changes: 18 additions & 0 deletions sdk/feature-set/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,10 @@ pub mod reserve_minimal_cus_for_builtin_instructions {
solana_pubkey::declare_id!("C9oAhLxDBm3ssWtJx1yBGzPY55r2rArHmN1pbQn6HogH");
}

pub mod enable_vote_address_leader_schedule {
solana_pubkey::declare_id!("5JsG4NWH8Jbrqdd8uL6BNwnyZK3dQSoieRXG5vmofj9y");
}

pub mod raise_block_limits_to_50m {
solana_pubkey::declare_id!("5oMCU3JPaFLr8Zr4ct7yFA7jdk6Mw1RmB8K4u9ZbS42z");
}
Expand Down Expand Up @@ -1149,6 +1153,7 @@ lazy_static! {
(deplete_cu_meter_on_vm_failure::id(), "Deplete compute meter for vm errors SIMD-0182 #3993"),
(reserve_minimal_cus_for_builtin_instructions::id(), "Reserve minimal CUs for builtin instructions SIMD-170 #2562"),
(raise_block_limits_to_50m::id(), "Raise block limit to 50M SIMD-0207"),
(enable_vote_address_leader_schedule::id(), "Enable vote address leader schedule SIMD-0180 #4573"),
(fix_alt_bn128_multiplication_input_length::id(), "fix alt_bn128 multiplication input length SIMD-0222 #3686"),
/*************** ADD NEW FEATURES HERE ***************/
]
Expand Down Expand Up @@ -1212,6 +1217,19 @@ impl FeatureSet {
self.active.get(feature_id).copied()
}

pub fn new_leader_schedule_epoch(&self, epoch_schedule: &EpochSchedule) -> Option<u64> {
// check the epoch of the slot when the new leader schedule feature was
// activated and then use the following epoch to start using the new
// leader schedule.
const NEW_LEADER_SCHEDULE_EPOCH_DELAY: u64 = 1;
self.activated_slot(&enable_vote_address_leader_schedule::id())
.map(|slot| {
epoch_schedule
.get_epoch(slot)
.wrapping_add(NEW_LEADER_SCHEDULE_EPOCH_DELAY)
})
}

/// List of enabled features that trigger full inflation
pub fn full_inflation_features_enabled(&self) -> AHashSet<Pubkey> {
let mut hash_set = FULL_INFLATION_FEATURE_PAIRS
Expand Down

0 comments on commit 9f16cee

Please sign in to comment.