From 7647c39259553926c07f2a0ec20a597dae4613fe Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 11 Feb 2020 18:52:59 +0100 Subject: [PATCH] pallet-evm: optional nonce parameter (#4893) * pallet-evm: optional nonce parameter * Consume all gases when nonce mismatches * Bump node runtime version --- bin/node/runtime/src/lib.rs | 4 ++-- frame/evm/src/lib.rs | 36 ++++++++++++++++++++++-------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index ca6ce955e665d..6c5b75482dec7 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -81,8 +81,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 215, - impl_version: 2, + spec_version: 216, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index edd3d46a9a2c8..7413292cd5ebd 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -117,19 +117,19 @@ impl Precompiles for () { struct WeightForCallCreate; -impl WeighData<(&H160, &Vec, &U256, &u32, &U256)> for WeightForCallCreate { +impl WeighData<(&H160, &Vec, &U256, &u32, &U256, &Option)> for WeightForCallCreate { fn weigh_data( &self, - (_, _, _, gas_provided, gas_price): (&H160, &Vec, &U256, &u32, &U256) + (_, _, _, gas_provided, gas_price, _): (&H160, &Vec, &U256, &u32, &U256, &Option) ) -> Weight { (*gas_price).saturated_into::().saturating_mul(*gas_provided) } } -impl WeighData<(&Vec, &U256, &u32, &U256)> for WeightForCallCreate { +impl WeighData<(&Vec, &U256, &u32, &U256, &Option)> for WeightForCallCreate { fn weigh_data( &self, - (_, _, gas_provided, gas_price): (&Vec, &U256, &u32, &U256) + (_, _, gas_provided, gas_price, _): (&Vec, &U256, &u32, &U256, &Option) ) -> Weight { (*gas_price).saturated_into::().saturating_mul(*gas_provided) } @@ -197,6 +197,8 @@ decl_error! { ExitReasonRevert, /// Call returned VM fatal error ExitReasonFatal, + /// Nonce is invalid + InvalidNonce, } } @@ -258,6 +260,7 @@ decl_module! { value: U256, gas_limit: u32, gas_price: U256, + nonce: Option, ) -> DispatchResult { let sender = ensure_signed(origin)?; ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::::GasPriceTooLow); @@ -278,13 +281,15 @@ decl_module! { let total_fee = gas_price.checked_mul(U256::from(gas_limit)) .ok_or(Error::::FeeOverflow)?; - if Accounts::get(&source).balance < - value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)? - { - Err(Error::::BalanceLow)? - } + let total_payment = value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)?; + let source_account = Accounts::get(&source); + ensure!(source_account.balance >= total_payment, Error::::BalanceLow); executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; + if let Some(nonce) = nonce { + ensure!(source_account.nonce == nonce, Error::::InvalidNonce); + } + let reason = executor.transact_call( source, target, @@ -317,6 +322,7 @@ decl_module! { value: U256, gas_limit: u32, gas_price: U256, + nonce: Option, ) -> DispatchResult { let sender = ensure_signed(origin)?; ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::::GasPriceTooLow); @@ -338,13 +344,15 @@ decl_module! { let total_fee = gas_price.checked_mul(U256::from(gas_limit)) .ok_or(Error::::FeeOverflow)?; - if Accounts::get(&source).balance < - value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)? - { - Err(Error::::BalanceLow)? - } + let total_payment = value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)?; + let source_account = Accounts::get(&source); + ensure!(source_account.balance >= total_payment, Error::::BalanceLow); executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; + if let Some(nonce) = nonce { + ensure!(source_account.nonce == nonce, Error::::InvalidNonce); + } + let create_address = executor.create_address(source, evm::CreateScheme::Dynamic); let reason = executor.transact_create( source,