Decouple accounts hash calculation from snapshot hash (#9507)
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
//! The `bank_forks` module implments BankForks a DAG of checkpointed Banks
|
||||
|
||||
use crate::snapshot_package::{SnapshotPackageSendError, SnapshotPackageSender};
|
||||
use crate::snapshot_package::{AccountsPackageSendError, AccountsPackageSender};
|
||||
use crate::snapshot_utils::{self, SnapshotError};
|
||||
use log::*;
|
||||
use solana_measure::measure::Measure;
|
||||
@ -27,7 +27,7 @@ pub enum CompressionType {
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct SnapshotConfig {
|
||||
// Generate a new snapshot every this many slots
|
||||
pub snapshot_interval_slots: usize,
|
||||
pub snapshot_interval_slots: u64,
|
||||
|
||||
// Where to store the latest packaged snapshot
|
||||
pub snapshot_package_output_path: PathBuf,
|
||||
@ -43,8 +43,8 @@ pub enum BankForksError {
|
||||
#[error("snapshot error")]
|
||||
SnapshotError(#[from] SnapshotError),
|
||||
|
||||
#[error("snapshot package send error")]
|
||||
SnapshotPackageSendError(#[from] SnapshotPackageSendError),
|
||||
#[error("accounts package send error")]
|
||||
AccountsPackageSendError(#[from] AccountsPackageSendError),
|
||||
}
|
||||
type Result<T> = std::result::Result<T, BankForksError>;
|
||||
|
||||
@ -54,6 +54,9 @@ pub struct BankForks {
|
||||
root: Slot,
|
||||
pub snapshot_config: Option<SnapshotConfig>,
|
||||
last_snapshot_slot: Slot,
|
||||
|
||||
pub accounts_hash_interval_slots: Slot,
|
||||
last_accounts_hash_slot: Slot,
|
||||
}
|
||||
|
||||
impl Index<u64> for BankForks {
|
||||
@ -74,6 +77,8 @@ impl BankForks {
|
||||
root: 0,
|
||||
snapshot_config: None,
|
||||
last_snapshot_slot: bank_slot,
|
||||
accounts_hash_interval_slots: std::u64::MAX,
|
||||
last_accounts_hash_slot: bank_slot,
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,6 +164,8 @@ impl BankForks {
|
||||
working_bank,
|
||||
snapshot_config: None,
|
||||
last_snapshot_slot: root,
|
||||
accounts_hash_interval_slots: std::u64::MAX,
|
||||
last_accounts_hash_slot: root,
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,7 +185,7 @@ impl BankForks {
|
||||
pub fn set_root(
|
||||
&mut self,
|
||||
root: Slot,
|
||||
snapshot_package_sender: &Option<SnapshotPackageSender>,
|
||||
accounts_package_sender: &Option<AccountsPackageSender>,
|
||||
) {
|
||||
let old_epoch = self.root_bank().epoch();
|
||||
self.root = root;
|
||||
@ -209,43 +216,46 @@ impl BankForks {
|
||||
.last()
|
||||
.map(|bank| bank.transaction_count())
|
||||
.unwrap_or(0);
|
||||
// Generate each snapshot at a fixed interval
|
||||
// Calculate the accounts hash at a fixed interval
|
||||
let mut is_root_bank_squashed = false;
|
||||
if self.snapshot_config.is_some() && snapshot_package_sender.is_some() {
|
||||
let config = self.snapshot_config.as_ref().unwrap();
|
||||
let mut banks = vec![root_bank];
|
||||
let parents = root_bank.parents();
|
||||
banks.extend(parents.iter());
|
||||
for bank in banks.iter() {
|
||||
let bank_slot = bank.slot();
|
||||
if bank.block_height() % (config.snapshot_interval_slots as u64) == 0 {
|
||||
// Generate a snapshot if snapshots are configured and it's been an appropriate number
|
||||
// of banks since the last snapshot
|
||||
if bank_slot > self.last_snapshot_slot {
|
||||
bank.squash();
|
||||
is_root_bank_squashed = bank_slot == root;
|
||||
let mut snapshot_time = Measure::start("total-snapshot-ms");
|
||||
let r = self.generate_snapshot(
|
||||
bank_slot,
|
||||
&bank.src.roots(),
|
||||
snapshot_package_sender.as_ref().unwrap(),
|
||||
);
|
||||
if r.is_err() {
|
||||
warn!(
|
||||
"Error generating snapshot for bank: {}, err: {:?}",
|
||||
bank_slot, r
|
||||
);
|
||||
} else {
|
||||
self.last_snapshot_slot = bank_slot;
|
||||
}
|
||||
let mut banks = vec![root_bank];
|
||||
let parents = root_bank.parents();
|
||||
banks.extend(parents.iter());
|
||||
for bank in banks.iter() {
|
||||
let bank_slot = bank.slot();
|
||||
if bank.block_height() % self.accounts_hash_interval_slots == 0
|
||||
&& bank_slot > self.last_accounts_hash_slot
|
||||
{
|
||||
self.last_accounts_hash_slot = bank_slot;
|
||||
bank.squash();
|
||||
is_root_bank_squashed = bank_slot == root;
|
||||
|
||||
// Cleanup outdated snapshots
|
||||
self.purge_old_snapshots();
|
||||
snapshot_time.stop();
|
||||
inc_new_counter_info!("total-snapshot-ms", snapshot_time.as_ms() as usize);
|
||||
bank.clean_accounts();
|
||||
bank.update_accounts_hash();
|
||||
|
||||
if self.snapshot_config.is_some() && accounts_package_sender.is_some() {
|
||||
// Generate an accounts package
|
||||
let mut snapshot_time = Measure::start("total-snapshot-ms");
|
||||
let r = self.generate_accounts_package(
|
||||
bank_slot,
|
||||
&bank.src.roots(),
|
||||
accounts_package_sender.as_ref().unwrap(),
|
||||
);
|
||||
if r.is_err() {
|
||||
warn!(
|
||||
"Error generating snapshot for bank: {}, err: {:?}",
|
||||
bank_slot, r
|
||||
);
|
||||
} else {
|
||||
self.last_snapshot_slot = bank_slot;
|
||||
}
|
||||
break;
|
||||
|
||||
// Cleanup outdated snapshots
|
||||
self.purge_old_snapshots();
|
||||
snapshot_time.stop();
|
||||
inc_new_counter_info!("total-snapshot-ms", snapshot_time.as_ms() as usize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !is_root_bank_squashed {
|
||||
@ -282,11 +292,11 @@ impl BankForks {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_snapshot(
|
||||
pub fn generate_accounts_package(
|
||||
&self,
|
||||
root: Slot,
|
||||
slots_to_snapshot: &[Slot],
|
||||
snapshot_package_sender: &SnapshotPackageSender,
|
||||
accounts_package_sender: &AccountsPackageSender,
|
||||
) -> Result<()> {
|
||||
let config = self.snapshot_config.as_ref().unwrap();
|
||||
|
||||
@ -319,8 +329,7 @@ impl BankForks {
|
||||
config.compression.clone(),
|
||||
)?;
|
||||
|
||||
// Send the package to the packaging thread
|
||||
snapshot_package_sender.send(package)?;
|
||||
accounts_package_sender.send(package)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -338,6 +347,10 @@ impl BankForks {
|
||||
pub fn snapshot_config(&self) -> &Option<SnapshotConfig> {
|
||||
&self.snapshot_config
|
||||
}
|
||||
|
||||
pub fn set_accounts_hash_interval_slots(&mut self, accounts_interval_slots: u64) {
|
||||
self.accounts_hash_interval_slots = accounts_interval_slots;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -8,13 +8,14 @@ use std::{
|
||||
};
|
||||
use tempfile::TempDir;
|
||||
|
||||
pub type SnapshotPackageSender = Sender<SnapshotPackage>;
|
||||
pub type SnapshotPackageReceiver = Receiver<SnapshotPackage>;
|
||||
pub type SnapshotPackageSendError = SendError<SnapshotPackage>;
|
||||
pub type AccountsPackageSender = Sender<AccountsPackage>;
|
||||
pub type AccountsPackageReceiver = Receiver<AccountsPackage>;
|
||||
pub type AccountsPackageSendError = SendError<AccountsPackage>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SnapshotPackage {
|
||||
pub struct AccountsPackage {
|
||||
pub root: Slot,
|
||||
pub block_height: Slot,
|
||||
pub slot_deltas: Vec<BankSlotDelta>,
|
||||
pub snapshot_links: TempDir,
|
||||
pub storages: SnapshotStorages,
|
||||
@ -23,9 +24,10 @@ pub struct SnapshotPackage {
|
||||
pub compression: CompressionType,
|
||||
}
|
||||
|
||||
impl SnapshotPackage {
|
||||
impl AccountsPackage {
|
||||
pub fn new(
|
||||
root: Slot,
|
||||
block_height: u64,
|
||||
slot_deltas: Vec<BankSlotDelta>,
|
||||
snapshot_links: TempDir,
|
||||
storages: SnapshotStorages,
|
||||
@ -35,6 +37,7 @@ impl SnapshotPackage {
|
||||
) -> Self {
|
||||
Self {
|
||||
root,
|
||||
block_height,
|
||||
slot_deltas,
|
||||
snapshot_links,
|
||||
storages,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::bank_forks::CompressionType;
|
||||
use crate::hardened_unpack::{unpack_snapshot, UnpackError};
|
||||
use crate::snapshot_package::SnapshotPackage;
|
||||
use crate::snapshot_package::AccountsPackage;
|
||||
use bincode::serialize_into;
|
||||
use bzip2::bufread::BzDecoder;
|
||||
use flate2::read::GzDecoder;
|
||||
@ -93,7 +93,7 @@ pub fn package_snapshot<P: AsRef<Path>, Q: AsRef<Path>>(
|
||||
snapshot_package_output_path: P,
|
||||
snapshot_storages: SnapshotStorages,
|
||||
compression: CompressionType,
|
||||
) -> Result<SnapshotPackage> {
|
||||
) -> Result<AccountsPackage> {
|
||||
// Hard link all the snapshots we need for this package
|
||||
let snapshot_hard_links_dir = tempfile::tempdir_in(snapshot_path)?;
|
||||
|
||||
@ -104,8 +104,8 @@ pub fn package_snapshot<P: AsRef<Path>, Q: AsRef<Path>>(
|
||||
snapshot_storages.len()
|
||||
);
|
||||
|
||||
// Any errors from this point on will cause the above SnapshotPackage to drop, clearing
|
||||
// any temporary state created for the SnapshotPackage (like the snapshot_hard_links_dir)
|
||||
// Any errors from this point on will cause the above AccountsPackage to drop, clearing
|
||||
// any temporary state created for the AccountsPackage (like the snapshot_hard_links_dir)
|
||||
snapshot_files.copy_snapshot_directory(snapshot_hard_links_dir.path())?;
|
||||
|
||||
let snapshot_package_output_file = get_snapshot_archive_path(
|
||||
@ -114,8 +114,9 @@ pub fn package_snapshot<P: AsRef<Path>, Q: AsRef<Path>>(
|
||||
&compression,
|
||||
);
|
||||
|
||||
let package = SnapshotPackage::new(
|
||||
let package = AccountsPackage::new(
|
||||
bank.slot(),
|
||||
bank.block_height(),
|
||||
bank.src.slot_deltas(slots_to_snapshot),
|
||||
snapshot_hard_links_dir,
|
||||
snapshot_storages,
|
||||
@ -136,7 +137,7 @@ fn get_compression_ext(compression: &CompressionType) -> (&'static str, &'static
|
||||
}
|
||||
}
|
||||
|
||||
pub fn archive_snapshot_package(snapshot_package: &SnapshotPackage) -> Result<()> {
|
||||
pub fn archive_snapshot_package(snapshot_package: &AccountsPackage) -> Result<()> {
|
||||
info!(
|
||||
"Generating snapshot archive for slot {}",
|
||||
snapshot_package.root
|
||||
@ -354,8 +355,6 @@ pub fn add_snapshot<P: AsRef<Path>>(
|
||||
bank: &Bank,
|
||||
snapshot_storages: &[SnapshotStorage],
|
||||
) -> Result<SlotSnapshotPaths> {
|
||||
bank.clean_accounts();
|
||||
bank.update_accounts_hash();
|
||||
let slot = bank.slot();
|
||||
// snapshot_path/slot
|
||||
let slot_snapshot_dir = get_bank_snapshot_dir(snapshot_path, slot);
|
||||
|
Reference in New Issue
Block a user