diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index e9c059aaa..330b00c58 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -30,7 +30,8 @@ "params": { "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", - "networkID" : "0x2A" + "networkID" : "0x2A", + "validateReceipts" : false }, "genesis": { "seal": { diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 28dc6a839..127fa9367 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -375,7 +375,7 @@ impl Client { })?; // Final Verification - if let Err(e) = self.verifier.verify_block_final(header, locked_block.block().header()) { + if let Err(e) = self.verifier.verify_block_final(header, locked_block.block().header(), self.engine().params().validate_receipts) { warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); return Err(()); } diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index b65dafe91..25f958bad 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -53,6 +53,8 @@ pub struct CommonParams { pub min_gas_limit: U256, /// Fork block to check. pub fork_block: Option<(BlockNumber, H256)>, + /// Validate block receipts root. + pub validate_receipts: bool, } impl From for CommonParams { @@ -65,6 +67,7 @@ impl From for CommonParams { subprotocol_name: p.subprotocol_name.unwrap_or_else(|| "eth".to_owned()), min_gas_limit: p.min_gas_limit.into(), fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None }, + validate_receipts: p.validate_receipts.unwrap_or(true), } } } diff --git a/ethcore/src/verification/canon_verifier.rs b/ethcore/src/verification/canon_verifier.rs index 75b0943ea..48dc5bbe9 100644 --- a/ethcore/src/verification/canon_verifier.rs +++ b/ethcore/src/verification/canon_verifier.rs @@ -31,7 +31,7 @@ impl Verifier for CanonVerifier { verification::verify_block_family(header, bytes, engine, bc) } - fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error> { - verification::verify_block_final(expected, got) + fn verify_block_final(&self, expected: &Header, got: &Header, receipts: bool) -> Result<(), Error> { + verification::verify_block_final(expected, got, receipts) } } diff --git a/ethcore/src/verification/noop_verifier.rs b/ethcore/src/verification/noop_verifier.rs index 83ca11efd..dca36020d 100644 --- a/ethcore/src/verification/noop_verifier.rs +++ b/ethcore/src/verification/noop_verifier.rs @@ -31,7 +31,7 @@ impl Verifier for NoopVerifier { Ok(()) } - fn verify_block_final(&self, _expected: &Header, _got: &Header) -> Result<(), Error> { + fn verify_block_final(&self, _expected: &Header, _got: &Header, _receipts: bool) -> Result<(), Error> { Ok(()) } } diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 6e2ba4492..93fa1c9aa 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -178,7 +178,7 @@ pub fn verify_block_family(header: &Header, bytes: &[u8], engine: &Engine, bc: & } /// Phase 4 verification. Check block information against transaction enactment results, -pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error> { +pub fn verify_block_final(expected: &Header, got: &Header, check_receipts: bool) -> Result<(), Error> { if expected.gas_used() != got.gas_used() { return Err(From::from(BlockError::InvalidGasUsed(Mismatch { expected: expected.gas_used().clone(), found: got.gas_used().clone() }))) } @@ -188,7 +188,7 @@ pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error> if expected.state_root() != got.state_root() { return Err(From::from(BlockError::InvalidStateRoot(Mismatch { expected: expected.state_root().clone(), found: got.state_root().clone() }))) } - if expected.receipts_root() != got.receipts_root() { + if check_receipts && expected.receipts_root() != got.receipts_root() { return Err(From::from(BlockError::InvalidReceiptsRoot(Mismatch { expected: expected.receipts_root().clone(), found: got.receipts_root().clone() }))) } Ok(()) diff --git a/ethcore/src/verification/verifier.rs b/ethcore/src/verification/verifier.rs index f3cea1a78..68de0bea0 100644 --- a/ethcore/src/verification/verifier.rs +++ b/ethcore/src/verification/verifier.rs @@ -26,5 +26,5 @@ pub trait Verifier: Send + Sync { /// Verify a block relative to its parent and uncles. fn verify_block_family(&self, header: &Header, bytes: &[u8], engine: &Engine, bc: &BlockProvider) -> Result<(), Error>; /// Do a final verification check for an enacted header vs its expected counterpart. - fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error>; + fn verify_block_final(&self, expected: &Header, got: &Header, receipts: bool) -> Result<(), Error>; } diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index 9831ce61e..94c17446d 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -49,6 +49,9 @@ pub struct Params { /// Expected fork block hash. #[serde(rename="forkCanonHash")] pub fork_hash: Option, + /// See `CommonParams` docs. + #[serde(rename="validateReceipts")] + pub validate_receipts: Option, } #[cfg(test)]