From facc38476f97d09148628d0d1a0585b45e4e070a Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 7 May 2021 19:14:41 -0700 Subject: [PATCH] Upgrade EVM pallet to FRAMEv2 --- frame/evm/src/backend.rs | 12 +- frame/evm/src/lib.rs | 620 ++++++++++++++++++---------------- frame/evm/src/runner/stack.rs | 33 +- frame/evm/src/tests.rs | 11 +- 4 files changed, 353 insertions(+), 323 deletions(-) diff --git a/frame/evm/src/backend.rs b/frame/evm/src/backend.rs index d129cd33e6..8074596295 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::{Trait, AccountStorages, AccountCodes, Module, Event}; +use crate::{AccountStorages, AccountCodes, Config, Event, Pallet}; #[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: Trait> BackendT for Backend<'vicinity, T> { +impl<'vicinity, T: Config> 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: Trait> BackendT for Backend<'vicinity, T> { H256::default() } else { let number = T::BlockNumber::from(number.as_u32()); - H256::from_slice(frame_system::Module::::block_hash(number).as_ref()) + H256::from_slice(frame_system::Pallet::::block_hash(number).as_ref()) } } fn block_number(&self) -> U256 { - let number: u128 = frame_system::Module::::block_number().unique_saturated_into(); + let number: u128 = frame_system::Pallet::::block_number().unique_saturated_into(); U256::from(number) } @@ -96,7 +96,7 @@ impl<'vicinity, T: Trait> BackendT for Backend<'vicinity, T> { } fn block_timestamp(&self) -> U256 { - let now: u128 = pallet_timestamp::Module::::get().unique_saturated_into(); + let now: u128 = pallet_timestamp::Pallet::::get().unique_saturated_into(); U256::from(now / 1000) } @@ -117,7 +117,7 @@ impl<'vicinity, T: Trait> BackendT for Backend<'vicinity, T> { } fn basic(&self, address: H160) -> evm::backend::Basic { - let account = Module::::account_basic(&address); + let account = Pallet::::account_basic(&address); evm::backend::Basic { balance: account.balance, diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index f16ee0d281..4471aac6bc 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 Module +//! # EVM Pallet //! -//! The EVM module allows unmodified EVM code to be executed in a Substrate-based blockchain. +//! The EVM pallet allows unmodified EVM code to be executed in a Substrate-based blockchain. //! - [`evm::Config`] //! //! ## EVM Engine //! -//! The EVM module uses [`SputnikVM`](https://github.com/rust-blockchain/evm) as the underlying EVM engine. +//! The EVM pallet 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 module. Substrate based accounts can call the EVM Module +//! There are a separate set of accounts managed by the EVM pallet. Substrate based accounts can call the EVM Pallet //! to deposit or withdraw balance from the Substrate base-currency into a different balance managed and used by -//! the EVM module. Once a user has populated their balance, they can create and call smart contracts using this module. +//! the EVM pallet. Once a user has populated their balance, they can create and call smart contracts using this pallet. //! //! There's one-to-one mapping from Substrate accounts and EVM external accounts that is defined by a conversion function. //! -//! ## EVM Module vs Ethereum Network +//! ## EVM Pallet vs Ethereum Network //! -//! The EVM module should be able to produce nearly identical results compared to the Ethereum mainnet, +//! The EVM pallet 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 module +//! - The available length of block hashes may not be 256 depending on the configuration of the System pallet //! in the Substrate runtime. -//! - Difficulty and coinbase, which do not make sense in this module and is currently hard coded to zero. +//! - Difficulty and coinbase, which do not make sense in this pallet 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 module. +//! private key, one should be able to convert any Ethereum transaction into a transaction compatible with this pallet. //! //! The gas configurations are configurable. Right now, a pre-defined Istanbul hard fork configuration option is provided. @@ -68,15 +68,315 @@ use sp_std::vec::Vec; 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, PostDispatchInfo}; -use frame_support::traits::{Currency, ExistenceRequirement, Get, WithdrawReasons, Imbalance, OnUnbalanced}; -use frame_support::dispatch::DispatchResultWithPostInfo; +use frame_support::weights::{Weight, PostDispatchInfo}; +use frame_support::traits::{Currency, ExistenceRequirement, WithdrawReasons, Imbalance, OnUnbalanced}; 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; @@ -228,46 +528,6 @@ 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. @@ -282,241 +542,11 @@ pub struct GenesisAccount { pub code: Vec, } -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 { +impl Pallet { /// Check whether an account is empty. pub fn is_account_empty(address: &H160) -> bool { let account = Self::account_basic(address); - let code_len = AccountCodes::decode_len(address).unwrap_or(0); + let code_len = >::decode_len(address).unwrap_or(0); account.nonce == U256::zero() && account.balance == U256::zero() && @@ -532,13 +562,13 @@ impl Module { /// Remove an account. pub fn remove_account(address: &H160) { - if AccountCodes::contains_key(address) { + if >::contains_key(address) { let account_id = T::AddressMapping::into_account_id(*address); - let _ = frame_system::Module::::dec_consumers(&account_id); + let _ = frame_system::Pallet::::dec_consumers(&account_id); } - AccountCodes::remove(address); - AccountStorages::remove_prefix(address); + >::remove(address); + >::remove_prefix(address); } /// Create an account. @@ -547,19 +577,19 @@ impl Module { return } - if !AccountCodes::contains_key(&address) { + if !>::contains_key(&address) { let account_id = T::AddressMapping::into_account_id(address); - let _ = frame_system::Module::::inc_consumers(&account_id); + let _ = frame_system::Pallet::::inc_consumers(&account_id); } - AccountCodes::insert(address, code); + >::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::Module::::account_nonce(&account_id); + let nonce = frame_system::Pallet::::account_nonce(&account_id); let balance = T::Currency::free_balance(&account_id); Account { @@ -588,7 +618,7 @@ pub trait OnChargeEVMTransaction { ) -> Result<(), Error>; } -/// Implements the transaction payment for a module implementing the `Currency` +/// Implements the transaction payment for a pallet 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 23157a3311..e0d635002f 100644 --- a/frame/evm/src/runner/stack.rs +++ b/frame/evm/src/runner/stack.rs @@ -22,7 +22,6 @@ 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}; @@ -30,7 +29,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, Module, Event, + Config, AccountStorages, FeeCalculator, AccountCodes, Pallet, Event, Error, AddressMapping, PrecompileSet, OnChargeEVMTransaction }; use crate::runner::Runner as RunnerT; @@ -78,7 +77,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 = Module::::account_basic(&source); + let source_account = Pallet::::account_basic(&source); ensure!(source_account.balance >= total_payment, Error::::BalanceLow); if let Some(nonce) = nonce { @@ -114,7 +113,7 @@ impl Runner { "Deleting account at {:?}", address ); - Module::::remove_account(&address) + Pallet::::remove_account(&address) } for log in &state.substate.logs { @@ -127,7 +126,7 @@ impl Runner { log.data.len(), log.data ); - Module::::deposit_event(Event::::Log(Log { + Pallet::::deposit_event(Event::::Log(Log { address: log.address, topics: log.topics.clone(), data: log.data.clone(), @@ -348,12 +347,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::Module::::block_hash(number).as_ref()) + H256::from_slice(frame_system::Pallet::::block_hash(number).as_ref()) } } fn block_number(&self) -> U256 { - let number: u128 = frame_system::Module::::block_number().unique_saturated_into(); + let number: u128 = frame_system::Pallet::::block_number().unique_saturated_into(); U256::from(number) } @@ -362,7 +361,7 @@ impl<'vicinity, 'config, T: Config> BackendT for SubstrateStackState<'vicinity, } fn block_timestamp(&self) -> U256 { - let now: u128 = pallet_timestamp::Module::::get().unique_saturated_into(); + let now: u128 = pallet_timestamp::Pallet::::get().unique_saturated_into(); U256::from(now / 1000) } @@ -383,7 +382,7 @@ impl<'vicinity, 'config, T: Config> BackendT for SubstrateStackState<'vicinity, } fn basic(&self, address: H160) -> evm::backend::Basic { - let account = Module::::account_basic(&address); + let account = Pallet::::account_basic(&address); evm::backend::Basic { balance: account.balance, @@ -392,11 +391,11 @@ impl<'vicinity, 'config, T: Config> BackendT for SubstrateStackState<'vicinity, } fn code(&self, address: H160) -> Vec { - AccountCodes::get(&address) + >::get(&address) } fn storage(&self, address: H160, index: H256) -> H256 { - AccountStorages::get(address, index) + >::get(address, index) } fn original_storage(&self, _address: H160, _index: H256) -> Option { @@ -430,7 +429,7 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> for SubstrateStackState } fn is_empty(&self, address: H160) -> bool { - Module::::is_account_empty(&address) + Pallet::::is_account_empty(&address) } fn deleted(&self, address: H160) -> bool { @@ -439,7 +438,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::Module::::inc_account_nonce(&account_id); + frame_system::Pallet::::inc_account_nonce(&account_id); } fn set_storage(&mut self, address: H160, index: H256, value: H256) { @@ -450,7 +449,7 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> for SubstrateStackState address, index, ); - AccountStorages::remove(address, index); + >::remove(address, index); } else { log::debug!( target: "evm", @@ -459,12 +458,12 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> for SubstrateStackState index, value, ); - AccountStorages::insert(address, index, value); + >::insert(address, index, value); } } fn reset_storage(&mut self, address: H160) { - AccountStorages::remove_prefix(address); + >::remove_prefix(address); } fn log(&mut self, address: H160, topics: Vec, data: Vec) { @@ -482,7 +481,7 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> for SubstrateStackState code.len(), address ); - Module::::create_account(address, code); + Pallet::::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 dfa204ac0d..5b1177378c 100644 --- a/frame/evm/src/tests.rs +++ b/frame/evm/src/tests.rs @@ -22,6 +22,7 @@ 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::{ @@ -126,16 +127,16 @@ impl Config for Test { type Currency = Balances; type Runner = crate::runner::stack::Runner; - type Event = Event; + type Event = (); type Precompiles = (); type ChainId = (); type BlockGasLimit = (); type OnChargeTransaction = (); } -type System = frame_system::Module; -type Balances = pallet_balances::Module; -type EVM = Module; +type System = frame_system::Pallet; +type Balances = pallet_balances::Pallet; +type EVM = Pallet; pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); @@ -165,7 +166,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { ); pallet_balances::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); - GenesisConfig { accounts }.assimilate_storage::(&mut t).unwrap(); + >::assimilate_storage(&GenesisConfig { accounts }, &mut t).unwrap(); t.into() }