Merge pull request #1364 from ethcore/miner-lock

Fix lock order when updating sealing
This commit is contained in:
Arkadiy Paronyan 2016-06-21 17:41:44 +02:00 committed by GitHub
commit 613d4c95f6

View File

@ -106,10 +106,11 @@ impl Miner {
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))] #[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
fn prepare_sealing(&self, chain: &MiningBlockChainClient) { fn prepare_sealing(&self, chain: &MiningBlockChainClient) {
trace!(target: "miner", "prepare_sealing: entering"); trace!(target: "miner", "prepare_sealing: entering");
let transactions = self.transaction_queue.lock().unwrap().top_transactions();
let (transactions, mut open_block) = {
let transactions = {self.transaction_queue.lock().unwrap().top_transactions()};
let mut sealing_work = self.sealing_work.lock().unwrap(); let mut sealing_work = self.sealing_work.lock().unwrap();
let best_hash = chain.best_block_header().sha3(); let best_hash = chain.best_block_header().sha3();
/* /*
// check to see if last ClosedBlock in would_seals is actually same parent block. // check to see if last ClosedBlock in would_seals is actually same parent block.
// if so // if so
@ -118,7 +119,7 @@ impl Miner {
// otherwise, leave everything alone. // otherwise, leave everything alone.
// otherwise, author a fresh block. // otherwise, author a fresh block.
*/ */
let mut open_block = match sealing_work.pop_if(|b| b.block().fields().header.parent_hash() == &best_hash) { let open_block = match sealing_work.pop_if(|b| b.block().fields().header.parent_hash() == &best_hash) {
Some(old_block) => { Some(old_block) => {
trace!(target: "miner", "Already have previous work; updating and returning"); trace!(target: "miner", "Already have previous work; updating and returning");
// add transactions to old_block // add transactions to old_block
@ -135,6 +136,8 @@ impl Miner {
) )
} }
}; };
(transactions, open_block)
};
let mut invalid_transactions = HashSet::new(); let mut invalid_transactions = HashSet::new();
let block_number = open_block.block().fields().header.number(); let block_number = open_block.block().fields().header.number();
@ -163,15 +166,17 @@ impl Miner {
let block = open_block.close(); let block = open_block.close();
let mut queue = self.transaction_queue.lock().unwrap();
let fetch_account = |a: &Address| AccountDetails { let fetch_account = |a: &Address| AccountDetails {
nonce: chain.latest_nonce(a), nonce: chain.latest_nonce(a),
balance: chain.latest_balance(a), balance: chain.latest_balance(a),
}; };
{
let mut queue = self.transaction_queue.lock().unwrap();
for hash in invalid_transactions.into_iter() { for hash in invalid_transactions.into_iter() {
queue.remove_invalid(&hash, &fetch_account); queue.remove_invalid(&hash, &fetch_account);
} }
}
if !block.transactions().is_empty() { if !block.transactions().is_empty() {
trace!(target: "miner", "prepare_sealing: block has transaction - attempting internal seal."); trace!(target: "miner", "prepare_sealing: block has transaction - attempting internal seal.");
@ -196,6 +201,8 @@ impl Miner {
trace!(target: "miner", "prepare_sealing: unable to generate seal internally"); trace!(target: "miner", "prepare_sealing: unable to generate seal internally");
} }
} }
let mut sealing_work = self.sealing_work.lock().unwrap();
if sealing_work.peek_last_ref().map_or(true, |pb| pb.block().fields().header.hash() != block.block().fields().header.hash()) { if sealing_work.peek_last_ref().map_or(true, |pb| pb.block().fields().header.hash() != block.block().fields().header.hash()) {
trace!(target: "miner", "Pushing a new, refreshed or borrowed pending {}...", block.block().fields().header.hash()); trace!(target: "miner", "Pushing a new, refreshed or borrowed pending {}...", block.block().fields().header.hash());
sealing_work.push(block); sealing_work.push(block);