diff --git a/Cargo.lock b/Cargo.lock index 982eb8dff236b4..a6cc974b99b266 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6850,6 +6850,7 @@ dependencies = [ "bitflags 2.6.0", "bs58", "byteorder", + "bzip2", "chrono", "chrono-humanize", "crossbeam-channel", @@ -6908,6 +6909,7 @@ dependencies = [ "static_assertions", "strum", "strum_macros", + "tar", "tempfile", "test-case", "thiserror", diff --git a/ledger/Cargo.toml b/ledger/Cargo.toml index 15c56d07c94c33..57bb0d1a0a8c73 100644 --- a/ledger/Cargo.toml +++ b/ledger/Cargo.toml @@ -14,6 +14,7 @@ assert_matches = { workspace = true } bincode = { workspace = true } bitflags = { workspace = true, features = ["serde"] } byteorder = { workspace = true } +bzip2 = { workspace = true } chrono = { workspace = true, features = ["default", "serde"] } chrono-humanize = { workspace = true } crossbeam-channel = { workspace = true } @@ -73,6 +74,7 @@ spl-token-2022 = { workspace = true, features = ["no-entrypoint"] } static_assertions = { workspace = true } strum = { workspace = true, features = ["derive"] } strum_macros = { workspace = true } +tar = { workspace = true } tempfile = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true, features = ["full"] } diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index 54f612483be958..80ce6b83dce1a3 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -71,7 +71,7 @@ use { }, convert::TryInto, fmt::Write, - fs, + fs::{self, File}, io::{Error as IoError, ErrorKind}, ops::Bound, path::{Path, PathBuf}, @@ -81,6 +81,7 @@ use { Arc, Mutex, RwLock, }, }, + tar, tempfile::{Builder, TempDir}, thiserror::Error, trees::{Tree, TreeWalk}, @@ -4835,32 +4836,12 @@ pub fn create_new_ledger( drop(blockstore); let archive_path = ledger_path.join(DEFAULT_GENESIS_ARCHIVE); - let args = vec![ - "jcfhS", - archive_path.to_str().unwrap(), - "-C", - ledger_path.to_str().unwrap(), - DEFAULT_GENESIS_FILE, - blockstore_dir, - ]; - let output = std::process::Command::new("tar") - .env("COPYFILE_DISABLE", "1") - .args(args) - .output() - .unwrap(); - if !output.status.success() { - use std::str::from_utf8; - error!("tar stdout: {}", from_utf8(&output.stdout).unwrap_or("?")); - error!("tar stderr: {}", from_utf8(&output.stderr).unwrap_or("?")); - - return Err(BlockstoreError::Io(IoError::new( - ErrorKind::Other, - format!( - "Error trying to generate snapshot archive: {}", - output.status - ), - ))); - } + let archive_file = File::create(&archive_path)?; + let encoder = bzip2::write::BzEncoder::new(archive_file, bzip2::Compression::best()); + let mut archive = tar::Builder::new(encoder); + archive.append_path_with_name(ledger_path.join(DEFAULT_GENESIS_FILE), DEFAULT_GENESIS_FILE)?; + archive.append_dir_all(blockstore_dir, ledger_path.join(blockstore_dir))?; + archive.into_inner()?; // ensure the genesis archive can be unpacked and it is under // max_genesis_archive_unpacked_size, immediately after creating it above. @@ -5352,6 +5333,9 @@ pub mod tests { crossbeam_channel::unbounded, rand::{seq::SliceRandom, thread_rng}, solana_account_decoder::parse_token::UiTokenAmount, + solana_accounts_db::hardened_unpack::{ + open_genesis_config, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, + }, solana_entry::entry::{next_entry, next_entry_mut}, solana_runtime::bank::{Bank, RewardType}, solana_sdk::{ @@ -5422,6 +5406,17 @@ pub mod tests { assert!(Path::new(ledger_path.path()) .join(BLOCKSTORE_DIRECTORY_ROCKS_LEVEL) .exists()); + + assert_eq!( + genesis_config, + open_genesis_config(ledger_path.path(), MAX_GENESIS_ARCHIVE_UNPACKED_SIZE).unwrap() + ); + // Remove DEFAULT_GENESIS_FILE to force extraction of DEFAULT_GENESIS_ARCHIVE + std::fs::remove_file(ledger_path.path().join(DEFAULT_GENESIS_FILE)).unwrap(); + assert_eq!( + genesis_config, + open_genesis_config(ledger_path.path(), MAX_GENESIS_ARCHIVE_UNPACKED_SIZE).unwrap() + ); } #[test] diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index 69c5ae6de9e2f0..1b5a8923be293e 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -5408,6 +5408,7 @@ dependencies = [ "bincode", "bitflags 2.6.0", "byteorder 1.5.0", + "bzip2", "chrono", "chrono-humanize", "crossbeam-channel", @@ -5462,6 +5463,7 @@ dependencies = [ "static_assertions", "strum", "strum_macros", + "tar", "tempfile", "thiserror", "tokio",