diff --git a/core/src/replay_stage.rs b/core/src/replay_stage.rs index db040aae6548d3..c8bd0b9b113545 100644 --- a/core/src/replay_stage.rs +++ b/core/src/replay_stage.rs @@ -4527,7 +4527,9 @@ pub(crate) mod tests { replay_stage::ReplayStage, vote_simulator::{self, VoteSimulator}, }, - blockstore_processor::{fill_blockstore_slot_with_ticks, ProcessOptions}, + blockstore_processor::{ + confirm_full_slot, fill_blockstore_slot_with_ticks, process_bank_0, ProcessOptions, + }, crossbeam_channel::unbounded, itertools::Itertools, solana_entry::entry::{self, Entry}, @@ -9042,6 +9044,7 @@ pub(crate) mod tests { #[test] fn test_initialize_progress_and_fork_choice_with_duplicates() { + solana_logger::setup(); let GenesisConfigInfo { mut genesis_config, .. } = create_genesis_config(123); @@ -9056,28 +9059,72 @@ pub(crate) mod tests { Bank forks with: slot 0 | - slot 1 -> Duplicate before restart + slot 1 -> Duplicate before restart, the restart slot + | + slot 2 + | + slot 3 -> Duplicate before restart, artificially rooted + | + slot 4 -> Duplicate before restart, artificially rooted + | + slot 5 -> Duplicate before restart + | + slot 6 */ let mut last_hash = blockhash; - for i in 0..1 { + for i in 0..6 { last_hash = fill_blockstore_slot_with_ticks(&blockstore, ticks_per_slot, i + 1, i, last_hash); } - blockstore.set_roots([0, 1].iter()).unwrap(); + // Artifically root + blockstore.set_roots([3, 4].iter()).unwrap(); // Set up bank0 let bank_forks = BankForks::new_rw_arc(Bank::new_for_tests(&genesis_config)); let bank0 = bank_forks.read().unwrap().get_with_scheduler(0).unwrap(); + let recyclers = VerifyRecyclers::default(); + let replay_tx_thread_pool = rayon::ThreadPoolBuilder::new() + .num_threads(1) + .thread_name(|i| format!("solReplayTx{i:02}")) + .build() + .expect("new rayon threadpool"); + + process_bank_0( + &bank0, + &blockstore, + &replay_tx_thread_pool, + &ProcessOptions::default(), + &recyclers, + None, + None, + ); - // Mark block 1 as duplicate + // Mark block 1, 3 , 4, 5 as duplicate blockstore.store_duplicate_slot(1, vec![], vec![]).unwrap(); + blockstore.store_duplicate_slot(3, vec![], vec![]).unwrap(); + blockstore.store_duplicate_slot(4, vec![], vec![]).unwrap(); + blockstore.store_duplicate_slot(5, vec![], vec![]).unwrap(); let bank1 = bank_forks.write().unwrap().insert(Bank::new_from_parent( bank0.clone_without_scheduler(), &Pubkey::default(), 1, )); + confirm_full_slot( + &blockstore, + &bank1, + &replay_tx_thread_pool, + &ProcessOptions::default(), + &recyclers, + &mut ConfirmationProgress::new(bank0.last_blockhash()), + None, + None, + None, + &mut ExecuteTimings::default(), + ) + .unwrap(); + bank_forks .write() .unwrap() @@ -9090,7 +9137,7 @@ pub(crate) mod tests { let leader_schedule_cache = LeaderScheduleCache::new_from_bank(&bank1); - // process_blockstore_from_root() from slot 1 onwards, should remove the duplicate proof from before the restart + // process_blockstore_from_root() from slot 1 onwards blockstore_processor::process_blockstore_from_root( &blockstore, &bank_forks, @@ -9103,7 +9150,9 @@ pub(crate) mod tests { ) .unwrap(); - // Verify that the duplicate information has been cleared and that fork choice can be initialized + assert_eq!(bank_forks.read().unwrap().root(), 4); + + // Verify that fork choice can be initialized and that the root is not marked duplicate let (_progress, fork_choice) = ReplayStage::initialize_progress_and_fork_choice_with_locked_bank_forks( &bank_forks, @@ -9112,7 +9161,16 @@ pub(crate) mod tests { &blockstore, ); - assert_eq!(fork_choice.tree_root().0, 1); - assert_eq!(fork_choice.best_overall_slot().0, 1); + let bank_forks = bank_forks.read().unwrap(); + // 4 (the artificial root) is the tree root and no longer duplicate + assert_eq!(fork_choice.tree_root().0, 4); + assert!(fork_choice + .is_candidate(&(4, bank_forks.bank_hash(4).unwrap())) + .unwrap()); + + // 5 is still duplicate, + assert!(!fork_choice + .is_candidate(&(5, bank_forks.bank_hash(5).unwrap())) + .unwrap()); } } diff --git a/ledger/src/blockstore_processor.rs b/ledger/src/blockstore_processor.rs index 9866ad2291f928..2c660cbcc51c08 100644 --- a/ledger/src/blockstore_processor.rs +++ b/ledger/src/blockstore_processor.rs @@ -1078,7 +1078,7 @@ fn verify_ticks( } #[allow(clippy::too_many_arguments)] -fn confirm_full_slot( +pub fn confirm_full_slot( blockstore: &Blockstore, bank: &BankWithScheduler, replay_tx_thread_pool: &ThreadPool, @@ -1684,7 +1684,7 @@ fn confirm_slot_entries( } // Special handling required for processing the entries in slot 0 -fn process_bank_0( +pub fn process_bank_0( bank0: &BankWithScheduler, blockstore: &Blockstore, replay_tx_thread_pool: &ThreadPool,