diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 627300ea6..666bbf691 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -756,7 +756,7 @@ impl BlockChainClient for Client where V: Verifier { } fn take_snapshot(&self, root_dir: &Path) { - use pv64::{BlockChunker, ManifestData, StateChunker}; + use pv64::{ManifestData, chunk_blocks, chunk_state}; let best_header_bytes = self.best_block_header(); let best_header = HeaderView::new(&best_header_bytes); @@ -771,13 +771,13 @@ impl BlockChainClient for Client where V: Verifier { // lock the state db while we create the state chunks. let state_hashes = { let state_db = self.state_db.lock().unwrap(); - StateChunker::chunk_all(state_db.as_hashdb(), &state_root, &path).unwrap() + chunk_state(state_db.as_hashdb(), &state_root, &path).unwrap() }; let best_hash = best_header.hash(); let genesis_hash = self.chain.genesis_hash(); - let block_chunk_hashes = BlockChunker::new(self, best_hash, genesis_hash).chunk_all(&path).unwrap(); + let block_chunk_hashes = chunk_blocks(self, best_hash, genesis_hash, &path).unwrap(); let manifest_data = ManifestData { state_hashes: state_hashes, diff --git a/ethcore/src/pv64/mod.rs b/ethcore/src/pv64/mod.rs index 9af689588..375a36def 100644 --- a/ethcore/src/pv64/mod.rs +++ b/ethcore/src/pv64/mod.rs @@ -36,7 +36,7 @@ use util::numbers::U256; use util::rlp::{DecoderError, Stream, Rlp, RlpStream, UntrustedRlp, View}; /// Used to build block chunks. -pub struct BlockChunker<'a> { +struct BlockChunker<'a> { client: &'a BlockChainClient, // block, receipt rlp pairs. rlps: VecDeque, @@ -46,18 +46,6 @@ pub struct BlockChunker<'a> { } impl<'a> BlockChunker<'a> { - /// Create a new BlockChunker given a client and the genesis hash. - pub fn new(client: &'a BlockChainClient, best_block_hash: H256, genesis_hash: H256) -> Self { - // Todo [rob]: find a way to reuse rlp allocations - BlockChunker { - client: client, - rlps: VecDeque::new(), - genesis_hash: genesis_hash, - current_hash: best_block_hash, - hashes: Vec::new(), - } - } - // Try to fill the buffers, moving backwards from current block hash. // This will return true if it created a block chunk, false otherwise. fn fill_buffers(&mut self) -> bool { @@ -118,27 +106,33 @@ impl<'a> BlockChunker<'a> { self.hashes.push(hash); Ok(()) } +} - /// Create and write out all block chunks to disk, returning a vector of all - /// the hashes of block chunks created. - /// - /// The path parameter is the directory to store the block chunks in. - /// This function assumes the directory exists already. - pub fn chunk_all(mut self, path: &Path) -> Result, Error> { - while self.fill_buffers() { - try!(self.write_chunk(path)); - } +/// Create and write out all block chunks to disk, returning a vector of all +/// the hashes of block chunks created. +/// +/// The path parameter is the directory to store the block chunks in. +/// This function assumes the directory exists already. +pub fn chunk_blocks(client: &BlockChainClient, best_block_hash: H256, genesis_hash: H256, path: &Path) -> Result, Error> { + let mut chunker = BlockChunker { + client: client, + rlps: VecDeque::new(), + genesis_hash: genesis_hash, + current_hash: best_block_hash, + hashes: Vec::new(), + }; - if self.rlps.len() != 0 { - try!(self.write_chunk(path)); - } - - Ok(self.hashes) + while chunker.fill_buffers() { + try!(chunker.write_chunk(path)); } + if chunker.rlps.len() != 0 { + try!(chunker.write_chunk(path)); + } + Ok(chunker.hashes) } /// State trie chunker. -pub struct StateChunker<'a> { +struct StateChunker<'a> { hashes: Vec, rlps: Vec, cur_size: usize, @@ -193,41 +187,41 @@ impl<'a> StateChunker<'a> { Ok(()) } +} - /// Walk the given state database starting from the given root, - /// creating chunks and writing them out. - /// - /// Returns a list of hashes of chunks created, or any error it may - /// have encountered. - pub fn chunk_all(db: &'a HashDB, root: &'a H256, path: &'a Path) -> Result, Error> { - let account_view = try!(TrieDB::new(db, &root)); +/// Walk the given state database starting from the given root, +/// creating chunks and writing them out. +/// +/// Returns a list of hashes of chunks created, or any error it may +/// have encountered. +pub fn chunk_state(db: &HashDB, root: &H256, path: &Path) -> Result, Error> { + let account_view = try!(TrieDB::new(db, &root)); - let mut chunker = StateChunker { - hashes: Vec::new(), - rlps: Vec::new(), - cur_size: 0, - snapshot_path: path, - }; + let mut chunker = StateChunker { + hashes: Vec::new(), + rlps: Vec::new(), + cur_size: 0, + snapshot_path: path, + }; - trace!(target: "pv64_snapshot", "beginning state chunking"); + trace!(target: "pv64_snapshot", "beginning state chunking"); - // account_key here is the address' hash. - for (account_key, account_data) in account_view.iter() { - let account = AccountReader::from_thin_rlp(account_data); - let account_key_hash = H256::from_slice(&account_key); + // account_key here is the address' hash. + for (account_key, account_data) in account_view.iter() { + let account = AccountReader::from_thin_rlp(account_data); + let account_key_hash = H256::from_slice(&account_key); - let account_db = AccountDB::from_hash(db, account_key_hash); + let account_db = AccountDB::from_hash(db, account_key_hash); - let fat_rlp = try!(account.to_fat_rlp(&account_db)); - try!(chunker.push(account_key, fat_rlp)); - } - - if chunker.cur_size != 0 { - try!(chunker.write_chunk()); - } - - Ok(chunker.hashes) + let fat_rlp = try!(account.to_fat_rlp(&account_db)); + try!(chunker.push(account_key, fat_rlp)); } + + if chunker.cur_size != 0 { + try!(chunker.write_chunk()); + } + + Ok(chunker.hashes) } // An alternate account structure, only used for reading the storage values