From 7cdba58cecc7b258f95e49d263e44de3ff972b16 Mon Sep 17 00:00:00 2001 From: Artem Vorotnikov Date: Thu, 21 May 2020 22:54:07 +0300 Subject: [PATCH] Implement EIP-2565 (option 2) --- ethcore/builtin/src/lib.rs | 29 +++++++++++++++++++++++++--- ethcore/res/ethereum/foundation.json | 5 ++--- json/src/spec/builtin.rs | 4 +++- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/ethcore/builtin/src/lib.rs b/ethcore/builtin/src/lib.rs index 8f9dde5fc3e..00709c87e07 100644 --- a/ethcore/builtin/src/lib.rs +++ b/ethcore/builtin/src/lib.rs @@ -102,6 +102,7 @@ struct Linear { #[derive(Debug)] struct ModexpPricer { divisor: u64, + new_formula: bool, } impl Pricer for Linear { @@ -180,7 +181,13 @@ impl Pricer for ModexpPricer { let adjusted_exp_len = Self::adjusted_exp_len(exp_len, exp_low); - let (gas, overflow) = Self::mult_complexity(m).overflowing_mul(max(adjusted_exp_len, 1)); + let complexity_formula = if self.new_formula { + Self::mult_complexity + } else { + Self::mult_complexity_new + }; + + let (gas, overflow) = (complexity_formula)(m).overflowing_mul(max(adjusted_exp_len, 1)); if overflow { return U256::max_value(); } @@ -205,6 +212,10 @@ impl ModexpPricer { x => (x * x) / 16 + 480 * x - 199_680, } } + + fn mult_complexity_new(x: u64) -> u64 { + ((x / 64) + if x % 64 == 0 { 0 } else { 1 }) ^ 2 + } } /// Pricing scheme, execution definition, and activation block for a built-in contract. @@ -281,7 +292,19 @@ impl From for Pricing { 10 } else { exp.divisor - } + }, + new_formula: false, + }) + } + ethjson::spec::builtin::Pricing::Modexp2(exp) => { + Pricing::Modexp(ModexpPricer { + divisor: if exp.divisor == 0 { + warn!(target: "builtin", "Zero modexp divisor specified. Falling back to default: 10."); + 10 + } else { + exp.divisor + }, + new_formula: true, }) } ethjson::spec::builtin::Pricing::AltBn128Pairing(pricer) => { @@ -1037,7 +1060,7 @@ mod tests { #[test] fn modexp() { let f = Builtin { - pricer: btreemap![0 => Pricing::Modexp(ModexpPricer { divisor: 20 })], + pricer: btreemap![0 => Pricing::Modexp(ModexpPricer { divisor: 20, new_formula: false })], native: EthereumBuiltin::from_str("modexp").unwrap(), }; diff --git a/ethcore/res/ethereum/foundation.json b/ethcore/res/ethereum/foundation.json index 1949efb0093..b2e1e1d6e24 100644 --- a/ethcore/res/ethereum/foundation.json +++ b/ethcore/res/ethereum/foundation.json @@ -4827,10 +4827,9 @@ "0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", - "activate_at": "0x42ae50", "pricing": { - "modexp": { - "divisor": 20 + "0x42ae50": { + "price": { "modexp": { "divisor": 20 } } } } } diff --git a/json/src/spec/builtin.rs b/json/src/spec/builtin.rs index 173975fafe7..e654b89e15b 100644 --- a/json/src/spec/builtin.rs +++ b/json/src/spec/builtin.rs @@ -69,8 +69,10 @@ pub enum Pricing { }, /// Linear pricing. Linear(Linear), - /// Pricing for modular exponentiation. + /// Pricing for modular exponentiation with original formula from EIP-198. Modexp(Modexp), + /// Pricing for modular exponentiation that includes new formula from EIP-2565. + Modexp2(Modexp), /// Pricing for alt_bn128_pairing exponentiation. AltBn128Pairing(AltBn128Pairing), /// Pricing for constant alt_bn128 operations