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 <teulberg@gmail.com>

* cargo fmt

* Remove highest_descendant

* Fix test

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>

* Fix crossed-in-flight compilation error

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
This commit is contained in:
Greg Fitzgerald
2020-07-20 17:03:40 -06:00
committed by GitHub
parent 0cb422fbbb
commit 23c2e55cbf
2 changed files with 47 additions and 19 deletions

View File

@ -112,36 +112,27 @@ impl JsonRpcRequestProcessor {
Some(config) => config.commitment, 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 => { CommitmentLevel::Recent => {
let slot = r_bank_forks.highest_slot(); debug!("RPC using the heaviest slot: {:?}", slot);
debug!("RPC using working_bank: {:?}", slot);
slot
} }
CommitmentLevel::Root => { CommitmentLevel::Root => {
let slot = r_bank_forks.root();
debug!("RPC using node root: {:?}", slot); debug!("RPC using node root: {:?}", slot);
slot
} }
CommitmentLevel::Single | CommitmentLevel::SingleGossip => { CommitmentLevel::Single | CommitmentLevel::SingleGossip => {
let slot = self
.block_commitment_cache
.read()
.unwrap()
.highest_confirmed_slot();
debug!("RPC using confirmed slot: {:?}", slot); debug!("RPC using confirmed slot: {:?}", slot);
slot
} }
CommitmentLevel::Max => { CommitmentLevel::Max => {
let slot = self
.block_commitment_cache
.read()
.unwrap()
.highest_confirmed_root();
debug!("RPC using block: {:?}", slot); debug!("RPC using block: {:?}", slot);
slot
} }
}; };
r_bank_forks.get(slot).cloned().unwrap() r_bank_forks.get(slot).cloned().unwrap()
} }
@ -3674,6 +3665,24 @@ pub mod tests {
assert_eq!(expected, result); assert_eq!(expected, result);
} }
fn advance_block_commitment_cache(
block_commitment_cache: &Arc<RwLock<BlockCommitmentCache>>,
bank_forks: &Arc<RwLock<BankForks>>,
) {
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] #[test]
fn test_get_vote_accounts() { fn test_get_vote_accounts() {
let RpcHandler { let RpcHandler {
@ -3683,6 +3692,7 @@ pub mod tests {
bank_forks, bank_forks,
alice, alice,
leader_vote_keypair, leader_vote_keypair,
block_commitment_cache,
.. ..
} = start_rpc_handler_with_tx(&Pubkey::new_rand()); } = start_rpc_handler_with_tx(&Pubkey::new_rand());
@ -3761,6 +3771,7 @@ pub mod tests {
&Pubkey::default(), &Pubkey::default(),
bank.slot() + 1, bank.slot() + 1,
)); ));
advance_block_commitment_cache(&block_commitment_cache, &bank_forks);
let transaction = Transaction::new_signed_with_payer( let transaction = Transaction::new_signed_with_payer(
&instructions, &instructions,
@ -3814,6 +3825,7 @@ pub mod tests {
&Pubkey::default(), &Pubkey::default(),
bank.slot() + TEST_SLOTS_PER_EPOCH, 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 // The leader vote account should now be delinquent, and the other vote account disappears
// because it's inactive with no stake // because it's inactive with no stake

View File

@ -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 solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
use std::collections::HashMap; use std::collections::HashMap;
@ -103,6 +103,22 @@ impl BlockCommitmentCache {
self.commitment_slots 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 { fn highest_slot_with_confirmation_count(&self, confirmation_count: usize) -> Slot {
assert!(confirmation_count > 0 && confirmation_count <= MAX_LOCKOUT_HISTORY); assert!(confirmation_count > 0 && confirmation_count <= MAX_LOCKOUT_HISTORY);
for slot in (self.root()..self.slot()).rev() { for slot in (self.root()..self.slot()).rev() {