2021-12-03 09:00:31 -08:00
|
|
|
use {
|
|
|
|
crate::{
|
2022-03-23 09:57:32 -07:00
|
|
|
accounts::Accounts,
|
2021-12-03 09:00:31 -08:00
|
|
|
accounts_db::SnapshotStorages,
|
|
|
|
bank::{Bank, BankSlotDelta},
|
|
|
|
snapshot_archive_info::{SnapshotArchiveInfo, SnapshotArchiveInfoGetter},
|
|
|
|
snapshot_utils::{
|
|
|
|
self, ArchiveFormat, BankSnapshotInfo, Result, SnapshotVersion,
|
|
|
|
TMP_BANK_SNAPSHOT_PREFIX,
|
|
|
|
},
|
2021-08-08 05:57:06 -07:00
|
|
|
},
|
2022-01-11 02:44:46 -08:00
|
|
|
crossbeam_channel::{Receiver, SendError, Sender},
|
2021-12-03 09:00:31 -08:00
|
|
|
log::*,
|
|
|
|
solana_sdk::{clock::Slot, genesis_config::ClusterType, hash::Hash},
|
|
|
|
std::{
|
|
|
|
fs,
|
|
|
|
path::{Path, PathBuf},
|
2022-01-11 02:44:46 -08:00
|
|
|
sync::{Arc, Mutex},
|
2021-08-17 11:01:59 -07:00
|
|
|
},
|
2021-12-03 09:00:31 -08:00
|
|
|
tempfile::TempDir,
|
2020-02-18 09:02:29 -08:00
|
|
|
};
|
2019-07-31 17:58:10 -07:00
|
|
|
|
2021-08-17 11:01:59 -07:00
|
|
|
/// The sender side of the AccountsPackage channel, used by AccountsBackgroundService
|
2021-08-13 14:08:09 -07:00
|
|
|
pub type AccountsPackageSender = Sender<AccountsPackage>;
|
2021-08-17 11:01:59 -07:00
|
|
|
|
|
|
|
/// The receiver side of the AccountsPackage channel, used by AccountsHashVerifier
|
2021-08-13 14:08:09 -07:00
|
|
|
pub type AccountsPackageReceiver = Receiver<AccountsPackage>;
|
2021-08-17 11:01:59 -07:00
|
|
|
|
|
|
|
/// The error type when sending an AccountsPackage over the channel fails
|
2021-08-13 14:08:09 -07:00
|
|
|
pub type AccountsPackageSendError = SendError<AccountsPackage>;
|
2019-07-31 17:58:10 -07:00
|
|
|
|
2021-08-17 11:01:59 -07:00
|
|
|
/// The PendingSnapshotPackage passes a SnapshotPackage from AccountsHashVerifier to
|
|
|
|
/// SnapshotPackagerService for archiving
|
|
|
|
pub type PendingSnapshotPackage = Arc<Mutex<Option<SnapshotPackage>>>;
|
|
|
|
|
2020-01-23 08:46:30 -08:00
|
|
|
#[derive(Debug)]
|
2021-08-13 14:08:09 -07:00
|
|
|
pub struct AccountsPackage {
|
2021-02-04 07:00:33 -08:00
|
|
|
pub slot: Slot,
|
|
|
|
pub block_height: Slot,
|
|
|
|
pub slot_deltas: Vec<BankSlotDelta>,
|
|
|
|
pub snapshot_links: TempDir,
|
2021-08-31 16:33:27 -07:00
|
|
|
pub snapshot_storages: SnapshotStorages,
|
2021-02-04 07:00:33 -08:00
|
|
|
pub hash: Hash, // temporarily here while we still have to calculate hash before serializing bank
|
|
|
|
pub archive_format: ArchiveFormat,
|
|
|
|
pub snapshot_version: SnapshotVersion,
|
2021-08-21 13:41:03 -07:00
|
|
|
pub snapshot_archives_dir: PathBuf,
|
2021-02-04 07:00:33 -08:00
|
|
|
pub expected_capitalization: u64,
|
|
|
|
pub hash_for_testing: Option<Hash>,
|
2021-03-31 13:39:34 -07:00
|
|
|
pub cluster_type: ClusterType,
|
2021-08-31 16:33:27 -07:00
|
|
|
pub snapshot_type: Option<SnapshotType>,
|
2022-03-23 09:57:32 -07:00
|
|
|
pub accounts: Arc<Accounts>,
|
2021-02-04 07:00:33 -08:00
|
|
|
}
|
|
|
|
|
2021-08-13 14:08:09 -07:00
|
|
|
impl AccountsPackage {
|
2021-08-31 16:33:27 -07:00
|
|
|
/// Package up bank files, storages, and slot deltas for a snapshot
|
2021-08-04 07:03:03 -07:00
|
|
|
#[allow(clippy::too_many_arguments)]
|
2021-08-31 16:33:27 -07:00
|
|
|
pub fn new(
|
2021-08-04 07:03:03 -07:00
|
|
|
bank: &Bank,
|
|
|
|
bank_snapshot_info: &BankSnapshotInfo,
|
2021-08-31 16:33:27 -07:00
|
|
|
bank_snapshots_dir: impl AsRef<Path>,
|
|
|
|
slot_deltas: Vec<BankSlotDelta>,
|
2021-08-21 13:41:03 -07:00
|
|
|
snapshot_archives_dir: impl AsRef<Path>,
|
2021-08-04 07:03:03 -07:00
|
|
|
snapshot_storages: SnapshotStorages,
|
|
|
|
archive_format: ArchiveFormat,
|
|
|
|
snapshot_version: SnapshotVersion,
|
|
|
|
hash_for_testing: Option<Hash>,
|
2021-08-31 16:33:27 -07:00
|
|
|
snapshot_type: Option<SnapshotType>,
|
2021-08-10 09:10:15 -07:00
|
|
|
) -> Result<Self> {
|
2021-08-31 16:33:27 -07:00
|
|
|
info!(
|
|
|
|
"Package snapshot for bank {} has {} account storage entries (snapshot type: {:?})",
|
|
|
|
bank.slot(),
|
|
|
|
snapshot_storages.len(),
|
|
|
|
snapshot_type,
|
|
|
|
);
|
|
|
|
|
|
|
|
if let Some(SnapshotType::IncrementalSnapshot(incremental_snapshot_base_slot)) =
|
|
|
|
snapshot_type
|
|
|
|
{
|
|
|
|
assert!(
|
|
|
|
bank.slot() > incremental_snapshot_base_slot,
|
|
|
|
"Incremental snapshot base slot must be less than the bank being snapshotted!"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-08-04 07:03:03 -07:00
|
|
|
// Hard link the snapshot into a tmpdir, to ensure its not removed prior to packaging.
|
2021-08-31 16:33:27 -07:00
|
|
|
let snapshot_links = tempfile::Builder::new()
|
|
|
|
.prefix(&format!("{}{}-", TMP_BANK_SNAPSHOT_PREFIX, bank.slot()))
|
|
|
|
.tempdir_in(bank_snapshots_dir)?;
|
2021-08-04 07:03:03 -07:00
|
|
|
{
|
2021-08-31 16:33:27 -07:00
|
|
|
let snapshot_hardlink_dir = snapshot_links
|
|
|
|
.path()
|
2021-08-04 07:03:03 -07:00
|
|
|
.join(bank_snapshot_info.slot.to_string());
|
|
|
|
fs::create_dir_all(&snapshot_hardlink_dir)?;
|
|
|
|
fs::hard_link(
|
|
|
|
&bank_snapshot_info.snapshot_path,
|
|
|
|
&snapshot_hardlink_dir.join(bank_snapshot_info.slot.to_string()),
|
|
|
|
)?;
|
|
|
|
}
|
|
|
|
|
2021-08-10 09:10:15 -07:00
|
|
|
Ok(Self {
|
|
|
|
slot: bank.slot(),
|
|
|
|
block_height: bank.block_height(),
|
2021-08-31 16:33:27 -07:00
|
|
|
slot_deltas,
|
|
|
|
snapshot_links,
|
|
|
|
snapshot_storages,
|
2021-08-10 09:10:15 -07:00
|
|
|
hash: bank.get_accounts_hash(),
|
2021-08-04 07:03:03 -07:00
|
|
|
archive_format,
|
|
|
|
snapshot_version,
|
2021-08-21 13:41:03 -07:00
|
|
|
snapshot_archives_dir: snapshot_archives_dir.as_ref().to_path_buf(),
|
2021-08-10 09:10:15 -07:00
|
|
|
expected_capitalization: bank.capitalization(),
|
2021-08-04 07:03:03 -07:00
|
|
|
hash_for_testing,
|
2021-08-10 09:10:15 -07:00
|
|
|
cluster_type: bank.cluster_type(),
|
2021-08-31 16:33:27 -07:00
|
|
|
snapshot_type,
|
2022-03-23 09:57:32 -07:00
|
|
|
accounts: bank.accounts(),
|
2021-08-10 09:10:15 -07:00
|
|
|
})
|
2021-08-04 07:03:03 -07:00
|
|
|
}
|
2021-02-04 07:00:33 -08:00
|
|
|
}
|
|
|
|
|
2021-08-13 14:08:09 -07:00
|
|
|
pub struct SnapshotPackage {
|
2021-08-06 18:16:06 -07:00
|
|
|
pub snapshot_archive_info: SnapshotArchiveInfo,
|
2020-04-16 15:12:20 -07:00
|
|
|
pub block_height: Slot,
|
2020-02-10 03:11:37 -08:00
|
|
|
pub slot_deltas: Vec<BankSlotDelta>,
|
2019-10-18 14:58:16 -07:00
|
|
|
pub snapshot_links: TempDir,
|
2021-08-31 16:33:27 -07:00
|
|
|
pub snapshot_storages: SnapshotStorages,
|
2020-06-18 22:38:37 -07:00
|
|
|
pub snapshot_version: SnapshotVersion,
|
2021-08-17 11:01:59 -07:00
|
|
|
pub snapshot_type: SnapshotType,
|
2019-07-31 17:58:10 -07:00
|
|
|
}
|
|
|
|
|
2021-08-31 16:33:27 -07:00
|
|
|
impl From<AccountsPackage> for SnapshotPackage {
|
|
|
|
fn from(accounts_package: AccountsPackage) -> Self {
|
|
|
|
assert!(
|
|
|
|
accounts_package.snapshot_type.is_some(),
|
|
|
|
"Cannot make a SnapshotPackage from an AccountsPackage when SnapshotType is None!"
|
|
|
|
);
|
|
|
|
|
2022-03-22 19:27:54 -07:00
|
|
|
let mut snapshot_storages = accounts_package.snapshot_storages;
|
2021-08-31 16:33:27 -07:00
|
|
|
let snapshot_archive_path = match accounts_package.snapshot_type.unwrap() {
|
|
|
|
SnapshotType::FullSnapshot => snapshot_utils::build_full_snapshot_archive_path(
|
|
|
|
accounts_package.snapshot_archives_dir,
|
|
|
|
accounts_package.slot,
|
|
|
|
&accounts_package.hash,
|
|
|
|
accounts_package.archive_format,
|
|
|
|
),
|
|
|
|
SnapshotType::IncrementalSnapshot(incremental_snapshot_base_slot) => {
|
2022-03-22 19:27:54 -07:00
|
|
|
snapshot_storages.retain(|storages| {
|
|
|
|
storages
|
|
|
|
.first() // storages are grouped by slot in the outer Vec, so all storages will have the same slot as the first
|
|
|
|
.map(|storage| storage.slot() > incremental_snapshot_base_slot)
|
|
|
|
.unwrap_or_default()
|
|
|
|
});
|
|
|
|
assert!(
|
|
|
|
snapshot_storages.iter().all(|storage| storage
|
|
|
|
.iter()
|
|
|
|
.all(|entry| entry.slot() > incremental_snapshot_base_slot)),
|
|
|
|
"Incremental snapshot package must only contain storage entries where slot > incremental snapshot base slot (i.e. full snapshot slot)!"
|
|
|
|
);
|
2021-08-31 16:33:27 -07:00
|
|
|
snapshot_utils::build_incremental_snapshot_archive_path(
|
|
|
|
accounts_package.snapshot_archives_dir,
|
|
|
|
incremental_snapshot_base_slot,
|
|
|
|
accounts_package.slot,
|
|
|
|
&accounts_package.hash,
|
|
|
|
accounts_package.archive_format,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-07-31 17:58:10 -07:00
|
|
|
Self {
|
2021-08-06 18:16:06 -07:00
|
|
|
snapshot_archive_info: SnapshotArchiveInfo {
|
|
|
|
path: snapshot_archive_path,
|
2021-08-31 16:33:27 -07:00
|
|
|
slot: accounts_package.slot,
|
|
|
|
hash: accounts_package.hash,
|
|
|
|
archive_format: accounts_package.archive_format,
|
2021-08-06 18:16:06 -07:00
|
|
|
},
|
2021-08-31 16:33:27 -07:00
|
|
|
block_height: accounts_package.block_height,
|
|
|
|
slot_deltas: accounts_package.slot_deltas,
|
|
|
|
snapshot_links: accounts_package.snapshot_links,
|
2022-03-22 19:27:54 -07:00
|
|
|
snapshot_storages,
|
2021-08-31 16:33:27 -07:00
|
|
|
snapshot_version: accounts_package.snapshot_version,
|
|
|
|
snapshot_type: accounts_package.snapshot_type.unwrap(),
|
2019-07-31 17:58:10 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-08-06 18:16:06 -07:00
|
|
|
|
2021-08-13 14:08:09 -07:00
|
|
|
impl SnapshotArchiveInfoGetter for SnapshotPackage {
|
2021-08-06 18:16:06 -07:00
|
|
|
fn snapshot_archive_info(&self) -> &SnapshotArchiveInfo {
|
|
|
|
&self.snapshot_archive_info
|
|
|
|
}
|
|
|
|
}
|
2021-08-17 11:01:59 -07:00
|
|
|
|
2021-08-31 16:33:27 -07:00
|
|
|
/// Snapshots come in two flavors, Full and Incremental. The IncrementalSnapshot has a Slot field,
|
|
|
|
/// which is the incremental snapshot base slot.
|
2021-08-17 11:01:59 -07:00
|
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
|
|
pub enum SnapshotType {
|
|
|
|
FullSnapshot,
|
2021-08-31 16:33:27 -07:00
|
|
|
IncrementalSnapshot(Slot),
|
2021-08-17 11:01:59 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl SnapshotType {
|
2021-08-31 16:33:27 -07:00
|
|
|
pub fn is_full_snapshot(&self) -> bool {
|
|
|
|
matches!(self, SnapshotType::FullSnapshot)
|
|
|
|
}
|
|
|
|
pub fn is_incremental_snapshot(&self) -> bool {
|
|
|
|
matches!(self, SnapshotType::IncrementalSnapshot(_))
|
2021-08-17 11:01:59 -07:00
|
|
|
}
|
|
|
|
}
|