solana_runtime/
snapshot_archive_info.rs

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