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