verification: fix race same block (#11400)

This commit is contained in:
rakita 2020-09-04 17:01:08 +02:00 committed by Artem Vorotnikov
parent f8326b6e27
commit c58b52c21c
No known key found for this signature in database
GPG Key ID: E0148C3F2FBB7A20
2 changed files with 28 additions and 8 deletions

View File

@ -1752,10 +1752,14 @@ impl ImportBlock for Client {
Ok(hash) Ok(hash)
} }
// we only care about block errors (not import errors) // we only care about block errors (not import errors)
Err((block, EthcoreError(EthcoreErrorKind::Block(err), _))) => { Err((Some(block), EthcoreError(EthcoreErrorKind::Block(err), _))) => {
self.importer self.importer
.bad_blocks .bad_blocks
.report(block.bytes, format!("{:?}", err)); .report(block.bytes, err.to_string());
bail!(EthcoreErrorKind::Block(err))
}
Err((None, EthcoreError(EthcoreErrorKind::Block(err), _))) => {
error!(target: "client", "BlockError {} detected but it was missing raw_bytes of the block", err);
bail!(EthcoreErrorKind::Block(err)) bail!(EthcoreErrorKind::Block(err))
} }
Err((_, e)) => Err(e), Err((_, e)) => Err(e),

View File

@ -507,36 +507,52 @@ impl<K: Kind> VerificationQueue<K> {
} }
/// Add a block to the queue. /// Add a block to the queue.
pub fn import(&self, input: K::Input) -> Result<H256, (K::Input, Error)> { pub fn import(&self, input: K::Input) -> Result<H256, (Option<K::Input>, Error)> {
let hash = input.hash(); let hash = input.hash();
let raw_hash = input.raw_hash(); let raw_hash = input.raw_hash();
{ {
if self.processing.read().contains_key(&hash) { if self.processing.read().contains_key(&hash) {
bail!(( bail!((
input, Some(input),
ErrorKind::Import(ImportErrorKind::AlreadyQueued).into() ErrorKind::Import(ImportErrorKind::AlreadyQueued).into()
)); ));
} }
let mut bad = self.verification.bad.lock(); let mut bad = self.verification.bad.lock();
if bad.contains(&hash) || bad.contains(&raw_hash) { if bad.contains(&hash) || bad.contains(&raw_hash) {
bail!((input, ErrorKind::Import(ImportErrorKind::KnownBad).into())); bail!((
Some(input),
ErrorKind::Import(ImportErrorKind::KnownBad).into()
));
} }
if bad.contains(&input.parent_hash()) { if bad.contains(&input.parent_hash()) {
bad.insert(hash); bad.insert(hash);
bail!((input, ErrorKind::Import(ImportErrorKind::KnownBad).into())); bail!((
Some(input),
ErrorKind::Import(ImportErrorKind::KnownBad).into()
));
} }
} }
match K::create(input, &*self.engine, self.verification.check_seal) { match K::create(input, &*self.engine, self.verification.check_seal) {
Ok(item) => { Ok(item) => {
if self
.processing
.write()
.insert(hash, item.difficulty())
.is_some()
{
bail!((
None,
ErrorKind::Import(ImportErrorKind::AlreadyQueued).into()
));
}
self.verification self.verification
.sizes .sizes
.unverified .unverified
.fetch_add(item.heap_size_of_children(), AtomicOrdering::SeqCst); .fetch_add(item.heap_size_of_children(), AtomicOrdering::SeqCst);
self.processing.write().insert(hash, item.difficulty());
{ {
let mut td = self.total_difficulty.write(); let mut td = self.total_difficulty.write();
*td = *td + item.difficulty(); *td = *td + item.difficulty();
@ -563,7 +579,7 @@ impl<K: Kind> VerificationQueue<K> {
self.verification.bad.lock().insert(hash); self.verification.bad.lock().insert(hash);
} }
} }
Err((input, err)) Err((Some(input), err))
} }
} }
} }