Eliminate BankForksInfo (#9887)

This commit is contained in:
Michael Vines 2020-05-06 08:24:59 -07:00 committed by GitHub
parent e951f8d0ed
commit 09ae61651a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 155 additions and 206 deletions

View File

@ -298,7 +298,7 @@ mod tests {
full_leader_cache: true,
..ProcessOptions::default()
};
let (bank_forks, _, cached_leader_schedule) =
let (bank_forks, cached_leader_schedule) =
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
let leader_schedule_cache = Arc::new(cached_leader_schedule);
let bank_forks = Arc::new(RwLock::new(bank_forks));

View File

@ -28,8 +28,7 @@ use solana_ledger::{
bank_forks::{BankForks, SnapshotConfig},
bank_forks_utils,
blockstore::{Blockstore, CompletedSlotsReceiver},
blockstore_processor::{self, BankForksInfo},
create_new_tmp_ledger,
blockstore_processor, create_new_tmp_ledger,
hardened_unpack::{open_genesis_config, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE},
leader_schedule::FixedSchedule,
leader_schedule_cache::LeaderScheduleCache,
@ -187,7 +186,6 @@ impl Validator {
let (
genesis_config,
bank_forks,
bank_forks_info,
blockstore,
ledger_signal_receiver,
completed_slots_receiver,
@ -197,8 +195,8 @@ impl Validator {
let leader_schedule_cache = Arc::new(leader_schedule_cache);
let exit = Arc::new(AtomicBool::new(false));
let bank_info = &bank_forks_info[0];
let bank = bank_forks[bank_info.bank_slot].clone();
let bank = bank_forks.working_bank();
let bank_forks = Arc::new(RwLock::new(bank_forks));
info!("Starting validator from slot {}", bank.slot());
{
@ -208,8 +206,6 @@ impl Validator {
}
}
let bank_forks = Arc::new(RwLock::new(bank_forks));
let mut validator_exit = ValidatorExit::default();
let exit_ = exit.clone();
validator_exit.register_exit(Box::new(move || exit_.store(true, Ordering::Relaxed)));
@ -564,7 +560,6 @@ fn new_banks_from_blockstore(
) -> (
GenesisConfig,
BankForks,
Vec<BankForksInfo>,
Blockstore,
Receiver<bool>,
CompletedSlotsReceiver,
@ -607,18 +602,17 @@ fn new_banks_from_blockstore(
..blockstore_processor::ProcessOptions::default()
};
let (mut bank_forks, bank_forks_info, mut leader_schedule_cache, snapshot_hash) =
bank_forks_utils::load(
&genesis_config,
&blockstore,
config.account_paths.clone(),
config.snapshot_config.as_ref(),
process_options,
)
.unwrap_or_else(|err| {
error!("Failed to load ledger: {:?}", err);
std::process::exit(1);
});
let (mut bank_forks, mut leader_schedule_cache, snapshot_hash) = bank_forks_utils::load(
&genesis_config,
&blockstore,
config.account_paths.clone(),
config.snapshot_config.as_ref(),
process_options,
)
.unwrap_or_else(|err| {
error!("Failed to load ledger: {:?}", err);
std::process::exit(1);
});
leader_schedule_cache.set_fixed_leader_schedule(config.fixed_leader_schedule.clone());
@ -628,7 +622,6 @@ fn new_banks_from_blockstore(
(
genesis_config,
bank_forks,
bank_forks_info,
blockstore,
ledger_signal_receiver,
completed_slots_receiver,

View File

@ -10,7 +10,7 @@ use solana_ledger::{
bank_forks_utils,
blockstore::Blockstore,
blockstore_db::{self, Column, Database},
blockstore_processor::{BankForksInfo, ProcessOptions},
blockstore_processor::ProcessOptions,
hardened_unpack::{open_genesis_config, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE},
rooted_slot_iterator::RootedSlotIterator,
snapshot_utils,
@ -192,15 +192,19 @@ fn render_dot(dot: String, output_file: &str, output_format: &str) -> io::Result
}
#[allow(clippy::cognitive_complexity)]
fn graph_forks(
bank_forks: &BankForks,
bank_forks_info: &[BankForksInfo],
include_all_votes: bool,
) -> String {
fn graph_forks(bank_forks: &BankForks, include_all_votes: bool) -> String {
let frozen_banks = bank_forks.frozen_banks();
let mut fork_slots: HashSet<_> = frozen_banks.keys().cloned().collect();
for (_, bank) in frozen_banks {
for parent in bank.parents() {
fork_slots.remove(&parent.slot());
}
}
// Search all forks and collect the last vote made by each validator
let mut last_votes = HashMap::new();
for bfi in bank_forks_info {
let bank = bank_forks.banks.get(&bfi.bank_slot).unwrap();
for fork_slot in &fork_slots {
let bank = &bank_forks[*fork_slot];
let total_stake = bank
.vote_accounts()
@ -241,9 +245,8 @@ fn graph_forks(
dot.push(" style=invis".to_string());
let mut styled_slots = HashSet::new();
let mut all_votes: HashMap<Pubkey, HashMap<Slot, VoteState>> = HashMap::new();
for bfi in bank_forks_info {
let bank = bank_forks.banks.get(&bfi.bank_slot).unwrap();
let mut bank = bank.clone();
for fork_slot in &fork_slots {
let mut bank = bank_forks[*fork_slot].clone();
let mut first = true;
loop {
@ -885,15 +888,12 @@ fn main() {
};
let genesis_config = open_genesis_config_by(&ledger_path, arg_matches);
match load_bank_forks(arg_matches, &ledger_path, &genesis_config, process_options) {
Ok((bank_forks, bank_forks_info, _leader_schedule_cache, _snapshot_hash)) => {
let bank_info = &bank_forks_info[0];
let bank = bank_forks[bank_info.bank_slot].clone();
Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => {
println!(
"{}",
compute_shred_version(
&genesis_config.hash(),
Some(&bank.hard_forks().read().unwrap())
Some(&bank_forks.working_bank().hard_forks().read().unwrap())
)
);
}
@ -979,12 +979,8 @@ fn main() {
&open_genesis_config_by(&ledger_path, arg_matches),
process_options,
) {
Ok((bank_forks, bank_forks_info, _leader_schedule_cache, _snapshot_hash)) => {
let dot = graph_forks(
&bank_forks,
&bank_forks_info,
arg_matches.is_present("include_all_votes"),
);
Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => {
let dot = graph_forks(&bank_forks, arg_matches.is_present("include_all_votes"));
let extension = Path::new(&output_file).extension();
let result = if extension == Some(OsStr::new("pdf")) {
@ -1019,7 +1015,7 @@ fn main() {
};
let genesis_config = open_genesis_config_by(&ledger_path, arg_matches);
match load_bank_forks(arg_matches, &ledger_path, &genesis_config, process_options) {
Ok((bank_forks, _bank_forks_info, _leader_schedule_cache, _snapshot_hash)) => {
Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => {
let bank = bank_forks.get(snapshot_slot).unwrap_or_else(|| {
eprintln!("Error: Slot {} is not available", snapshot_slot);
exit(1);
@ -1084,15 +1080,8 @@ fn main() {
let genesis_config = open_genesis_config_by(&ledger_path, arg_matches);
let include_sysvars = arg_matches.is_present("include_sysvars");
match load_bank_forks(arg_matches, &ledger_path, &genesis_config, process_options) {
Ok((bank_forks, bank_forks_info, _leader_schedule_cache, _snapshot_hash)) => {
let slot = dev_halt_at_slot.unwrap_or_else(|| {
if bank_forks_info.len() > 1 {
eprintln!("Error: multiple forks present");
exit(1);
}
bank_forks_info[0].bank_slot
});
Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => {
let slot = bank_forks.working_bank().slot();
let bank = bank_forks.get(slot).unwrap_or_else(|| {
eprintln!("Error: Slot {} is not available", slot);
exit(1);

View File

@ -143,7 +143,13 @@ impl BankForks {
pub fn new_from_banks(initial_forks: &[Arc<Bank>], root: Slot) -> Self {
let mut banks = HashMap::new();
let working_bank = initial_forks[0].clone();
// Set working bank to the highest available bank
let working_bank = initial_forks
.iter()
.max_by(|a, b| a.slot().cmp(&b.slot()))
.expect("working bank")
.clone();
// Iterate through the heads of all the different forks
for bank in initial_forks {
@ -375,7 +381,7 @@ mod tests {
use solana_sdk::pubkey::Pubkey;
#[test]
fn test_bank_forks() {
fn test_bank_forks_new() {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Bank::new(&genesis_config);
let mut bank_forks = BankForks::new(0, bank);
@ -386,6 +392,21 @@ mod tests {
assert_eq!(bank_forks.working_bank().tick_height(), 1);
}
#[test]
fn test_bank_forks_new_from_banks() {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
let bank = Arc::new(Bank::new(&genesis_config));
let child_bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), 1));
let bank_forks = BankForks::new_from_banks(&[bank.clone(), child_bank.clone()], 0);
assert_eq!(bank_forks.root(), 0);
assert_eq!(bank_forks.working_bank().slot(), 1);
let bank_forks = BankForks::new_from_banks(&[child_bank.clone(), bank.clone()], 0);
assert_eq!(bank_forks.root(), 0);
assert_eq!(bank_forks.working_bank().slot(), 1);
}
#[test]
fn test_bank_forks_descendants() {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);

View File

@ -2,7 +2,7 @@ use crate::{
bank_forks::{BankForks, SnapshotConfig},
blockstore::Blockstore,
blockstore_processor::{
self, BankForksInfo, BlockstoreProcessorError, BlockstoreProcessorResult, ProcessOptions,
self, BlockstoreProcessorError, BlockstoreProcessorResult, ProcessOptions,
},
entry::VerifyRecyclers,
leader_schedule_cache::LeaderScheduleCache,
@ -13,12 +13,7 @@ use solana_sdk::{clock::Slot, genesis_config::GenesisConfig, hash::Hash};
use std::{fs, path::PathBuf, process, result, sync::Arc};
pub type LoadResult = result::Result<
(
BankForks,
Vec<BankForksInfo>,
LeaderScheduleCache,
Option<(Slot, Hash)>,
),
(BankForks, LeaderScheduleCache, Option<(Slot, Hash)>),
BlockstoreProcessorError,
>;
@ -26,13 +21,8 @@ fn to_loadresult(
brp: BlockstoreProcessorResult,
snapshot_hash: Option<(Slot, Hash)>,
) -> LoadResult {
brp.map(|(bank_forks, bank_forks_info, leader_schedule_cache)| {
(
bank_forks,
bank_forks_info,
leader_schedule_cache,
snapshot_hash,
)
brp.map(|(bank_forks, leader_schedule_cache)| {
(bank_forks, leader_schedule_cache, snapshot_hash)
})
}

View File

@ -39,7 +39,7 @@ use std::{
use thiserror::Error;
pub type BlockstoreProcessorResult =
result::Result<(BankForks, Vec<BankForksInfo>, LeaderScheduleCache), BlockstoreProcessorError>;
result::Result<(BankForks, LeaderScheduleCache), BlockstoreProcessorError>;
thread_local!(static PAR_THREAD_POOL: RefCell<ThreadPool> = RefCell::new(rayon::ThreadPoolBuilder::new()
.num_threads(get_thread_count())
@ -235,11 +235,6 @@ fn process_entries_with_callback(
Ok(())
}
#[derive(Debug, PartialEq)]
pub struct BankForksInfo {
pub bank_slot: u64,
}
#[derive(Error, Debug)]
pub enum BlockstoreProcessorError {
#[error("failed to load entries")]
@ -351,17 +346,18 @@ pub fn process_blockstore_from_root(
}
}
let meta = blockstore.meta(start_slot).unwrap();
// Iterate and replay slots from blockstore starting from `start_slot`
let (bank_forks, bank_forks_info, leader_schedule_cache) = {
if let Some(meta) = meta {
let (initial_forks, leader_schedule_cache) = {
if let Some(meta) = blockstore
.meta(start_slot)
.unwrap_or_else(|_| panic!("Failed to get meta for slot {}", start_slot))
{
let epoch_schedule = bank.epoch_schedule();
let mut leader_schedule_cache = LeaderScheduleCache::new(*epoch_schedule, &bank);
if opts.full_leader_cache {
leader_schedule_cache.set_max_schedules(std::usize::MAX);
}
let fork_info = process_pending_slots(
let initial_forks = load_frozen_forks(
&bank,
&meta,
blockstore,
@ -370,35 +366,30 @@ pub fn process_blockstore_from_root(
opts,
recyclers,
)?;
let (banks, bank_forks_info): (Vec<_>, Vec<_>) =
fork_info.into_iter().map(|(_, v)| v).unzip();
if banks.is_empty() {
return Err(BlockstoreProcessorError::NoValidForksFound);
}
let bank_forks = BankForks::new_from_banks(&banks, root);
(bank_forks, bank_forks_info, leader_schedule_cache)
(initial_forks, leader_schedule_cache)
} else {
// If there's no meta for the input `start_slot`, then we started from a snapshot
// and there's no point in processing the rest of blockstore and implies blockstore
// should be empty past this point.
let bfi = BankForksInfo {
bank_slot: start_slot,
};
let leader_schedule_cache = LeaderScheduleCache::new_from_bank(&bank);
let bank_forks = BankForks::new_from_banks(&[bank], root);
(bank_forks, vec![bfi], leader_schedule_cache)
(vec![bank], leader_schedule_cache)
}
};
if initial_forks.is_empty() {
return Err(BlockstoreProcessorError::NoValidForksFound);
}
let bank_forks = BankForks::new_from_banks(&initial_forks, root);
info!(
"ledger processed in {}ms. {} MB allocated. {} fork{} at {}, with {} frozen bank{}",
"ledger processed in {}ms. {} MB allocated. root={}, {} fork{} at {}, with {} frozen bank{}",
duration_as_ms(&now.elapsed()),
allocated.since(initial_allocation) / 1_000_000,
bank_forks_info.len(),
if bank_forks_info.len() > 1 { "s" } else { "" },
bank_forks_info
bank_forks.root(),
initial_forks.len(),
if initial_forks.len() > 1 { "s" } else { "" },
initial_forks
.iter()
.map(|bfi| bfi.bank_slot.to_string())
.map(|b| b.slot().to_string())
.join(", "),
bank_forks.frozen_banks().len(),
if bank_forks.frozen_banks().len() > 1 {
@ -409,7 +400,7 @@ pub fn process_blockstore_from_root(
);
assert!(bank_forks.active_banks().is_empty());
Ok((bank_forks, bank_forks_info, leader_schedule_cache))
Ok((bank_forks, leader_schedule_cache))
}
/// Verify that a segment of entries has the correct number of ticks and hashes
@ -645,15 +636,12 @@ fn process_next_slots(
blockstore: &Blockstore,
leader_schedule_cache: &LeaderScheduleCache,
pending_slots: &mut Vec<(SlotMeta, Arc<Bank>, Hash)>,
fork_info: &mut HashMap<u64, (Arc<Bank>, BankForksInfo)>,
initial_forks: &mut HashMap<Slot, Arc<Bank>>,
) -> result::Result<(), BlockstoreProcessorError> {
if let Some(parent) = bank.parent() {
fork_info.remove(&parent.slot());
initial_forks.remove(&parent.slot());
}
let bfi = BankForksInfo {
bank_slot: bank.slot(),
};
fork_info.insert(bank.slot(), (bank.clone(), bfi));
initial_forks.insert(bank.slot(), bank.clone());
if meta.next_slots.is_empty() {
return Ok(());
@ -698,8 +686,8 @@ fn process_next_slots(
}
// Iterate through blockstore processing slots starting from the root slot pointed to by the
// given `meta`
fn process_pending_slots(
// given `meta` and return a vector of frozen bank forks
fn load_frozen_forks(
root_bank: &Arc<Bank>,
root_meta: &SlotMeta,
blockstore: &Blockstore,
@ -707,8 +695,8 @@ fn process_pending_slots(
root: &mut Slot,
opts: &ProcessOptions,
recyclers: &VerifyRecyclers,
) -> result::Result<HashMap<u64, (Arc<Bank>, BankForksInfo)>, BlockstoreProcessorError> {
let mut fork_info = HashMap::new();
) -> result::Result<Vec<Arc<Bank>>, BlockstoreProcessorError> {
let mut initial_forks = HashMap::new();
let mut last_status_report = Instant::now();
let mut pending_slots = vec![];
let mut last_root_slot = root_bank.slot();
@ -720,7 +708,7 @@ fn process_pending_slots(
blockstore,
leader_schedule_cache,
&mut pending_slots,
&mut fork_info,
&mut initial_forks,
)?;
let dev_halt_at_slot = opts.dev_halt_at_slot.unwrap_or(std::u64::MAX);
@ -756,7 +744,7 @@ fn process_pending_slots(
leader_schedule_cache.set_root(&bank);
bank.squash();
pending_slots.clear();
fork_info.clear();
initial_forks.clear();
last_root_slot = slot;
}
slots_elapsed += 1;
@ -774,7 +762,7 @@ fn process_pending_slots(
blockstore,
leader_schedule_cache,
&mut pending_slots,
&mut fork_info,
&mut initial_forks,
)?;
if slot >= dev_halt_at_slot {
@ -782,7 +770,7 @@ fn process_pending_slots(
}
}
Ok(fork_info)
Ok(initial_forks.values().cloned().collect::<Vec<_>>())
}
// Processes and replays the contents of a single slot, returns Error
@ -926,7 +914,7 @@ pub mod tests {
Ok(_)
);
let (_bank_forks, bank_forks_info, _) = process_blockstore(
let (bank_forks, _leader_schedule) = process_blockstore(
&genesis_config,
&blockstore,
Vec::new(),
@ -936,7 +924,7 @@ pub mod tests {
},
)
.unwrap();
assert_eq!(bank_forks_info, vec![BankForksInfo { bank_slot: 0 }]);
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
}
#[test]
@ -970,7 +958,7 @@ pub mod tests {
);
// Should return slot 0, the last slot on the fork that is valid
let (_bank_forks, bank_forks_info, _) = process_blockstore(
let (bank_forks, _leader_schedule) = process_blockstore(
&genesis_config,
&blockstore,
Vec::new(),
@ -980,13 +968,13 @@ pub mod tests {
},
)
.unwrap();
assert_eq!(bank_forks_info, vec![BankForksInfo { bank_slot: 0 }]);
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
// Write slot 2 fully
let _last_slot2_entry_hash =
fill_blockstore_slot_with_ticks(&blockstore, ticks_per_slot, 2, 0, blockhash);
let (_bank_forks, bank_forks_info, _) = process_blockstore(
let (bank_forks, _leader_schedule) = process_blockstore(
&genesis_config,
&blockstore,
Vec::new(),
@ -998,7 +986,9 @@ pub mod tests {
.unwrap();
// One valid fork, one bad fork. process_blockstore() should only return the valid fork
assert_eq!(bank_forks_info, vec![BankForksInfo { bank_slot: 2 }]);
assert_eq!(frozen_bank_slots(&bank_forks), vec![0, 2]);
assert_eq!(bank_forks.working_bank().slot(), 2);
assert_eq!(bank_forks.root(), 0);
}
#[test]
@ -1046,9 +1036,9 @@ pub mod tests {
poh_verify: true,
..ProcessOptions::default()
};
let (_bank_forks, bank_forks_info, _) =
let (bank_forks, _leader_schedule) =
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
assert_eq!(bank_forks_info, vec![BankForksInfo { bank_slot: 0 }]);
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
}
#[test]
@ -1111,16 +1101,10 @@ pub mod tests {
poh_verify: true,
..ProcessOptions::default()
};
let (mut _bank_forks, bank_forks_info, _) =
let (bank_forks, _leader_schedule) =
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts.clone()).unwrap();
assert_eq!(bank_forks_info.len(), 1);
assert_eq!(
bank_forks_info[0],
BankForksInfo {
bank_slot: 0, // slot 1 isn't "full", we stop at slot zero
}
);
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]); // slot 1 isn't "full", we stop at slot zero
/* Add a complete slot such that the store looks like:
@ -1136,16 +1120,11 @@ pub mod tests {
};
fill_blockstore_slot_with_ticks(&blockstore, ticks_per_slot, 3, 0, blockhash);
// Slot 0 should not show up in the ending bank_forks_info
let (mut _bank_forks, bank_forks_info, _) =
let (bank_forks, _leader_schedule) =
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
assert_eq!(bank_forks_info.len(), 1);
assert_eq!(
bank_forks_info[0],
BankForksInfo {
bank_slot: 3, // slot 1 isn't "full", we stop at slot zero
}
);
// slot 1 isn't "full", we stop at slot zero
assert_eq!(frozen_bank_slots(&bank_forks), vec![0, 3]);
}
#[test]
@ -1208,17 +1187,12 @@ pub mod tests {
poh_verify: true,
..ProcessOptions::default()
};
let (bank_forks, bank_forks_info, _) =
let (bank_forks, _leader_schedule) =
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
assert_eq!(bank_forks_info.len(), 1); // One fork, other one is ignored b/c not a descendant of the root
// One fork, other one is ignored b/c not a descendant of the root
assert_eq!(frozen_bank_slots(&bank_forks), vec![4]);
assert_eq!(
bank_forks_info[0],
BankForksInfo {
bank_slot: 4, // Fork 2's head is slot 4
}
);
assert!(&bank_forks[4]
.parents()
.iter()
@ -1227,7 +1201,7 @@ pub mod tests {
.is_empty());
// Ensure bank_forks holds the right banks
verify_fork_infos(&bank_forks, &bank_forks_info);
verify_fork_infos(&bank_forks);
assert_eq!(bank_forks.root(), 4);
}
@ -1292,17 +1266,13 @@ pub mod tests {
poh_verify: true,
..ProcessOptions::default()
};
let (bank_forks, mut bank_forks_info, _) =
let (bank_forks, _leader_schedule) =
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
bank_forks_info.sort_by(|a, b| a.bank_slot.cmp(&b.bank_slot));
assert_eq!(bank_forks_info.len(), 2); // There are two forks
assert_eq!(
bank_forks_info[0],
BankForksInfo {
bank_slot: 3, // Fork 1's head is slot 3
}
);
assert_eq!(frozen_bank_slots(&bank_forks), vec![1, 2, 3, 4]);
assert_eq!(bank_forks.working_bank().slot(), 4);
assert_eq!(bank_forks.root(), 1);
assert_eq!(
&bank_forks[3]
.parents()
@ -1311,12 +1281,6 @@ pub mod tests {
.collect::<Vec<_>>(),
&[2, 1]
);
assert_eq!(
bank_forks_info[1],
BankForksInfo {
bank_slot: 4, // Fork 2's head is slot 4
}
);
assert_eq!(
&bank_forks[4]
.parents()
@ -1329,7 +1293,7 @@ pub mod tests {
assert_eq!(bank_forks.root(), 1);
// Ensure bank_forks holds the right banks
verify_fork_infos(&bank_forks, &bank_forks_info);
verify_fork_infos(&bank_forks);
}
#[test]
@ -1358,7 +1322,7 @@ pub mod tests {
blockstore.set_dead_slot(2).unwrap();
fill_blockstore_slot_with_ticks(&blockstore, ticks_per_slot, 3, 1, slot1_blockhash);
let (bank_forks, bank_forks_info, _) = process_blockstore(
let (bank_forks, _leader_schedule) = process_blockstore(
&genesis_config,
&blockstore,
Vec::new(),
@ -1366,8 +1330,8 @@ pub mod tests {
)
.unwrap();
assert_eq!(bank_forks_info.len(), 1);
assert_eq!(bank_forks_info[0], BankForksInfo { bank_slot: 3 });
assert_eq!(frozen_bank_slots(&bank_forks), vec![0, 1, 3]);
assert_eq!(bank_forks.working_bank().slot(), 3);
assert_eq!(
&bank_forks[3]
.parents()
@ -1376,7 +1340,7 @@ pub mod tests {
.collect::<Vec<_>>(),
&[1, 0]
);
verify_fork_infos(&bank_forks, &bank_forks_info);
verify_fork_infos(&bank_forks);
}
#[test]
@ -1407,7 +1371,7 @@ pub mod tests {
blockstore.set_dead_slot(4).unwrap();
fill_blockstore_slot_with_ticks(&blockstore, ticks_per_slot, 3, 1, slot1_blockhash);
let (bank_forks, mut bank_forks_info, _) = process_blockstore(
let (bank_forks, _leader_schedule) = process_blockstore(
&genesis_config,
&blockstore,
Vec::new(),
@ -1415,12 +1379,10 @@ pub mod tests {
)
.unwrap();
bank_forks_info.sort_by(|a, b| a.bank_slot.cmp(&b.bank_slot));
assert_eq!(bank_forks_info.len(), 2);
// Should see the parent of the dead child
assert_eq!(bank_forks_info[0], BankForksInfo { bank_slot: 2 },);
assert_eq!(bank_forks_info[1], BankForksInfo { bank_slot: 3 },);
assert_eq!(frozen_bank_slots(&bank_forks), vec![0, 1, 2, 3]);
assert_eq!(bank_forks.working_bank().slot(), 3);
assert_eq!(
&bank_forks[3]
.parents()
@ -1437,7 +1399,8 @@ pub mod tests {
.collect::<Vec<_>>(),
&[1, 0]
);
verify_fork_infos(&bank_forks, &bank_forks_info);
assert_eq!(bank_forks.working_bank().slot(), 3);
verify_fork_infos(&bank_forks);
}
#[test]
@ -1460,7 +1423,7 @@ pub mod tests {
fill_blockstore_slot_with_ticks(&blockstore, ticks_per_slot, 2, 0, blockhash);
blockstore.set_dead_slot(1).unwrap();
blockstore.set_dead_slot(2).unwrap();
let (bank_forks, bank_forks_info, _) = process_blockstore(
let (bank_forks, _leader_schedule) = process_blockstore(
&genesis_config,
&blockstore,
Vec::new(),
@ -1469,9 +1432,8 @@ pub mod tests {
.unwrap();
// Should see only the parent of the dead children
assert_eq!(bank_forks_info.len(), 1);
assert_eq!(bank_forks_info[0], BankForksInfo { bank_slot: 0 },);
verify_fork_infos(&bank_forks, &bank_forks_info);
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
verify_fork_infos(&bank_forks);
}
#[test]
@ -1515,16 +1477,11 @@ pub mod tests {
poh_verify: true,
..ProcessOptions::default()
};
let (bank_forks, bank_forks_info, _) =
let (bank_forks, _leader_schedule) =
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
assert_eq!(bank_forks_info.len(), 1); // There is one fork
assert_eq!(
bank_forks_info[0],
BankForksInfo {
bank_slot: last_slot + 1, // Head is last_slot + 1
}
);
// There is one fork, head is last_slot + 1
assert_eq!(frozen_bank_slots(&bank_forks), vec![last_slot + 1]);
// The latest root should have purged all its parents
assert!(&bank_forks[last_slot + 1]
@ -1663,12 +1620,12 @@ pub mod tests {
poh_verify: true,
..ProcessOptions::default()
};
let (bank_forks, bank_forks_info, _) =
let (bank_forks, _leader_schedule) =
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
assert_eq!(bank_forks_info.len(), 1);
assert_eq!(frozen_bank_slots(&bank_forks), vec![0, 1]);
assert_eq!(bank_forks.root(), 0);
assert_eq!(bank_forks_info[0], BankForksInfo { bank_slot: 1 });
assert_eq!(bank_forks.working_bank().slot(), 1);
let bank = bank_forks[1].clone();
assert_eq!(
@ -1692,11 +1649,10 @@ pub mod tests {
poh_verify: true,
..ProcessOptions::default()
};
let (bank_forks, bank_forks_info, _) =
let (bank_forks, _leader_schedule) =
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
assert_eq!(bank_forks_info.len(), 1);
assert_eq!(bank_forks_info[0], BankForksInfo { bank_slot: 0 });
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
let bank = bank_forks[0].clone();
assert_eq!(bank.tick_height(), 1);
}
@ -1727,9 +1683,9 @@ pub mod tests {
full_leader_cache: true,
..ProcessOptions::default()
};
let (_bank_forks, _bank_forks_info, cached_leader_schedule) =
let (_bank_forks, leader_schedule) =
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
assert_eq!(cached_leader_schedule.max_schedules(), std::usize::MAX);
assert_eq!(leader_schedule.max_schedules(), std::usize::MAX);
}
#[test]
@ -2464,17 +2420,12 @@ pub mod tests {
bank1.squash();
// Test process_blockstore_from_root() from slot 1 onwards
let (bank_forks, bank_forks_info, _) =
let (bank_forks, _leader_schedule) =
process_blockstore_from_root(&genesis_config, &blockstore, bank1, &opts, &recyclers)
.unwrap();
assert_eq!(bank_forks_info.len(), 1); // One fork
assert_eq!(
bank_forks_info[0],
BankForksInfo {
bank_slot: 6, // The head of the fork is slot 6
}
);
assert_eq!(frozen_bank_slots(&bank_forks), vec![5, 6]);
assert_eq!(bank_forks.working_bank().slot(), 6);
assert_eq!(bank_forks.root(), 5);
// Verify the parents of the head of the fork
@ -2488,7 +2439,7 @@ pub mod tests {
);
// Check that bank forks has the correct banks
verify_fork_infos(&bank_forks, &bank_forks_info);
verify_fork_infos(&bank_forks);
}
#[test]
@ -2636,12 +2587,17 @@ pub mod tests {
bank.epoch_schedule().clone()
}
fn frozen_bank_slots(bank_forks: &BankForks) -> Vec<Slot> {
let mut slots: Vec<_> = bank_forks.frozen_banks().keys().cloned().collect();
slots.sort();
slots
}
// Check that `bank_forks` contains all the ancestors and banks for each fork identified in
// `bank_forks_info`
fn verify_fork_infos(bank_forks: &BankForks, bank_forks_info: &[BankForksInfo]) {
for fork in bank_forks_info {
let head_slot = fork.bank_slot;
let head_bank = &bank_forks[head_slot];
fn verify_fork_infos(bank_forks: &BankForks) {
for slot in frozen_bank_slots(bank_forks) {
let head_bank = &bank_forks[slot];
let mut parents = head_bank.parents();
parents.push(head_bank.clone());