From 23c2e55cbf00ee339380e5b28c3b1a7629cd927b Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Mon, 20 Jul 2020 17:03:40 -0600 Subject: [PATCH] Use BlockCommitmentCache for RPC slots, take 2 (#11137) * Use BlockCommitmentCache for RPC slots (#11103) * Add BankForks::highest_descendant(slot) * Update debug messages * Update core/src/rpc.rs Co-authored-by: Tyera Eulberg * cargo fmt * Remove highest_descendant * Fix test Co-authored-by: Tyera Eulberg * Fix crossed-in-flight compilation error Co-authored-by: Tyera Eulberg --- core/src/rpc.rs | 48 ++++++++++++++++++++++++--------------- runtime/src/commitment.rs | 18 ++++++++++++++- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/core/src/rpc.rs b/core/src/rpc.rs index 63f0e1b56d..31ee28f13d 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -112,36 +112,27 @@ impl JsonRpcRequestProcessor { Some(config) => config.commitment, }; - let slot = match commitment_level { + let slot = self + .block_commitment_cache + .read() + .unwrap() + .slot_with_commitment(commitment_level); + + match commitment_level { CommitmentLevel::Recent => { - let slot = r_bank_forks.highest_slot(); - debug!("RPC using working_bank: {:?}", slot); - slot + debug!("RPC using the heaviest slot: {:?}", slot); } CommitmentLevel::Root => { - let slot = r_bank_forks.root(); debug!("RPC using node root: {:?}", slot); - slot } CommitmentLevel::Single | CommitmentLevel::SingleGossip => { - let slot = self - .block_commitment_cache - .read() - .unwrap() - .highest_confirmed_slot(); debug!("RPC using confirmed slot: {:?}", slot); - slot } CommitmentLevel::Max => { - let slot = self - .block_commitment_cache - .read() - .unwrap() - .highest_confirmed_root(); debug!("RPC using block: {:?}", slot); - slot } }; + r_bank_forks.get(slot).cloned().unwrap() } @@ -3674,6 +3665,24 @@ pub mod tests { assert_eq!(expected, result); } + fn advance_block_commitment_cache( + block_commitment_cache: &Arc>, + bank_forks: &Arc>, + ) { + let mut new_block_commitment = BlockCommitmentCache::new( + HashMap::new(), + 0, + CommitmentSlots { + root: 0, + slot: bank_forks.read().unwrap().highest_slot(), + highest_confirmed_slot: 0, + highest_confirmed_root: 0, + }, + ); + let mut w_block_commitment_cache = block_commitment_cache.write().unwrap(); + std::mem::swap(&mut *w_block_commitment_cache, &mut new_block_commitment); + } + #[test] fn test_get_vote_accounts() { let RpcHandler { @@ -3683,6 +3692,7 @@ pub mod tests { bank_forks, alice, leader_vote_keypair, + block_commitment_cache, .. } = start_rpc_handler_with_tx(&Pubkey::new_rand()); @@ -3761,6 +3771,7 @@ pub mod tests { &Pubkey::default(), bank.slot() + 1, )); + advance_block_commitment_cache(&block_commitment_cache, &bank_forks); let transaction = Transaction::new_signed_with_payer( &instructions, @@ -3814,6 +3825,7 @@ pub mod tests { &Pubkey::default(), bank.slot() + TEST_SLOTS_PER_EPOCH, )); + advance_block_commitment_cache(&block_commitment_cache, &bank_forks); // The leader vote account should now be delinquent, and the other vote account disappears // because it's inactive with no stake diff --git a/runtime/src/commitment.rs b/runtime/src/commitment.rs index 7ad0cddd5d..47a00feb77 100644 --- a/runtime/src/commitment.rs +++ b/runtime/src/commitment.rs @@ -1,4 +1,4 @@ -use solana_sdk::clock::Slot; +use solana_sdk::{clock::Slot, commitment_config::CommitmentLevel}; use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY; use std::collections::HashMap; @@ -103,6 +103,22 @@ impl BlockCommitmentCache { self.commitment_slots } + pub fn highest_gossip_confirmed_slot(&self) -> Slot { + // TODO: see solana_core::RpcSubscriptions: + //self.last_checked_slots.get(&CommitmentLevel::SingleGossip).unwrap_or(&0) + self.highest_confirmed_slot() + } + + pub fn slot_with_commitment(&self, commitment_level: CommitmentLevel) -> Slot { + match commitment_level { + CommitmentLevel::Recent => self.slot(), + CommitmentLevel::Root => self.root(), + CommitmentLevel::Single => self.highest_confirmed_slot(), + CommitmentLevel::SingleGossip => self.highest_gossip_confirmed_slot(), + CommitmentLevel::Max => self.highest_confirmed_root(), + } + } + fn highest_slot_with_confirmation_count(&self, confirmation_count: usize) -> Slot { assert!(confirmation_count > 0 && confirmation_count <= MAX_LOCKOUT_HISTORY); for slot in (self.root()..self.slot()).rev() {