diff --git a/Cargo.lock b/Cargo.lock index 5033fc987c..9d36eaf6fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2243,6 +2243,7 @@ dependencies = [ "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index d4d833a6c1..0933fa908a 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -15,6 +15,7 @@ fnv = "1.0.6" hashbrown = "0.1.8" log = "0.4.2" rand = "0.6.5" +rand_chacha = "0.1.1" serde = "1.0.88" serde_derive = "1.0.88" serde_json = "1.0.38" diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 08e9242d47..0cc8c13e8d 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -5,6 +5,7 @@ use crate::accounts::{Accounts, ErrorCounters, InstructionAccounts, InstructionLoaders}; use crate::last_id_queue::LastIdQueue; +use crate::leader_schedule::LeaderSchedule; use crate::runtime::{self, RuntimeError}; use crate::status_cache::StatusCache; use bincode::serialize; @@ -675,7 +676,7 @@ impl Bank { /// Return the checkpointed bank that should be used to generate a leader schedule. /// Return None if a sufficiently old bank checkpoint doesn't exist. - pub fn leader_schedule_bank(&self) -> Option> { + fn leader_schedule_bank(&self) -> Option> { let epoch_slot_height = self.slot_height() - self.slot_index(); let expected = epoch_slot_height.saturating_sub(self.leader_schedule_slot_offset); self.parents() @@ -683,6 +684,19 @@ impl Bank { .find(|bank| bank.slot_height() <= expected) } + /// Return the leader schedule for the current epoch. + fn leader_schedule(&self) -> LeaderSchedule { + match self.leader_schedule_bank() { + None => LeaderSchedule::new_with_bank(self), + Some(bank) => LeaderSchedule::new_with_bank(&bank), + } + } + + /// Return the leader for the current slot. + pub fn slot_leader(&self) -> Pubkey { + self.leader_schedule()[self.slot_index() as usize] + } + /// Return the number of ticks since genesis. pub fn tick_height(&self) -> u64 { self.last_id_queue.read().unwrap().tick_height @@ -1365,4 +1379,11 @@ mod tests { bank.merge_parents(); } } + + #[test] + fn test_bank_slot_leader_basic() { + let pubkey = Keypair::new().pubkey(); + let bank = Bank::new(&GenesisBlock::new_with_leader(2, pubkey, 2).0); + assert_eq!(bank.slot_leader(), pubkey); + } } diff --git a/src/leader_schedule.rs b/runtime/src/leader_schedule.rs similarity index 75% rename from src/leader_schedule.rs rename to runtime/src/leader_schedule.rs index 0c884bd2d0..8c95fe9105 100644 --- a/src/leader_schedule.rs +++ b/runtime/src/leader_schedule.rs @@ -1,11 +1,11 @@ +use crate::bank::Bank; use rand::distributions::{Distribution, WeightedIndex}; use rand::SeedableRng; use rand_chacha::ChaChaRng; -use solana_runtime::bank::Bank; use solana_sdk::pubkey::Pubkey; use std::ops::Index; -/// Round-robin leader schedule. +/// Stake-weighted leader schedule for one epoch. #[derive(Debug, PartialEq)] pub struct LeaderSchedule { slot_leaders: Vec, @@ -43,27 +43,6 @@ impl Index for LeaderSchedule { } } -pub trait LeaderScheduleUtil { - /// Return the leader schedule for the current epoch. - fn leader_schedule(&self) -> LeaderSchedule; - - /// Return the leader id for the current slot. - fn slot_leader(&self) -> Pubkey; -} - -impl LeaderScheduleUtil for Bank { - fn leader_schedule(&self) -> LeaderSchedule { - match self.leader_schedule_bank() { - None => LeaderSchedule::new_with_bank(self), - Some(bank) => LeaderSchedule::new_with_bank(&bank), - } - } - - fn slot_leader(&self) -> Pubkey { - self.leader_schedule()[self.slot_index() as usize] - } -} - #[cfg(test)] mod tests { use super::*; @@ -110,13 +89,5 @@ mod tests { let len = bank.slots_per_epoch() as usize; let expected: Vec<_> = iter::repeat(pubkey).take(len).collect(); assert_eq!(leader_schedule.slot_leaders, expected); - assert_eq!(bank.leader_schedule().slot_leaders, expected); // Same thing, but with the trait - } - - #[test] - fn test_leader_schedule_slot_leader_basic() { - let pubkey = Keypair::new().pubkey(); - let bank = Bank::new(&GenesisBlock::new_with_leader(2, pubkey, 2).0); - assert_eq!(bank.slot_leader(), pubkey); } } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index a797fa286b..e070e3e6de 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -2,6 +2,7 @@ mod accounts; pub mod bank; pub mod bloom; mod last_id_queue; +mod leader_schedule; mod runtime; mod status_cache; diff --git a/src/lib.rs b/src/lib.rs index 67afad24e7..72e4f81af0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,6 @@ pub mod fullnode; pub mod gen_keys; pub mod gossip_service; pub mod leader_confirmation_service; -pub mod leader_schedule; pub mod leader_scheduler; pub mod local_vote_signer_service; pub mod packet;