Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(state): delete old database directories #4586

Merged
merged 14 commits into from
Jun 21, 2022
8 changes: 8 additions & 0 deletions zebra-state/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ pub struct Config {
///
/// Set to `None` by default: Zebra continues syncing indefinitely.
pub debug_stop_at_height: Option<u32>,

/// Whether to delete the old database directories when present.
///
/// Set to `true` by default. If this is set to `false`,
/// no check for old database versions will be made and nothing will be
/// deleted.
pub delete_old_database: bool,
}

fn gen_temp_path(prefix: &str) -> PathBuf {
Expand Down Expand Up @@ -108,6 +115,7 @@ impl Default for Config {
cache_dir,
ephemeral: false,
debug_stop_at_height: None,
delete_old_database: true,
}
}
}
47 changes: 46 additions & 1 deletion zebrad/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
//! * answers RPC client requests using the State Service and Mempool Service
//! * submits client transactions to the node's mempool

use std::{cmp::max, ops::Add, time::Duration};
use std::{cmp::max, fs::remove_dir_all, ops::Add, path::PathBuf, time::Duration};

use abscissa_core::{config, Command, FrameworkError, Options, Runnable};
use chrono::Utc;
Expand Down Expand Up @@ -105,6 +105,11 @@ impl StartCmd {
let config = app_config().clone();
info!(?config);

if config.state.delete_old_database {
info!("checking old database versions");
check_and_delete_old_databases(config.state.cache_dir.clone())?;
}
teor2345 marked this conversation as resolved.
Show resolved Hide resolved

info!("initializing node state");
let (state_service, read_only_state_service, latest_chain_tip, chain_tip_change) =
zebra_state::init(config.state.clone(), config.network.network);
Expand Down Expand Up @@ -601,3 +606,43 @@ impl config::Override<ZebradConfig> for StartCmd {
Ok(config)
}
}

/// Check if there are old database folders and delete them from the filesystem.
///
/// Iterate over the files and directories in the databases folder and delete if:
/// - The entry is a directory.
/// - The directory name has a lenght of at least 2 characters.
/// - The directory name has a prefix `v`.
/// - The directory name without the prefix can be parsed as an unsigned number.
/// - The parsed number is lower than the hardcoded `DATABASE_FORMAT_VERSION`.
fn check_and_delete_old_databases(cache_dir: PathBuf) -> Result<(), Report> {
teor2345 marked this conversation as resolved.
Show resolved Hide resolved
let cache_dir = cache_dir.join("state");
oxarbitrage marked this conversation as resolved.
Show resolved Hide resolved
for entry in (cache_dir.read_dir()?).flatten() {
if entry.file_type()?.is_dir() {
let dir_name = entry
.file_name()
.into_string()
.expect("conversion from osstring to string should work.");
if dir_name.len() >= 2 && dir_name.starts_with('v') {
let potential_version_number_string = dir_name
.strip_prefix('v')
.expect("should not panic as we know there is a `v` prefix.")
.to_string();
let version_number: u32 =
potential_version_number_string.parse().unwrap_or(u32::MAX);
oxarbitrage marked this conversation as resolved.
Show resolved Hide resolved
if version_number < zebra_state::constants::DATABASE_FORMAT_VERSION {
let delete_path = cache_dir.join(dir_name);
info!(
"deleting {}",
delete_path
.to_str()
.expect("path is valid, should not panic")
);
remove_dir_all(delete_path)?;
}
}
}
}

Ok(())
}