atlas_runtime/
snapshot_package.rs

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