Optimizing the code and making it more idiomatic (#2269)

This commit is contained in:
Elichai Turkel 2019-01-02 01:29:16 +02:00 committed by Ignotus Peverell
parent 23df6fa976
commit f2a29ce37a
17 changed files with 119 additions and 104 deletions

3
.gitignore vendored
View file

@ -5,10 +5,11 @@ node*
!node_clients !node_clients
!node_clients.rs !node_clients.rs
target target
Cargo.lock */Cargo.lock
*.iml *.iml
grin.log grin.log
wallet.seed wallet.seed
test_output test_output
wallet_data wallet_data
wallet/db wallet/db
.idea/

View file

@ -270,7 +270,7 @@ impl<'a> Batch<'a> {
fn save_block_input_bitmap(&self, bh: &Hash, bm: &Bitmap) -> Result<(), Error> { fn save_block_input_bitmap(&self, bh: &Hash, bm: &Bitmap) -> Result<(), Error> {
self.db.put( self.db.put(
&to_key(BLOCK_INPUT_BITMAP_PREFIX, &mut bh.to_vec())[..], &to_key(BLOCK_INPUT_BITMAP_PREFIX, &mut bh.to_vec())[..],
bm.serialize(), &bm.serialize(),
) )
} }

View file

@ -309,19 +309,13 @@ where
/// Count, in units of 1/100 (a percent), the number of "secondary" (AR) blocks in the provided window of blocks. /// Count, in units of 1/100 (a percent), the number of "secondary" (AR) blocks in the provided window of blocks.
pub fn ar_count(_height: u64, diff_data: &[HeaderInfo]) -> u64 { pub fn ar_count(_height: u64, diff_data: &[HeaderInfo]) -> u64 {
100 * diff_data 100 * diff_data.iter().filter(|n| n.is_secondary).count() as u64
.iter()
.filter(|n| n.is_secondary)
.count() as u64
} }
/// Factor by which the secondary proof of work difficulty will be adjusted /// Factor by which the secondary proof of work difficulty will be adjusted
pub fn secondary_pow_scaling(height: u64, diff_data: &[HeaderInfo]) -> u32 { pub fn secondary_pow_scaling(height: u64, diff_data: &[HeaderInfo]) -> u32 {
// Get the scaling factor sum of the last DIFFICULTY_ADJUST_WINDOW elements // Get the scaling factor sum of the last DIFFICULTY_ADJUST_WINDOW elements
let scale_sum: u64 = diff_data let scale_sum: u64 = diff_data.iter().map(|dd| dd.secondary_scaling as u64).sum();
.iter()
.map(|dd| dd.secondary_scaling as u64)
.sum();
// compute ideal 2nd_pow_fraction in pct and across window // compute ideal 2nd_pow_fraction in pct and across window
let target_pct = secondary_pow_ratio(height); let target_pct = secondary_pow_ratio(height);

View file

@ -27,10 +27,7 @@ use crate::core::committed::{self, Committed};
use crate::core::compact_block::{CompactBlock, CompactBlockBody}; use crate::core::compact_block::{CompactBlock, CompactBlockBody};
use crate::core::hash::{Hash, Hashed, ZERO_HASH}; use crate::core::hash::{Hash, Hashed, ZERO_HASH};
use crate::core::verifier_cache::VerifierCache; use crate::core::verifier_cache::VerifierCache;
use crate::core::{ use crate::core::{transaction, Commitment, Input, Output, Transaction, TransactionBody, TxKernel};
transaction, Commitment, Input, Output, Transaction,
TransactionBody, TxKernel,
};
use crate::global; use crate::global;
use crate::keychain::{self, BlindingFactor}; use crate::keychain::{self, BlindingFactor};
use crate::pow::{Difficulty, Proof, ProofOfWork}; use crate::pow::{Difficulty, Proof, ProofOfWork};

View file

@ -17,6 +17,7 @@ use croaring::Bitmap;
use crate::core::hash::Hash; use crate::core::hash::Hash;
use crate::core::BlockHeader; use crate::core::BlockHeader;
use crate::ser::PMMRable; use crate::ser::PMMRable;
use std::path::Path;
/// Storage backend for the MMR, just needs to be indexed by order of insertion. /// Storage backend for the MMR, just needs to be indexed by order of insertion.
/// The PMMR itself does not need the Backend to be accurate on the existence /// The PMMR itself does not need the Backend to be accurate on the existence
@ -59,7 +60,7 @@ pub trait Backend<T: PMMRable> {
/// Returns the data file path.. this is a bit of a hack now that doesn't /// Returns the data file path.. this is a bit of a hack now that doesn't
/// sit well with the design, but TxKernels have to be summed and the /// sit well with the design, but TxKernels have to be summed and the
/// fastest way to to be able to allow direct access to the file /// fastest way to to be able to allow direct access to the file
fn get_data_file_path(&self) -> &str; fn get_data_file_path(&self) -> &Path;
/// Also a bit of a hack... /// Also a bit of a hack...
/// Saves a snapshot of the rewound utxo file with the block hash as /// Saves a snapshot of the rewound utxo file with the block hash as

View file

@ -22,6 +22,7 @@ use crate::core::merkle_proof::MerkleProof;
use crate::core::pmmr::{Backend, ReadonlyPMMR}; use crate::core::pmmr::{Backend, ReadonlyPMMR};
use crate::core::BlockHeader; use crate::core::BlockHeader;
use crate::ser::{PMMRIndexHashable, PMMRable}; use crate::ser::{PMMRIndexHashable, PMMRable};
use std::path::Path;
/// 64 bits all ones: 0b11111111...1 /// 64 bits all ones: 0b11111111...1
const ALL_ONES: u64 = u64::MAX; const ALL_ONES: u64 = u64::MAX;
@ -323,7 +324,7 @@ where
} }
/// Return the path of the data file (needed to sum kernels efficiently) /// Return the path of the data file (needed to sum kernels efficiently)
pub fn data_file_path(&self) -> &str { pub fn data_file_path(&self) -> &Path {
self.backend.get_data_file_path() self.backend.get_data_file_path()
} }

View file

@ -23,11 +23,7 @@ use crate::libtx::{aggsig, proof};
use crate::util::static_secp_instance; use crate::util::static_secp_instance;
/// output a reward output /// output a reward output
pub fn output<K>( pub fn output<K>(keychain: &K, key_id: &Identifier, fees: u64) -> Result<(Output, TxKernel), Error>
keychain: &K,
key_id: &Identifier,
fees: u64,
) -> Result<(Output, TxKernel), Error>
where where
K: Keychain, K: Keychain,
{ {

View file

@ -342,7 +342,6 @@ fn adjustment_scenarios() {
println!("*********************************************************"); println!("*********************************************************");
print_chain_sim(chain_sim); print_chain_sim(chain_sim);
println!("*********************************************************"); println!("*********************************************************");
} }
/// Checks different next_target adjustments and difficulty boundaries /// Checks different next_target adjustments and difficulty boundaries

View file

@ -20,6 +20,7 @@ use self::core::ser::{FixedLength, PMMRable, Readable, Reader, Writeable, Writer
use croaring; use croaring;
use croaring::Bitmap; use croaring::Bitmap;
use grin_core as core; use grin_core as core;
use std::path::Path;
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct TestElem(pub [u32; 4]); pub struct TestElem(pub [u32; 4]);
@ -117,8 +118,8 @@ impl<T: PMMRable> Backend<T> for VecBackend<T> {
Ok(()) Ok(())
} }
fn get_data_file_path(&self) -> &str { fn get_data_file_path(&self) -> &Path {
"" Path::new("")
} }
fn dump_stats(&self) {} fn dump_stats(&self) {}

View file

@ -15,7 +15,7 @@
//! Compact (roaring) bitmap representing the set of leaf positions //! Compact (roaring) bitmap representing the set of leaf positions
//! that exist and are not currently pruned in the MMR. //! that exist and are not currently pruned in the MMR.
use std::path::Path; use std::path::{Path, PathBuf};
use croaring::Bitmap; use croaring::Bitmap;
@ -31,7 +31,7 @@ use std::io::{self, BufWriter, Write};
/// Compact (roaring) bitmap representing the set of positions of /// Compact (roaring) bitmap representing the set of positions of
/// leaves that are currently unpruned in the MMR. /// leaves that are currently unpruned in the MMR.
pub struct LeafSet { pub struct LeafSet {
path: String, path: PathBuf,
bitmap: Bitmap, bitmap: Bitmap,
bitmap_bak: Bitmap, bitmap_bak: Bitmap,
} }
@ -39,35 +39,42 @@ pub struct LeafSet {
impl LeafSet { impl LeafSet {
/// Open the remove log file. /// Open the remove log file.
/// The content of the file will be read in memory for fast checking. /// The content of the file will be read in memory for fast checking.
pub fn open(path: &str) -> io::Result<LeafSet> { pub fn open<P: AsRef<Path>>(path: P) -> io::Result<LeafSet> {
let file_path = Path::new(&path); let file_path = path.as_ref();
let bitmap = if file_path.exists() { let bitmap = if file_path.exists() {
read_bitmap(file_path)? read_bitmap(&file_path)?
} else { } else {
Bitmap::create() Bitmap::create()
}; };
Ok(LeafSet { Ok(LeafSet {
path: path.to_string(), path: file_path.to_path_buf(),
bitmap_bak: bitmap.clone(), bitmap_bak: bitmap.clone(),
bitmap, bitmap,
}) })
} }
/// Copies a snapshot of the utxo file into the primary utxo file. /// Copies a snapshot of the utxo file into the primary utxo file.
pub fn copy_snapshot(path: &str, cp_path: &str) -> io::Result<()> { pub fn copy_snapshot<P: AsRef<Path>>(path: P, cp_path: P) -> io::Result<()> {
let cp_file_path = Path::new(&cp_path); let cp_file_path = cp_path.as_ref();
if !cp_file_path.exists() { if !cp_file_path.exists() {
debug!("leaf_set: rewound leaf file not found: {}", cp_path); debug!(
"leaf_set: rewound leaf file not found: {}",
cp_file_path.display()
);
return Ok(()); return Ok(());
} }
let bitmap = read_bitmap(cp_file_path)?; let bitmap = read_bitmap(&cp_file_path)?;
debug!("leaf_set: copying rewound file {} to {}", cp_path, path); debug!(
"leaf_set: copying rewound file {} to {}",
cp_file_path.display(),
path.as_ref().display()
);
let mut leaf_set = LeafSet { let mut leaf_set = LeafSet {
path: path.to_string(), path: path.as_ref().to_path_buf(),
bitmap_bak: bitmap.clone(), bitmap_bak: bitmap.clone(),
bitmap, bitmap,
}; };
@ -148,7 +155,7 @@ impl LeafSet {
let mut cp_bitmap = self.bitmap.clone(); let mut cp_bitmap = self.bitmap.clone();
cp_bitmap.run_optimize(); cp_bitmap.run_optimize();
let cp_path = format!("{}.{}", self.path, header.hash()); let cp_path = self.path.join(header.hash().to_string());
let mut file = BufWriter::new(File::create(cp_path)?); let mut file = BufWriter::new(File::create(cp_path)?);
file.write_all(&cp_bitmap.serialize())?; file.write_all(&cp_bitmap.serialize())?;
file.flush()?; file.flush()?;

View file

@ -56,7 +56,7 @@ pub fn to_key(prefix: u8, k: &mut Vec<u8>) -> Vec<u8> {
/// Build a db key from a prefix and a byte vector identifier and numeric identifier /// Build a db key from a prefix and a byte vector identifier and numeric identifier
pub fn to_key_u64(prefix: u8, k: &mut Vec<u8>, val: u64) -> Vec<u8> { pub fn to_key_u64(prefix: u8, k: &mut Vec<u8>, val: u64) -> Vec<u8> {
let mut res = vec![]; let mut res = Vec::with_capacity(k.len() + 10);
res.push(prefix); res.push(prefix);
res.push(SEP); res.push(SEP);
res.append(k); res.append(k);
@ -65,31 +65,36 @@ pub fn to_key_u64(prefix: u8, k: &mut Vec<u8>, val: u64) -> Vec<u8> {
} }
/// Build a db key from a prefix and a numeric identifier. /// Build a db key from a prefix and a numeric identifier.
pub fn u64_to_key(prefix: u8, val: u64) -> Vec<u8> { pub fn u64_to_key(prefix: u8, val: u64) -> Vec<u8> {
let mut u64_vec = vec![]; let mut res = Vec::with_capacity(10);
u64_vec.write_u64::<BigEndian>(val).unwrap(); res.push(prefix);
u64_vec.insert(0, SEP); res.push(SEP);
u64_vec.insert(0, prefix); res.write_u64::<BigEndian>(val).unwrap();
u64_vec res
} }
use std::ffi::OsStr;
use std::fs::{remove_file, rename, File};
use std::path::Path;
/// Creates temporary file with name created by adding `temp_suffix` to `path`. /// Creates temporary file with name created by adding `temp_suffix` to `path`.
/// Applies writer function to it and renames temporary file into original specified by `path`. /// Applies writer function to it and renames temporary file into original specified by `path`.
pub fn save_via_temp_file<F>( pub fn save_via_temp_file<F, P, E>(
path: &str, path: P,
temp_suffix: &str, temp_suffix: E,
mut writer: F, mut writer: F,
) -> Result<(), std::io::Error> ) -> Result<(), std::io::Error>
where where
F: FnMut(Box<dyn std::io::Write>) -> Result<(), std::io::Error>, F: FnMut(Box<dyn std::io::Write>) -> Result<(), std::io::Error>,
P: AsRef<Path>,
E: AsRef<OsStr>,
{ {
assert_ne!(*temp_suffix, *""); let temp_suffix = temp_suffix.as_ref();
assert!(!temp_suffix.is_empty());
use std::fs::{remove_file, rename, File};
use std::path::Path;
let original = path.as_ref();
let mut _original = original.as_os_str().to_os_string();
_original.push(temp_suffix);
// Write temporary file // Write temporary file
let temp_name = format!("{}{}", &path, temp_suffix); let temp_path = Path::new(&_original);
let temp_path = Path::new(&temp_name);
if temp_path.exists() { if temp_path.exists() {
remove_file(&temp_path)?; remove_file(&temp_path)?;
} }
@ -98,7 +103,6 @@ where
writer(Box::new(file))?; writer(Box::new(file))?;
// Move temporary file into original // Move temporary file into original
let original = Path::new(&path);
if original.exists() { if original.exists() {
remove_file(&original)?; remove_file(&original)?;
} }
@ -110,10 +114,8 @@ where
use croaring::Bitmap; use croaring::Bitmap;
use std::io::{self, Read}; use std::io::{self, Read};
use std::path::Path;
/// Read Bitmap from a file /// Read Bitmap from a file
pub fn read_bitmap<P: AsRef<Path>>(file_path: P) -> io::Result<Bitmap> { pub fn read_bitmap<P: AsRef<Path>>(file_path: P) -> io::Result<Bitmap> {
use std::fs::File;
let mut bitmap_file = File::open(file_path)?; let mut bitmap_file = File::open(file_path)?;
let f_md = bitmap_file.metadata()?; let f_md = bitmap_file.metadata()?;
let mut buffer = Vec::with_capacity(f_md.len() as usize); let mut buffer = Vec::with_capacity(f_md.len() as usize);

View file

@ -67,15 +67,17 @@ pub fn new_env(path: String) -> lmdb::Environment {
pub fn new_named_env(path: String, name: String) -> lmdb::Environment { pub fn new_named_env(path: String, name: String) -> lmdb::Environment {
let full_path = [path, name].join("/"); let full_path = [path, name].join("/");
fs::create_dir_all(&full_path).unwrap(); fs::create_dir_all(&full_path).unwrap();
unsafe {
let mut env_builder = lmdb::EnvBuilder::new().unwrap(); let mut env_builder = lmdb::EnvBuilder::new().unwrap();
env_builder.set_maxdbs(8).unwrap(); env_builder.set_maxdbs(8).unwrap();
// half a TB should give us plenty room, will be an issue on 32 bits // half a TB should give us plenty room, will be an issue on 32 bits
// (which we don't support anyway) // (which we don't support anyway)
env_builder.set_mapsize(549755813888).unwrap_or_else(|e| { env_builder
.set_mapsize(549_755_813_888)
.unwrap_or_else(|e| {
panic!("Unable to allocate LMDB space: {:?}", e); panic!("Unable to allocate LMDB space: {:?}", e);
}); });
unsafe {
env_builder env_builder
.open(&full_path, lmdb::open::Flags::empty(), 0o600) .open(&full_path, lmdb::open::Flags::empty(), 0o600)
.unwrap() .unwrap()
@ -178,10 +180,10 @@ pub struct Batch<'a> {
impl<'a> Batch<'a> { impl<'a> Batch<'a> {
/// Writes a single key/value pair to the db /// Writes a single key/value pair to the db
pub fn put(&self, key: &[u8], value: Vec<u8>) -> Result<(), Error> { pub fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error> {
self.tx self.tx
.access() .access()
.put(&self.store.db, key, &value, lmdb::put::Flags::empty())?; .put(&self.store.db, key, value, lmdb::put::Flags::empty())?;
Ok(()) Ok(())
} }
@ -190,7 +192,7 @@ impl<'a> Batch<'a> {
pub fn put_ser<W: ser::Writeable>(&self, key: &[u8], value: &W) -> Result<(), Error> { pub fn put_ser<W: ser::Writeable>(&self, key: &[u8], value: &W) -> Result<(), Error> {
let ser_value = ser::ser_vec(value); let ser_value = ser::ser_vec(value);
match ser_value { match ser_value {
Ok(data) => self.put(key, data), Ok(data) => self.put(key, &data),
Err(err) => Err(Error::SerErr(format!("{}", err))), Err(err) => Err(Error::SerErr(format!("{}", err))),
} }
} }

View file

@ -23,6 +23,7 @@ use crate::leaf_set::LeafSet;
use crate::prune_list::PruneList; use crate::prune_list::PruneList;
use crate::types::{prune_noop, DataFile}; use crate::types::{prune_noop, DataFile};
use croaring::Bitmap; use croaring::Bitmap;
use std::path::{Path, PathBuf};
const PMMR_HASH_FILE: &str = "pmmr_hash.bin"; const PMMR_HASH_FILE: &str = "pmmr_hash.bin";
const PMMR_DATA_FILE: &str = "pmmr_data.bin"; const PMMR_DATA_FILE: &str = "pmmr_data.bin";
@ -50,7 +51,7 @@ pub const PMMR_FILES: [&str; 4] = [
/// * A prune_list tracks the positions of pruned (and compacted) roots in the /// * A prune_list tracks the positions of pruned (and compacted) roots in the
/// MMR. /// MMR.
pub struct PMMRBackend<T: PMMRable> { pub struct PMMRBackend<T: PMMRable> {
data_dir: String, data_dir: PathBuf,
prunable: bool, prunable: bool,
hash_file: DataFile<Hash>, hash_file: DataFile<Hash>,
data_file: DataFile<T::E>, data_file: DataFile<T::E>,
@ -147,7 +148,7 @@ impl<T: PMMRable> Backend<T> for PMMRBackend<T> {
} }
/// Return data file path /// Return data file path
fn get_data_file_path(&self) -> &str { fn get_data_file_path(&self) -> &Path {
self.data_file.path() self.data_file.path()
} }
@ -173,28 +174,32 @@ impl<T: PMMRable> Backend<T> for PMMRBackend<T> {
impl<T: PMMRable> PMMRBackend<T> { impl<T: PMMRable> PMMRBackend<T> {
/// Instantiates a new PMMR backend. /// Instantiates a new PMMR backend.
/// Use the provided dir to store its files. /// Use the provided dir to store its files.
pub fn new( pub fn new<P: AsRef<Path>>(
data_dir: String, data_dir: P,
prunable: bool, prunable: bool,
header: Option<&BlockHeader>, header: Option<&BlockHeader>,
) -> io::Result<PMMRBackend<T>> { ) -> io::Result<PMMRBackend<T>> {
let hash_file = DataFile::open(&format!("{}/{}", data_dir, PMMR_HASH_FILE))?; let data_dir = data_dir.as_ref();
let data_file = DataFile::open(&format!("{}/{}", data_dir, PMMR_DATA_FILE))?; let hash_file = DataFile::open(&data_dir.join(PMMR_HASH_FILE))?;
let data_file = DataFile::open(&data_dir.join(PMMR_DATA_FILE))?;
let leaf_set_path = format!("{}/{}", data_dir, PMMR_LEAF_FILE); let leaf_set_path = data_dir.join(PMMR_LEAF_FILE);
// If we received a rewound "snapshot" leaf_set file move it into // If we received a rewound "snapshot" leaf_set file move it into
// place so we use it. // place so we use it.
if let Some(header) = header { if let Some(header) = header {
let leaf_snapshot_path = format!("{}/{}.{}", data_dir, PMMR_LEAF_FILE, header.hash()); let _leaf_snapshot_path = (data_dir.join(PMMR_LEAF_FILE).to_string_lossy()
+ header.hash().to_string().as_ref())
.into_owned();
let leaf_snapshot_path = PathBuf::from(_leaf_snapshot_path);
LeafSet::copy_snapshot(&leaf_set_path, &leaf_snapshot_path)?; LeafSet::copy_snapshot(&leaf_set_path, &leaf_snapshot_path)?;
} }
let leaf_set = LeafSet::open(&leaf_set_path)?; let leaf_set = LeafSet::open(&leaf_set_path)?;
let prune_list = PruneList::open(&format!("{}/{}", data_dir, PMMR_PRUN_FILE))?; let prune_list = PruneList::open(&data_dir.join(PMMR_PRUN_FILE))?;
Ok(PMMRBackend { Ok(PMMRBackend {
data_dir, data_dir: data_dir.to_path_buf(),
prunable, prunable,
hash_file, hash_file,
data_file, data_file,
@ -278,9 +283,10 @@ impl<T: PMMRable> PMMRBackend<T> {
assert!(self.prunable, "Trying to compact a non-prunable PMMR"); assert!(self.prunable, "Trying to compact a non-prunable PMMR");
// Paths for tmp hash and data files. // Paths for tmp hash and data files.
let tmp_prune_file_hash = format!("{}/{}.hashprune", self.data_dir, PMMR_HASH_FILE); let tmp_prune_file_hash =
let tmp_prune_file_data = format!("{}/{}.dataprune", self.data_dir, PMMR_DATA_FILE); format!("{}.hashprune", self.data_dir.join(PMMR_HASH_FILE).display());
let tmp_prune_file_data =
format!("{}.dataprune", self.data_dir.join(PMMR_DATA_FILE).display());
// Calculate the sets of leaf positions and node positions to remove based // Calculate the sets of leaf positions and node positions to remove based
// on the cutoff_pos provided. // on the cutoff_pos provided.
let (leaves_removed, pos_to_rm) = self.pos_to_rm(cutoff_pos, rewind_rm_pos); let (leaves_removed, pos_to_rm) = self.pos_to_rm(cutoff_pos, rewind_rm_pos);
@ -293,7 +299,7 @@ impl<T: PMMRable> PMMRBackend<T> {
}); });
self.hash_file self.hash_file
.save_prune(tmp_prune_file_hash.clone(), &off_to_rm, &prune_noop)?; .save_prune(&tmp_prune_file_hash, &off_to_rm, &prune_noop)?;
} }
// 2. Save compact copy of the data file, skipping removed leaves. // 2. Save compact copy of the data file, skipping removed leaves.
@ -311,7 +317,7 @@ impl<T: PMMRable> PMMRBackend<T> {
}); });
self.data_file self.data_file
.save_prune(tmp_prune_file_data.clone(), &off_to_rm, prune_cb)?; .save_prune(&tmp_prune_file_data, &off_to_rm, prune_cb)?;
} }
// 3. Update the prune list and write to disk. // 3. Update the prune list and write to disk.
@ -325,16 +331,16 @@ impl<T: PMMRable> PMMRBackend<T> {
// 4. Rename the compact copy of hash file and reopen it. // 4. Rename the compact copy of hash file and reopen it.
fs::rename( fs::rename(
tmp_prune_file_hash.clone(), tmp_prune_file_hash.clone(),
format!("{}/{}", self.data_dir, PMMR_HASH_FILE), self.data_dir.join(PMMR_HASH_FILE),
)?; )?;
self.hash_file = DataFile::open(&format!("{}/{}", self.data_dir, PMMR_HASH_FILE))?; self.hash_file = DataFile::open(self.data_dir.join(PMMR_HASH_FILE))?;
// 5. Rename the compact copy of the data file and reopen it. // 5. Rename the compact copy of the data file and reopen it.
fs::rename( fs::rename(
tmp_prune_file_data.clone(), tmp_prune_file_data.clone(),
format!("{}/{}", self.data_dir, PMMR_DATA_FILE), self.data_dir.join(PMMR_DATA_FILE),
)?; )?;
self.data_file = DataFile::open(&format!("{}/{}", self.data_dir, PMMR_DATA_FILE))?; self.data_file = DataFile::open(self.data_dir.join(PMMR_DATA_FILE))?;
// 6. Write the leaf_set to disk. // 6. Write the leaf_set to disk.
// Optimize the bitmap storage in the process. // Optimize the bitmap storage in the process.

View file

@ -22,7 +22,7 @@
//! files. //! files.
use std::io::{self, BufWriter, Write}; use std::io::{self, BufWriter, Write};
use std::path::Path; use std::path::{Path, PathBuf};
use croaring::Bitmap; use croaring::Bitmap;
@ -41,7 +41,7 @@ use crate::{read_bitmap, save_via_temp_file};
/// backend storage anymore. The PruneList accounts for that mismatch and does /// backend storage anymore. The PruneList accounts for that mismatch and does
/// the position translation. /// the position translation.
pub struct PruneList { pub struct PruneList {
path: Option<String>, path: Option<PathBuf>,
/// Bitmap representing pruned root node positions. /// Bitmap representing pruned root node positions.
bitmap: Bitmap, bitmap: Bitmap,
/// Bitmap representing all pruned node positions (everything under the pruned roots). /// Bitmap representing all pruned node positions (everything under the pruned roots).
@ -63,8 +63,8 @@ impl PruneList {
} }
/// Open an existing prune_list or create a new one. /// Open an existing prune_list or create a new one.
pub fn open(path: &str) -> io::Result<PruneList> { pub fn open<P: AsRef<Path>>(path: P) -> io::Result<PruneList> {
let file_path = Path::new(&path); let file_path = PathBuf::from(path.as_ref());
let bitmap = if file_path.exists() { let bitmap = if file_path.exists() {
read_bitmap(&file_path)? read_bitmap(&file_path)?
} else { } else {
@ -72,7 +72,7 @@ impl PruneList {
}; };
let mut prune_list = PruneList { let mut prune_list = PruneList {
path: Some(path.to_string()), path: Some(file_path),
bitmap, bitmap,
pruned_cache: Bitmap::create(), pruned_cache: Bitmap::create(),
shift_cache: vec![], shift_cache: vec![],
@ -111,7 +111,7 @@ impl PruneList {
// Write the updated bitmap file to disk. // Write the updated bitmap file to disk.
if let Some(ref path) = self.path { if let Some(ref path) = self.path {
save_via_temp_file(&path, ".tmp", |w| { save_via_temp_file(path, ".tmp", |w| {
let mut w = BufWriter::new(w); let mut w = BufWriter::new(w);
w.write_all(&self.bitmap.serialize())?; w.write_all(&self.bitmap.serialize())?;
w.flush() w.flush()
@ -264,7 +264,7 @@ impl PruneList {
return; return;
} }
self.pruned_cache = Bitmap::create_with_capacity(self.bitmap.maximum()); self.pruned_cache = Bitmap::create_with_capacity(self.bitmap.maximum());
for pos in 1..(self.bitmap.maximum() + 1) { for pos in 1..=self.bitmap.maximum() {
let path = path(pos as u64, self.bitmap.maximum() as u64); let path = path(pos as u64, self.bitmap.maximum() as u64);
let pruned = path.into_iter().any(|x| self.bitmap.contains(x as u32)); let pruned = path.into_iter().any(|x| self.bitmap.contains(x as u32));
if pruned { if pruned {
@ -279,3 +279,9 @@ impl PruneList {
self.bitmap.contains(pos as u32) self.bitmap.contains(pos as u32)
} }
} }
impl Default for PruneList {
fn default() -> Self {
Self::new()
}
}

View file

@ -18,6 +18,7 @@ use crate::core::ser::{self, FixedLength, Readable, Writeable};
use std::fs::{self, File, OpenOptions}; use std::fs::{self, File, OpenOptions};
use std::io::{self, BufWriter, ErrorKind, Read, Write}; use std::io::{self, BufWriter, ErrorKind, Read, Write};
use std::marker; use std::marker;
use std::path::{Path, PathBuf};
/// A no-op function for doing nothing with some pruned data. /// A no-op function for doing nothing with some pruned data.
pub fn prune_noop(_pruned_data: &[u8]) {} pub fn prune_noop(_pruned_data: &[u8]) {}
@ -33,7 +34,7 @@ where
T: FixedLength + Readable + Writeable, T: FixedLength + Readable + Writeable,
{ {
/// Open (or create) a file at the provided path on disk. /// Open (or create) a file at the provided path on disk.
pub fn open(path: &str) -> io::Result<DataFile<T>> { pub fn open<P: AsRef<Path>>(path: P) -> io::Result<DataFile<T>> {
let file = AppendOnlyFile::open(path)?; let file = AppendOnlyFile::open(path)?;
Ok(DataFile { Ok(DataFile {
file, file,
@ -96,12 +97,12 @@ where
} }
/// Path of the underlying file /// Path of the underlying file
pub fn path(&self) -> &str { pub fn path(&self) -> &Path {
self.file.path() self.file.path()
} }
/// Write the file out to disk, pruning removed elements. /// Write the file out to disk, pruning removed elements.
pub fn save_prune<F>(&self, target: String, prune_offs: &[u64], prune_cb: F) -> io::Result<()> pub fn save_prune<F>(&self, target: &str, prune_offs: &[u64], prune_cb: F) -> io::Result<()>
where where
F: Fn(&[u8]), F: Fn(&[u8]),
{ {
@ -123,7 +124,7 @@ where
/// former simply happens by rewriting it, ignoring some of the data. The /// former simply happens by rewriting it, ignoring some of the data. The
/// latter by truncating the underlying file and re-creating the mmap. /// latter by truncating the underlying file and re-creating the mmap.
pub struct AppendOnlyFile { pub struct AppendOnlyFile {
path: String, path: PathBuf,
file: File, file: File,
mmap: Option<memmap::Mmap>, mmap: Option<memmap::Mmap>,
buffer_start: usize, buffer_start: usize,
@ -133,7 +134,7 @@ pub struct AppendOnlyFile {
impl AppendOnlyFile { impl AppendOnlyFile {
/// Open a file (existing or not) as append-only, backed by a mmap. /// Open a file (existing or not) as append-only, backed by a mmap.
pub fn open(path: &str) -> io::Result<AppendOnlyFile> { pub fn open<P: AsRef<Path>>(path: P) -> io::Result<AppendOnlyFile> {
let file = OpenOptions::new() let file = OpenOptions::new()
.read(true) .read(true)
.append(true) .append(true)
@ -141,7 +142,7 @@ impl AppendOnlyFile {
.open(&path)?; .open(&path)?;
let mut aof = AppendOnlyFile { let mut aof = AppendOnlyFile {
file, file,
path: path.to_string(), path: path.as_ref().to_path_buf(),
mmap: None, mmap: None,
buffer_start: 0, buffer_start: 0,
buffer: vec![], buffer: vec![],
@ -258,15 +259,16 @@ impl AppendOnlyFile {
/// Saves a copy of the current file content, skipping data at the provided /// Saves a copy of the current file content, skipping data at the provided
/// prune indices. The prune Vec must be ordered. /// prune indices. The prune Vec must be ordered.
pub fn save_prune<T>( pub fn save_prune<T, P>(
&self, &self,
target: String, target: P,
prune_offs: &[u64], prune_offs: &[u64],
prune_len: u64, prune_len: u64,
prune_cb: T, prune_cb: T,
) -> io::Result<()> ) -> io::Result<()>
where where
T: Fn(&[u8]), T: Fn(&[u8]),
P: AsRef<Path>,
{ {
if prune_offs.is_empty() { if prune_offs.is_empty() {
fs::copy(&self.path, &target)?; fs::copy(&self.path, &target)?;
@ -322,7 +324,7 @@ impl AppendOnlyFile {
} }
/// Path of the underlying file /// Path of the underlying file
pub fn path(&self) -> &str { pub fn path(&self) -> &Path {
&self.path &self.path
} }
} }

View file

@ -17,7 +17,6 @@ use grin_core as core;
use grin_store as store; use grin_store as store;
use std::fs; use std::fs;
use std::io::prelude::*;
use chrono::prelude::Utc; use chrono::prelude::Utc;
use croaring::Bitmap; use croaring::Bitmap;
@ -822,9 +821,9 @@ fn create_numbered_files(
prefix, prefix,
start_index + rewind_file_num start_index + rewind_file_num
)); ));
let mut file = fs::File::create(path.clone()).unwrap(); let file = fs::File::create(path.clone()).unwrap();
let metadata = file.metadata().unwrap(); let metadata = file.metadata().unwrap();
filetime::set_file_times(path, time_to_set_ft, time_to_set_ft); filetime::set_file_times(path, time_to_set_ft, time_to_set_ft).unwrap();
} }
} }

View file

@ -111,7 +111,8 @@ where
verifier_cache, verifier_cache,
false, false,
Arc::new(Mutex::new(StopState::new())), Arc::new(Mutex::new(StopState::new())),
).unwrap(); )
.unwrap();
let (tx, rx) = channel(); let (tx, rx) = channel();
let retval = WalletProxy { let retval = WalletProxy {
chain_dir: chain_dir.to_owned(), chain_dir: chain_dir.to_owned(),