Flip the dependency; Create bank before scheduler

This commit is contained in:
Greg Fitzgerald
2019-02-16 12:36:22 -07:00
parent 3d70afc578
commit ac35fe9ed1
8 changed files with 69 additions and 91 deletions

View File

@ -123,18 +123,6 @@ impl Bank {
bank bank
} }
pub fn new_with_leader_scheduler(
genesis_block: &GenesisBlock,
leader_scheduler: Arc<RwLock<LeaderScheduler>>,
) -> Self {
let bank = Bank::new(genesis_block);
leader_scheduler
.write()
.unwrap()
.update_tick_height(0, &bank);
bank
}
pub fn set_subscriptions(&self, subscriptions: Arc<RpcSubscriptions>) { pub fn set_subscriptions(&self, subscriptions: Arc<RpcSubscriptions>) {
let mut sub = self.subscriptions.write().unwrap(); let mut sub = self.subscriptions.write().unwrap();
*sub = Some(subscriptions) *sub = Some(subscriptions)

View File

@ -262,11 +262,10 @@ mod tests {
use super::*; use super::*;
use crate::entry::EntrySlice; use crate::entry::EntrySlice;
use crate::genesis_block::GenesisBlock; 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 crate::packet::to_packets;
use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::system_transaction::SystemTransaction;
use std::sync::RwLock;
use std::thread::sleep; use std::thread::sleep;
#[test] #[test]
@ -459,13 +458,8 @@ mod tests {
fn test_returns_unprocessed_packet() { fn test_returns_unprocessed_packet() {
solana_logger::setup(); solana_logger::setup();
let (genesis_block, mint_keypair) = GenesisBlock::new(2); let (genesis_block, mint_keypair) = GenesisBlock::new(2);
let leader_scheduler_config = LeaderSchedulerConfig::new(1, 1, 1); let bank = Arc::new(Bank::new(&genesis_block));
let leader_scheduler = let ticks_per_slot = 1;
Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config)));
let bank = Arc::new(Bank::new_with_leader_scheduler(
&genesis_block,
leader_scheduler,
));
let (verified_sender, verified_receiver) = channel(); let (verified_sender, verified_receiver) = channel();
let (to_validator_sender, to_validator_receiver) = channel(); let (to_validator_sender, to_validator_receiver) = channel();
let (mut banking_stage, _entry_receiver) = BankingStage::new( let (mut banking_stage, _entry_receiver) = BankingStage::new(
@ -473,16 +467,13 @@ mod tests {
verified_receiver, verified_receiver,
PohServiceConfig::default(), PohServiceConfig::default(),
&bank.last_id(), &bank.last_id(),
leader_scheduler_config.ticks_per_slot, ticks_per_slot,
genesis_block.bootstrap_leader_id, genesis_block.bootstrap_leader_id,
&to_validator_sender, &to_validator_sender,
); );
// Wait for Poh recorder to hit max height // Wait for Poh recorder to hit max height
assert_eq!( assert_eq!(to_validator_receiver.recv().unwrap(), ticks_per_slot);
to_validator_receiver.recv().unwrap(),
leader_scheduler_config.ticks_per_slot
);
// Now send a transaction to the banking stage // Now send a transaction to the banking stage
let transaction = SystemTransaction::new_account( let transaction = SystemTransaction::new_account(

View File

@ -166,9 +166,10 @@ mod test {
// Set up bank and leader_scheduler // Set up bank and leader_scheduler
let leader_scheduler_config = LeaderSchedulerConfig::new(5, 2, 10); let leader_scheduler_config = LeaderSchedulerConfig::new(5, 2, 10);
let (genesis_block, _mint_keypair) = GenesisBlock::new(1_000_000); let (genesis_block, _mint_keypair) = GenesisBlock::new(1_000_000);
let leader_scheduler = let bank = Bank::new(&genesis_block);
Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); let leader_scheduler = LeaderScheduler::new_with_bank(&leader_scheduler_config, &bank);
let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); let leader_scheduler = Arc::new(RwLock::new(leader_scheduler));
// Set up entry stream // Set up entry stream
let entry_stream = let entry_stream =
MockEntryStream::new("test_stream".to_string(), leader_scheduler.clone()); MockEntryStream::new("test_stream".to_string(), leader_scheduler.clone());

View File

@ -124,13 +124,12 @@ mod test {
fn test_entry_stream_stage_process_entries() { fn test_entry_stream_stage_process_entries() {
// Set up the bank and leader_scheduler // Set up the bank and leader_scheduler
let ticks_per_slot = 5; 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); 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 // Set up entry stream
let mut entry_stream = let mut entry_stream =

View File

@ -466,7 +466,11 @@ pub fn new_bank_from_ledger(
.expect("Expected to successfully open database ledger"); .expect("Expected to successfully open database ledger");
let genesis_block = let genesis_block =
GenesisBlock::load(ledger_path).expect("Expected to successfully open 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(); let now = Instant::now();
info!("processing ledger..."); info!("processing ledger...");

View File

@ -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 { pub fn tick_height_to_slot(&self, tick_height: u64) -> u64 {
tick_height / self.ticks_per_slot tick_height / self.ticks_per_slot
} }
@ -481,14 +487,14 @@ pub mod tests {
ticks_per_epoch / ticks_per_slot, ticks_per_epoch / ticks_per_slot,
active_window_tick_length, 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 // Create the bank and validators, which are inserted in order of account balance
let num_vote_account_tokens = 1; let num_vote_account_tokens = 1;
let (genesis_block, mint_keypair) = GenesisBlock::new(10_000); let (genesis_block, mint_keypair) = GenesisBlock::new(10_000);
info!("bootstrap_leader_id: {}", genesis_block.bootstrap_leader_id); 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 mut validators = vec![];
let last_id = genesis_block.last_id(); let last_id = genesis_block.last_id();
for i in 0..num_validators { 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 // Generate the schedule for first epoch, bootstrap_leader will be the only leader
leader_scheduler.generate_schedule(0, &bank); leader_scheduler.generate_schedule(0, &bank);
@ -597,9 +604,9 @@ pub mod tests {
let leader_id = Keypair::new().pubkey(); let leader_id = Keypair::new().pubkey();
let leader_tokens = 2; let leader_tokens = 2;
let (genesis_block, _) = GenesisBlock::new_with_leader(5, leader_id, leader_tokens); 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(&genesis_block);
let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); let leader_scheduler =
let leader_scheduler = leader_scheduler.read().unwrap(); LeaderScheduler::new_with_bank(&LeaderSchedulerConfig::default(), &bank);
let slot = leader_scheduler.tick_height_to_slot(bank.tick_height()); let slot = leader_scheduler.tick_height_to_slot(bank.tick_height());
assert_eq!(leader_scheduler.get_leader_for_slot(slot), Some(leader_id)); 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 leader_id = Keypair::new().pubkey();
let active_window_tick_length = 1000; let active_window_tick_length = 1000;
let leader_scheduler_config = LeaderSchedulerConfig::new(100, 1, active_window_tick_length); 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 (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]); 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 // 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); let result = leader_scheduler.get_active_set(0, &bank);
assert_eq!(result, bootstrap_ids); assert_eq!(result, bootstrap_ids);
@ -933,17 +937,16 @@ pub mod tests {
let slots_per_epoch = num_validators; let slots_per_epoch = num_validators;
let active_window_tick_length = ticks_per_slot * slots_per_epoch; 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 // Create the bank and validators
let (genesis_block, mint_keypair) = GenesisBlock::new( let (genesis_block, mint_keypair) = GenesisBlock::new(
((((num_validators + 1) / 2) * (num_validators + 1)) ((((num_validators + 1) / 2) * (num_validators + 1))
+ (num_vote_account_tokens * num_validators)) as u64, + (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 mut validators = vec![];
let last_id = genesis_block.last_id(); let last_id = genesis_block.last_id();
for i in 0..num_validators { for i in 0..num_validators {
@ -980,7 +983,6 @@ pub mod tests {
// Generate schedule every active_window_tick_length entries and check that // Generate schedule every active_window_tick_length entries and check that
// validators are falling out of the rotation as they fall out of the // validators are falling out of the rotation as they fall out of the
// active set // active set
let mut leader_scheduler = leader_scheduler.write().unwrap();
trace!("bootstrap_leader_id: {}", genesis_block.bootstrap_leader_id); trace!("bootstrap_leader_id: {}", genesis_block.bootstrap_leader_id);
for i in 0..num_validators { for i in 0..num_validators {
trace!("validators[{}]: {}", i, validators[i as usize]); trace!("validators[{}]: {}", i, validators[i as usize]);
@ -1012,10 +1014,12 @@ pub mod tests {
let leader_id = leader_keypair.pubkey(); let leader_id = leader_keypair.pubkey();
let active_window_tick_length = 1000; let active_window_tick_length = 1000;
let (genesis_block, _mint_keypair) = GenesisBlock::new_with_leader(10000, leader_id, 500); 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_config = LeaderSchedulerConfig::new(100, 1, active_window_tick_length);
let leader_scheduler = let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::new_with_bank(
Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); &leader_scheduler_config,
let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); &bank,
)));
// Bootstrap leader should be in the active set even without explicit votes // 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 ticks_per_epoch = ticks_per_slot * slots_per_epoch;
let active_window_tick_length = 1; 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 // Check that the generate_schedule() function is being called by the
// update_tick_height() function at the correct entry heights. // update_tick_height() function at the correct entry heights.
let (genesis_block, _) = GenesisBlock::new(10_000); let (genesis_block, _) = GenesisBlock::new(10_000);
let bank = Bank::new_with_leader_scheduler(&genesis_block, leader_scheduler.clone()); let bank = Bank::new(&genesis_block);
let mut leader_scheduler = leader_scheduler.write().unwrap(); 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!( info!(
"bootstrap_leader_id: {:?}", "bootstrap_leader_id: {:?}",
genesis_block.bootstrap_leader_id genesis_block.bootstrap_leader_id
@ -1220,15 +1221,10 @@ pub mod tests {
let ticks_per_slot = 100; let ticks_per_slot = 100;
let active_window_tick_length = slots_per_epoch * ticks_per_slot; 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 // Create mint and bank
let (genesis_block, mint_keypair) = let (genesis_block, mint_keypair) =
GenesisBlock::new_with_leader(10_000, bootstrap_leader_id, BOOTSTRAP_LEADER_TOKENS); 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 last_id = genesis_block.last_id();
let initial_vote_height = 1; let initial_vote_height = 1;
@ -1291,7 +1287,10 @@ pub mod tests {
genesis_block.last_id(), 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); leader_scheduler.generate_schedule(0, &bank);
assert_eq!(leader_scheduler.current_epoch, 0); assert_eq!(leader_scheduler.current_epoch, 0);
assert_eq!(leader_scheduler.epoch_schedule[0], [bootstrap_leader_id]); assert_eq!(leader_scheduler.epoch_schedule[0], [bootstrap_leader_id]);

View File

@ -783,13 +783,12 @@ mod test {
} }
let genesis_block = GenesisBlock::new(10_000).0; 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 my_keypair = Arc::new(my_keypair);
let voting_keypair = Arc::new(VotingKeypair::new_local(&my_keypair)); let voting_keypair = Arc::new(VotingKeypair::new_local(&my_keypair));
let bank = Arc::new(Bank::new_with_leader_scheduler( let bank = Arc::new(Bank::new(&genesis_block));
&genesis_block, let leader_scheduler_config = LeaderSchedulerConfig::default();
leader_scheduler.clone(), 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( let res = ReplayStage::process_entries(
entries.clone(), entries.clone(),
&bank, &bank,
@ -812,10 +811,9 @@ mod test {
entries.push(entry); entries.push(entry);
} }
let bank = Arc::new(Bank::new_with_leader_scheduler( let bank = Arc::new(Bank::new(&genesis_block));
&genesis_block, let leader_scheduler = LeaderScheduler::new_with_bank(&leader_scheduler_config, &bank);
leader_scheduler.clone(), let leader_scheduler = Arc::new(RwLock::new(leader_scheduler));
));
let res = ReplayStage::process_entries( let res = ReplayStage::process_entries(
entries.clone(), entries.clone(),
&bank, &bank,

View File

@ -245,11 +245,10 @@ pub mod tests {
let starting_balance = 10_000; let starting_balance = 10_000;
let (genesis_block, _mint_keypair) = GenesisBlock::new(starting_balance); let (genesis_block, _mint_keypair) = GenesisBlock::new(starting_balance);
let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::default())); let bank = Arc::new(Bank::new(&genesis_block));
let bank = Arc::new(Bank::new_with_leader_scheduler( let leader_scheduler_config = LeaderSchedulerConfig::default();
&genesis_block, let leader_scheduler = LeaderScheduler::new_with_bank(&leader_scheduler_config, &bank);
leader_scheduler.clone(), let leader_scheduler = Arc::new(RwLock::new(leader_scheduler));
));
//start cluster_info1 //start cluster_info1
let mut cluster_info1 = ClusterInfo::new(target1.info.clone()); let mut cluster_info1 = ClusterInfo::new(target1.info.clone());
@ -340,12 +339,11 @@ pub mod tests {
let starting_balance = 10_000; let starting_balance = 10_000;
let (genesis_block, mint_keypair) = GenesisBlock::new(starting_balance); let (genesis_block, mint_keypair) = GenesisBlock::new(starting_balance);
let tvu_addr = target1.info.tvu; let tvu_addr = target1.info.tvu;
let leader_scheduler = let bank = Arc::new(Bank::new(&genesis_block));
Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))); let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::new_with_bank(
let bank = Arc::new(Bank::new_with_leader_scheduler( &leader_scheduler_config,
&genesis_block, &bank,
leader_scheduler.clone(), )));
));
assert_eq!(bank.get_balance(&mint_keypair.pubkey()), starting_balance); assert_eq!(bank.get_balance(&mint_keypair.pubkey()), starting_balance);
// start cluster_info1 // start cluster_info1