diff --git a/core/src/commitment_service.rs b/core/src/commitment_service.rs index 54c85728310869..247f3cea60ba9d 100644 --- a/core/src/commitment_service.rs +++ b/core/src/commitment_service.rs @@ -108,7 +108,7 @@ impl AggregateCommitmentService { let aggregation_data = receiver.recv_timeout(Duration::from_secs(1))?; let aggregation_data = receiver.try_iter().last().unwrap_or(aggregation_data); - let ancestors = aggregation_data.bank.status_cache_ancestors(); + let ancestors = aggregation_data.bank.seen_transaction_cache_ancestors(); if ancestors.is_empty() { continue; } @@ -607,7 +607,7 @@ mod tests { let working_bank = bank_forks.read().unwrap().working_bank(); let vote_state = get_vote_state(vote_pubkey, &working_bank); let root = vote_state.root_slot.unwrap(); - let ancestors = working_bank.status_cache_ancestors(); + let ancestors = working_bank.seen_transaction_cache_ancestors(); let _ = AggregateCommitmentService::update_commitment_cache( &block_commitment_cache, CommitmentAggregationData { @@ -642,7 +642,7 @@ mod tests { ); let working_bank = bank_forks.read().unwrap().working_bank(); - let ancestors = working_bank.status_cache_ancestors(); + let ancestors = working_bank.seen_transaction_cache_ancestors(); let _ = AggregateCommitmentService::update_commitment_cache( &block_commitment_cache, CommitmentAggregationData { @@ -691,7 +691,7 @@ mod tests { let vote_state = get_vote_state(validator_vote_keypairs.vote_keypair.pubkey(), &working_bank); let root = vote_state.root_slot.unwrap(); - let ancestors = working_bank.status_cache_ancestors(); + let ancestors = working_bank.seen_transaction_cache_ancestors(); let _ = AggregateCommitmentService::update_commitment_cache( &block_commitment_cache, CommitmentAggregationData { diff --git a/core/tests/snapshots.rs b/core/tests/snapshots.rs index c7a41ad21472f0..9f6bec2b987f24 100644 --- a/core/tests/snapshots.rs +++ b/core/tests/snapshots.rs @@ -217,7 +217,7 @@ fn run_bank_forks_snapshot_n( let bank = bank_forks.write().unwrap().insert(bank); f(bank.clone_without_scheduler().as_ref(), mint_keypair); // Set root to make sure we don't end up with too many account storage entries - // and to allow snapshotting of bank and the purging logic on status_cache to + // and to allow snapshotting of bank and the purging logic on `seen_transaction_cache` to // kick in if slot % set_root_interval == 0 || slot == last_slot { if !bank.is_complete() { @@ -365,7 +365,7 @@ fn test_slots_to_snapshot(snapshot_version: SnapshotVersion, cluster_type: Clust .read() .unwrap() .root_bank() - .status_cache + .seen_transaction_cache .read() .unwrap() .roots() @@ -380,13 +380,13 @@ fn test_slots_to_snapshot(snapshot_version: SnapshotVersion, cluster_type: Clust #[test_case(V1_2_0, Devnet)] #[test_case(V1_2_0, Testnet)] #[test_case(V1_2_0, MainnetBeta)] -fn test_bank_forks_status_cache_snapshot( +fn test_bank_forks_seen_transaction_cache_snapshot( snapshot_version: SnapshotVersion, cluster_type: ClusterType, ) { // create banks up to slot (MAX_CACHE_ENTRIES * 2) + 1 while transferring 1 lamport into 2 different accounts each time // this is done to ensure the AccountStorageEntries keep getting cleaned up as the root moves - // ahead. Also tests the status_cache purge and status cache snapshotting. + // ahead. Also tests the `seen_transaction_cache` purge and snapshotting. // Makes sure that the last bank is restored correctly let key1 = Keypair::new().pubkey(); let key2 = Keypair::new().pubkey(); @@ -502,7 +502,7 @@ fn test_bank_forks_incremental_snapshot( }; // Set root to make sure we don't end up with too many account storage entries - // and to allow snapshotting of bank and the purging logic on status_cache to + // and to allow snapshotting of bank and the purging logic on `seen_transaction_cache` to // kick in if slot % SET_ROOT_INTERVAL == 0 { // set_root sends a snapshot request diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index 1464a290e6c943..d9ff2433c361aa 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -156,7 +156,7 @@ fn is_finalized( slot: Slot, ) -> bool { slot <= block_commitment_cache.highest_super_majority_root() - && (blockstore.is_root(slot) || bank.status_cache_ancestors().contains(&slot)) + && (blockstore.is_root(slot) || bank.seen_transaction_cache_ancestors().contains(&slot)) } #[derive(Debug, Clone)] @@ -1357,7 +1357,10 @@ impl JsonRpcRequestProcessor { } else if commitment.is_confirmed() { // Check if block is confirmed let confirmed_bank = self.bank(Some(CommitmentConfig::confirmed())); - if confirmed_bank.status_cache_ancestors().contains(&slot) { + if confirmed_bank + .seen_transaction_cache_ancestors() + .contains(&slot) + { self.check_blockstore_writes_complete(slot)?; let result = self .runtime @@ -1487,7 +1490,7 @@ impl JsonRpcRequestProcessor { let confirmed_bank = self.get_bank_with_config(config)?; if last_element < end_slot { let mut confirmed_blocks = confirmed_bank - .status_cache_ancestors() + .seen_transaction_cache_ancestors() .into_iter() .filter(|&slot| slot <= end_slot && slot > last_element) .collect(); @@ -1565,7 +1568,7 @@ impl JsonRpcRequestProcessor { .cloned() .unwrap_or_else(|| start_slot.saturating_sub(1)); let mut confirmed_blocks = confirmed_bank - .status_cache_ancestors() + .seen_transaction_cache_ancestors() .into_iter() .filter(|&slot| slot > last_element) .collect(); @@ -1779,7 +1782,7 @@ impl JsonRpcRequestProcessor { Some(mut confirmed_transaction) => { if commitment.is_confirmed() && confirmed_bank // should be redundant - .status_cache_ancestors() + .seen_transaction_cache_ancestors() .contains(&confirmed_transaction.slot) { if confirmed_transaction.block_time.is_none() { diff --git a/runtime/src/accounts_background_service.rs b/runtime/src/accounts_background_service.rs index 9c8f7e3c96d578..d312a3ccb780a8 100644 --- a/runtime/src/accounts_background_service.rs +++ b/runtime/src/accounts_background_service.rs @@ -106,7 +106,7 @@ impl SendDroppedBankCallback { pub struct SnapshotRequest { pub snapshot_root_bank: Arc, - pub status_cache_slot_deltas: Vec, + pub seen_transaction_cache_slot_deltas: Vec, pub request_kind: SnapshotRequestKind, /// The instant this request was send to the queue. @@ -280,7 +280,7 @@ impl SnapshotRequestHandler { let mut total_time = Measure::start("snapshot_request_receiver_total_time"); let SnapshotRequest { snapshot_root_bank, - status_cache_slot_deltas, + seen_transaction_cache_slot_deltas, request_kind, enqueued: _, } = snapshot_request; @@ -367,7 +367,7 @@ impl SnapshotRequestHandler { accounts_package_kind, &snapshot_root_bank, snapshot_storages, - status_cache_slot_deltas, + seen_transaction_cache_slot_deltas, accounts_hash_for_testing, ), AccountsPackageKind::EpochAccountsHash => panic!( @@ -887,7 +887,7 @@ mod test { let send_snapshot_request = |snapshot_root_bank, request_kind| { let snapshot_request = SnapshotRequest { snapshot_root_bank, - status_cache_slot_deltas: Vec::default(), + seen_transaction_cache_slot_deltas: Vec::default(), request_kind, enqueued: Instant::now(), }; diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index cd86ada1a4d03b..c3264e934f05c6 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -519,6 +519,7 @@ impl PartialEq for Bank { let Self { skipped_rewrites: _, rc: _, + seen_transaction_cache: _, status_cache: _, blockhash_queue, ancestors, @@ -744,7 +745,10 @@ pub struct Bank { /// References to accounts, parent and signature status pub rc: BankRc, - /// A cache of signature statuses + /// A cache of seen transactions by message hash + pub seen_transaction_cache: Arc>, + + /// A cache of transaction statuses by signature pub status_cache: Arc>, /// FIFO queue of `recent_blockhash` items @@ -1082,6 +1086,7 @@ impl Bank { let mut bank = Self { skipped_rewrites: Mutex::default(), rc: BankRc::new(accounts), + seen_transaction_cache: Arc::>::default(), status_cache: Arc::>::default(), blockhash_queue: RwLock::::default(), ancestors: Ancestors::default(), @@ -1286,6 +1291,8 @@ impl Bank { } }); + let (seen_transaction_cache, seen_transaction_cache_time_us) = + measure_us!(Arc::clone(&parent.seen_transaction_cache)); let (status_cache, status_cache_time_us) = measure_us!(Arc::clone(&parent.status_cache)); let (fee_rate_governor, fee_components_time_us) = measure_us!( @@ -1320,6 +1327,7 @@ impl Bank { let mut new = Self { skipped_rewrites: Mutex::default(), rc, + seen_transaction_cache, status_cache, slot, bank_id, @@ -1482,6 +1490,7 @@ impl Bank { NewBankTimings { bank_rc_creation_time_us, total_elapsed_time_us: time.as_us(), + seen_transaction_cache_time_us, status_cache_time_us, fee_components_time_us, blockhash_queue_time_us, @@ -1815,6 +1824,7 @@ impl Bank { let mut bank = Self { skipped_rewrites: Mutex::default(), rc: bank_rc, + seen_transaction_cache: Arc::>::default(), status_cache: Arc::>::default(), blockhash_queue: RwLock::new(fields.blockhash_queue), ancestors, @@ -2092,8 +2102,8 @@ impl Bank { self.freeze_started.load(Relaxed) } - pub fn status_cache_ancestors(&self) -> Vec { - let mut roots = self.status_cache.read().unwrap().roots().clone(); + pub fn seen_transaction_cache_ancestors(&self) -> Vec { + let mut roots = self.seen_transaction_cache.read().unwrap().roots().clone(); let min = roots.iter().min().cloned().unwrap_or(0); for ancestor in self.ancestors.keys() { if ancestor >= min { @@ -2737,9 +2747,10 @@ impl Bank { *self.rc.parent.write().unwrap() = None; let mut squash_cache_time = Measure::start("squash_cache_time"); - roots - .iter() - .for_each(|slot| self.status_cache.write().unwrap().add_root(*slot)); + roots.iter().for_each(|slot| { + self.seen_transaction_cache.write().unwrap().add_root(*slot); + self.status_cache.write().unwrap().add_root(*slot); + }); squash_cache_time.stop(); SquashTiming { @@ -3005,10 +3016,15 @@ impl Bank { /// Forget all signatures. Useful for benchmarking. pub fn clear_signatures(&self) { + self.seen_transaction_cache.write().unwrap().clear(); self.status_cache.write().unwrap().clear(); } pub fn clear_slot_signatures(&self, slot: Slot) { + self.seen_transaction_cache + .write() + .unwrap() + .clear_slot_entries(slot); self.status_cache.write().unwrap().clear_slot_entries(slot); } @@ -3017,13 +3033,14 @@ impl Bank { sanitized_txs: &[impl TransactionWithMeta], processing_results: &[TransactionProcessingResult], ) { + let mut seen_transaction_cache = self.seen_transaction_cache.write().unwrap(); let mut status_cache = self.status_cache.write().unwrap(); assert_eq!(sanitized_txs.len(), processing_results.len()); for (tx, processing_result) in sanitized_txs.iter().zip(processing_results) { if let Ok(processed_tx) = &processing_result { // Add the message hash to the status cache to ensure that this message // won't be processed again with a different signature. - status_cache.insert( + seen_transaction_cache.insert( tx.recent_blockhash(), tx.message_hash(), self.slot(), diff --git a/runtime/src/bank/check_transactions.rs b/runtime/src/bank/check_transactions.rs index e2da75f1cc890b..57a11f7fb121f6 100644 --- a/runtime/src/bank/check_transactions.rs +++ b/runtime/src/bank/check_transactions.rs @@ -71,7 +71,7 @@ impl Bank { max_age, error_counters, ); - self.check_status_cache(sanitized_txs, lock_results, error_counters) + self.check_seen_transaction_cache(sanitized_txs, lock_results, error_counters) } fn check_age_and_compute_budget_limits( @@ -249,15 +249,15 @@ impl Bank { Some((*nonce_address, nonce_account, nonce_data)) } - fn check_status_cache( + fn check_seen_transaction_cache( &self, sanitized_txs: &[impl core::borrow::Borrow], lock_results: Vec, error_counters: &mut TransactionErrorMetrics, ) -> Vec { - // Do allocation before acquiring the lock on the status cache. + // Do allocation before acquiring the lock on the seen transaction cache. let mut check_results = Vec::with_capacity(sanitized_txs.len()); - let rcache = self.status_cache.read().unwrap(); + let rcache = self.seen_transaction_cache.read().unwrap(); check_results.extend(sanitized_txs.iter().zip(lock_results).map( |(sanitized_tx, lock_result)| { @@ -278,11 +278,11 @@ impl Bank { fn is_transaction_already_processed( &self, sanitized_tx: &impl TransactionWithMeta, - status_cache: &BankStatusCache, + seen_transaction_cache: &BankStatusCache, ) -> bool { let key = sanitized_tx.message_hash(); let transaction_blockhash = sanitized_tx.recent_blockhash(); - status_cache + seen_transaction_cache .get_status(key, transaction_blockhash, &self.ancestors) .is_some() } diff --git a/runtime/src/bank/metrics.rs b/runtime/src/bank/metrics.rs index ae0c2b714f7ad0..562b4eb7e4ccbc 100644 --- a/runtime/src/bank/metrics.rs +++ b/runtime/src/bank/metrics.rs @@ -27,6 +27,7 @@ pub(crate) struct RewardsMetrics { pub(crate) struct NewBankTimings { pub(crate) bank_rc_creation_time_us: u64, pub(crate) total_elapsed_time_us: u64, + pub(crate) seen_transaction_cache_time_us: u64, pub(crate) status_cache_time_us: u64, pub(crate) fee_components_time_us: u64, pub(crate) blockhash_queue_time_us: u64, @@ -108,6 +109,7 @@ pub(crate) fn report_new_bank_metrics( ("parent_slot", parent_slot, i64), ("bank_rc_creation_us", timings.bank_rc_creation_time_us, i64), ("total_elapsed_us", timings.total_elapsed_time_us, i64), + ("seen_transaction_cache_us", timings.seen_transaction_cache_time_us, i64), ("status_cache_us", timings.status_cache_time_us, i64), ("fee_components_us", timings.fee_components_time_us, i64), ("blockhash_queue_us", timings.blockhash_queue_time_us, i64), diff --git a/runtime/src/bank/tests.rs b/runtime/src/bank/tests.rs index d603f295e6188e..64b39b8f396d25 100644 --- a/runtime/src/bank/tests.rs +++ b/runtime/src/bank/tests.rs @@ -4773,7 +4773,7 @@ fn test_get_filtered_indexed_accounts() { } #[test] -fn test_status_cache_ancestors() { +fn test_seen_transaction_cache_ancestors() { solana_logger::setup(); let (parent, _bank_forks) = create_simple_test_arc_bank(500); let bank1 = Arc::new(new_from_parent(parent)); @@ -4785,7 +4785,7 @@ fn test_status_cache_ancestors() { let bank = new_from_parent(bank); assert_eq!( - bank.status_cache_ancestors(), + bank.seen_transaction_cache_ancestors(), (bank.slot() - MAX_CACHE_ENTRIES as u64..=bank.slot()).collect::>() ); } diff --git a/runtime/src/snapshot_bank_utils.rs b/runtime/src/snapshot_bank_utils.rs index 17cab92dfe8bbb..33db69431073bf 100644 --- a/runtime/src/snapshot_bank_utils.rs +++ b/runtime/src/snapshot_bank_utils.rs @@ -57,11 +57,11 @@ pub const DEFAULT_FULL_SNAPSHOT_ARCHIVE_INTERVAL_SLOTS: Slot = 50_000; pub const DEFAULT_INCREMENTAL_SNAPSHOT_ARCHIVE_INTERVAL_SLOTS: Slot = 100; pub const DISABLED_SNAPSHOT_ARCHIVE_INTERVAL: Slot = Slot::MAX; -pub fn serialize_status_cache( +pub fn serialize_seen_transaction_cache( slot_deltas: &[BankSlotDelta], - status_cache_path: &Path, + seen_transaction_cache_path: &Path, ) -> snapshot_utils::Result { - serialize_snapshot_data_file(status_cache_path, |stream| { + serialize_snapshot_data_file(seen_transaction_cache_path, |stream| { serialize_into(stream, slot_deltas)?; Ok(()) }) @@ -578,13 +578,13 @@ fn snapshot_version_and_root_paths( Ok((snapshot_version, snapshot_root_paths)) } -fn deserialize_status_cache( - status_cache_path: &Path, +fn deserialize_seen_transaction_cache( + seen_transaction_cache_path: &Path, ) -> snapshot_utils::Result> { - deserialize_snapshot_data_file(status_cache_path, |stream| { + deserialize_snapshot_data_file(seen_transaction_cache_path, |stream| { info!( - "Rebuilding status cache from {}", - status_cache_path.display() + "Rebuilding seen transaction cache from {}", + seen_transaction_cache_path.display() ); let slot_delta: Vec = bincode::options() .with_limit(snapshot_utils::MAX_SNAPSHOT_DATA_FILE_SIZE) @@ -651,9 +651,9 @@ fn rebuild_bank_from_unarchived_snapshots( verify_epoch_stakes(&bank)?; - // The status cache is rebuilt from the latest snapshot. So, if there's an incremental - // snapshot, use that. Otherwise use the full snapshot. - let status_cache_path = incremental_snapshot_unpacked_snapshots_dir_and_version + // The seen transaction cache is rebuilt from the latest snapshot. So, if there's an + // incremental snapshot, use that. Otherwise use the full snapshot. + let seen_transaction_cache_path = incremental_snapshot_unpacked_snapshots_dir_and_version .map_or_else( || { full_snapshot_unpacked_snapshots_dir_and_version @@ -666,12 +666,15 @@ fn rebuild_bank_from_unarchived_snapshots( .as_path() }, ) - .join(snapshot_utils::SNAPSHOT_STATUS_CACHE_FILENAME); - let slot_deltas = deserialize_status_cache(&status_cache_path)?; + .join(snapshot_utils::SNAPSHOT_SEEN_TRANSACTION_CACHE_FILENAME); + let slot_deltas = deserialize_seen_transaction_cache(&seen_transaction_cache_path)?; verify_slot_deltas(slot_deltas.as_slice(), &bank)?; - bank.status_cache.write().unwrap().append(&slot_deltas); + bank.seen_transaction_cache + .write() + .unwrap() + .append(&slot_deltas); info!("Rebuilt bank for slot: {}", bank.slot()); Ok(( @@ -726,14 +729,17 @@ fn rebuild_bank_from_snapshot( verify_epoch_stakes(&bank)?; - let status_cache_path = bank_snapshot + let seen_transaction_cache_path = bank_snapshot .snapshot_dir - .join(snapshot_utils::SNAPSHOT_STATUS_CACHE_FILENAME); - let slot_deltas = deserialize_status_cache(&status_cache_path)?; + .join(snapshot_utils::SNAPSHOT_SEEN_TRANSACTION_CACHE_FILENAME); + let slot_deltas = deserialize_seen_transaction_cache(&seen_transaction_cache_path)?; verify_slot_deltas(slot_deltas.as_slice(), &bank)?; - bank.status_cache.write().unwrap().append(&slot_deltas); + bank.seen_transaction_cache + .write() + .unwrap() + .append(&slot_deltas); info!("Rebuilt bank for slot: {}", bank.slot()); Ok(( @@ -971,12 +977,16 @@ fn bank_to_full_snapshot_archive_with( }; let snapshot_storages = bank.get_snapshot_storages(None); - let status_cache_slot_deltas = bank.status_cache.read().unwrap().root_slot_deltas(); + let seen_transaction_cache_slot_deltas = bank + .seen_transaction_cache + .read() + .unwrap() + .root_slot_deltas(); let accounts_package = AccountsPackage::new_for_snapshot( AccountsPackageKind::Snapshot(SnapshotKind::FullSnapshot), bank, snapshot_storages, - status_cache_slot_deltas, + seen_transaction_cache_slot_deltas, None, ); let snapshot_package = @@ -1066,12 +1076,16 @@ pub fn bank_to_incremental_snapshot_archive( }; let snapshot_storages = bank.get_snapshot_storages(Some(full_snapshot_slot)); - let status_cache_slot_deltas = bank.status_cache.read().unwrap().root_slot_deltas(); + let seen_transaction_cache_slot_deltas = bank + .seen_transaction_cache + .read() + .unwrap() + .root_slot_deltas(); let accounts_package = AccountsPackage::new_for_snapshot( AccountsPackageKind::Snapshot(SnapshotKind::IncrementalSnapshot(full_snapshot_slot)), bank, snapshot_storages, - status_cache_slot_deltas, + seen_transaction_cache_slot_deltas, None, ); let snapshot_package = SnapshotPackage::new( @@ -2011,10 +2025,10 @@ mod tests { let snapshot = get_highest_bank_snapshot(&bank_snapshots_dir).unwrap(); assert_eq!(snapshot.slot, 2); - let status_cache_file = snapshot + let seen_transaction_cache_file = snapshot .snapshot_dir - .join(snapshot_utils::SNAPSHOT_STATUS_CACHE_FILENAME); - fs::remove_file(status_cache_file).unwrap(); + .join(snapshot_utils::SNAPSHOT_SEEN_TRANSACTION_CACHE_FILENAME); + fs::remove_file(seen_transaction_cache_file).unwrap(); let snapshot = get_highest_bank_snapshot(&bank_snapshots_dir).unwrap(); assert_eq!(snapshot.slot, 1); } diff --git a/runtime/src/snapshot_controller.rs b/runtime/src/snapshot_controller.rs index bf388fa13e7e40..def28edfd471ca 100644 --- a/runtime/src/snapshot_controller.rs +++ b/runtime/src/snapshot_controller.rs @@ -98,13 +98,16 @@ impl SnapshotController { let mut snapshot_time = Measure::start("squash::snapshot_time"); if bank.is_startup_verification_complete() { - // Save off the status cache because these may get pruned if another + // Save off the seen transaction cache because these may get pruned if another // `set_root()` is called before the snapshots package can be generated - let status_cache_slot_deltas = - bank.status_cache.read().unwrap().root_slot_deltas(); + let seen_transaction_cache_slot_deltas = bank + .seen_transaction_cache + .read() + .unwrap() + .root_slot_deltas(); if let Err(e) = self.abs_request_sender.send(SnapshotRequest { snapshot_root_bank: Arc::clone(bank), - status_cache_slot_deltas, + seen_transaction_cache_slot_deltas, request_kind, enqueued: Instant::now(), }) { @@ -185,7 +188,7 @@ impl SnapshotController { if let Err(err) = self.abs_request_sender.send(SnapshotRequest { snapshot_root_bank: Arc::clone(eah_bank), - status_cache_slot_deltas: Vec::default(), + seen_transaction_cache_slot_deltas: Vec::default(), request_kind: SnapshotRequestKind::EpochAccountsHash, enqueued: Instant::now(), }) { diff --git a/runtime/src/snapshot_package.rs b/runtime/src/snapshot_package.rs index 12fc3b4910bc19..a9ac68a856d6f5 100644 --- a/runtime/src/snapshot_package.rs +++ b/runtime/src/snapshot_package.rs @@ -54,7 +54,7 @@ impl AccountsPackage { package_kind: AccountsPackageKind, bank: &Bank, snapshot_storages: Vec>, - status_cache_slot_deltas: Vec, + seen_transaction_cache_slot_deltas: Vec, accounts_hash_for_testing: Option, ) -> Self { let slot = bank.slot(); @@ -91,7 +91,7 @@ impl AccountsPackage { let bank_hash_stats = bank.get_bank_hash_stats(); let bank_fields_to_serialize = bank.get_fields_to_serialize(); SupplementalSnapshotInfo { - status_cache_slot_deltas, + seen_transaction_cache_slot_deltas, bank_fields_to_serialize, bank_hash_stats, accounts_delta_hash, @@ -178,7 +178,7 @@ impl AccountsPackage { rent_collector: RentCollector::default(), accounts_hash_algorithm: AccountsHashAlgorithm::Merkle, snapshot_info: Some(SupplementalSnapshotInfo { - status_cache_slot_deltas: Vec::default(), + seen_transaction_cache_slot_deltas: Vec::default(), bank_fields_to_serialize: BankFieldsToSerialize::default_for_tests(), bank_hash_stats: BankHashStats::default(), accounts_delta_hash: AccountsDeltaHash(Hash::default()), @@ -203,7 +203,7 @@ impl std::fmt::Debug for AccountsPackage { /// Supplemental information needed for snapshots pub struct SupplementalSnapshotInfo { - pub status_cache_slot_deltas: Vec, + pub seen_transaction_cache_slot_deltas: Vec, pub bank_fields_to_serialize: BankFieldsToSerialize, pub bank_hash_stats: BankHashStats, pub accounts_delta_hash: AccountsDeltaHash, @@ -227,7 +227,7 @@ pub struct SnapshotPackage { pub block_height: Slot, pub hash: SnapshotHash, pub snapshot_storages: Vec>, - pub status_cache_slot_deltas: Vec, + pub seen_transaction_cache_slot_deltas: Vec, pub bank_fields_to_serialize: BankFieldsToSerialize, pub bank_hash_stats: BankHashStats, pub accounts_delta_hash: AccountsDeltaHash, @@ -308,7 +308,7 @@ impl SnapshotPackage { .map(|accounts_lt_hash| accounts_lt_hash.0.checksum()), ), snapshot_storages: accounts_package.snapshot_storages, - status_cache_slot_deltas: snapshot_info.status_cache_slot_deltas, + seen_transaction_cache_slot_deltas: snapshot_info.seen_transaction_cache_slot_deltas, bank_fields_to_serialize: snapshot_info.bank_fields_to_serialize, accounts_delta_hash: snapshot_info.accounts_delta_hash, bank_hash_stats: snapshot_info.bank_hash_stats, @@ -332,7 +332,7 @@ impl SnapshotPackage { block_height: Slot::default(), hash: SnapshotHash(Hash::default()), snapshot_storages: Vec::default(), - status_cache_slot_deltas: Vec::default(), + seen_transaction_cache_slot_deltas: Vec::default(), bank_fields_to_serialize: BankFieldsToSerialize::default_for_tests(), accounts_delta_hash: AccountsDeltaHash(Hash::default()), bank_hash_stats: BankHashStats::default(), diff --git a/runtime/src/snapshot_utils.rs b/runtime/src/snapshot_utils.rs index 54b928308069b3..9f364b5ec16641 100644 --- a/runtime/src/snapshot_utils.rs +++ b/runtime/src/snapshot_utils.rs @@ -63,7 +63,7 @@ mod archive_format; pub mod snapshot_storage_rebuilder; pub use archive_format::*; -pub const SNAPSHOT_STATUS_CACHE_FILENAME: &str = "status_cache"; +pub const SNAPSHOT_SEEN_TRANSACTION_CACHE_FILENAME: &str = "status_cache"; // This name purposefully mismatches its use to maintain backward compatibility with snapshots from old validators. pub const SNAPSHOT_VERSION_FILENAME: &str = "version"; pub const SNAPSHOT_STATE_COMPLETE_FILENAME: &str = "state_complete"; pub const SNAPSHOT_STORAGES_FLUSHED_FILENAME: &str = "storages_flushed"; @@ -183,10 +183,11 @@ impl BankSnapshotInfo { return Err(SnapshotNewFromDirError::IncompleteDir(bank_snapshot_dir)); } - let status_cache_file = bank_snapshot_dir.join(SNAPSHOT_STATUS_CACHE_FILENAME); - if !status_cache_file.is_file() { + let seen_transaction_cache_file = + bank_snapshot_dir.join(SNAPSHOT_SEEN_TRANSACTION_CACHE_FILENAME); + if !seen_transaction_cache_file.is_file() { return Err(SnapshotNewFromDirError::MissingStatusCacheFile( - status_cache_file, + seen_transaction_cache_file, )); } @@ -802,7 +803,7 @@ pub fn serialize_and_archive_snapshot_package( block_height, hash: snapshot_hash, mut snapshot_storages, - status_cache_slot_deltas, + seen_transaction_cache_slot_deltas, bank_fields_to_serialize, bank_hash_stats, accounts_delta_hash, @@ -817,7 +818,7 @@ pub fn serialize_and_archive_snapshot_package( &snapshot_config.bank_snapshots_dir, snapshot_config.snapshot_version, snapshot_storages.as_slice(), - status_cache_slot_deltas.as_slice(), + seen_transaction_cache_slot_deltas.as_slice(), bank_fields_to_serialize, bank_hash_stats, accounts_delta_hash, @@ -962,11 +963,14 @@ fn serialize_snapshot( "bank serialize" ); - let status_cache_path = bank_snapshot_dir.join(SNAPSHOT_STATUS_CACHE_FILENAME); - let (status_cache_consumed_size, status_cache_serialize_us) = measure_us!( - snapshot_bank_utils::serialize_status_cache(slot_deltas, &status_cache_path) - .map_err(|err| AddBankSnapshotError::SerializeStatusCache(Box::new(err)))? - ); + let seen_transaction_cache_path = + bank_snapshot_dir.join(SNAPSHOT_SEEN_TRANSACTION_CACHE_FILENAME); + let (seen_transaction_cache_consumed_size, seen_transaction_cache_serialize_us) = + measure_us!(snapshot_bank_utils::serialize_seen_transaction_cache( + slot_deltas, + &seen_transaction_cache_path + ) + .map_err(|err| AddBankSnapshotError::SerializeStatusCache(Box::new(err)))?); let version_path = bank_snapshot_dir.join(SNAPSHOT_VERSION_FILENAME); let (_, write_version_file_us) = measure_us!(fs::write( @@ -988,11 +992,11 @@ fn serialize_snapshot( "snapshot_bank", ("slot", slot, i64), ("bank_size", bank_snapshot_consumed_size, i64), - ("status_cache_size", status_cache_consumed_size, i64), + ("status_cache_size", seen_transaction_cache_consumed_size, i64), ("flush_storages_us", flush_storages_us, Option), ("hard_link_storages_us", hard_link_storages_us, Option), ("bank_serialize_us", bank_serialize.as_us(), i64), - ("status_cache_serialize_us", status_cache_serialize_us, i64), + ("status_cache_serialize_us", seen_transaction_cache_serialize_us, i64), ("write_version_file_us", write_version_file_us, i64), ( "write_state_complete_file_us", @@ -1068,10 +1072,19 @@ fn archive_snapshot( // Following the existing archive format, the status cache is under snapshots/, not under / // like in the snapshot dir. - let staging_status_cache = staging_snapshots_dir.join(SNAPSHOT_STATUS_CACHE_FILENAME); - let src_status_cache = src_snapshot_dir.join(SNAPSHOT_STATUS_CACHE_FILENAME); - symlink::symlink_file(&src_status_cache, &staging_status_cache) - .map_err(|err| E::SymlinkStatusCache(err, src_status_cache, staging_status_cache))?; + let staging_seen_transaction_cache = + staging_snapshots_dir.join(SNAPSHOT_SEEN_TRANSACTION_CACHE_FILENAME); + let src_seen_transaction_cache = + src_snapshot_dir.join(SNAPSHOT_SEEN_TRANSACTION_CACHE_FILENAME); + symlink::symlink_file(&src_seen_transaction_cache, &staging_seen_transaction_cache).map_err( + |err| { + E::SymlinkStatusCache( + err, + src_seen_transaction_cache, + staging_seen_transaction_cache, + ) + }, + )?; // The bank snapshot has the version file, so symlink it to the correct staging path let staging_version_file = staging_dir.path().join(SNAPSHOT_VERSION_FILENAME); @@ -1704,10 +1717,10 @@ fn create_snapshot_meta_files_for_unarchived_snapshot(unpack_dir: impl AsRef