From 9c8b7c23d173f3a768550f956d0e0f34a9a74ae2 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 17 Oct 2019 14:02:41 +0200 Subject: [PATCH] [ethash] chainspec validate `ecip1017EraRounds` non-zero (#11123) * [ethash]: validate `ecip1017EraRounds` non-zero When `ecip1017EraRounds` ethash will divide by zero. This commit ensures that the chainspec deserialization fails and gives a better error message. * [ecip1017_eras_block_reward]: document behaviour * nit * docs(ethash ecip1071): resolve `TODO` --- ethcore/engines/ethash/src/lib.rs | 11 ++++++++++- json/src/spec/ethash.rs | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ethcore/engines/ethash/src/lib.rs b/ethcore/engines/ethash/src/lib.rs index bd901ef88..acac922fd 100644 --- a/ethcore/engines/ethash/src/lib.rs +++ b/ethcore/engines/ethash/src/lib.rs @@ -464,7 +464,16 @@ impl Ethash { } } -fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number:u64) -> (u64, U256) { + +/// Calculates the number of eras and reward +/// +/// # Panics +/// +/// This function will panic if `era_rounds` is less than `2` +fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number: u64) -> (u64, U256) { + // NOTE(niklasad1): all numbers is divisible by 1, it will cause the if below + // to succeed except for the first block. Thus, `era_rounds - 1 == 0` and cause `divide by zero` + assert!(era_rounds > 1, "ecip1017EraRounds must be bigger than 1"); let eras = if block_number != 0 && block_number % era_rounds == 0 { block_number / era_rounds - 1 } else { diff --git a/json/src/spec/ethash.rs b/json/src/spec/ethash.rs index eee44d02b..2db689275 100644 --- a/json/src/spec/ethash.rs +++ b/json/src/spec/ethash.rs @@ -91,6 +91,7 @@ pub struct EthashParams { pub ecip1010_continue_transition: Option, /// See main EthashParams docs. + #[serde(default, deserialize_with="uint::validate_optional_non_zero")] pub ecip1017_era_rounds: Option, /// Delays of difficulty bombs. @@ -101,7 +102,6 @@ pub struct EthashParams { /// EXPIP-2 duration limit pub expip2_duration_limit: Option, /// Block to transition to progpow - #[serde(rename="progpowTransition")] pub progpow_transition: Option, }