diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index aa88e03aa..1cf81409b 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -25,7 +25,8 @@ use frame_support::{ decl_module, decl_storage, decl_error, decl_event, - traits::Get, traits::FindAuthor, + traits::Get, traits::FindAuthor, weights::Weight, + dispatch::DispatchResultWithPostInfo, }; use sp_std::prelude::*; use frame_system::ensure_none; @@ -38,7 +39,7 @@ use sp_runtime::{ }; use evm::ExitReason; use fp_evm::CallOrCreateInfo; -use pallet_evm::Runner; +use pallet_evm::{Runner, GasToWeight}; use sha3::{Digest, Keccak256}; use codec::Encode; use fp_consensus::{FRONTIER_ENGINE_ID, ConsensusLog}; @@ -112,8 +113,8 @@ decl_module! { fn deposit_event() = default; /// Transact an Ethereum transaction. - #[weight = 0] - fn transact(origin, transaction: ethereum::Transaction) { + #[weight = ::GasToWeight::gas_to_weight(transaction.gas_limit.low_u32())] + fn transact(origin, transaction: ethereum::Transaction) -> DispatchResultWithPostInfo { ensure_none(origin)?; let source = Self::recover_signer(&transaction) @@ -183,13 +184,14 @@ decl_module! { Pending::append((transaction, status, receipt)); Self::deposit_event(Event::Executed(source, transaction_hash, reason)); + Ok(Some(T::GasToWeight::gas_to_weight(used_gas.low_u32())).into()) } fn on_finalize(n: T::BlockNumber) { >::store_block(); } - fn on_initialize(n: T::BlockNumber) -> frame_support::weights::Weight { + fn on_initialize(n: T::BlockNumber) -> Weight { Pending::kill(); 0 } diff --git a/frame/ethereum/src/mock.rs b/frame/ethereum/src/mock.rs index dc35506c4..ce83b85c4 100644 --- a/frame/ethereum/src/mock.rs +++ b/frame/ethereum/src/mock.rs @@ -138,6 +138,7 @@ impl AddressMapping for HashedAddressMapping { impl pallet_evm::Trait for Test { type FeeCalculator = FixedGasPrice; + type GasToWeight = (); type CallOrigin = EnsureAddressTruncated; type WithdrawOrigin = EnsureAddressTruncated; type AddressMapping = HashedAddressMapping; diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index a9ac1ea5c..ed4ee14f6 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -68,12 +68,12 @@ use codec::{Encode, Decode}; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use frame_support::{decl_module, decl_storage, decl_event, decl_error}; -use frame_support::weights::{Weight, Pays}; +use frame_support::weights::{Weight, Pays, PostDispatchInfo}; use frame_support::traits::{Currency, ExistenceRequirement, Get}; use frame_support::dispatch::DispatchResultWithPostInfo; use frame_system::RawOrigin; use sp_core::{U256, H256, H160, Hasher}; -use sp_runtime::{AccountId32, traits::{UniqueSaturatedInto, SaturatedConversion, BadOrigin}}; +use sp_runtime::{AccountId32, traits::{UniqueSaturatedInto, BadOrigin}}; use evm::Config; /// Type alias for currency balance. @@ -207,6 +207,17 @@ impl> AddressMapping for HashedAddressMapping Weight; +} + +impl GasToWeight for () { + fn gas_to_weight(gas: u32) -> Weight { + gas as Weight + } +} + /// Substrate system chain ID. pub struct SystemChainId; @@ -223,6 +234,9 @@ pub trait Trait: frame_system::Trait + pallet_timestamp::Trait { /// Calculator for current gas price. type FeeCalculator: FeeCalculator; + /// Maps Ethereum gas to Substrate weight. + type GasToWeight: GasToWeight; + /// Allow the origin to call on behalf of given address. type CallOrigin: EnsureAddressOrigin; /// Allow the origin to withdraw on behalf of given address. @@ -356,7 +370,7 @@ decl_module! { } /// Issue an EVM call operation. This is similar to a message call transaction in Ethereum. - #[weight = (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight)] + #[weight = T::GasToWeight::gas_to_weight(*gas_limit)] fn call( origin, source: H160, @@ -369,7 +383,7 @@ decl_module! { ) -> DispatchResultWithPostInfo { T::CallOrigin::ensure_address_origin(&source, origin)?; - match T::Runner::call( + let info = T::Runner::call( source, target, input, @@ -377,24 +391,26 @@ decl_module! { gas_limit, Some(gas_price), nonce, - )? { - CallInfo { - exit_reason: ExitReason::Succeed(_), - .. - } => { + )?; + + match info.exit_reason { + ExitReason::Succeed(_) => { Module::::deposit_event(Event::::Executed(target)); }, _ => { Module::::deposit_event(Event::::ExecutedFailed(target)); }, - } + }; - Ok(Pays::No.into()) + Ok(PostDispatchInfo { + actual_weight: Some(T::GasToWeight::gas_to_weight(info.used_gas.low_u32())), + pays_fee: Pays::No, + }) } /// Issue an EVM create operation. This is similar to a contract creation transaction in /// Ethereum. - #[weight = (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight)] + #[weight = T::GasToWeight::gas_to_weight(*gas_limit)] fn create( origin, source: H160, @@ -406,14 +422,16 @@ decl_module! { ) -> DispatchResultWithPostInfo { T::CallOrigin::ensure_address_origin(&source, origin)?; - match T::Runner::create( + let info = T::Runner::create( source, init, value, gas_limit, Some(gas_price), nonce, - )? { + )?; + + match info { CreateInfo { exit_reason: ExitReason::Succeed(_), value: create_address, @@ -430,11 +448,14 @@ decl_module! { }, } - Ok(Pays::No.into()) + Ok(PostDispatchInfo { + actual_weight: Some(T::GasToWeight::gas_to_weight(info.used_gas.low_u32())), + pays_fee: Pays::No, + }) } /// Issue an EVM create2 operation. - #[weight = (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight)] + #[weight = T::GasToWeight::gas_to_weight(*gas_limit)] fn create2( origin, source: H160, @@ -447,7 +468,7 @@ decl_module! { ) -> DispatchResultWithPostInfo { T::CallOrigin::ensure_address_origin(&source, origin)?; - match T::Runner::create2( + let info = T::Runner::create2( source, init, salt, @@ -455,7 +476,9 @@ decl_module! { gas_limit, Some(gas_price), nonce, - )? { + )?; + + match info { CreateInfo { exit_reason: ExitReason::Succeed(_), value: create_address, @@ -472,7 +495,10 @@ decl_module! { }, } - Ok(Pays::No.into()) + Ok(PostDispatchInfo { + actual_weight: Some(T::GasToWeight::gas_to_weight(info.used_gas.low_u32())), + pays_fee: Pays::No, + }) } } } diff --git a/frame/evm/src/tests.rs b/frame/evm/src/tests.rs index 06ffd59c6..5fb245a53 100644 --- a/frame/evm/src/tests.rs +++ b/frame/evm/src/tests.rs @@ -110,6 +110,7 @@ impl FeeCalculator for FixedGasPrice { impl Trait for Test { type FeeCalculator = FixedGasPrice; + type GasToWeight = (); type CallOrigin = EnsureAddressRoot; type WithdrawOrigin = EnsureAddressNever; diff --git a/template/runtime/src/lib.rs b/template/runtime/src/lib.rs index daf38bd11..0c20e7e2c 100644 --- a/template/runtime/src/lib.rs +++ b/template/runtime/src/lib.rs @@ -284,6 +284,7 @@ parameter_types! { impl pallet_evm::Trait for Runtime { type FeeCalculator = FixedGasPrice; + type GasToWeight = (); type CallOrigin = EnsureAddressTruncated; type WithdrawOrigin = EnsureAddressTruncated; type AddressMapping = HashedAddressMapping;