Skip to main content

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