diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index becd872e5..a423592b3 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -301,6 +301,10 @@ impl Miner { let have_work = self.sealing_work.locked().peek_last_ref().is_some(); trace!(target: "miner", "enable_and_prepare_sealing: have_work={}", have_work); if !have_work { + // -------------------------------------------------------------------------- + // | NOTE Code below requires transaction_queue and sealing_work locks. | + // | Make sure to release the locks before calling that method. | + // -------------------------------------------------------------------------- self.sealing_enabled.store(true, atomic::Ordering::Relaxed); self.prepare_sealing(chain); } @@ -338,6 +342,10 @@ impl MinerService for Miner { fn clear_and_reset(&self, chain: &MiningBlockChainClient) { self.transaction_queue.locked().clear(); + // -------------------------------------------------------------------------- + // | NOTE Code below requires transaction_queue and sealing_work locks. | + // | Make sure to release the locks before calling that method. | + // -------------------------------------------------------------------------- self.update_sealing(chain); } @@ -493,11 +501,18 @@ impl MinerService for Miner { fn import_external_transactions(&self, chain: &MiningBlockChainClient, transactions: Vec) -> Vec> { - let mut transaction_queue = self.transaction_queue.locked(); - let results = self.add_transactions_to_queue(chain, transactions, TransactionOrigin::External, - &mut transaction_queue); + let results = { + let mut transaction_queue = self.transaction_queue.locked(); + self.add_transactions_to_queue( + chain, transactions, TransactionOrigin::External, &mut transaction_queue + ) + }; if !results.is_empty() && self.options.reseal_on_external_tx && self.tx_reseal_allowed() { + // -------------------------------------------------------------------------- + // | NOTE Code below requires transaction_queue and sealing_work locks. | + // | Make sure to release the locks before calling that method. | + // -------------------------------------------------------------------------- self.update_sealing(chain); } results @@ -531,6 +546,10 @@ impl MinerService for Miner { import }; + // -------------------------------------------------------------------------- + // | NOTE Code below requires transaction_queue and sealing_work locks. | + // | Make sure to release the locks before calling that method. | + // -------------------------------------------------------------------------- if imported.is_ok() && self.options.reseal_on_own_tx && self.tx_reseal_allowed() { // Make sure to do it after transaction is imported and lock is droped. // We need to create pending block and enable sealing @@ -625,6 +644,10 @@ impl MinerService for Miner { self.sealing_work.locked().reset(); } else { *self.next_allowed_reseal.locked() = Instant::now() + self.options.reseal_min_period; + // -------------------------------------------------------------------------- + // | NOTE Code below requires transaction_queue and sealing_work locks. | + // | Make sure to release the locks before calling that method. | + // -------------------------------------------------------------------------- self.prepare_sealing(chain); } } @@ -715,6 +738,10 @@ impl MinerService for Miner { }); } + // -------------------------------------------------------------------------- + // | NOTE Code below requires transaction_queue and sealing_work locks. | + // | Make sure to release the locks before calling that method. | + // -------------------------------------------------------------------------- self.update_sealing(chain); } }