Use cluster confirmations in rpc and pubsub (#9138)

* Add runtime methods to simply get status and slot

* Add helper function to get slot confirmation_count from BlockCommitmentCache

* Return cluster confirmations in getSignatureStatus

* Remove use of invalid get_signature_confirmation_status

* Remove unused methods

* Update pubsub to use cluster confirmations

* Fix test_check_signature_subscribe failure

* Refactor confirmations to read commitment cache only once

* Review comments

* Use bank, root from BlockCommitmentCache

* Update docs

* Add metric for block-commitment aggregations

Co-authored-by: Justin Starry <justin@solana.com>
This commit is contained in:
Tyera Eulberg
2020-03-30 17:53:25 -06:00
committed by GitHub
parent 8636ef5e24
commit 50fa577af8
15 changed files with 400 additions and 344 deletions

View File

@ -14,7 +14,7 @@ use crate::{
deserialize_atomicbool, deserialize_atomicu64, serialize_atomicbool, serialize_atomicu64,
},
stakes::Stakes,
status_cache::{SignatureConfirmationStatus, SlotDelta, StatusCache},
status_cache::{SlotDelta, StatusCache},
storage_utils,
storage_utils::StorageAccounts,
system_instruction_processor::{get_system_account_kind, SystemAccountKind},
@ -1845,29 +1845,25 @@ impl Bank {
&self,
signature: &Signature,
) -> Option<Result<()>> {
if let Some(status) = self.get_signature_confirmation_status(signature) {
if status.slot == self.slot() {
return Some(status.status);
if let Some((slot, status)) = self.get_signature_status_slot(signature) {
if slot <= self.slot() {
return Some(status);
}
}
None
}
pub fn get_signature_confirmation_status(
&self,
signature: &Signature,
) -> Option<SignatureConfirmationStatus<Result<()>>> {
pub fn get_signature_status_slot(&self, signature: &Signature) -> Option<(Slot, Result<()>)> {
let rcache = self.src.status_cache.read().unwrap();
rcache.get_signature_status_slow(signature, &self.ancestors)
rcache.get_signature_slot(signature, &self.ancestors)
}
pub fn get_signature_status(&self, signature: &Signature) -> Option<Result<()>> {
self.get_signature_confirmation_status(signature)
.map(|v| v.status)
self.get_signature_status_slot(signature).map(|v| v.1)
}
pub fn has_signature(&self, signature: &Signature) -> bool {
self.get_signature_confirmation_status(signature).is_some()
self.get_signature_status_slot(signature).is_some()
}
/// Hash the `accounts` HashMap. This represents a validator's interpretation

View File

@ -1,4 +1,4 @@
use crate::{bank::Bank, status_cache::SignatureConfirmationStatus};
use crate::bank::Bank;
use solana_sdk::{
account::Account,
client::{AsyncClient, Client, SyncClient},
@ -184,26 +184,15 @@ impl SyncClient for BankClient {
signature: &Signature,
min_confirmed_blocks: usize,
) -> Result<usize> {
let mut now = Instant::now();
let mut confirmed_blocks = 0;
// https://github.com/solana-labs/solana/issues/7199
assert_eq!(min_confirmed_blocks, 1, "BankClient cannot observe the passage of multiple blocks, so min_confirmed_blocks must be 1");
let now = Instant::now();
let confirmed_blocks;
loop {
let response = self.bank.get_signature_confirmation_status(signature);
if let Some(SignatureConfirmationStatus {
confirmations,
status,
..
}) = response
{
if status.is_ok() {
if confirmed_blocks != confirmations {
now = Instant::now();
confirmed_blocks = confirmations;
}
if confirmations >= min_confirmed_blocks {
break;
}
}
};
if self.bank.get_signature_status(signature).is_some() {
confirmed_blocks = 1;
break;
}
if now.elapsed().as_secs() > 15 {
return Err(TransportError::IoError(io::Error::new(
io::ErrorKind::Other,

View File

@ -103,29 +103,20 @@ impl<T: Serialize + Clone> StatusCache<T> {
None
}
pub fn get_signature_status_slow(
pub fn get_signature_slot(
&self,
sig: &Signature,
signature: &Signature,
ancestors: &HashMap<Slot, usize>,
) -> Option<SignatureConfirmationStatus<T>> {
trace!("get_signature_status_slow");
) -> Option<(Slot, T)> {
let mut keys = vec![];
let mut val: Vec<_> = self.cache.iter().map(|(k, _)| *k).collect();
keys.append(&mut val);
for blockhash in keys.iter() {
trace!("get_signature_status_slow: trying {}", blockhash);
if let Some((forkid, res)) = self.get_signature_status(sig, blockhash, ancestors) {
trace!("get_signature_status_slow: got {}", forkid);
let confirmations = ancestors
.get(&forkid)
.copied()
.unwrap_or_else(|| ancestors.len());
return Some(SignatureConfirmationStatus {
slot: forkid,
confirmations,
status: res,
});
trace!("get_signature_slot: trying {}", blockhash);
let status = self.get_signature_status(signature, blockhash, ancestors);
if status.is_some() {
return status;
}
}
None
@ -265,10 +256,7 @@ mod tests {
status_cache.get_signature_status(&sig, &blockhash, &HashMap::new()),
None
);
assert_eq!(
status_cache.get_signature_status_slow(&sig, &HashMap::new()),
None
);
assert_eq!(status_cache.get_signature_slot(&sig, &HashMap::new()), None);
}
#[test]
@ -283,12 +271,8 @@ mod tests {
Some((0, ()))
);
assert_eq!(
status_cache.get_signature_status_slow(&sig, &ancestors),
Some(SignatureConfirmationStatus {
slot: 0,
confirmations: 1,
status: ()
})
status_cache.get_signature_slot(&sig, &ancestors),
Some((0, ()))
);
}
@ -303,10 +287,7 @@ mod tests {
status_cache.get_signature_status(&sig, &blockhash, &ancestors),
None
);
assert_eq!(
status_cache.get_signature_status_slow(&sig, &ancestors),
None
);
assert_eq!(status_cache.get_signature_slot(&sig, &ancestors), None);
}
#[test]
@ -323,24 +304,6 @@ mod tests {
);
}
#[test]
fn test_find_sig_with_root_ancestor_fork_max_len() {
let sig = Signature::default();
let mut status_cache = BankStatusCache::default();
let blockhash = hash(Hash::default().as_ref());
let ancestors = vec![(2, 2)].into_iter().collect();
status_cache.insert(&blockhash, &sig, 0, ());
status_cache.add_root(0);
assert_eq!(
status_cache.get_signature_status_slow(&sig, &ancestors),
Some(SignatureConfirmationStatus {
slot: 0,
confirmations: ancestors.len(),
status: ()
})
);
}
#[test]
fn test_insert_picks_latest_blockhash_fork() {
let sig = Signature::default();
@ -371,10 +334,6 @@ mod tests {
status_cache.get_signature_status(&sig, &blockhash, &ancestors),
None
);
assert_eq!(
status_cache.get_signature_status_slow(&sig, &ancestors),
None
);
}
#[test]