diff --git a/frame/evm/src/backend.rs b/frame/evm/src/backend.rs index 8074596295..d129cd33e6 100644 --- a/frame/evm/src/backend.rs +++ b/frame/evm/src/backend.rs @@ -26,7 +26,7 @@ use frame_support::traits::Get; use frame_support::{debug, storage::{StorageMap, StorageDoubleMap}}; use sha3::{Keccak256, Digest}; use evm::backend::{Backend as BackendT, ApplyBackend, Apply}; -use crate::{AccountStorages, AccountCodes, Config, Event, Pallet}; +use crate::{Trait, AccountStorages, AccountCodes, Module, Event}; #[derive(Clone, Eq, PartialEq, Encode, Decode, Default)] #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] @@ -73,7 +73,7 @@ impl<'vicinity, T> Backend<'vicinity, T> { } } -impl<'vicinity, T: Config> BackendT for Backend<'vicinity, T> { +impl<'vicinity, T: Trait> BackendT for Backend<'vicinity, T> { fn gas_price(&self) -> U256 { self.vicinity.gas_price } fn origin(&self) -> H160 { self.vicinity.origin } @@ -82,12 +82,12 @@ impl<'vicinity, T: Config> BackendT for Backend<'vicinity, T> { H256::default() } else { let number = T::BlockNumber::from(number.as_u32()); - H256::from_slice(frame_system::Pallet::::block_hash(number).as_ref()) + H256::from_slice(frame_system::Module::::block_hash(number).as_ref()) } } fn block_number(&self) -> U256 { - let number: u128 = frame_system::Pallet::::block_number().unique_saturated_into(); + let number: u128 = frame_system::Module::::block_number().unique_saturated_into(); U256::from(number) } @@ -96,7 +96,7 @@ impl<'vicinity, T: Config> BackendT for Backend<'vicinity, T> { } fn block_timestamp(&self) -> U256 { - let now: u128 = pallet_timestamp::Pallet::::get().unique_saturated_into(); + let now: u128 = pallet_timestamp::Module::::get().unique_saturated_into(); U256::from(now / 1000) } @@ -117,7 +117,7 @@ impl<'vicinity, T: Config> BackendT for Backend<'vicinity, T> { } fn basic(&self, address: H160) -> evm::backend::Basic { - let account = Pallet::::account_basic(&address); + let account = Module::::account_basic(&address); evm::backend::Basic { balance: account.balance, diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 4471aac6bc..f16ee0d281 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -15,38 +15,38 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # EVM Pallet +//! # EVM Module //! -//! The EVM pallet allows unmodified EVM code to be executed in a Substrate-based blockchain. +//! The EVM module allows unmodified EVM code to be executed in a Substrate-based blockchain. //! - [`evm::Config`] //! //! ## EVM Engine //! -//! The EVM pallet uses [`SputnikVM`](https://github.com/rust-blockchain/evm) as the underlying EVM engine. +//! The EVM module uses [`SputnikVM`](https://github.com/rust-blockchain/evm) as the underlying EVM engine. //! The engine is overhauled so that it's [`modular`](https://github.com/corepaper/evm). //! //! ## Execution Lifecycle //! -//! There are a separate set of accounts managed by the EVM pallet. Substrate based accounts can call the EVM Pallet +//! There are a separate set of accounts managed by the EVM module. Substrate based accounts can call the EVM Module //! to deposit or withdraw balance from the Substrate base-currency into a different balance managed and used by -//! the EVM pallet. Once a user has populated their balance, they can create and call smart contracts using this pallet. +//! the EVM module. Once a user has populated their balance, they can create and call smart contracts using this module. //! //! There's one-to-one mapping from Substrate accounts and EVM external accounts that is defined by a conversion function. //! -//! ## EVM Pallet vs Ethereum Network +//! ## EVM Module vs Ethereum Network //! -//! The EVM pallet should be able to produce nearly identical results compared to the Ethereum mainnet, +//! The EVM module should be able to produce nearly identical results compared to the Ethereum mainnet, //! including gas cost and balance changes. //! //! Observable differences include: //! -//! - The available length of block hashes may not be 256 depending on the configuration of the System pallet +//! - The available length of block hashes may not be 256 depending on the configuration of the System module //! in the Substrate runtime. -//! - Difficulty and coinbase, which do not make sense in this pallet and is currently hard coded to zero. +//! - Difficulty and coinbase, which do not make sense in this module and is currently hard coded to zero. //! //! We currently do not aim to make unobservable behaviors, such as state root, to be the same. We also don't aim to follow //! the exact same transaction / receipt format. However, given one Ethereum transaction and one Substrate account's -//! private key, one should be able to convert any Ethereum transaction into a transaction compatible with this pallet. +//! private key, one should be able to convert any Ethereum transaction into a transaction compatible with this module. //! //! The gas configurations are configurable. Right now, a pre-defined Istanbul hard fork configuration option is provided. @@ -68,315 +68,15 @@ use sp_std::vec::Vec; use codec::{Encode, Decode}; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; -use frame_support::weights::{Weight, PostDispatchInfo}; -use frame_support::traits::{Currency, ExistenceRequirement, WithdrawReasons, Imbalance, OnUnbalanced}; +use frame_support::{decl_module, decl_storage, decl_event, decl_error}; +use frame_support::weights::{Weight, Pays, PostDispatchInfo}; +use frame_support::traits::{Currency, ExistenceRequirement, Get, WithdrawReasons, Imbalance, OnUnbalanced}; +use frame_support::dispatch::DispatchResultWithPostInfo; use frame_system::RawOrigin; use sp_core::{U256, H256, H160, Hasher}; use sp_runtime::{AccountId32, traits::{UniqueSaturatedInto, BadOrigin, Saturating}}; use evm::Config as EvmConfig; -pub use pallet::*; - -#[frame_support::pallet] -pub mod pallet { - use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; - use super::*; - - #[pallet::pallet] - #[pallet::generate_store(pub(super) trait Store)] - pub struct Pallet(_); - - #[pallet::config] - pub trait Config: frame_system::Config + pallet_timestamp::Config { - /// Calculator for current gas price. - type FeeCalculator: FeeCalculator; - - /// Maps Ethereum gas to Substrate weight. - type GasWeightMapping: GasWeightMapping; - - /// Allow the origin to call on behalf of given address. - type CallOrigin: EnsureAddressOrigin; - /// Allow the origin to withdraw on behalf of given address. - type WithdrawOrigin: EnsureAddressOrigin; - - /// Mapping from address to account id. - type AddressMapping: AddressMapping; - /// Currency type for withdraw and balance storage. - type Currency: Currency; - - /// The overarching event type. - type Event: From> + IsType<::Event>; - /// Precompiles associated with this EVM engine. - type Precompiles: PrecompileSet; - /// Chain ID of EVM. - type ChainId: Get; - /// The block gas limit. Can be a simple constant, or an adjustment algorithm in another pallet. - type BlockGasLimit: Get; - /// EVM execution runner. - type Runner: Runner; - - /// To handle fee deduction for EVM transactions. An example is this pallet being used by `pallet_ethereum` - /// where the chain implementing `pallet_ethereum` should be able to configure what happens to the fees - /// Similar to `OnChargeTransaction` of `pallet_transaction_payment` - type OnChargeTransaction: OnChargeEVMTransaction; - - /// EVM config used in the pallet. - fn config() -> &'static EvmConfig { - &ISTANBUL_CONFIG - } - } - - #[pallet::hooks] - impl Hooks> for Pallet {} - - #[pallet::call] - impl Pallet { - /// Withdraw balance from EVM into currency/balances pallet. - #[pallet::weight(0)] - fn withdraw(origin: OriginFor, address: H160, value: BalanceOf) -> DispatchResult { - let destination = T::WithdrawOrigin::ensure_address_origin(&address, origin)?; - let address_account_id = T::AddressMapping::into_account_id(address); - - T::Currency::transfer( - &address_account_id, - &destination, - value, - ExistenceRequirement::AllowDeath, - )?; - - Ok(()) - } - - /// Issue an EVM call operation. This is similar to a message call transaction in Ethereum. - #[pallet::weight(T::GasWeightMapping::gas_to_weight(*gas_limit))] - pub(super) fn call( - origin: OriginFor, - source: H160, - target: H160, - input: Vec, - value: U256, - gas_limit: u64, - gas_price: U256, - nonce: Option, - ) -> DispatchResultWithPostInfo { - T::CallOrigin::ensure_address_origin(&source, origin)?; - - let info = T::Runner::call( - source, - target, - input, - value, - gas_limit, - Some(gas_price), - nonce, - T::config(), - )?; - - match info.exit_reason { - ExitReason::Succeed(_) => { - Pallet::::deposit_event(Event::::Executed(target)); - }, - _ => { - Pallet::::deposit_event(Event::::ExecutedFailed(target)); - }, - }; - - Ok(PostDispatchInfo { - actual_weight: Some(T::GasWeightMapping::gas_to_weight(info.used_gas.unique_saturated_into())), - pays_fee: Pays::No, - }) - } - - /// Issue an EVM create operation. This is similar to a contract creation transaction in - /// Ethereum. - #[pallet::weight(T::GasWeightMapping::gas_to_weight(*gas_limit))] - fn create( - origin: OriginFor, - source: H160, - init: Vec, - value: U256, - gas_limit: u64, - gas_price: U256, - nonce: Option, - ) -> DispatchResultWithPostInfo { - T::CallOrigin::ensure_address_origin(&source, origin)?; - - let info = T::Runner::create( - source, - init, - value, - gas_limit, - Some(gas_price), - nonce, - T::config(), - )?; - - match info { - CreateInfo { - exit_reason: ExitReason::Succeed(_), - value: create_address, - .. - } => { - Pallet::::deposit_event(Event::::Created(create_address)); - }, - CreateInfo { - exit_reason: _, - value: create_address, - .. - } => { - Pallet::::deposit_event(Event::::CreatedFailed(create_address)); - }, - } - - Ok(PostDispatchInfo { - actual_weight: Some(T::GasWeightMapping::gas_to_weight(info.used_gas.unique_saturated_into())), - pays_fee: Pays::No, - }) - } - - /// Issue an EVM create2 operation. - #[pallet::weight(T::GasWeightMapping::gas_to_weight(*gas_limit))] - fn create2( - origin: OriginFor, - source: H160, - init: Vec, - salt: H256, - value: U256, - gas_limit: u64, - gas_price: U256, - nonce: Option, - ) -> DispatchResultWithPostInfo { - T::CallOrigin::ensure_address_origin(&source, origin)?; - - let info = T::Runner::create2( - source, - init, - salt, - value, - gas_limit, - Some(gas_price), - nonce, - T::config(), - )?; - - match info { - CreateInfo { - exit_reason: ExitReason::Succeed(_), - value: create_address, - .. - } => { - Pallet::::deposit_event(Event::::Created(create_address)); - }, - CreateInfo { - exit_reason: _, - value: create_address, - .. - } => { - Pallet::::deposit_event(Event::::CreatedFailed(create_address)); - }, - } - - Ok(PostDispatchInfo { - actual_weight: Some(T::GasWeightMapping::gas_to_weight(info.used_gas.unique_saturated_into())), - pays_fee: Pays::No, - }) - } - } - - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - #[pallet::metadata(T::AccountId = "AccountId")] - pub enum Event { - /// Ethereum events from contracts. - Log(Log), - /// A contract has been created at given \[address\]. - Created(H160), - /// A \[contract\] was attempted to be created, but the execution failed. - CreatedFailed(H160), - /// A \[contract\] has been executed successfully with states applied. - Executed(H160), - /// A \[contract\] has been executed with errors. States are reverted with only gas fees applied. - ExecutedFailed(H160), - /// A deposit has been made at a given address. \[sender, address, value\] - BalanceDeposit(T::AccountId, H160, U256), - /// A withdrawal has been made from a given address. \[sender, address, value\] - BalanceWithdraw(T::AccountId, H160, U256), - } - - #[pallet::error] - pub enum Error { - /// Not enough balance to perform action - BalanceLow, - /// Calculating total fee overflowed - FeeOverflow, - /// Calculating total payment overflowed - PaymentOverflow, - /// Withdraw fee failed - WithdrawFailed, - /// Gas price is too low. - GasPriceTooLow, - /// Nonce is invalid - InvalidNonce, - } - - #[pallet::genesis_config] - pub struct GenesisConfig { - pub accounts: std::collections::BTreeMap, - } - - #[cfg(feature = "std")] - impl Default for GenesisConfig { - fn default() -> Self { - Self { - accounts: Default::default(), - } - } - } - - #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig { - fn build(&self) { - for (address, account) in &self.accounts { - let account_id = T::AddressMapping::into_account_id(*address); - - // ASSUME: in one single EVM transaction, the nonce will not increase more than - // `u128::max_value()`. - for _ in 0..account.nonce.low_u128() { - frame_system::Pallet::::inc_account_nonce(&account_id); - } - - T::Currency::deposit_creating( - &account_id, - account.balance.low_u128().unique_saturated_into(), - ); - - >::insert(address, &account.code); - - for (index, value) in &account.storage { - >::insert(address, index, value); - } - } - } - } - - #[pallet::storage] - #[pallet::getter(fn account_codes)] - pub type AccountCodes = StorageMap<_, Blake2_128Concat, H160, Vec, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn account_storages)] - pub type AccountStorages = StorageDoubleMap< - _, - Blake2_128Concat, - H160, - Blake2_128Concat, - H256, - H256, - ValueQuery, - >; -} - /// Type alias for currency balance. pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; @@ -528,6 +228,46 @@ impl GasWeightMapping for () { static ISTANBUL_CONFIG: EvmConfig = EvmConfig::istanbul(); +/// EVM module trait +pub trait Config: frame_system::Config + pallet_timestamp::Config { + /// Calculator for current gas price. + type FeeCalculator: FeeCalculator; + + /// Maps Ethereum gas to Substrate weight. + type GasWeightMapping: GasWeightMapping; + + /// Allow the origin to call on behalf of given address. + type CallOrigin: EnsureAddressOrigin; + /// Allow the origin to withdraw on behalf of given address. + type WithdrawOrigin: EnsureAddressOrigin; + + /// Mapping from address to account id. + type AddressMapping: AddressMapping; + /// Currency type for withdraw and balance storage. + type Currency: Currency; + + /// The overarching event type. + type Event: From> + Into<::Event>; + /// Precompiles associated with this EVM engine. + type Precompiles: PrecompileSet; + /// Chain ID of EVM. + type ChainId: Get; + /// The block gas limit. Can be a simple constant, or an adjustment algorithm in another pallet. + type BlockGasLimit: Get; + /// EVM execution runner. + type Runner: Runner; + + /// To handle fee deduction for EVM transactions. An example is this pallet being used by `pallet_ethereum` + /// where the chain implementing `pallet_ethereum` should be able to configure what happens to the fees + /// Similar to `OnChargeTransaction` of `pallet_transaction_payment` + type OnChargeTransaction: OnChargeEVMTransaction; + + /// EVM config used in the module. + fn config() -> &'static EvmConfig { + &ISTANBUL_CONFIG + } +} + #[cfg(feature = "std")] #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, Serialize, Deserialize)] /// Account definition used for genesis block construction. @@ -542,11 +282,241 @@ pub struct GenesisAccount { pub code: Vec, } -impl Pallet { +decl_storage! { + trait Store for Module as EVM { + pub AccountCodes get(fn account_codes): map hasher(blake2_128_concat) H160 => Vec; + pub AccountStorages get(fn account_storages): + double_map hasher(blake2_128_concat) H160, hasher(blake2_128_concat) H256 => H256; + } + + add_extra_genesis { + config(accounts): std::collections::BTreeMap; + build(|config: &GenesisConfig| { + for (address, account) in &config.accounts { + let account_id = T::AddressMapping::into_account_id(*address); + + // ASSUME: in one single EVM transaction, the nonce will not increase more than + // `u128::max_value()`. + for _ in 0..account.nonce.low_u128() { + frame_system::Module::::inc_account_nonce(&account_id); + } + + T::Currency::deposit_creating( + &account_id, + account.balance.low_u128().unique_saturated_into(), + ); + + AccountCodes::insert(address, &account.code); + + for (index, value) in &account.storage { + AccountStorages::insert(address, index, value); + } + } + }); + } +} + +decl_event! { + /// EVM events + pub enum Event where + ::AccountId, + { + /// Ethereum events from contracts. + Log(Log), + /// A contract has been created at given \[address\]. + Created(H160), + /// A \[contract\] was attempted to be created, but the execution failed. + CreatedFailed(H160), + /// A \[contract\] has been executed successfully with states applied. + Executed(H160), + /// A \[contract\] has been executed with errors. States are reverted with only gas fees applied. + ExecutedFailed(H160), + /// A deposit has been made at a given address. \[sender, address, value\] + BalanceDeposit(AccountId, H160, U256), + /// A withdrawal has been made from a given address. \[sender, address, value\] + BalanceWithdraw(AccountId, H160, U256), + } +} + +decl_error! { + pub enum Error for Module { + /// Not enough balance to perform action + BalanceLow, + /// Calculating total fee overflowed + FeeOverflow, + /// Calculating total payment overflowed + PaymentOverflow, + /// Withdraw fee failed + WithdrawFailed, + /// Gas price is too low. + GasPriceTooLow, + /// Nonce is invalid + InvalidNonce, + } +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + + fn deposit_event() = default; + + /// Withdraw balance from EVM into currency/balances module. + #[weight = 0] + fn withdraw(origin, address: H160, value: BalanceOf) { + let destination = T::WithdrawOrigin::ensure_address_origin(&address, origin)?; + let address_account_id = T::AddressMapping::into_account_id(address); + + T::Currency::transfer( + &address_account_id, + &destination, + value, + ExistenceRequirement::AllowDeath + )?; + } + + /// Issue an EVM call operation. This is similar to a message call transaction in Ethereum. + #[weight = T::GasWeightMapping::gas_to_weight(*gas_limit)] + fn call( + origin, + source: H160, + target: H160, + input: Vec, + value: U256, + gas_limit: u64, + gas_price: U256, + nonce: Option, + ) -> DispatchResultWithPostInfo { + T::CallOrigin::ensure_address_origin(&source, origin)?; + + let info = T::Runner::call( + source, + target, + input, + value, + gas_limit, + Some(gas_price), + nonce, + T::config(), + )?; + + match info.exit_reason { + ExitReason::Succeed(_) => { + Module::::deposit_event(Event::::Executed(target)); + }, + _ => { + Module::::deposit_event(Event::::ExecutedFailed(target)); + }, + }; + + Ok(PostDispatchInfo { + actual_weight: Some(T::GasWeightMapping::gas_to_weight(info.used_gas.unique_saturated_into())), + pays_fee: Pays::No, + }) + } + + /// Issue an EVM create operation. This is similar to a contract creation transaction in + /// Ethereum. + #[weight = T::GasWeightMapping::gas_to_weight(*gas_limit)] + fn create( + origin, + source: H160, + init: Vec, + value: U256, + gas_limit: u64, + gas_price: U256, + nonce: Option, + ) -> DispatchResultWithPostInfo { + T::CallOrigin::ensure_address_origin(&source, origin)?; + + let info = T::Runner::create( + source, + init, + value, + gas_limit, + Some(gas_price), + nonce, + T::config(), + )?; + + match info { + CreateInfo { + exit_reason: ExitReason::Succeed(_), + value: create_address, + .. + } => { + Module::::deposit_event(Event::::Created(create_address)); + }, + CreateInfo { + exit_reason: _, + value: create_address, + .. + } => { + Module::::deposit_event(Event::::CreatedFailed(create_address)); + }, + } + + Ok(PostDispatchInfo { + actual_weight: Some(T::GasWeightMapping::gas_to_weight(info.used_gas.unique_saturated_into())), + pays_fee: Pays::No, + }) + } + + /// Issue an EVM create2 operation. + #[weight = T::GasWeightMapping::gas_to_weight(*gas_limit)] + fn create2( + origin, + source: H160, + init: Vec, + salt: H256, + value: U256, + gas_limit: u64, + gas_price: U256, + nonce: Option, + ) -> DispatchResultWithPostInfo { + T::CallOrigin::ensure_address_origin(&source, origin)?; + + let info = T::Runner::create2( + source, + init, + salt, + value, + gas_limit, + Some(gas_price), + nonce, + T::config(), + )?; + + match info { + CreateInfo { + exit_reason: ExitReason::Succeed(_), + value: create_address, + .. + } => { + Module::::deposit_event(Event::::Created(create_address)); + }, + CreateInfo { + exit_reason: _, + value: create_address, + .. + } => { + Module::::deposit_event(Event::::CreatedFailed(create_address)); + }, + } + + Ok(PostDispatchInfo { + actual_weight: Some(T::GasWeightMapping::gas_to_weight(info.used_gas.unique_saturated_into())), + pays_fee: Pays::No, + }) + } + } +} + +impl Module { /// Check whether an account is empty. pub fn is_account_empty(address: &H160) -> bool { let account = Self::account_basic(address); - let code_len = >::decode_len(address).unwrap_or(0); + let code_len = AccountCodes::decode_len(address).unwrap_or(0); account.nonce == U256::zero() && account.balance == U256::zero() && @@ -562,13 +532,13 @@ impl Pallet { /// Remove an account. pub fn remove_account(address: &H160) { - if >::contains_key(address) { + if AccountCodes::contains_key(address) { let account_id = T::AddressMapping::into_account_id(*address); - let _ = frame_system::Pallet::::dec_consumers(&account_id); + let _ = frame_system::Module::::dec_consumers(&account_id); } - >::remove(address); - >::remove_prefix(address); + AccountCodes::remove(address); + AccountStorages::remove_prefix(address); } /// Create an account. @@ -577,19 +547,19 @@ impl Pallet { return } - if !>::contains_key(&address) { + if !AccountCodes::contains_key(&address) { let account_id = T::AddressMapping::into_account_id(address); - let _ = frame_system::Pallet::::inc_consumers(&account_id); + let _ = frame_system::Module::::inc_consumers(&account_id); } - >::insert(address, code); + AccountCodes::insert(address, code); } /// Get the account basic in EVM format. pub fn account_basic(address: &H160) -> Account { let account_id = T::AddressMapping::into_account_id(*address); - let nonce = frame_system::Pallet::::account_nonce(&account_id); + let nonce = frame_system::Module::::account_nonce(&account_id); let balance = T::Currency::free_balance(&account_id); Account { @@ -618,7 +588,7 @@ pub trait OnChargeEVMTransaction { ) -> Result<(), Error>; } -/// Implements the transaction payment for a pallet implementing the `Currency` +/// Implements the transaction payment for a module implementing the `Currency` /// trait (eg. the pallet_balances) using an unbalance handler (implementing /// `OnUnbalanced`). /// Similar to `CurrencyAdapter` of `pallet_transaction_payment` diff --git a/frame/evm/src/runner/stack.rs b/frame/evm/src/runner/stack.rs index e0d635002f..23157a3311 100644 --- a/frame/evm/src/runner/stack.rs +++ b/frame/evm/src/runner/stack.rs @@ -22,6 +22,7 @@ use sp_core::{U256, H256, H160}; use sp_runtime::traits::UniqueSaturatedInto; use frame_support::{ ensure, traits::{Get, Currency, ExistenceRequirement}, + storage::{StorageMap, StorageDoubleMap}, }; use sha3::{Keccak256, Digest}; use fp_evm::{ExecutionInfo, CallInfo, CreateInfo, Log, Vicinity}; @@ -29,7 +30,7 @@ use evm::{ExitReason, ExitError, Transfer}; use evm::backend::Backend as BackendT; use evm::executor::{StackExecutor, StackSubstateMetadata, StackState as StackStateT}; use crate::{ - Config, AccountStorages, FeeCalculator, AccountCodes, Pallet, Event, + Config, AccountStorages, FeeCalculator, AccountCodes, Module, Event, Error, AddressMapping, PrecompileSet, OnChargeEVMTransaction }; use crate::runner::Runner as RunnerT; @@ -77,7 +78,7 @@ impl Runner { let total_fee = gas_price.checked_mul(U256::from(gas_limit)) .ok_or(Error::::FeeOverflow)?; let total_payment = value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)?; - let source_account = Pallet::::account_basic(&source); + let source_account = Module::::account_basic(&source); ensure!(source_account.balance >= total_payment, Error::::BalanceLow); if let Some(nonce) = nonce { @@ -113,7 +114,7 @@ impl Runner { "Deleting account at {:?}", address ); - Pallet::::remove_account(&address) + Module::::remove_account(&address) } for log in &state.substate.logs { @@ -126,7 +127,7 @@ impl Runner { log.data.len(), log.data ); - Pallet::::deposit_event(Event::::Log(Log { + Module::::deposit_event(Event::::Log(Log { address: log.address, topics: log.topics.clone(), data: log.data.clone(), @@ -347,12 +348,12 @@ impl<'vicinity, 'config, T: Config> BackendT for SubstrateStackState<'vicinity, H256::default() } else { let number = T::BlockNumber::from(number.as_u32()); - H256::from_slice(frame_system::Pallet::::block_hash(number).as_ref()) + H256::from_slice(frame_system::Module::::block_hash(number).as_ref()) } } fn block_number(&self) -> U256 { - let number: u128 = frame_system::Pallet::::block_number().unique_saturated_into(); + let number: u128 = frame_system::Module::::block_number().unique_saturated_into(); U256::from(number) } @@ -361,7 +362,7 @@ impl<'vicinity, 'config, T: Config> BackendT for SubstrateStackState<'vicinity, } fn block_timestamp(&self) -> U256 { - let now: u128 = pallet_timestamp::Pallet::::get().unique_saturated_into(); + let now: u128 = pallet_timestamp::Module::::get().unique_saturated_into(); U256::from(now / 1000) } @@ -382,7 +383,7 @@ impl<'vicinity, 'config, T: Config> BackendT for SubstrateStackState<'vicinity, } fn basic(&self, address: H160) -> evm::backend::Basic { - let account = Pallet::::account_basic(&address); + let account = Module::::account_basic(&address); evm::backend::Basic { balance: account.balance, @@ -391,11 +392,11 @@ impl<'vicinity, 'config, T: Config> BackendT for SubstrateStackState<'vicinity, } fn code(&self, address: H160) -> Vec { - >::get(&address) + AccountCodes::get(&address) } fn storage(&self, address: H160, index: H256) -> H256 { - >::get(address, index) + AccountStorages::get(address, index) } fn original_storage(&self, _address: H160, _index: H256) -> Option { @@ -429,7 +430,7 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> for SubstrateStackState } fn is_empty(&self, address: H160) -> bool { - Pallet::::is_account_empty(&address) + Module::::is_account_empty(&address) } fn deleted(&self, address: H160) -> bool { @@ -438,7 +439,7 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> for SubstrateStackState fn inc_nonce(&mut self, address: H160) { let account_id = T::AddressMapping::into_account_id(address); - frame_system::Pallet::::inc_account_nonce(&account_id); + frame_system::Module::::inc_account_nonce(&account_id); } fn set_storage(&mut self, address: H160, index: H256, value: H256) { @@ -449,7 +450,7 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> for SubstrateStackState address, index, ); - >::remove(address, index); + AccountStorages::remove(address, index); } else { log::debug!( target: "evm", @@ -458,12 +459,12 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> for SubstrateStackState index, value, ); - >::insert(address, index, value); + AccountStorages::insert(address, index, value); } } fn reset_storage(&mut self, address: H160) { - >::remove_prefix(address); + AccountStorages::remove_prefix(address); } fn log(&mut self, address: H160, topics: Vec, data: Vec) { @@ -481,7 +482,7 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> for SubstrateStackState code.len(), address ); - Pallet::::create_account(address, code); + Module::::create_account(address, code); } fn transfer(&mut self, transfer: Transfer) -> Result<(), ExitError> { diff --git a/frame/evm/src/tests.rs b/frame/evm/src/tests.rs index 5b1177378c..dfa204ac0d 100644 --- a/frame/evm/src/tests.rs +++ b/frame/evm/src/tests.rs @@ -22,7 +22,6 @@ use super::*; use std::{str::FromStr, collections::BTreeMap}; use frame_support::{ assert_ok, impl_outer_origin, parameter_types, impl_outer_dispatch, - traits::GenesisBuild, }; use sp_core::{Blake2Hasher, H256}; use sp_runtime::{ @@ -127,16 +126,16 @@ impl Config for Test { type Currency = Balances; type Runner = crate::runner::stack::Runner; - type Event = (); + type Event = Event; type Precompiles = (); type ChainId = (); type BlockGasLimit = (); type OnChargeTransaction = (); } -type System = frame_system::Pallet; -type Balances = pallet_balances::Pallet; -type EVM = Pallet; +type System = frame_system::Module; +type Balances = pallet_balances::Module; +type EVM = Module; pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); @@ -166,7 +165,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { ); pallet_balances::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); - >::assimilate_storage(&GenesisConfig { accounts }, &mut t).unwrap(); + GenesisConfig { accounts }.assimilate_storage::(&mut t).unwrap(); t.into() }