solana_runtime/
snapshot_package.rs

1#[cfg(feature = "dev-context-only-utils")]
2use solana_hash::Hash;
3use {
4    crate::bank::{Bank, BankFieldsToSerialize, BankHashStats, BankSlotDelta},
5    agave_snapshots::{snapshot_hash::SnapshotHash, SnapshotKind},
6    solana_accounts_db::accounts_db::AccountStorageEntry,
7    solana_clock::Slot,
8    std::{
9        sync::{atomic::Ordering, Arc},
10        time::Instant,
11    },
12};
13
14mod compare;
15pub use compare::*;
16
17/// This struct packages up fields to send to SnapshotPackagerService
18pub struct SnapshotPackage {
19    pub snapshot_kind: SnapshotKind,
20    pub slot: Slot,
21    pub block_height: Slot,
22    pub hash: SnapshotHash,
23    pub snapshot_storages: Vec<Arc<AccountStorageEntry>>,
24    pub status_cache_slot_deltas: Vec<BankSlotDelta>,
25    pub bank_fields_to_serialize: BankFieldsToSerialize,
26    pub bank_hash_stats: BankHashStats,
27    pub write_version: u64,
28
29    /// The instant this snapshot package was sent to the queue.
30    /// Used to track how long snapshot packages wait before handling.
31    pub enqueued: Instant,
32}
33
34impl SnapshotPackage {
35    pub fn new(
36        snapshot_kind: SnapshotKind,
37        bank: &Bank,
38        snapshot_storages: Vec<Arc<AccountStorageEntry>>,
39        status_cache_slot_deltas: Vec<BankSlotDelta>,
40    ) -> Self {
41        let slot = bank.slot();
42        if let SnapshotKind::IncrementalSnapshot(incremental_snapshot_base_slot) = snapshot_kind {
43            assert!(
44                slot > incremental_snapshot_base_slot,
45                "Incremental snapshot base slot must be less than the bank being snapshotted!"
46            );
47        }
48
49        let bank_fields_to_serialize = bank.get_fields_to_serialize();
50        Self {
51            snapshot_kind,
52            slot,
53            block_height: bank.block_height(),
54            hash: SnapshotHash::new(bank_fields_to_serialize.accounts_lt_hash.0.checksum()),
55            snapshot_storages,
56            status_cache_slot_deltas,
57            bank_fields_to_serialize,
58            bank_hash_stats: bank.get_bank_hash_stats(),
59            write_version: bank
60                .rc
61                .accounts
62                .accounts_db
63                .write_version
64                .load(Ordering::Acquire),
65            enqueued: Instant::now(),
66        }
67    }
68}
69
70#[cfg(feature = "dev-context-only-utils")]
71impl SnapshotPackage {
72    /// Create a new SnapshotPackage where basically every field is defaulted.
73    /// Only use for tests; many of the fields are invalid!
74    pub fn default_for_tests() -> Self {
75        Self {
76            snapshot_kind: SnapshotKind::FullSnapshot,
77            slot: Slot::default(),
78            block_height: Slot::default(),
79            hash: SnapshotHash(Hash::default()),
80            snapshot_storages: Vec::default(),
81            status_cache_slot_deltas: Vec::default(),
82            bank_fields_to_serialize: BankFieldsToSerialize::default_for_tests(),
83            bank_hash_stats: BankHashStats::default(),
84            write_version: u64::default(),
85            enqueued: Instant::now(),
86        }
87    }
88}
89
90impl std::fmt::Debug for SnapshotPackage {
91    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92        f.debug_struct("SnapshotPackage")
93            .field("kind", &self.snapshot_kind)
94            .field("slot", &self.slot)
95            .field("block_height", &self.block_height)
96            .finish_non_exhaustive()
97    }
98}