protection of parallel requests of TxHashSetRequest ()

* protection of parallel requests of TxHashSetRequest

* fix: adapt the test of test_unexpected_zip
This commit is contained in:
Gary Yu 2018-11-05 22:56:45 +08:00 committed by GitHub
parent 24ed4b787a
commit 1b264d3554
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 14 deletions

View file

@ -626,7 +626,7 @@ impl Chain {
} }
// prepares the zip and return the corresponding Read // 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(( Ok((
header.output_mmr_size, header.output_mmr_size,
header.kernel_mmr_size, header.kernel_mmr_size,

View file

@ -19,7 +19,7 @@ use std::collections::HashSet;
use std::fs::{self, File}; use std::fs::{self, File};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::Arc; use std::sync::Arc;
use std::time::Instant; use std::time::{Instant, SystemTime, UNIX_EPOCH};
use croaring::Bitmap; use croaring::Bitmap;
@ -52,7 +52,7 @@ const OUTPUT_SUBDIR: &'static str = "output";
const RANGE_PROOF_SUBDIR: &'static str = "rangeproof"; const RANGE_PROOF_SUBDIR: &'static str = "rangeproof";
const KERNEL_SUBDIR: &'static str = "kernel"; const KERNEL_SUBDIR: &'static str = "kernel";
const TXHASHSET_ZIP: &'static str = "txhashset_snapshot.zip"; const TXHASHSET_ZIP: &'static str = "txhashset_snapshot";
struct HashOnlyMMRHandle { struct HashOnlyMMRHandle {
backend: HashOnlyMMRBackend, backend: HashOnlyMMRBackend,
@ -1349,13 +1349,22 @@ impl<'a> Extension<'a> {
/// Packages the txhashset data files into a zip and returns a Read to the /// Packages the txhashset data files into a zip and returns a Read to the
/// resulting file /// 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 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 // create the zip archive
{ {
// Temp txhashset directory // 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 // Remove temp dir if it exist
if temp_txhashset_path.exists() { if temp_txhashset_path.exists() {
fs::remove_dir_all(&temp_txhashset_path)?; 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 { for diff in difference {
let diff_path = subdirectory_path.join(diff); 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
);
} }
} }
} }

View file

@ -23,6 +23,7 @@ use std::fs::{self, File, OpenOptions};
use std::iter::FromIterator; use std::iter::FromIterator;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::Arc; use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};
use chain::store::ChainStore; use chain::store::ChainStore;
use chain::txhashset; use chain::txhashset;
@ -35,6 +36,9 @@ fn clean_output_dir(dir_name: &str) {
#[test] #[test]
fn test_unexpected_zip() { 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"); let db_root = format!(".grin_txhashset_zip");
clean_output_dir(&db_root); clean_output_dir(&db_root);
let db_env = Arc::new(store::new_env(db_root.clone())); 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); let store = Arc::new(chain_store);
txhashset::TxHashSet::open(db_root.clone(), store.clone(), None).unwrap(); txhashset::TxHashSet::open(db_root.clone(), store.clone(), None).unwrap();
// First check if everything works out of the box // First check if everything works out of the box
assert!(txhashset::zip_read(db_root.clone(), &BlockHeader::default()).is_ok()); assert!(txhashset::zip_read(db_root.clone(), &BlockHeader::default(), Some(rand)).is_ok());
let zip_path = Path::new(&db_root).join("txhashset_snapshot.zip"); let zip_path = Path::new(&db_root).join(format!("txhashset_snapshot_{}.zip", rand));
let zip_file = File::open(&zip_path).unwrap(); let zip_file = File::open(&zip_path).unwrap();
assert!(txhashset::zip_write(db_root.clone(), zip_file, &BlockHeader::default()).is_ok()); assert!(txhashset::zip_write(db_root.clone(), zip_file, &BlockHeader::default()).is_ok());
// Remove temp txhashset dir // 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 // Then add strange files in the original txhashset folder
write_file(db_root.clone()); 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 // 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( assert!(txhashset_contains_expected_files(
"txhashset_zip".to_string(), format!("txhashset_zip_{}", rand),
txhashset_zip_path.clone() 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(); let zip_file = File::open(zip_path).unwrap();
assert!(txhashset::zip_write(db_root.clone(), zip_file, &BlockHeader::default()).is_ok()); assert!(txhashset::zip_write(db_root.clone(), zip_file, &BlockHeader::default()).is_ok());