diff --git a/ethcore/res/ethereum/kovan.json b/ethcore/res/ethereum/kovan.json index 330b00c58..78a82ccca 100644 --- a/ethcore/res/ethereum/kovan.json +++ b/ethcore/res/ethereum/kovan.json @@ -23,7 +23,8 @@ "0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de" ] - } + }, + "validateScoreTransition": 1000000 } } }, @@ -31,7 +32,7 @@ "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x2A", - "validateReceipts" : false + "validateReceiptsTransition" : 1000000 }, "genesis": { "seal": { diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 978f7a99c..12f92177c 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -393,7 +393,7 @@ impl Client { })?; // Final Verification - if let Err(e) = self.verifier.verify_block_final(header, locked_block.block().header(), self.engine().params().validate_receipts) { + if let Err(e) = self.verifier.verify_block_final(header, locked_block.block().header(), self.engine().params().validate_receipts_transition) { warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); return Err(()); } diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index 4f823fa8d..aeef176a9 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -53,6 +53,8 @@ pub struct AuthorityRoundParams { pub start_step: Option, /// Valid validators. pub validators: ethjson::spec::ValidatorSet, + /// Chain score validation transition block. + pub validate_score_transition: u64, } impl From for AuthorityRoundParams { @@ -64,6 +66,7 @@ impl From for AuthorityRoundParams { block_reward: p.block_reward.map_or_else(U256::zero, Into::into), registrar: p.registrar.map_or_else(Address::new, Into::into), start_step: p.start_step.map(Into::into), + validate_score_transition: p.validate_score_transition.map_or(0, Into::into), } } } @@ -85,6 +88,7 @@ pub struct AuthorityRound { validators: Box, /// Is this Engine just for testing (prevents step calibration). calibrate_step: bool, + validate_score_transition: u64, } fn header_step(header: &Header) -> Result { @@ -125,6 +129,7 @@ impl AuthorityRound { signer: Default::default(), validators: new_validator_set(our_params.validators), calibrate_step: our_params.start_step.is_none(), + validate_score_transition: our_params.validate_score_transition, }); // Do not initialize timeouts for tests. if should_timeout { @@ -295,13 +300,17 @@ impl Engine for AuthorityRound { Err(From::from(BlockError::InvalidSealArity( Mismatch { expected: self.seal_fields(), found: header.seal().len() } ))) + } else if header.number() >= self.validate_score_transition && *header.difficulty() >= U256::from(U128::max_value()) { + Err(From::from(BlockError::DifficultyOutOfBounds( + OutOfBounds { min: None, max: Some(U256::from(U128::max_value())), found: *header.difficulty() } + ))) } else { Ok(()) } } fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { - Ok(()) + Ok(()) } /// Do the validator and gas limit validation. @@ -327,7 +336,8 @@ impl Engine for AuthorityRound { } // Check if parent is from a previous step. - if step == header_step(parent)? { + let parent_step = header_step(parent)?; + if step == parent_step { trace!(target: "engine", "Multiple blocks proposed for step {}.", step); self.validators.report_malicious(header.author()); Err(EngineError::DoubleVote(header.author().clone()))?; diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 455d0745f..9080f2929 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -56,7 +56,7 @@ pub struct CommonParams { /// Number of first block where EIP-98 rules begin. pub eip98_transition: BlockNumber, /// Validate block receipts root. - pub validate_receipts: bool, + pub validate_receipts_transition: u64, } impl From for CommonParams { @@ -70,7 +70,7 @@ impl From for CommonParams { 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 }, eip98_transition: p.eip98_transition.map_or(0, Into::into), - validate_receipts: p.validate_receipts.unwrap_or(true), + validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into), } } } diff --git a/ethcore/src/verification/canon_verifier.rs b/ethcore/src/verification/canon_verifier.rs index 67d7e0e85..188d94a10 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, receipts: bool) -> Result<(), Error> { + fn verify_block_final(&self, expected: &Header, got: &Header, receipts: u64) -> 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 b60dbed2e..0512c8208 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, _receipts: bool) -> Result<(), Error> { + fn verify_block_final(&self, _expected: &Header, _got: &Header, _receipts: u64) -> Result<(), Error> { Ok(()) } } diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index ab21ef6c2..2e913a305 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, check_receipts: bool) -> Result<(), Error> { +pub fn verify_block_final(expected: &Header, got: &Header, check_receipts: u64) -> 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, check_receipts: bool) 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 check_receipts && expected.receipts_root() != got.receipts_root() { + if got.number() >= 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 9f0173003..08ec8c25a 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, receipts: bool) -> Result<(), Error>; + fn verify_block_final(&self, expected: &Header, got: &Header, receipts: u64) -> Result<(), Error>; } diff --git a/json/src/spec/authority_round.rs b/json/src/spec/authority_round.rs index 35f6298ae..1c01d81fe 100644 --- a/json/src/spec/authority_round.rs +++ b/json/src/spec/authority_round.rs @@ -40,6 +40,9 @@ pub struct AuthorityRoundParams { /// To be used for testing only. #[serde(rename="startStep")] pub start_step: Option, + /// Block at which score validation should start. + #[serde(rename="validateScoreTransition")] + pub validate_score_transition: Option, } /// Authority engine deserialization. diff --git a/json/src/spec/params.rs b/json/src/spec/params.rs index 1b2622316..aa2c15da4 100644 --- a/json/src/spec/params.rs +++ b/json/src/spec/params.rs @@ -54,8 +54,8 @@ pub struct Params { #[serde(rename="eip98Transition")] pub eip98_transition: Option, /// See `CommonParams` docs. - #[serde(rename="validateReceipts")] - pub validate_receipts: Option, + #[serde(rename="validateReceiptsTransition")] + pub validate_receipts_transition: Option, } #[cfg(test)]