From ac35fe9ed1e5be60cff61ed39f7127f7d6646fac Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Sat, 16 Feb 2019 12:36:22 -0700 Subject: [PATCH] Flip the dependency; Create bank before scheduler --- src/bank.rs | 12 ------- src/banking_stage.rs | 19 +++-------- src/entry_stream.rs | 7 ++-- src/entry_stream_stage.rs | 9 +++-- src/fullnode.rs | 6 +++- src/leader_scheduler.rs | 71 +++++++++++++++++++-------------------- src/replay_stage.rs | 16 ++++----- src/tvu.rs | 20 +++++------ 8 files changed, 69 insertions(+), 91 deletions(-) diff --git a/src/bank.rs b/src/bank.rs index 2b0eb548d3..598b4ce988 100644 --- a/src/bank.rs +++ b/src/bank.rs @@ -123,18 +123,6 @@ impl Bank { bank } - pub fn new_with_leader_scheduler( - genesis_block: &GenesisBlock, - leader_scheduler: Arc>, - ) -> Self { - let bank = Bank::new(genesis_block); - leader_scheduler - .write() - .unwrap() - .update_tick_height(0, &bank); - bank - } - pub fn set_subscriptions(&self, subscriptions: Arc) { let mut sub = self.subscriptions.write().unwrap(); *sub = Some(subscriptions) diff --git a/src/banking_stage.rs b/src/banking_stage.rs index 30f6a716de..3458c6a2be 100644 --- a/src/banking_stage.rs +++ b/src/banking_stage.rs @@ -262,11 +262,10 @@ mod tests { use super::*; use crate::entry::EntrySlice; use crate::genesis_block::GenesisBlock; - use crate::leader_scheduler::{LeaderScheduler, LeaderSchedulerConfig, DEFAULT_TICKS_PER_SLOT}; + use crate::leader_scheduler::DEFAULT_TICKS_PER_SLOT; use crate::packet::to_packets; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction::SystemTransaction; - use std::sync::RwLock; use std::thread::sleep; #[test] @@ -459,13 +458,8 @@ mod tests { fn test_returns_unprocessed_packet() { solana_logger::setup(); let (genesis_block, mint_keypair) = GenesisBlock::new(2); - let leader_scheduler_config = LeaderSchedulerConfig::new(1, 1, 1); - let leader_scheduler = - Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); - let bank = Arc::new(Bank::new_with_leader_scheduler( - &genesis_block, - leader_scheduler, - )); + let bank = Arc::new(Bank::new(&genesis_block)); + let ticks_per_slot = 1; let (verified_sender, verified_receiver) = channel(); let (to_validator_sender, to_validator_receiver) = channel(); let (mut banking_stage, _entry_receiver) = BankingStage::new( @@ -473,16 +467,13 @@ mod tests { verified_receiver, PohServiceConfig::default(), &bank.last_id(), - leader_scheduler_config.ticks_per_slot, + ticks_per_slot, genesis_block.bootstrap_leader_id, &to_validator_sender, ); // Wait for Poh recorder to hit max height - assert_eq!( - to_validator_receiver.recv().unwrap(), - leader_scheduler_config.ticks_per_slot - ); + assert_eq!(to_validator_receiver.recv().unwrap(), ticks_per_slot); // Now send a transaction to the banking stage let transaction = SystemTransaction::new_account( diff --git a/src/entry_stream.rs b/src/entry_stream.rs index 6cf43e9ce6..38f261fd35 100644 --- a/src/entry_stream.rs +++ b/src/entry_stream.rs @@ -166,9 +166,10 @@ mod test { // Set up bank and leader_scheduler let leader_scheduler_config = LeaderSchedulerConfig::new(5, 2, 10); let (genesis_block, _mint_keypair) = GenesisBlock::new(1_000_000); - let leader_scheduler = - Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); - let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); + let bank = Bank::new(&genesis_block); + let leader_scheduler = LeaderScheduler::new_with_bank(&leader_scheduler_config, &bank); + let leader_scheduler = Arc::new(RwLock::new(leader_scheduler)); + // Set up entry stream let entry_stream = MockEntryStream::new("test_stream".to_string(), leader_scheduler.clone()); diff --git a/src/entry_stream_stage.rs b/src/entry_stream_stage.rs index 13a7e4b4e3..2a9ae6393c 100644 --- a/src/entry_stream_stage.rs +++ b/src/entry_stream_stage.rs @@ -124,13 +124,12 @@ mod test { fn test_entry_stream_stage_process_entries() { // Set up the bank and leader_scheduler let ticks_per_slot = 5; - let leader_scheduler_config = LeaderSchedulerConfig::new(ticks_per_slot, 2, 10); - let leader_scheduler = - Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); - // Side-effect: Register a bank with the leader_scheduler let (genesis_block, _mint_keypair) = GenesisBlock::new(1_000_000); - Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); + let bank = Bank::new(&genesis_block); + let leader_scheduler_config = LeaderSchedulerConfig::new(ticks_per_slot, 2, 10); + let leader_scheduler = LeaderScheduler::new_with_bank(&leader_scheduler_config, &bank); + let leader_scheduler = Arc::new(RwLock::new(leader_scheduler)); // Set up entry stream let mut entry_stream = diff --git a/src/fullnode.rs b/src/fullnode.rs index 41bb14de61..4839e02bff 100644 --- a/src/fullnode.rs +++ b/src/fullnode.rs @@ -466,7 +466,11 @@ pub fn new_bank_from_ledger( .expect("Expected to successfully open database ledger"); let genesis_block = GenesisBlock::load(ledger_path).expect("Expected to successfully open genesis block"); - let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); + let bank = Bank::new(&genesis_block); + leader_scheduler + .write() + .unwrap() + .update_tick_height(0, &bank); let now = Instant::now(); info!("processing ledger..."); diff --git a/src/leader_scheduler.rs b/src/leader_scheduler.rs index 6ae5fd51ec..63b12ee133 100644 --- a/src/leader_scheduler.rs +++ b/src/leader_scheduler.rs @@ -113,6 +113,12 @@ impl LeaderScheduler { } } + pub fn new_with_bank(config: &LeaderSchedulerConfig, bank: &Bank) -> Self { + let mut leader_schedule = Self::new(config); + leader_schedule.update_tick_height(bank.tick_height(), bank); + leader_schedule + } + pub fn tick_height_to_slot(&self, tick_height: u64) -> u64 { tick_height / self.ticks_per_slot } @@ -481,14 +487,14 @@ pub mod tests { ticks_per_epoch / ticks_per_slot, active_window_tick_length, ); - let leader_scheduler = - Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); // Create the bank and validators, which are inserted in order of account balance let num_vote_account_tokens = 1; let (genesis_block, mint_keypair) = GenesisBlock::new(10_000); info!("bootstrap_leader_id: {}", genesis_block.bootstrap_leader_id); - let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); + + let bank = Bank::new(&genesis_block); + let mut validators = vec![]; let last_id = genesis_block.last_id(); for i in 0..num_validators { @@ -521,7 +527,8 @@ pub mod tests { ); } - let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config); + let mut leader_scheduler = LeaderScheduler::new_with_bank(&leader_scheduler_config, &bank); + // Generate the schedule for first epoch, bootstrap_leader will be the only leader leader_scheduler.generate_schedule(0, &bank); @@ -597,9 +604,9 @@ pub mod tests { let leader_id = Keypair::new().pubkey(); let leader_tokens = 2; let (genesis_block, _) = GenesisBlock::new_with_leader(5, leader_id, leader_tokens); - let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::default())); - let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); - let leader_scheduler = leader_scheduler.read().unwrap(); + let bank = Bank::new(&genesis_block); + let leader_scheduler = + LeaderScheduler::new_with_bank(&LeaderSchedulerConfig::default(), &bank); let slot = leader_scheduler.tick_height_to_slot(bank.tick_height()); assert_eq!(leader_scheduler.get_leader_for_slot(slot), Some(leader_id)); } @@ -641,10 +648,9 @@ pub mod tests { let leader_id = Keypair::new().pubkey(); let active_window_tick_length = 1000; let leader_scheduler_config = LeaderSchedulerConfig::new(100, 1, active_window_tick_length); - let leader_scheduler = - Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); let (genesis_block, mint_keypair) = GenesisBlock::new_with_leader(10000, leader_id, 500); - let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); + let bank = Bank::new(&genesis_block); + let mut leader_scheduler = LeaderScheduler::new_with_bank(&leader_scheduler_config, &bank); let bootstrap_ids = to_hashset_owned(&vec![genesis_block.bootstrap_leader_id]); @@ -710,8 +716,6 @@ pub mod tests { } // Query for the active set at various heights - let mut leader_scheduler = leader_scheduler.write().unwrap(); - let result = leader_scheduler.get_active_set(0, &bank); assert_eq!(result, bootstrap_ids); @@ -933,17 +937,16 @@ pub mod tests { let slots_per_epoch = num_validators; let active_window_tick_length = ticks_per_slot * slots_per_epoch; - let leader_scheduler_config = - LeaderSchedulerConfig::new(ticks_per_slot, slots_per_epoch, active_window_tick_length); - let leader_scheduler = - Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); - // Create the bank and validators let (genesis_block, mint_keypair) = GenesisBlock::new( ((((num_validators + 1) / 2) * (num_validators + 1)) + (num_vote_account_tokens * num_validators)) as u64, ); - let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); + let bank = Bank::new(&genesis_block); + let leader_scheduler_config = + LeaderSchedulerConfig::new(ticks_per_slot, slots_per_epoch, active_window_tick_length); + let mut leader_scheduler = LeaderScheduler::new_with_bank(&leader_scheduler_config, &bank); + let mut validators = vec![]; let last_id = genesis_block.last_id(); for i in 0..num_validators { @@ -980,7 +983,6 @@ pub mod tests { // Generate schedule every active_window_tick_length entries and check that // validators are falling out of the rotation as they fall out of the // active set - let mut leader_scheduler = leader_scheduler.write().unwrap(); trace!("bootstrap_leader_id: {}", genesis_block.bootstrap_leader_id); for i in 0..num_validators { trace!("validators[{}]: {}", i, validators[i as usize]); @@ -1012,10 +1014,12 @@ pub mod tests { let leader_id = leader_keypair.pubkey(); let active_window_tick_length = 1000; let (genesis_block, _mint_keypair) = GenesisBlock::new_with_leader(10000, leader_id, 500); + let bank = Bank::new(&genesis_block); let leader_scheduler_config = LeaderSchedulerConfig::new(100, 1, active_window_tick_length); - let leader_scheduler = - Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); - let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); + let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::new_with_bank( + &leader_scheduler_config, + &bank, + ))); // Bootstrap leader should be in the active set even without explicit votes { @@ -1077,16 +1081,13 @@ pub mod tests { let ticks_per_epoch = ticks_per_slot * slots_per_epoch; let active_window_tick_length = 1; - let leader_scheduler_config = - LeaderSchedulerConfig::new(ticks_per_slot, slots_per_epoch, active_window_tick_length); - let leader_scheduler = - Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); - // Check that the generate_schedule() function is being called by the // update_tick_height() function at the correct entry heights. let (genesis_block, _) = GenesisBlock::new(10_000); - let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); - let mut leader_scheduler = leader_scheduler.write().unwrap(); + let bank = Bank::new(&genesis_block); + let leader_scheduler_config = + LeaderSchedulerConfig::new(ticks_per_slot, slots_per_epoch, active_window_tick_length); + let mut leader_scheduler = LeaderScheduler::new_with_bank(&leader_scheduler_config, &bank); info!( "bootstrap_leader_id: {:?}", genesis_block.bootstrap_leader_id @@ -1220,15 +1221,10 @@ pub mod tests { let ticks_per_slot = 100; let active_window_tick_length = slots_per_epoch * ticks_per_slot; - let leader_scheduler_config = - LeaderSchedulerConfig::new(ticks_per_slot, slots_per_epoch, active_window_tick_length); - let leader_scheduler = - Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); - // Create mint and bank let (genesis_block, mint_keypair) = GenesisBlock::new_with_leader(10_000, bootstrap_leader_id, BOOTSTRAP_LEADER_TOKENS); - let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); + let bank = Bank::new(&genesis_block); let last_id = genesis_block.last_id(); let initial_vote_height = 1; @@ -1291,7 +1287,10 @@ pub mod tests { genesis_block.last_id(), ); - let mut leader_scheduler = LeaderScheduler::default(); + let leader_scheduler_config = + LeaderSchedulerConfig::new(ticks_per_slot, slots_per_epoch, active_window_tick_length); + let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config); + leader_scheduler.generate_schedule(0, &bank); assert_eq!(leader_scheduler.current_epoch, 0); assert_eq!(leader_scheduler.epoch_schedule[0], [bootstrap_leader_id]); diff --git a/src/replay_stage.rs b/src/replay_stage.rs index b378fc7f53..69de55efa6 100644 --- a/src/replay_stage.rs +++ b/src/replay_stage.rs @@ -783,13 +783,12 @@ mod test { } let genesis_block = GenesisBlock::new(10_000).0; - let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::default())); let my_keypair = Arc::new(my_keypair); let voting_keypair = Arc::new(VotingKeypair::new_local(&my_keypair)); - let bank = Arc::new(Bank::new_with_leader_scheduler( - &genesis_block, - leader_scheduler.clone(), - )); + let bank = Arc::new(Bank::new(&genesis_block)); + let leader_scheduler_config = LeaderSchedulerConfig::default(); + let leader_scheduler = LeaderScheduler::new_with_bank(&leader_scheduler_config, &bank); + let leader_scheduler = Arc::new(RwLock::new(leader_scheduler)); let res = ReplayStage::process_entries( entries.clone(), &bank, @@ -812,10 +811,9 @@ mod test { entries.push(entry); } - let bank = Arc::new(Bank::new_with_leader_scheduler( - &genesis_block, - leader_scheduler.clone(), - )); + let bank = Arc::new(Bank::new(&genesis_block)); + let leader_scheduler = LeaderScheduler::new_with_bank(&leader_scheduler_config, &bank); + let leader_scheduler = Arc::new(RwLock::new(leader_scheduler)); let res = ReplayStage::process_entries( entries.clone(), &bank, diff --git a/src/tvu.rs b/src/tvu.rs index 0a963b0bc7..a74d02c02d 100644 --- a/src/tvu.rs +++ b/src/tvu.rs @@ -245,11 +245,10 @@ pub mod tests { let starting_balance = 10_000; let (genesis_block, _mint_keypair) = GenesisBlock::new(starting_balance); - let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::default())); - let bank = Arc::new(Bank::new_with_leader_scheduler( - &genesis_block, - leader_scheduler.clone(), - )); + let bank = Arc::new(Bank::new(&genesis_block)); + let leader_scheduler_config = LeaderSchedulerConfig::default(); + let leader_scheduler = LeaderScheduler::new_with_bank(&leader_scheduler_config, &bank); + let leader_scheduler = Arc::new(RwLock::new(leader_scheduler)); //start cluster_info1 let mut cluster_info1 = ClusterInfo::new(target1.info.clone()); @@ -340,12 +339,11 @@ pub mod tests { let starting_balance = 10_000; let (genesis_block, mint_keypair) = GenesisBlock::new(starting_balance); let tvu_addr = target1.info.tvu; - let leader_scheduler = - Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); - let bank = Arc::new(Bank::new_with_leader_scheduler( - &genesis_block, - leader_scheduler.clone(), - )); + let bank = Arc::new(Bank::new(&genesis_block)); + let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::new_with_bank( + &leader_scheduler_config, + &bank, + ))); assert_eq!(bank.get_balance(&mint_keypair.pubkey()), starting_balance); // start cluster_info1