diff --git a/core/src/banking_stage.rs b/core/src/banking_stage.rs index f2de19a8a9c979..0770bef48d029b 100644 --- a/core/src/banking_stage.rs +++ b/core/src/banking_stage.rs @@ -897,8 +897,8 @@ pub(crate) fn update_bank_forks_and_poh_recorder_for_new_tpu_bank( // A write lock for the poh recorder must be grabbed for the entire duration of inserting new // tpu bank into the bank forks. That's because any buffered transactions could immediately be // executed after the bank forks update, when unified scheduler is enabled for block - // production. And then, the unified scheduler would be hit with false errors due to having no - // bank in the poh recorder otherwise. + // production. If transactions were executed prematurely, the unified scheduler would be hit + // with false errors due to having no bank in the poh recorder otherwise. let mut poh_recorder = poh_recorder.write().unwrap(); let tpu_bank = bank_forks diff --git a/core/src/validator.rs b/core/src/validator.rs index 6612196ebdbfd3..5f3f2cfb5b3f48 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -1439,6 +1439,18 @@ impl Validator { let cluster_slots = Arc::new(crate::cluster_slots_service::cluster_slots::ClusterSlots::default()); + // bank_forks could be write-locked temporarily here, if unified scheduler is enabled for + // block production. That's because the started ReplayStage inside Tvu could immediately + // try to insert a tpu bank into bank_forks, like with local development clusters + // consisting of a single staked node. Such insertion could be blocked with the lock held + // by unified scheduler until it's fully setup by the banking stage. This is needed, + // because completion of insertion needs to strictly correspond with the initiation of + // producing blocks in unified scheduler. + // As a consequence of this, there's a corner case where the banking stage hasn't called + // register_banking_stage() yet for unified scheduler because Tpu setup follows Tvu setup. + // This means any setup which accesses bank_forks must be done before or after the short + // duration of Tvu setup and Tpu setup to avoid deadlocks. So, RootBankCache must be setup + // here in advance as being one of such setups. let root_bank_cache = RootBankCache::new(bank_forks.clone()); let tvu = Tvu::new( vote_account,