diff --git a/core/benches/blocktree.rs b/core/benches/blocktree.rs index 8930ffca56..966b187379 100644 --- a/core/benches/blocktree.rs +++ b/core/benches/blocktree.rs @@ -11,12 +11,13 @@ use rand::{thread_rng, Rng}; use solana::blocktree::{get_tmp_ledger_path, Blocktree}; use solana::entry::{make_large_test_entries, make_tiny_test_entries, EntrySlice}; use solana::packet::{Blob, BLOB_HEADER_SIZE}; +use std::path::Path; use test::Bencher; // Given some blobs and a ledger at ledger_path, benchmark writing the blobs to the ledger -fn bench_write_blobs(bench: &mut Bencher, blobs: &mut Vec, ledger_path: &str) { +fn bench_write_blobs(bench: &mut Bencher, blobs: &mut Vec, ledger_path: &Path) { let blocktree = - Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); + Blocktree::open(ledger_path).expect("Expected to be able to open database ledger"); let num_blobs = blobs.len(); @@ -36,7 +37,7 @@ fn bench_write_blobs(bench: &mut Bencher, blobs: &mut Vec, ledger_path: &s } }); - Blocktree::destroy(&ledger_path).expect("Expected successful database destruction"); + Blocktree::destroy(ledger_path).expect("Expected successful database destruction"); } // Insert some blobs into the ledger in preparation for read benchmarks diff --git a/core/src/blocktree.rs b/core/src/blocktree.rs index b6c360a03d..d69b4d93ac 100644 --- a/core/src/blocktree.rs +++ b/core/src/blocktree.rs @@ -27,6 +27,7 @@ use std::cell::RefCell; use std::cmp; use std::fs; use std::io; +use std::path::{Path, PathBuf}; use std::rc::Rc; use std::sync::mpsc::{sync_channel, Receiver, SyncSender, TrySendError}; use std::sync::{Arc, RwLock}; @@ -113,14 +114,12 @@ pub const INDEX_CF: &str = "index"; impl Blocktree { /// Opens a Ledger in directory, provides "infinite" window of blobs - pub fn open(ledger_path: &str) -> Result { - use std::path::Path; - + pub fn open(ledger_path: &Path) -> Result { fs::create_dir_all(&ledger_path)?; - let ledger_path = Path::new(&ledger_path).join(BLOCKTREE_DIRECTORY); + let blocktree_path = ledger_path.join(BLOCKTREE_DIRECTORY); // Open the database - let db = Database::open(&ledger_path)?; + let db = Database::open(&blocktree_path)?; let batch_processor = unsafe { Arc::new(RwLock::new(db.batch_processor())) }; @@ -162,7 +161,7 @@ impl Blocktree { } pub fn open_with_signal( - ledger_path: &str, + ledger_path: &Path, ) -> Result<(Self, Receiver, CompletedSlotsReceiver)> { let mut blocktree = Self::open(ledger_path)?; let (signal_sender, signal_receiver) = sync_channel(1); @@ -174,11 +173,11 @@ impl Blocktree { Ok((blocktree, signal_receiver, completed_slots_receiver)) } - pub fn destroy(ledger_path: &str) -> Result<()> { - // Database::destroy() fails is the path doesn't exist + pub fn destroy(ledger_path: &Path) -> Result<()> { + // Database::destroy() fails if the path doesn't exist fs::create_dir_all(ledger_path)?; - let path = std::path::Path::new(ledger_path).join(BLOCKTREE_DIRECTORY); - Database::destroy(&path) + let blocktree_path = ledger_path.join(BLOCKTREE_DIRECTORY); + Database::destroy(&blocktree_path) } pub fn meta(&self, slot: u64) -> Result> { @@ -1958,7 +1957,7 @@ fn slot_has_updates(slot_meta: &SlotMeta, slot_meta_backup: &Option) - // Creates a new ledger with slot 0 full of ticks (and only ticks). // // Returns the blockhash that can be used to append entries with. -pub fn create_new_ledger(ledger_path: &str, genesis_block: &GenesisBlock) -> Result { +pub fn create_new_ledger(ledger_path: &Path, genesis_block: &GenesisBlock) -> Result { let ticks_per_slot = genesis_block.ticks_per_slot; Blocktree::destroy(ledger_path)?; genesis_block.write(&ledger_path)?; @@ -1971,7 +1970,7 @@ pub fn create_new_ledger(ledger_path: &str, genesis_block: &GenesisBlock) -> Res Ok(entries.last().unwrap().hash) } -pub fn genesis<'a, I>(ledger_path: &str, keypair: &Keypair, entries: I) -> Result<()> +pub fn genesis<'a, I>(ledger_path: &Path, keypair: &Keypair, entries: I) -> Result<()> where I: IntoIterator, { @@ -2008,12 +2007,18 @@ macro_rules! get_tmp_ledger_path { }; } -pub fn get_tmp_ledger_path(name: &str) -> String { +pub fn get_tmp_ledger_path(name: &str) -> PathBuf { use std::env; let out_dir = env::var("FARF_DIR").unwrap_or_else(|_| "farf".to_string()); let keypair = Keypair::new(); - let path = format!("{}/ledger/{}-{}", out_dir, name, keypair.pubkey()); + let path = [ + out_dir, + "ledger".to_string(), + format!("{}-{}", name, keypair.pubkey()), + ] + .iter() + .collect(); // whack any possible collision let _ignored = fs::remove_dir_all(&path); @@ -2032,7 +2037,7 @@ macro_rules! create_new_tmp_ledger { // // Note: like `create_new_ledger` the returned ledger will have slot 0 full of ticks (and only // ticks) -pub fn create_new_tmp_ledger(name: &str, genesis_block: &GenesisBlock) -> (String, Hash) { +pub fn create_new_tmp_ledger(name: &str, genesis_block: &GenesisBlock) -> (PathBuf, Hash) { let ledger_path = get_tmp_ledger_path(name); let blockhash = create_new_ledger(&ledger_path, genesis_block).unwrap(); (ledger_path, blockhash) @@ -2045,7 +2050,7 @@ macro_rules! tmp_copy_blocktree { }; } -pub fn tmp_copy_blocktree(from: &str, name: &str) -> String { +pub fn tmp_copy_blocktree(from: &Path, name: &str) -> PathBuf { let path = get_tmp_ledger_path(name); let blocktree = Blocktree::open(from).unwrap(); diff --git a/core/src/broadcast_stage.rs b/core/src/broadcast_stage.rs index 17db905de9..ea0e164a87 100644 --- a/core/src/broadcast_stage.rs +++ b/core/src/broadcast_stage.rs @@ -241,6 +241,7 @@ mod test { use solana_sdk::hash::Hash; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; + use std::path::Path; use std::sync::atomic::AtomicBool; use std::sync::mpsc::channel; use std::sync::{Arc, RwLock}; @@ -255,7 +256,7 @@ mod test { fn setup_dummy_broadcast_service( leader_pubkey: &Pubkey, - ledger_path: &str, + ledger_path: &Path, entry_receiver: Receiver, ) -> MockBroadcastStage { // Make the database ledger diff --git a/core/src/cluster_tests.rs b/core/src/cluster_tests.rs index 475d5c2667..d134c59969 100644 --- a/core/src/cluster_tests.rs +++ b/core/src/cluster_tests.rs @@ -22,6 +22,7 @@ use solana_sdk::timing::{ NUM_CONSECUTIVE_LEADER_SLOTS, }; use solana_sdk::transport::TransportError; +use std::path::Path; use std::thread::sleep; use std::time::Duration; @@ -94,7 +95,7 @@ pub fn fullnode_exit(entry_point_info: &ContactInfo, nodes: usize) { } } -pub fn verify_ledger_ticks(ledger_path: &str, ticks_per_slot: usize) { +pub fn verify_ledger_ticks(ledger_path: &Path, ticks_per_slot: usize) { let ledger = Blocktree::open(ledger_path).unwrap(); let zeroth_slot = ledger.get_slot_entries(0, 0, None).unwrap(); let last_id = zeroth_slot.last().unwrap().hash; diff --git a/core/src/erasure.rs b/core/src/erasure.rs index a62381a823..0b7b6901b1 100644 --- a/core/src/erasure.rs +++ b/core/src/erasure.rs @@ -334,6 +334,7 @@ pub mod test { use solana_sdk::signature::Signable; use solana_sdk::signature::{Keypair, KeypairUtil}; use std::borrow::Borrow; + use std::path::Path; /// Specifies the contents of a 16-data-blob and 4-coding-blob erasure set /// Exists to be passed to `generate_blocktree_with_coding` @@ -748,7 +749,7 @@ pub mod test { /// Genarates a ledger according to the given specs. /// Blocktree should have correct SlotMeta and ErasureMeta and so on but will not have done any /// possible recovery. - pub fn generate_blocktree_with_coding(ledger_path: &str, specs: &[SlotSpec]) -> Blocktree { + pub fn generate_blocktree_with_coding(ledger_path: &Path, specs: &[SlotSpec]) -> Blocktree { let blocktree = Blocktree::open(ledger_path).unwrap(); let model = generate_ledger_model(specs); diff --git a/core/src/local_cluster.rs b/core/src/local_cluster.rs index f0142a9ce7..54d88914b9 100644 --- a/core/src/local_cluster.rs +++ b/core/src/local_cluster.rs @@ -27,6 +27,7 @@ use solana_vote_api::vote_state::VoteState; use std::collections::HashMap; use std::fs::remove_dir_all; use std::io::{Error, ErrorKind, Result}; +use std::path::PathBuf; use std::sync::Arc; use solana_librapay_api::librapay_transaction; @@ -36,17 +37,17 @@ pub struct ValidatorInfo { pub keypair: Arc, pub voting_keypair: Arc, pub storage_keypair: Arc, - pub ledger_path: String, + pub ledger_path: PathBuf, pub contact_info: ContactInfo, } pub struct ReplicatorInfo { pub replicator_storage_pubkey: Pubkey, - pub ledger_path: String, + pub ledger_path: PathBuf, } impl ReplicatorInfo { - fn new(storage_pubkey: Pubkey, ledger_path: String) -> Self { + fn new(storage_pubkey: Pubkey, ledger_path: PathBuf) -> Self { Self { replicator_storage_pubkey: storage_pubkey, ledger_path, @@ -395,7 +396,7 @@ impl LocalCluster { .chain(self.replicator_infos.values().map(|info| &info.ledger_path)) { remove_dir_all(&ledger_path) - .unwrap_or_else(|_| panic!("Unable to remove {}", ledger_path)); + .unwrap_or_else(|_| panic!("Unable to remove {:?}", ledger_path)); } } diff --git a/core/src/replicator.rs b/core/src/replicator.rs index 926a870f11..1e7288f4f3 100644 --- a/core/src/replicator.rs +++ b/core/src/replicator.rs @@ -62,7 +62,7 @@ pub struct Replicator { struct ReplicatorMeta { slot: u64, slots_per_segment: u64, - ledger_path: String, + ledger_path: PathBuf, signature: Signature, ledger_data_file_encrypted: PathBuf, sampling_offsets: Vec, @@ -200,7 +200,7 @@ impl Replicator { /// * `keypair` - Keypair for this replicator #[allow(clippy::new_ret_no_self)] pub fn new( - ledger_path: &str, + ledger_path: &Path, node: Node, cluster_entrypoint: ContactInfo, keypair: Arc, @@ -263,7 +263,7 @@ impl Replicator { let exit = exit.clone(); let node_info = node.info.clone(); let mut meta = ReplicatorMeta { - ledger_path: ledger_path.to_string(), + ledger_path: ledger_path.to_path_buf(), ..ReplicatorMeta::default() }; spawn(move || { @@ -516,8 +516,7 @@ impl Replicator { } fn encrypt_ledger(meta: &mut ReplicatorMeta, blocktree: &Arc) -> Result<()> { - let ledger_path = Path::new(&meta.ledger_path); - meta.ledger_data_file_encrypted = ledger_path.join(ENCRYPTED_FILENAME); + meta.ledger_data_file_encrypted = meta.ledger_path.join(ENCRYPTED_FILENAME); { let mut ivec = [0u8; 64]; diff --git a/core/src/validator.rs b/core/src/validator.rs index e067f112ff..c6e8ee2581 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -26,6 +26,7 @@ use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::timing::{timestamp, DEFAULT_SLOTS_PER_TURN}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::Receiver; use std::sync::{Arc, Mutex, RwLock}; @@ -79,7 +80,7 @@ impl Validator { pub fn new( mut node: Node, keypair: &Arc, - ledger_path: &str, + ledger_path: &Path, vote_account: &Pubkey, voting_keypair: &Arc, storage_keypair: &Arc, @@ -340,7 +341,7 @@ fn get_bank_forks( } pub fn new_banks_from_blocktree( - blocktree_path: &str, + blocktree_path: &Path, account_paths: Option, snapshot_path: Option, verify_ledger: bool, @@ -401,7 +402,7 @@ impl Service for Validator { } } -pub fn new_validator_for_tests() -> (Validator, ContactInfo, Keypair, String) { +pub fn new_validator_for_tests() -> (Validator, ContactInfo, Keypair, PathBuf) { use crate::blocktree::create_new_tmp_ledger; use crate::genesis_utils::{create_genesis_block_with_leader, GenesisBlockInfo}; diff --git a/core/tests/replicator.rs b/core/tests/replicator.rs index 854c3deb01..88f38d1ff8 100644 --- a/core/tests/replicator.rs +++ b/core/tests/replicator.rs @@ -93,7 +93,7 @@ fn test_replicator_startup_leader_hang() { solana_logger::setup(); info!("starting replicator test"); - let leader_ledger_path = "replicator_test_leader_ledger"; + let leader_ledger_path = std::path::PathBuf::from("replicator_test_leader_ledger"); let (genesis_block, _mint_keypair) = create_genesis_block(10_000); let (replicator_ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block); diff --git a/genesis/src/main.rs b/genesis/src/main.rs index cc881a5e89..29cb9037e7 100644 --- a/genesis/src/main.rs +++ b/genesis/src/main.rs @@ -34,6 +34,7 @@ use std::collections::HashMap; use std::error; use std::fs::File; use std::io; +use std::path::PathBuf; use std::str::FromStr; use std::time::{Duration, Instant}; @@ -248,7 +249,7 @@ fn main() -> Result<(), Box> { let bootstrap_storage_keypair_file = matches.value_of("bootstrap_storage_keypair_file").unwrap(); let mint_keypair_file = matches.value_of("mint_keypair_file").unwrap(); - let ledger_path = matches.value_of("ledger_path").unwrap(); + let ledger_path = PathBuf::from(matches.value_of("ledger_path").unwrap()); let lamports = value_t_or_exit!(matches, "lamports", u64); let bootstrap_leader_lamports = value_t_or_exit!(matches, "bootstrap_leader_lamports", u64); let bootstrap_leader_stake_lamports = @@ -359,7 +360,7 @@ fn main() -> Result<(), Box> { builder = solana_storage_api::rewards_pools::genesis(builder); builder = solana_stake_api::rewards_pools::genesis(builder); - create_new_ledger(ledger_path, &builder.build())?; + create_new_ledger(&ledger_path, &builder.build())?; Ok(()) } diff --git a/ledger-tool/src/main.rs b/ledger-tool/src/main.rs index 9c64ca614a..ff4031a8a3 100644 --- a/ledger-tool/src/main.rs +++ b/ledger-tool/src/main.rs @@ -5,6 +5,7 @@ use solana_sdk::genesis_block::GenesisBlock; use std::collections::BTreeMap; use std::fs::File; use std::io::{stdout, Write}; +use std::path::PathBuf; use std::process::exit; use std::str::FromStr; @@ -119,20 +120,20 @@ fn main() { )) .get_matches(); - let ledger_path = matches.value_of("ledger").unwrap(); + let ledger_path = PathBuf::from(matches.value_of("ledger").unwrap()); - let genesis_block = GenesisBlock::load(ledger_path).unwrap_or_else(|err| { + let genesis_block = GenesisBlock::load(&ledger_path).unwrap_or_else(|err| { eprintln!( - "Failed to open ledger genesis_block at {}: {}", + "Failed to open ledger genesis_block at {:?}: {}", ledger_path, err ); exit(1); }); - let blocktree = match Blocktree::open(ledger_path) { + let blocktree = match Blocktree::open(&ledger_path) { Ok(blocktree) => blocktree, Err(err) => { - eprintln!("Failed to open ledger at {}: {}", ledger_path, err); + eprintln!("Failed to open ledger at {:?}: {}", ledger_path, err); exit(1); } }; diff --git a/ledger-tool/tests/basic.rs b/ledger-tool/tests/basic.rs index 48e0a5b7f5..2b01ff14eb 100644 --- a/ledger-tool/tests/basic.rs +++ b/ledger-tool/tests/basic.rs @@ -38,6 +38,8 @@ fn nominal() { let (ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block); let ticks = ticks_per_slot as usize; + let ledger_path = ledger_path.to_str().unwrap(); + // Basic validation let output = run_ledger_tool(&["-l", &ledger_path, "verify"]); assert!(output.status.success()); diff --git a/replicator/src/main.rs b/replicator/src/main.rs index dcf9b915e7..383b251daa 100644 --- a/replicator/src/main.rs +++ b/replicator/src/main.rs @@ -4,6 +4,7 @@ use solana::contact_info::ContactInfo; use solana::replicator::Replicator; use solana_sdk::signature::{read_keypair, Keypair, KeypairUtil}; use std::net::SocketAddr; +use std::path::PathBuf; use std::process::exit; use std::sync::Arc; @@ -50,7 +51,7 @@ fn main() { ) .get_matches(); - let ledger_path = matches.value_of("ledger").unwrap(); + let ledger_path = PathBuf::from(matches.value_of("ledger").unwrap()); let keypair = if let Some(identity) = matches.value_of("identity") { read_keypair(identity).unwrap_or_else(|err| { @@ -93,7 +94,7 @@ fn main() { let entrypoint_info = ContactInfo::new_gossip_entry_point(&entrypoint_addr); let replicator = Replicator::new( - ledger_path, + &ledger_path, node, entrypoint_info, Arc::new(keypair), diff --git a/sdk/src/genesis_block.rs b/sdk/src/genesis_block.rs index 4bb6fba838..138e4756af 100644 --- a/sdk/src/genesis_block.rs +++ b/sdk/src/genesis_block.rs @@ -166,7 +166,7 @@ impl GenesisBlock { hash(&serialized.into_bytes()) } - pub fn load(ledger_path: &str) -> Result { + pub fn load(ledger_path: &Path) -> Result { let file = OpenOptions::new() .read(true) .open(&Path::new(ledger_path).join("genesis.bin")) @@ -179,14 +179,13 @@ impl GenesisBlock { Ok(genesis_block) } - pub fn write(&self, ledger_path: &str) -> Result<(), std::io::Error> { + pub fn write(&self, ledger_path: &Path) -> Result<(), std::io::Error> { let serialized = serialize(&self) .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, format!("{:?}", err)))?; - let dir = Path::new(ledger_path); - std::fs::create_dir_all(&dir)?; + std::fs::create_dir_all(&ledger_path)?; - let mut file = File::create(&dir.join("genesis.bin"))?; + let mut file = File::create(&ledger_path.join("genesis.bin"))?; file.write_all(&serialized) } } @@ -195,12 +194,19 @@ impl GenesisBlock { mod tests { use super::*; use crate::signature::{Keypair, KeypairUtil}; + use std::path::PathBuf; - fn make_tmp_path(name: &str) -> String { + fn make_tmp_path(name: &str) -> PathBuf { let out_dir = std::env::var("FARF_DIR").unwrap_or_else(|_| "farf".to_string()); let keypair = Keypair::new(); - let path = format!("{}/tmp/{}-{}", out_dir, name, keypair.pubkey()); + let path = [ + out_dir, + "tmp".to_string(), + format!("{}-{}", name, keypair.pubkey()), + ] + .iter() + .collect(); // whack any possible collision let _ignored = std::fs::remove_dir_all(&path); diff --git a/validator/src/main.rs b/validator/src/main.rs index aa2a2f55fd..082e4f3c2c 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -11,6 +11,7 @@ use solana_netutil::parse_port_range; use solana_sdk::signature::{read_keypair, Keypair, KeypairUtil}; use std::fs::File; use std::net::SocketAddr; +use std::path::PathBuf; use std::process::exit; use std::sync::Arc; @@ -75,7 +76,7 @@ fn main() { .help("Create this file, if it doesn't already exist, once node initialization is complete"), ) .arg( - Arg::with_name("ledger") + Arg::with_name("ledger_path") .short("l") .long("ledger") .value_name("DIR") @@ -208,7 +209,7 @@ fn main() { pubkey.parse().expect("failed to parse vote_account") }); - let ledger_path = matches.value_of("ledger").unwrap(); + let ledger_path = PathBuf::from(matches.value_of("ledger_path").unwrap()); validator_config.sigverify_disabled = matches.is_present("no_sigverify"); @@ -283,7 +284,7 @@ fn main() { let validator = Validator::new( node, &keypair, - ledger_path, + &ledger_path, &vote_account, &Arc::new(voting_keypair), &Arc::new(storage_keypair),