Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Make sure to not mark block header hash as invalid if only the body i…
Browse files Browse the repository at this point in the history
…s wrong. (#11356)

* Patch invalid transaction root.

* Add raw hash to bad and include fix for uncles too.

* Fix submodules.
  • Loading branch information
tomusdrw authored and s3krit committed Dec 30, 2019
1 parent ba1b879 commit 34a1f7c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
14 changes: 13 additions & 1 deletion ethcore/src/verification/queue/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ pub use self::headers::Headers;

/// Something which can produce a hash and a parent hash.
pub trait BlockLike {
/// Get the hash of this item.
/// Get the hash of this item - i.e. the header hash.
fn hash(&self) -> H256;

/// Get a raw hash of this item - i.e. the hash of the RLP representation.
fn raw_hash(&self) -> H256;

/// Get the hash of this item's parent.
fn parent_hash(&self) -> H256;

Expand Down Expand Up @@ -151,6 +154,10 @@ pub mod blocks {
self.header.hash()
}

fn raw_hash(&self) -> H256 {
hash::keccak(&self.bytes)
}

fn parent_hash(&self) -> H256 {
self.header.parent_hash().clone()
}
Expand All @@ -165,6 +172,10 @@ pub mod blocks {
self.header.hash()
}

fn raw_hash(&self) -> H256 {
hash::keccak(&self.bytes)
}

fn parent_hash(&self) -> H256 {
self.header.parent_hash().clone()
}
Expand All @@ -188,6 +199,7 @@ pub mod headers {

impl BlockLike for Header {
fn hash(&self) -> H256 { self.hash() }
fn raw_hash(&self) -> H256 { self.hash() }
fn parent_hash(&self) -> H256 { self.parent_hash().clone() }
fn difficulty(&self) -> U256 { self.difficulty().clone() }
}
Expand Down
17 changes: 14 additions & 3 deletions ethcore/src/verification/queue/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,14 +467,15 @@ impl<K: Kind> VerificationQueue<K> {
/// Add a block to the queue.
pub fn import(&self, input: K::Input) -> Result<H256, (K::Input, Error)> {
let hash = input.hash();
let raw_hash = input.raw_hash();
{
if self.processing.read().contains_key(&hash) {
return Err((input, Error::Import(ImportError::AlreadyQueued).into()));
}

let mut bad = self.verification.bad.lock();
if bad.contains(&hash) {
return Err((input, Error::Import(ImportError::KnownBad).into()));
if bad.contains(&hash) || bad.contains(&raw_hash) {
bail!((input, ErrorKind::Import(ImportErrorKind::KnownBad).into()));
}

if bad.contains(&input.parent_hash()) {
Expand All @@ -499,7 +500,17 @@ impl<K: Kind> VerificationQueue<K> {
Err((input, err)) => {
match err {
// Don't mark future blocks as bad.
Error::Block(BlockError::TemporarilyInvalid(_)) => {},
Error(ErrorKind::Block(BlockError::TemporarilyInvalid(_)), _) => {},
// If the transaction root or uncles hash is invalid, it doesn't necessarily mean
// that the header is invalid. We might have just received a malformed block body,
// so we shouldn't put the header hash to `bad`.
//
// We still put the entire `Item` hash to bad, so that we can early reject
// the items that are malformed.
Error(ErrorKind::Block(BlockError::InvalidTransactionsRoot(_)), _) |
Error(ErrorKind::Block(BlockError::InvalidUnclesHash(_)), _) => {
self.verification.bad.lock().insert(raw_hash);
},
_ => {
self.verification.bad.lock().insert(hash);
}
Expand Down

0 comments on commit 34a1f7c

Please sign in to comment.