mirror of
https://github.com/mimblewimble/grin.git
synced 2025-05-02 15:21:14 +03:00
protection of parallel requests of TxHashSetRequest (#1923)
* protection of parallel requests of TxHashSetRequest * fix: adapt the test of test_unexpected_zip
This commit is contained in:
parent
24ed4b787a
commit
1b264d3554
3 changed files with 31 additions and 14 deletions
chain
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Add table
Reference in a new issue