diff --git a/CHANGELOG.md b/CHANGELOG.md index 606d1129b..ce704ffa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## Parity-Ethereum [v2.6.8](https://github.com/paritytech/parity-ethereum/releases/tag/v2.6.8) + +Parity Ethereum v2.6.8-beta is a security release. Valid blocks with manipulated transactions (added/replaced) cause the client to stall. + +The full list of included changes: +* Make sure to not mark block header hash as invalid if only the body is wrong (#11356) + ## Parity-Ethereum [v2.6.7](https://github.com/paritytech/parity-ethereum/releases/tag/v2.6.7) Parity Ethereum v2.6.7-beta is a patch release that adds Istanbul hardfork diff --git a/ethcore/src/verification/queue/kind.rs b/ethcore/src/verification/queue/kind.rs index 0ac0b4f34..621ca974b 100644 --- a/ethcore/src/verification/queue/kind.rs +++ b/ethcore/src/verification/queue/kind.rs @@ -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; @@ -151,6 +154,10 @@ pub mod blocks { self.header.hash() } + fn raw_hash(&self) -> H256 { + keccak_hash::keccak(&self.bytes) + } + fn parent_hash(&self) -> H256 { self.header.parent_hash().clone() } @@ -165,6 +172,10 @@ pub mod blocks { self.header.hash() } + fn raw_hash(&self) -> H256 { + keccak_hash::keccak(&self.bytes) + } + fn parent_hash(&self) -> H256 { self.header.parent_hash().clone() } @@ -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() } } diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index 21e9f92ef..857f94347 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -467,13 +467,14 @@ impl VerificationQueue { /// Add a block to the queue. pub fn import(&self, input: K::Input) -> Result { 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) { + if bad.contains(&hash) || bad.contains(&raw_hash) { return Err((input, Error::Import(ImportError::KnownBad).into())); } @@ -500,6 +501,16 @@ impl VerificationQueue { match err { // Don't mark future blocks as bad. Error::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::Block(BlockError::InvalidTransactionsRoot(_)) | + Error::Block(BlockError::InvalidUnclesHash(_)) => { + self.verification.bad.lock().insert(raw_hash); + }, _ => { self.verification.bad.lock().insert(hash); }