diff --git a/chain/src/chain.rs b/chain/src/chain.rs index 5ffd58d2e..d15bb8bf6 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -626,7 +626,7 @@ impl Chain { } // prepares the zip and return the corresponding Read - let txhashset_reader = txhashset::zip_read(self.db_root.clone(), &header)?; + let txhashset_reader = txhashset::zip_read(self.db_root.clone(), &header, None)?; Ok(( header.output_mmr_size, header.kernel_mmr_size, diff --git a/chain/src/txhashset/txhashset.rs b/chain/src/txhashset/txhashset.rs index c5761e3e7..23a50631c 100644 --- a/chain/src/txhashset/txhashset.rs +++ b/chain/src/txhashset/txhashset.rs @@ -19,7 +19,7 @@ use std::collections::HashSet; use std::fs::{self, File}; use std::path::{Path, PathBuf}; use std::sync::Arc; -use std::time::Instant; +use std::time::{Instant, SystemTime, UNIX_EPOCH}; use croaring::Bitmap; @@ -52,7 +52,7 @@ const OUTPUT_SUBDIR: &'static str = "output"; const RANGE_PROOF_SUBDIR: &'static str = "rangeproof"; const KERNEL_SUBDIR: &'static str = "kernel"; -const TXHASHSET_ZIP: &'static str = "txhashset_snapshot.zip"; +const TXHASHSET_ZIP: &'static str = "txhashset_snapshot"; struct HashOnlyMMRHandle { backend: HashOnlyMMRBackend, @@ -1349,13 +1349,22 @@ impl<'a> Extension<'a> { /// Packages the txhashset data files into a zip and returns a Read to the /// resulting file -pub fn zip_read(root_dir: String, header: &BlockHeader) -> Result<File, Error> { +pub fn zip_read(root_dir: String, header: &BlockHeader, rand: Option<u32>) -> Result<File, Error> { + let ts = if let None = rand { + let now = SystemTime::now(); + now.duration_since(UNIX_EPOCH).unwrap().subsec_micros() + } else { + rand.unwrap() + }; + let txhashset_zip = format!("{}_{}.zip", TXHASHSET_ZIP, ts); + let txhashset_path = Path::new(&root_dir).join(TXHASHSET_SUBDIR); - let zip_path = Path::new(&root_dir).join(TXHASHSET_ZIP); + let zip_path = Path::new(&root_dir).join(txhashset_zip); // create the zip archive { // Temp txhashset directory - let temp_txhashset_path = Path::new(&root_dir).join(TXHASHSET_SUBDIR.to_string() + "_zip"); + let temp_txhashset_path = + Path::new(&root_dir).join(format!("{}_zip_{}", TXHASHSET_SUBDIR, ts)); // Remove temp dir if it exist if temp_txhashset_path.exists() { fs::remove_dir_all(&temp_txhashset_path)?; @@ -1455,7 +1464,11 @@ fn check_and_remove_files(txhashset_path: &PathBuf, header: &BlockHeader) -> Res ); for diff in difference { let diff_path = subdirectory_path.join(diff); - file::delete(diff_path)?; + file::delete(diff_path.clone())?; + debug!( + "check_and_remove_files: unexpected file '{:?}' removed", + diff_path + ); } } } diff --git a/chain/tests/test_txhashset.rs b/chain/tests/test_txhashset.rs index 5cd8548cc..40f872773 100644 --- a/chain/tests/test_txhashset.rs +++ b/chain/tests/test_txhashset.rs @@ -23,6 +23,7 @@ use std::fs::{self, File, OpenOptions}; use std::iter::FromIterator; use std::path::{Path, PathBuf}; use std::sync::Arc; +use std::time::{SystemTime, UNIX_EPOCH}; use chain::store::ChainStore; use chain::txhashset; @@ -35,6 +36,9 @@ fn clean_output_dir(dir_name: &str) { #[test] fn test_unexpected_zip() { + let now = SystemTime::now(); + let rand = now.duration_since(UNIX_EPOCH).unwrap().subsec_micros(); + let db_root = format!(".grin_txhashset_zip"); clean_output_dir(&db_root); let db_env = Arc::new(store::new_env(db_root.clone())); @@ -42,22 +46,22 @@ fn test_unexpected_zip() { let store = Arc::new(chain_store); txhashset::TxHashSet::open(db_root.clone(), store.clone(), None).unwrap(); // First check if everything works out of the box - assert!(txhashset::zip_read(db_root.clone(), &BlockHeader::default()).is_ok()); - let zip_path = Path::new(&db_root).join("txhashset_snapshot.zip"); + assert!(txhashset::zip_read(db_root.clone(), &BlockHeader::default(), Some(rand)).is_ok()); + let zip_path = Path::new(&db_root).join(format!("txhashset_snapshot_{}.zip", rand)); let zip_file = File::open(&zip_path).unwrap(); assert!(txhashset::zip_write(db_root.clone(), zip_file, &BlockHeader::default()).is_ok()); // Remove temp txhashset dir - fs::remove_dir_all(Path::new(&db_root).join("txhashset_zip")).unwrap(); + fs::remove_dir_all(Path::new(&db_root).join(format!("txhashset_zip_{}", rand))).unwrap(); // Then add strange files in the original txhashset folder write_file(db_root.clone()); - assert!(txhashset::zip_read(db_root.clone(), &BlockHeader::default()).is_ok()); + assert!(txhashset::zip_read(db_root.clone(), &BlockHeader::default(), Some(rand)).is_ok()); // Check that the temp dir dos not contains the strange files - let txhashset_zip_path = Path::new(&db_root).join("txhashset_zip"); + let txhashset_zip_path = Path::new(&db_root).join(format!("txhashset_zip_{}", rand)); assert!(txhashset_contains_expected_files( - "txhashset_zip".to_string(), + format!("txhashset_zip_{}", rand), txhashset_zip_path.clone() )); - fs::remove_dir_all(Path::new(&db_root).join("txhashset_zip")).unwrap(); + fs::remove_dir_all(Path::new(&db_root).join(format!("txhashset_zip_{}", rand))).unwrap(); let zip_file = File::open(zip_path).unwrap(); assert!(txhashset::zip_write(db_root.clone(), zip_file, &BlockHeader::default()).is_ok());