From 23c50a23899442f2f116215fc808131c764ecbde Mon Sep 17 00:00:00 2001 From: Brooks Prumo Date: Thu, 23 Jun 2022 15:19:06 -0500 Subject: [PATCH] Add StatusCache::root_slot_deltas() and use it (#26170) --- core/tests/snapshots.rs | 16 ++++++++++++++-- runtime/benches/status_cache.rs | 16 ++++++++++++++++ runtime/src/bank.rs | 18 ------------------ runtime/src/bank_forks.rs | 13 +++++++++---- runtime/src/snapshot_utils.rs | 6 ++++-- runtime/src/status_cache.rs | 20 +++++++++++++++++--- 6 files changed, 60 insertions(+), 29 deletions(-) diff --git a/core/tests/snapshots.rs b/core/tests/snapshots.rs index b0499d072..174ee22ed 100644 --- a/core/tests/snapshots.rs +++ b/core/tests/snapshots.rs @@ -281,11 +281,17 @@ mod tests { let last_bank_snapshot_info = snapshot_utils::get_highest_bank_snapshot_pre(bank_snapshots_dir) .expect("no bank snapshots found in path"); + let slot_deltas = last_bank + .src + .status_cache + .read() + .unwrap() + .root_slot_deltas(); let accounts_package = AccountsPackage::new( &last_bank, &last_bank_snapshot_info, bank_snapshots_dir, - last_bank.src.slot_deltas(&last_bank.src.roots()), + slot_deltas, &snapshot_config.full_snapshot_archives_dir, &snapshot_config.incremental_snapshot_archives_dir, last_bank.get_snapshot_storages(None), @@ -626,7 +632,13 @@ mod tests { .get(snapshot_test_config.bank_forks.root()) .unwrap() .src - .roots(); + .status_cache + .read() + .unwrap() + .roots() + .iter() + .cloned() + .sorted(); assert!(slots_to_snapshot.into_iter().eq(expected_slots_to_snapshot)); } } diff --git a/runtime/benches/status_cache.rs b/runtime/benches/status_cache.rs index b95e41add..c207a7124 100644 --- a/runtime/benches/status_cache.rs +++ b/runtime/benches/status_cache.rs @@ -47,3 +47,19 @@ fn bench_status_cache_slot_deltas(bencher: &mut Bencher) { bencher.iter(|| test::black_box(status_cache.slot_deltas(&slots))); } + +#[bench] +fn bench_status_cache_root_slot_deltas(bencher: &mut Bencher) { + let mut status_cache = BankStatusCache::default(); + + // fill the status cache + let slots: Vec<_> = (42..).take(MAX_CACHE_ENTRIES).collect(); + for slot in &slots { + for _ in 0..5 { + status_cache.insert(&Hash::new_unique(), Hash::new_unique(), *slot, Ok(())); + } + status_cache.add_root(*slot); + } + + bencher.iter(|| test::black_box(status_cache.root_slot_deltas())); +} diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index fd992910a..543ccf37d 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -598,24 +598,6 @@ pub struct StatusCacheRc { pub status_cache: Arc>, } -impl StatusCacheRc { - pub fn slot_deltas(&self, slots: &[Slot]) -> Vec { - let sc = self.status_cache.read().unwrap(); - sc.slot_deltas(slots) - } - - pub fn roots(&self) -> Vec { - self.status_cache - .read() - .unwrap() - .roots() - .iter() - .cloned() - .sorted() - .collect() - } -} - pub type TransactionCheckResult = (Result<()>, Option); pub struct TransactionResults { diff --git a/runtime/src/bank_forks.rs b/runtime/src/bank_forks.rs index 2e0da5e92..b9640336e 100644 --- a/runtime/src/bank_forks.rs +++ b/runtime/src/bank_forks.rs @@ -278,13 +278,18 @@ impl BankForks { { let snapshot_root_bank = self.root_bank(); let root_slot = snapshot_root_bank.slot(); + // Save off the status cache because these may get pruned if another + // `set_root()` is called before the snapshots package can be generated + let status_cache_slot_deltas = snapshot_root_bank + .src + .status_cache + .read() + .unwrap() + .root_slot_deltas(); if let Err(e) = accounts_background_request_sender.send_snapshot_request(SnapshotRequest { snapshot_root_bank, - // Save off the status cache because these may get pruned - // if another `set_root()` is called before the snapshots package - // can be generated - status_cache_slot_deltas: bank.src.slot_deltas(&bank.src.roots()), + status_cache_slot_deltas, }) { warn!( diff --git a/runtime/src/snapshot_utils.rs b/runtime/src/snapshot_utils.rs index ad5afb4b3..a0be8c334 100644 --- a/runtime/src/snapshot_utils.rs +++ b/runtime/src/snapshot_utils.rs @@ -1949,11 +1949,12 @@ pub fn package_and_archive_full_snapshot( maximum_full_snapshot_archives_to_retain: usize, maximum_incremental_snapshot_archives_to_retain: usize, ) -> Result { + let slot_deltas = bank.src.status_cache.read().unwrap().root_slot_deltas(); let accounts_package = AccountsPackage::new( bank, bank_snapshot_info, bank_snapshots_dir, - bank.src.slot_deltas(&bank.src.roots()), + slot_deltas, &full_snapshot_archives_dir, &incremental_snapshot_archives_dir, snapshot_storages, @@ -1998,11 +1999,12 @@ pub fn package_and_archive_incremental_snapshot( maximum_full_snapshot_archives_to_retain: usize, maximum_incremental_snapshot_archives_to_retain: usize, ) -> Result { + let slot_deltas = bank.src.status_cache.read().unwrap().root_slot_deltas(); let accounts_package = AccountsPackage::new( bank, bank_snapshot_info, bank_snapshots_dir, - bank.src.slot_deltas(&bank.src.roots()), + slot_deltas, &full_snapshot_archives_dir, &incremental_snapshot_archives_dir, snapshot_storages, diff --git a/runtime/src/status_cache.rs b/runtime/src/status_cache.rs index 9903092f8..f9d48941e 100644 --- a/runtime/src/status_cache.rs +++ b/runtime/src/status_cache.rs @@ -47,7 +47,7 @@ impl Default for StatusCache { Self { cache: HashMap::default(), // 0 is always a root - roots: [0].iter().cloned().collect(), + roots: HashSet::from([0]), slot_deltas: HashMap::default(), } } @@ -230,7 +230,21 @@ impl StatusCache { ( *slot, self.roots.contains(slot), - self.slot_deltas.get(slot).unwrap_or(&empty).clone(), + Arc::clone(self.slot_deltas.get(slot).unwrap_or(&empty)), + ) + }) + .collect() + } + + /// Get the statuses for all the root slots + pub fn root_slot_deltas(&self) -> Vec> { + self.roots + .iter() + .map(|slot| { + ( + *slot, + true, + self.slot_deltas.get(slot).cloned().unwrap_or_default(), ) }) .collect() @@ -450,7 +464,7 @@ mod tests { for i in 0..(MAX_CACHE_ENTRIES + 1) { status_cache.add_root(i as u64); } - let slots: Vec<_> = (0_u64..MAX_CACHE_ENTRIES as u64 + 1).collect(); + let slots: Vec<_> = (0..MAX_CACHE_ENTRIES as u64 + 1).collect(); assert_eq!(status_cache.slot_deltas.len(), 1); assert!(status_cache.slot_deltas.get(&1).is_some()); let slot_deltas = status_cache.slot_deltas(&slots);