solana_runtime/
snapshot_hash.rs

1//! Helper types and functions for handling and dealing with snapshot hashes.
2use {
3    solana_accounts_db::{
4        accounts_hash::MerkleOrLatticeAccountsHash, epoch_accounts_hash::EpochAccountsHash,
5    },
6    solana_clock::Slot,
7    solana_hash::Hash,
8    solana_lattice_hash::lt_hash::Checksum as AccountsLtHashChecksum,
9    solana_sha256_hasher::Hasher,
10};
11
12/// At startup, when loading from snapshots, the starting snapshot hashes need to be passed to
13/// SnapshotPackagerService, which is in charge of pushing the hashes to CRDS.  This struct wraps
14/// up those values make it easier to pass from bank_forks_utils, through validator, to
15/// SnapshotPackagerService.
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub struct StartingSnapshotHashes {
18    pub full: FullSnapshotHash,
19    pub incremental: Option<IncrementalSnapshotHash>,
20}
21
22/// Used by SnapshotPackagerService and SnapshotGossipManager, this struct adds type safety to
23/// ensure a full snapshot hash is pushed to the right CRDS.
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub struct FullSnapshotHash(pub (Slot, SnapshotHash));
26
27/// Used by SnapshotPackagerService and SnapshotGossipManager, this struct adds type safety to
28/// ensure an incremental snapshot hash is pushed to the right CRDS.
29#[derive(Debug, Clone, Copy, PartialEq, Eq)]
30pub struct IncrementalSnapshotHash(pub (Slot, SnapshotHash));
31
32/// The hash used for snapshot archives
33#[derive(Debug, PartialEq, Eq, Clone, Copy)]
34pub struct SnapshotHash(pub Hash);
35
36impl SnapshotHash {
37    /// Make a snapshot hash from accounts hashes
38    #[must_use]
39    pub fn new(
40        merkle_or_lattice_accounts_hash: &MerkleOrLatticeAccountsHash,
41        epoch_accounts_hash: Option<&EpochAccountsHash>,
42        accounts_lt_hash_checksum: Option<AccountsLtHashChecksum>,
43    ) -> Self {
44        let accounts_hash = match merkle_or_lattice_accounts_hash {
45            MerkleOrLatticeAccountsHash::Merkle(accounts_hash_kind) => {
46                *accounts_hash_kind.as_hash()
47            }
48            MerkleOrLatticeAccountsHash::Lattice => Hash::new_from_array(
49                accounts_lt_hash_checksum
50                    .expect("lattice kind must have lt hash checksum")
51                    .0,
52            ),
53        };
54        let snapshot_hash = match epoch_accounts_hash {
55            None => accounts_hash,
56            Some(epoch_accounts_hash) => {
57                let mut hasher = Hasher::default();
58                hasher.hash(accounts_hash.as_ref());
59                hasher.hash(epoch_accounts_hash.as_ref().as_ref());
60                hasher.result()
61            }
62        };
63        Self(snapshot_hash)
64    }
65}