guard import order

This commit is contained in:
Robert Habermeier 2016-12-16 23:53:20 +01:00
parent e57ab96731
commit 2c0f456e4d
2 changed files with 10 additions and 4 deletions

View File

@ -104,13 +104,16 @@ impl HeaderChain {
let number = view.number(); let number = view.number();
let parent_hash = view.parent_hash(); let parent_hash = view.parent_hash();
// hold candidates the whole time to guard import order.
let mut candidates = self.candidates.write();
// find parent details. // find parent details.
let parent_td = { let parent_td = {
if number == 1 { if number == 1 {
let g_view = HeaderView::new(&self.genesis_header); let g_view = HeaderView::new(&self.genesis_header);
g_view.difficulty() g_view.difficulty()
} else { } 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)) .and_then(|entry| entry.candidates.iter().find(|c| c.hash == parent_hash))
.map(|c| c.total_difficulty); .map(|c| c.total_difficulty);
@ -124,7 +127,6 @@ impl HeaderChain {
let total_difficulty = parent_td + view.difficulty(); let total_difficulty = parent_td + view.difficulty();
// insert headers and candidates entries. // 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.entry(number).or_insert_with(|| Entry { candidates: SmallVec::new(), canonical_hash: hash})
.candidates.push(Candidate { .candidates.push(Candidate {
hash: hash, hash: hash,

View File

@ -76,6 +76,7 @@ pub struct Client {
queue: HeaderQueue, queue: HeaderQueue,
chain: HeaderChain, chain: HeaderChain,
tx_pool: Mutex<H256FastMap<SignedTransaction>>, tx_pool: Mutex<H256FastMap<SignedTransaction>>,
import_lock: Mutex<()>,
} }
impl Client { impl Client {
@ -85,6 +86,7 @@ impl Client {
queue: HeaderQueue::new(config.queue, spec.engine.clone(), io_channel, true), queue: HeaderQueue::new(config.queue, spec.engine.clone(), io_channel, true),
chain: HeaderChain::new(&::rlp::encode(&spec.genesis_header())), chain: HeaderChain::new(&::rlp::encode(&spec.genesis_header())),
tx_pool: Mutex::new(Default::default()), tx_pool: Mutex::new(Default::default()),
import_lock: Mutex::new(()),
} }
} }
@ -149,15 +151,17 @@ impl Client {
pub fn import_verified(&self) { pub fn import_verified(&self) {
const MAX: usize = 256; const MAX: usize = 256;
let _lock = self.import_lock.lock();
let mut bad = Vec::new(); let mut bad = Vec::new();
let mut good = Vec::new(); let mut good = Vec::new();
for verified_header in self.queue.drain(MAX) { 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()) { match self.chain.insert(::rlp::encode(&verified_header).to_vec()) {
Ok(()) => good.push(hash), Ok(()) => good.push(hash),
Err(e) => { Err(e) => {
debug!(target: "client", "Error importing header {}: {}", hash, e); debug!(target: "client", "Error importing header {:?}: {}", (num, hash), e);
bad.push(hash); bad.push(hash);
} }
} }