From 796482c12917768e09376557f0c37adc057bf322 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Thu, 22 Jun 2017 20:44:04 +0200 Subject: [PATCH] fix minor race condition in aura seal generation (#5910) --- ethcore/src/engines/authority_round.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index 22860ebbd..a00fe70ca 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -319,14 +319,20 @@ impl Engine for AuthorityRound { /// This operation is synchronous and may (quite reasonably) not be available, in which `false` will /// be returned. fn generate_seal(&self, block: &ExecutedBlock) -> Seal { + // first check to avoid generating signature most of the time + // (but there's still a race to the `compare_and_swap`) if self.proposed.load(AtomicOrdering::SeqCst) { return Seal::None; } + let header = block.header(); let step = self.step.load(); if self.is_step_proposer(header.parent_hash(), step, header.author()) { if let Ok(signature) = self.signer.sign(header.bare_hash()) { trace!(target: "engine", "generate_seal: Issuing a block for step {}.", step); - self.proposed.store(true, AtomicOrdering::SeqCst); - return Seal::Regular(vec![encode(&step).to_vec(), encode(&(&H520::from(signature) as &[u8])).to_vec()]); + + // only issue the seal if we were the first to reach the compare_and_swap. + if !self.proposed.compare_and_swap(false, true, AtomicOrdering::SeqCst) { + return Seal::Regular(vec![encode(&step).to_vec(), encode(&(&H520::from(signature) as &[u8])).to_vec()]); + } } else { warn!(target: "engine", "generate_seal: FAIL: Accounts secret key unavailable."); }