From c6aea0cae6ff52b6424750a987b45705a2bd4be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 2 Jan 2018 09:43:08 +0100 Subject: [PATCH] Move StateDB to RwLock --- ethcore/src/client/client.rs | 33 ++++++++++++++++----------------- ethcore/src/state_db.rs | 9 +++++---- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 6bb445399..c114a62ac 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -152,7 +152,7 @@ pub struct Client { config: ClientConfig, pruning: journaldb::Algorithm, db: RwLock>, - state_db: Mutex, + state_db: RwLock, block_queue: BlockQueue, report: RwLock, import_lock: Mutex<()>, @@ -166,7 +166,6 @@ pub struct Client { last_hashes: RwLock>, factories: Factories, history: u64, - rng: Mutex, ancient_verifier: Mutex>, on_user_defaults_change: Mutex) + 'static + Send>>>, registrar: Mutex>, @@ -242,7 +241,7 @@ impl Client { verifier: verification::new(config.verifier_type.clone()), config: config, db: RwLock::new(db), - state_db: Mutex::new(state_db), + state_db: RwLock::new(state_db), block_queue: block_queue, report: RwLock::new(Default::default()), import_lock: Mutex::new(()), @@ -253,7 +252,6 @@ impl Client { last_hashes: RwLock::new(VecDeque::new()), factories: factories, history: history, - rng: Mutex::new(OsRng::new().map_err(UtilError::from)?), ancient_verifier: Mutex::new(None), on_user_defaults_change: Mutex::new(None), registrar: Mutex::new(None), @@ -262,7 +260,7 @@ impl Client { // prune old states. { - let state_db = client.state_db.lock().boxed_clone(); + let state_db = client.state_db.read().boxed_clone(); let chain = client.chain.read(); client.prune_ancient(state_db, &chain)?; } @@ -452,7 +450,7 @@ impl Client { // Enact Verified Block let last_hashes = self.build_last_hashes(header.parent_hash().clone()); - let db = self.state_db.lock().boxed_clone_canon(header.parent_hash()); + let db = self.state_db.read().boxed_clone_canon(header.parent_hash()); let is_epoch_begin = chain.epoch_transition(parent.number(), *header.parent_hash()).is_some(); let enact_result = enact_verified(block, @@ -611,7 +609,8 @@ impl Client { let verify_with = |verifier: &AncientVerifier| -> Result<(), ::error::Error> { // verify the block, passing the chain for updating the epoch // verifier. - verifier.verify(&mut *self.rng.lock(), &header, &chain) + let mut rng = OsRng::new().map_err(UtilError::from)?; + verifier.verify(&mut rng, &header, &chain) }; // initialize the ancient block verifier if we don't have one already. @@ -937,7 +936,7 @@ impl Client { }; self.block_header(id).and_then(|header| { - let db = self.state_db.lock().boxed_clone(); + let db = self.state_db.read().boxed_clone(); // early exit for pruned blocks if db.is_pruned() && self.pruning_info().earliest_state > block_number { @@ -968,7 +967,7 @@ impl Client { pub fn state(&self) -> State { let header = self.best_block_header(); State::from_existing( - self.state_db.lock().boxed_clone_canon(&header.hash()), + self.state_db.read().boxed_clone_canon(&header.hash()), header.state_root(), self.engine.account_start_nonce(header.number()), self.factories.clone()) @@ -983,7 +982,7 @@ impl Client { /// Get the report. pub fn report(&self) -> ClientReport { let mut report = self.report.read().clone(); - report.state_db_mem = self.state_db.lock().mem_used(); + report.state_db_mem = self.state_db.read().mem_used(); report } @@ -1039,7 +1038,7 @@ impl Client { /// Take a snapshot at the given block. /// If the ID given is "latest", this will default to 1000 blocks behind. pub fn take_snapshot(&self, writer: W, at: BlockId, p: &snapshot::Progress) -> Result<(), EthcoreError> { - let db = self.state_db.lock().journal_db().boxed_clone(); + let db = self.state_db.read().journal_db().boxed_clone(); let best_block_number = self.chain_info().best_block_number; let block_number = self.block_number(at).ok_or(snapshot::Error::InvalidStartingBlock(at))?; @@ -1187,7 +1186,7 @@ impl snapshot::DatabaseRestore for Client { trace!(target: "snapshot", "Replacing client database with {:?}", new_db); let _import_lock = self.import_lock.lock(); - let mut state_db = self.state_db.lock(); + let mut state_db = self.state_db.write(); let mut chain = self.chain.write(); let mut tracedb = self.tracedb.write(); self.miner.clear(); @@ -1608,7 +1607,7 @@ impl BlockChainClient for Client { } fn state_data(&self, hash: &H256) -> Option { - self.state_db.lock().journal_db().state(hash) + self.state_db.read().journal_db().state(hash) } fn block_receipts(&self, hash: &H256) -> Option { @@ -1790,7 +1789,7 @@ impl BlockChainClient for Client { fn pruning_info(&self) -> PruningInfo { PruningInfo { earliest_chain: self.chain.read().first_block_number().unwrap_or(1), - earliest_state: self.state_db.lock().journal_db().earliest_era().unwrap_or(0), + earliest_state: self.state_db.read().journal_db().earliest_era().unwrap_or(0), } } @@ -1858,7 +1857,7 @@ impl MiningBlockChainClient for Client { engine, self.factories.clone(), self.tracedb.read().tracing_enabled(), - self.state_db.lock().boxed_clone_canon(&h), + self.state_db.read().boxed_clone_canon(&h), best_header, self.build_last_hashes(h.clone()), author, @@ -1943,7 +1942,7 @@ impl MiningBlockChainClient for Client { let route = self.commit_block(block, &header, &block_data); trace!(target: "client", "Imported sealed block #{} ({})", number, h); - self.state_db.lock().sync_cache(&route.enacted, &route.retracted, false); + self.state_db.write().sync_cache(&route.enacted, &route.retracted, false); route }; let (enacted, retracted) = self.calculate_enacted_retracted(&[route]); @@ -2012,7 +2011,7 @@ impl ProvingBlockChainClient for Client { }; env_info.gas_limit = transaction.gas.clone(); - let mut jdb = self.state_db.lock().journal_db().boxed_clone(); + let mut jdb = self.state_db.read().journal_db().boxed_clone(); state::prove_transaction( jdb.as_hashdb_mut(), diff --git a/ethcore/src/state_db.rs b/ethcore/src/state_db.rs index 1b8d4c406..60ece54d6 100644 --- a/ethcore/src/state_db.rs +++ b/ethcore/src/state_db.rs @@ -58,7 +58,7 @@ struct CacheQueueItem { /// Account address. address: Address, /// Acccount data or `None` if account does not exist. - account: Option, + account: Mutex>, /// Indicates that the account was modified before being /// added to the cache. modified: bool, @@ -268,15 +268,16 @@ impl StateDB { modifications.insert(account.address.clone()); } if is_best { + let acc = account.account.lock().take(); if let Some(&mut Some(ref mut existing)) = cache.accounts.get_mut(&account.address) { - if let Some(new) = account.account { + if let Some(new) = acc { if account.modified { existing.overwrite_with(new); } continue; } } - cache.accounts.insert(account.address, account.account); + cache.accounts.insert(account.address, acc); } } @@ -408,7 +409,7 @@ impl state::Backend for StateDB { fn add_to_account_cache(&mut self, addr: Address, data: Option, modified: bool) { self.local_cache.push(CacheQueueItem { address: addr, - account: data, + account: Mutex::new(data), modified: modified, }) }