From 2c0f456e4dbac03108dbedd6bcc9f9b785d47404 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Fri, 16 Dec 2016 23:53:20 +0100 Subject: [PATCH] guard import order --- ethcore/light/src/client/header_chain.rs | 6 ++++-- ethcore/light/src/client/mod.rs | 8 ++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ethcore/light/src/client/header_chain.rs b/ethcore/light/src/client/header_chain.rs index 847b0251f..a093dd170 100644 --- a/ethcore/light/src/client/header_chain.rs +++ b/ethcore/light/src/client/header_chain.rs @@ -104,13 +104,16 @@ impl HeaderChain { let number = view.number(); let parent_hash = view.parent_hash(); + // hold candidates the whole time to guard import order. + let mut candidates = self.candidates.write(); + // find parent details. let parent_td = { if number == 1 { let g_view = HeaderView::new(&self.genesis_header); g_view.difficulty() } else { - let maybe_td = self.candidates.read().get(&(number - 1)) + let maybe_td = candidates.get(&(number - 1)) .and_then(|entry| entry.candidates.iter().find(|c| c.hash == parent_hash)) .map(|c| c.total_difficulty); @@ -124,7 +127,6 @@ impl HeaderChain { let total_difficulty = parent_td + view.difficulty(); // insert headers and candidates entries. - let mut candidates = self.candidates.write(); candidates.entry(number).or_insert_with(|| Entry { candidates: SmallVec::new(), canonical_hash: hash}) .candidates.push(Candidate { hash: hash, diff --git a/ethcore/light/src/client/mod.rs b/ethcore/light/src/client/mod.rs index d51f2c484..d9ce036c7 100644 --- a/ethcore/light/src/client/mod.rs +++ b/ethcore/light/src/client/mod.rs @@ -76,6 +76,7 @@ pub struct Client { queue: HeaderQueue, chain: HeaderChain, tx_pool: Mutex>, + import_lock: Mutex<()>, } impl Client { @@ -85,6 +86,7 @@ impl Client { queue: HeaderQueue::new(config.queue, spec.engine.clone(), io_channel, true), chain: HeaderChain::new(&::rlp::encode(&spec.genesis_header())), tx_pool: Mutex::new(Default::default()), + import_lock: Mutex::new(()), } } @@ -149,15 +151,17 @@ impl Client { pub fn import_verified(&self) { const MAX: usize = 256; + let _lock = self.import_lock.lock(); + let mut bad = Vec::new(); let mut good = Vec::new(); for verified_header in self.queue.drain(MAX) { - let hash = verified_header.hash(); + let (num, hash) = (verified_header.number(), verified_header.hash()); match self.chain.insert(::rlp::encode(&verified_header).to_vec()) { Ok(()) => good.push(hash), Err(e) => { - debug!(target: "client", "Error importing header {}: {}", hash, e); + debug!(target: "client", "Error importing header {:?}: {}", (num, hash), e); bad.push(hash); } }