solana_runtime/
snapshot_archive_info.rs

1//! Information about snapshot archives
2
3use {
4    crate::{
5        snapshot_hash::SnapshotHash,
6        snapshot_utils::{self, ArchiveFormat, Result},
7    },
8    solana_sdk::clock::Slot,
9    std::{cmp::Ordering, path::PathBuf},
10};
11
12/// Trait to query the snapshot archive information
13pub trait SnapshotArchiveInfoGetter {
14    fn snapshot_archive_info(&self) -> &SnapshotArchiveInfo;
15
16    fn path(&self) -> &PathBuf {
17        &self.snapshot_archive_info().path
18    }
19
20    fn slot(&self) -> Slot {
21        self.snapshot_archive_info().slot
22    }
23
24    fn hash(&self) -> &SnapshotHash {
25        &self.snapshot_archive_info().hash
26    }
27
28    fn archive_format(&self) -> ArchiveFormat {
29        self.snapshot_archive_info().archive_format
30    }
31
32    fn is_remote(&self) -> bool {
33        self.snapshot_archive_info()
34            .path
35            .parent()
36            .is_some_and(|p| p.ends_with(snapshot_utils::SNAPSHOT_ARCHIVE_DOWNLOAD_DIR))
37    }
38}
39
40/// Common information about a snapshot archive
41#[derive(PartialEq, Eq, Debug, Clone)]
42pub struct SnapshotArchiveInfo {
43    /// Path to the snapshot archive file
44    pub path: PathBuf,
45
46    /// Slot that the snapshot was made
47    pub slot: Slot,
48
49    /// Hash for the snapshot
50    pub hash: SnapshotHash,
51
52    /// Archive format for the snapshot file
53    pub archive_format: ArchiveFormat,
54}
55
56/// Information about a full snapshot archive: its path, slot, hash, and archive format
57#[derive(PartialEq, Eq, Debug, Clone)]
58pub struct FullSnapshotArchiveInfo(SnapshotArchiveInfo);
59
60impl FullSnapshotArchiveInfo {
61    /// Parse the path to a full snapshot archive and return a new `FullSnapshotArchiveInfo`
62    pub fn new_from_path(path: PathBuf) -> Result<Self> {
63        let filename = snapshot_utils::path_to_file_name_str(path.as_path())?;
64        let (slot, hash, archive_format) =
65            snapshot_utils::parse_full_snapshot_archive_filename(filename)?;
66
67        Ok(Self::new(SnapshotArchiveInfo {
68            path,
69            slot,
70            hash,
71            archive_format,
72        }))
73    }
74
75    pub(crate) fn new(snapshot_archive_info: SnapshotArchiveInfo) -> Self {
76        Self(snapshot_archive_info)
77    }
78}
79
80impl SnapshotArchiveInfoGetter for FullSnapshotArchiveInfo {
81    fn snapshot_archive_info(&self) -> &SnapshotArchiveInfo {
82        &self.0
83    }
84}
85
86impl PartialOrd for FullSnapshotArchiveInfo {
87    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
88        Some(self.cmp(other))
89    }
90}
91
92// Order `FullSnapshotArchiveInfo` by slot (ascending), which practically is sorting chronologically
93impl Ord for FullSnapshotArchiveInfo {
94    fn cmp(&self, other: &Self) -> Ordering {
95        self.slot().cmp(&other.slot())
96    }
97}
98
99/// Information about an incremental snapshot archive: its path, slot, base slot, hash, and archive format
100#[derive(PartialEq, Eq, Debug, Clone)]
101pub struct IncrementalSnapshotArchiveInfo {
102    /// The slot that the incremental snapshot was based from.  This is the same as the full
103    /// snapshot slot used when making the incremental snapshot.
104    base_slot: Slot,
105
106    /// Use the `SnapshotArchiveInfo` struct for the common fields: path, slot, hash, and
107    /// archive_format, but as they pertain to the incremental snapshot.
108    inner: SnapshotArchiveInfo,
109}
110
111impl IncrementalSnapshotArchiveInfo {
112    /// Parse the path to an incremental snapshot archive and return a new `IncrementalSnapshotArchiveInfo`
113    pub fn new_from_path(path: PathBuf) -> Result<Self> {
114        let filename = snapshot_utils::path_to_file_name_str(path.as_path())?;
115        let (base_slot, slot, hash, archive_format) =
116            snapshot_utils::parse_incremental_snapshot_archive_filename(filename)?;
117
118        Ok(Self::new(
119            base_slot,
120            SnapshotArchiveInfo {
121                path,
122                slot,
123                hash,
124                archive_format,
125            },
126        ))
127    }
128
129    pub(crate) fn new(base_slot: Slot, snapshot_archive_info: SnapshotArchiveInfo) -> Self {
130        Self {
131            base_slot,
132            inner: snapshot_archive_info,
133        }
134    }
135
136    pub fn base_slot(&self) -> Slot {
137        self.base_slot
138    }
139}
140
141impl SnapshotArchiveInfoGetter for IncrementalSnapshotArchiveInfo {
142    fn snapshot_archive_info(&self) -> &SnapshotArchiveInfo {
143        &self.inner
144    }
145}
146
147impl PartialOrd for IncrementalSnapshotArchiveInfo {
148    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
149        Some(self.cmp(other))
150    }
151}
152
153// Order `IncrementalSnapshotArchiveInfo` by base slot (ascending), then slot (ascending), which
154// practically is sorting chronologically
155impl Ord for IncrementalSnapshotArchiveInfo {
156    fn cmp(&self, other: &Self) -> Ordering {
157        self.base_slot()
158            .cmp(&other.base_slot())
159            .then(self.slot().cmp(&other.slot()))
160    }
161}