diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 7c87a0fc1..de42c2a72 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -103,7 +103,7 @@ const HISTORY: u64 = 1200; const CLIENT_DB_VER_STR: &'static str = "5.3"; impl Client { - /// Create a new client with given spec and DB path. + /// Create a new client with given spec and root path. pub fn new(config: ClientConfig, spec: Spec, path: &Path, miner: Arc, message_channel: IoChannel ) -> Result, ClientError> { Client::::new_with_verifier(config, spec, path, miner, message_channel) } @@ -127,7 +127,7 @@ pub fn append_path(path: &Path, item: &str) -> String { } impl Client where V: Verifier { - /// Create a new client with given spec and DB path and custom verifier. + /// Create a new client with given spec and root path and custom verifier. pub fn new_with_verifier( config: ClientConfig, spec: Spec, @@ -754,17 +754,32 @@ impl BlockChainClient for Client where V: Verifier { self.miner.all_transactions() } - fn take_snapshot(&self) { + fn take_snapshot(&self, root_dir: &Path) { + use pv64::BlockChunker; + let best_header_bytes = self.best_block_header(); let best_header = HeaderView::new(&best_header_bytes); - let hash = best_header.hash(); - let state_root = best_header.state_root(); + + let mut manifest_hashes = Vec::new(); // lock the state db while we create the state chunks. { - let state_db = self.state_db.lock().unwrap(); + let _state_db = self.state_db.lock().unwrap(); + let _state_root = best_header.state_root(); // todo [rob] actually create the state chunks. } + + let best_hash = best_header.hash(); + let genesis_hash = self.chain.genesis_hash(); + + let mut path = root_dir.to_owned(); + path.push("snapshot/"); + ::std::fs::create_dir(&path).unwrap(); + + let block_chunk_hashes = BlockChunker::new(self, best_hash, genesis_hash).chunk_all(&path); + for hash in block_chunk_hashes { + manifest_hashes.push(hash); + } } } diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 9fdcdb1d4..53ecb40c2 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -32,6 +32,7 @@ pub use executive::{Executed, Executive, TransactOptions}; pub use env_info::{LastHashes, EnvInfo}; use std::collections::HashSet; +use std::path::Path; use util::bytes::Bytes; use util::hash::{Address, H256, H2048}; use util::numbers::U256; @@ -195,8 +196,9 @@ pub trait BlockChainClient : Sync + Send { /// list all transactions fn all_transactions(&self) -> Vec; - /// Generate a PV64 snapshot for the current best block. - fn take_snapshot(&self); + /// Generate a PV64 snapshot for the current best block, saving it within the + /// root directory, whose path is given. + fn take_snapshot(&self, root_dir: &Path); } /// Extended client interface used for mining diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index ec48810c5..31d70ff1d 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -502,7 +502,7 @@ impl BlockChainClient for TestBlockChainClient { self.miner.all_transactions() } - fn take_snapshot(&self) { + fn take_snapshot(&self, _root_dir: &Path) { unimplemented!() } } diff --git a/ethcore/src/pv64/mod.rs b/ethcore/src/pv64/mod.rs index 3b3cb02de..62572c2a4 100644 --- a/ethcore/src/pv64/mod.rs +++ b/ethcore/src/pv64/mod.rs @@ -25,11 +25,11 @@ const SIZE_TOLERANCE: usize = 250 * 1024; use std::collections::VecDeque; use std::fs::File; use std::io::Write; -use std::path::Path +use std::path::Path; use client::BlockChainClient; use ids::BlockID; -use views::{BlockView, HeaderView}; +use views::BlockView; use util::{Bytes, Hashable}; use util::hash::H256; @@ -46,13 +46,13 @@ 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, genesis_hash: H256) -> Self { + 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: HeaderView::new(&client.best_block_header()).hash(), + current_hash: best_block_hash, } } @@ -95,10 +95,9 @@ impl<'a> BlockChunker<'a> { let raw_data = rlp_stream.out(); let hash = raw_data.sha3(); - let hash_str = hash.to_string(); let mut file_path = path.to_owned(); - file_path.push(&hash_str[2..]); + file_path.push(hash.hex()); let mut file = File::create(file_path).unwrap(); file.write_all(&raw_data);