Support local cluster edge case testing (#7135)

* Refactor local cluster to support killing a partition

* Rework run_network_partition

* Introduce fixed leader schedule

* Plumb fixed schedule into test
This commit is contained in:
carllin
2019-12-03 16:31:59 -08:00
committed by GitHub
parent f75c51ff71
commit f0a40862d6
10 changed files with 311 additions and 94 deletions

View File

@@ -3,6 +3,14 @@ use rand::SeedableRng;
use rand_chacha::ChaChaRng;
use solana_sdk::pubkey::Pubkey;
use std::ops::Index;
use std::sync::Arc;
// Used for testing
#[derive(Clone, Debug)]
pub struct FixedSchedule {
pub leader_schedule: Arc<LeaderSchedule>,
pub start_epoch: u64,
}
/// Stake-weighted leader schedule for one epoch.
#[derive(Debug, Default, PartialEq)]
@@ -30,9 +38,17 @@ impl LeaderSchedule {
Self { slot_leaders }
}
pub fn new_from_schedule(slot_leaders: Vec<Pubkey>) -> Self {
Self { slot_leaders }
}
pub fn get_slot_leaders(&self) -> &[Pubkey] {
&self.slot_leaders
}
pub fn num_slots(&self) -> usize {
self.slot_leaders.len()
}
}
impl Index<u64> for LeaderSchedule {

View File

@@ -1,4 +1,8 @@
use crate::{blocktree::Blocktree, leader_schedule::LeaderSchedule, leader_schedule_utils};
use crate::{
blocktree::Blocktree,
leader_schedule::{FixedSchedule, LeaderSchedule},
leader_schedule_utils,
};
use log::*;
use solana_runtime::bank::Bank;
use solana_sdk::{
@@ -28,6 +32,7 @@ pub struct LeaderScheduleCache {
epoch_schedule: EpochSchedule,
max_epoch: RwLock<Epoch>,
max_schedules: CacheCapacity,
fixed_schedule: Option<Arc<FixedSchedule>>,
}
impl LeaderScheduleCache {
@@ -41,6 +46,7 @@ impl LeaderScheduleCache {
epoch_schedule,
max_epoch: RwLock::new(0),
max_schedules: CacheCapacity::default(),
fixed_schedule: None,
};
// This sets the root and calculates the schedule at leader_schedule_epoch(root)
@@ -153,8 +159,17 @@ impl LeaderScheduleCache {
first_slot.map(|slot| (slot, last_slot))
}
pub fn set_fixed_leader_schedule(&mut self, fixed_schedule: Option<FixedSchedule>) {
self.fixed_schedule = fixed_schedule.map(Arc::new);
}
fn slot_leader_at_no_compute(&self, slot: Slot) -> Option<Pubkey> {
let (epoch, slot_index) = self.epoch_schedule.get_epoch_and_slot_index(slot);
if let Some(ref fixed_schedule) = self.fixed_schedule {
if epoch >= fixed_schedule.start_epoch {
return Some(fixed_schedule.leader_schedule[slot_index]);
}
}
self.cached_schedules
.read()
.unwrap()
@@ -191,6 +206,11 @@ impl LeaderScheduleCache {
epoch: Epoch,
bank: &Bank,
) -> Option<Arc<LeaderSchedule>> {
if let Some(ref fixed_schedule) = self.fixed_schedule {
if epoch >= fixed_schedule.start_epoch {
return Some(fixed_schedule.leader_schedule.clone());
}
}
let epoch_schedule = self.cached_schedules.read().unwrap().0.get(&epoch).cloned();
if epoch_schedule.is_some() {