diff --git a/src/blockchain.rs b/src/blockchain.rs index abd6db203..98b3bfbd1 100644 --- a/src/blockchain.rs +++ b/src/blockchain.rs @@ -248,6 +248,14 @@ impl BlockChain { bc } + /// Ensure that the best block does indeed have a state_root in the state DB. + /// If it doesn't, then rewind down until we find one that does and delete data to ensure that + /// later blocks will be reimported. + pub fn ensure_good(&mut self, _state: &OverlayDB) { + info!("Rescuing database."); + // TODO. + } + /// Returns a tree route between `from` and `to`, which is a tuple of: /// /// - a vector of hashes of all blocks, ordered from `from` to `to`. diff --git a/src/client.rs b/src/client.rs index dd036a858..19a858564 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,5 +1,6 @@ use util::*; -use rocksdb::{DB}; +use rocksdb::{Options, DB}; +use rocksdb::DBCompactionStyle::DBUniversalCompaction; use blockchain::{BlockChain, BlockProvider}; use views::BlockView; use error::*; @@ -111,19 +112,42 @@ impl Client { /// Create a new client with given spec and DB path. pub fn new(spec: Spec, path: &Path, message_channel: IoChannel ) -> Result { let chain = Arc::new(RwLock::new(BlockChain::new(&spec.genesis_block(), path))); - let engine = Arc::new(try!(spec.to_engine())); + let mut opts = Options::new(); + opts.create_if_missing(true); + opts.set_max_open_files(256); + opts.set_use_fsync(false); + opts.set_bytes_per_sync(8388608); + opts.set_disable_data_sync(false); + opts.set_block_cache_size_mb(1024); + opts.set_table_cache_num_shard_bits(6); + opts.set_max_write_buffer_number(32); + opts.set_write_buffer_size(536870912); + opts.set_target_file_size_base(1073741824); + opts.set_min_write_buffer_number_to_merge(4); + opts.set_level_zero_stop_writes_trigger(2000); + opts.set_level_zero_slowdown_writes_trigger(0); + opts.set_compaction_style(DBUniversalCompaction); + opts.set_max_background_compactions(4); + opts.set_max_background_flushes(4); + opts.set_filter_deletes(false); + opts.set_disable_auto_compactions(true); + let mut state_path = path.to_path_buf(); state_path.push("state"); - let db = DB::open_default(state_path.to_str().unwrap()).unwrap(); + let db = DB::open(&opts, state_path.to_str().unwrap()).unwrap(); let mut state_db = OverlayDB::new(db); + + let engine = Arc::new(try!(spec.to_engine())); engine.spec().ensure_db_good(&mut state_db); state_db.commit().expect("Error commiting genesis state to state DB"); + chain.write().unwrap().ensure_good(&state_db); + Ok(Client { - chain: chain.clone(), + chain: chain, engine: engine.clone(), state_db: state_db, - queue: BlockQueue::new(engine.clone(), message_channel), + queue: BlockQueue::new(engine, message_channel), }) }