diff --git a/frame/evm/src/backend.rs b/frame/evm/src/backend.rs index d129cd33e..807459629 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 20b2fa6f3..5edb5d6ac 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. @@ -77,7 +77,6 @@ use frame_support::traits::{ Currency, ExistenceRequirement, FindAuthor, Get, Imbalance, OnUnbalanced, WithdrawReasons, }; use frame_support::weights::{Pays, PostDispatchInfo, Weight}; -use frame_support::{decl_error, decl_event, decl_module, decl_storage}; use frame_system::RawOrigin; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; @@ -88,6 +87,317 @@ use sp_runtime::{ }; use sp_std::vec::Vec; +pub use pallet::*; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[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; + + /// Block number to block hash. + type BlockHashMapping: BlockHashMapping; + + /// 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; + + /// Find author for the current block. + type FindAuthor: FindAuthor; + + /// EVM config used in the module. + 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)] + pub 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 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))] + pub 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))] + pub 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; @@ -230,7 +540,7 @@ pub struct SubstrateBlockHashMapping(sp_std::marker::PhantomData); impl BlockHashMapping for SubstrateBlockHashMapping { fn block_hash(number: u32) -> H256 { let number = T::BlockNumber::from(number); - H256::from_slice(frame_system::Module::::block_hash(number).as_ref()) + H256::from_slice(frame_system::Pallet::::block_hash(number).as_ref()) } } @@ -251,52 +561,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; - - /// Block number to block hash. - type BlockHashMapping: BlockHashMapping; - - /// 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; - - /// Find author for the current block. - type FindAuthor: FindAuthor; - - /// 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. @@ -311,241 +575,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() && code_len == 0 } @@ -559,13 +593,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, None); + >::remove(address); + >::remove_prefix(address, None); } /// Create an account. @@ -574,19 +608,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 { @@ -597,7 +631,7 @@ impl Module { /// Get the author using the FindAuthor trait. pub fn find_author() -> H160 { - let digest = >::digest(); + let digest = >::digest(); let pre_runtime_digests = digest.logs.iter().filter_map(|d| d.as_pre_runtime()); T::FindAuthor::find_author(pre_runtime_digests).unwrap_or_default() @@ -623,7 +657,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 ea7db531a..288ecf0bf 100644 --- a/frame/evm/src/runner/stack.rs +++ b/frame/evm/src/runner/stack.rs @@ -20,7 +20,7 @@ use crate::runner::Runner as RunnerT; use crate::{ AccountCodes, AccountStorages, AddressMapping, BlockHashMapping, Config, Error, Event, - FeeCalculator, Module, OnChargeEVMTransaction, PrecompileSet, + FeeCalculator, OnChargeEVMTransaction, Pallet, PrecompileSet, }; use evm::backend::Backend as BackendT; use evm::executor::{StackExecutor, StackState as StackStateT, StackSubstateMetadata}; @@ -28,7 +28,6 @@ use evm::{ExitError, ExitReason, Transfer}; use fp_evm::{CallInfo, CreateInfo, ExecutionInfo, Log, Vicinity}; use frame_support::{ ensure, - storage::{StorageDoubleMap, StorageMap}, traits::{Currency, ExistenceRequirement, Get}, }; use sha3::{Digest, Keccak256}; @@ -85,7 +84,7 @@ impl Runner { 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 @@ -124,7 +123,7 @@ impl Runner { "Deleting account at {:?}", address ); - Module::::remove_account(&address) + Pallet::::remove_account(&address) } for log in &state.substate.logs { @@ -137,7 +136,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(), @@ -361,16 +360,16 @@ impl<'vicinity, 'config, T: Config> BackendT for SubstrateStackState<'vicinity, } 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) } fn block_coinbase(&self) -> H160 { - Module::::find_author() + Pallet::::find_author() } 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) } @@ -391,7 +390,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, @@ -400,11 +399,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 { @@ -440,7 +439,7 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> } fn is_empty(&self, address: H160) -> bool { - Module::::is_account_empty(&address) + Pallet::::is_account_empty(&address) } fn deleted(&self, address: H160) -> bool { @@ -449,7 +448,7 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> 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) { @@ -460,7 +459,7 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> address, index, ); - AccountStorages::remove(address, index); + >::remove(address, index); } else { log::debug!( target: "evm", @@ -469,12 +468,12 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> index, value, ); - AccountStorages::insert(address, index, value); + >::insert(address, index, value); } } fn reset_storage(&mut self, address: H160) { - AccountStorages::remove_prefix(address, None); + >::remove_prefix(address, None); } fn log(&mut self, address: H160, topics: Vec, data: Vec) { @@ -492,7 +491,7 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config> 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 6b7fa9b53..35d3911f1 100644 --- a/frame/evm/src/tests.rs +++ b/frame/evm/src/tests.rs @@ -21,10 +21,11 @@ use super::*; use crate::mock::*; use frame_support::assert_ok; +use frame_support::traits::GenesisBuild; use std::{collections::BTreeMap, str::FromStr}; -type Balances = pallet_balances::Module; -type EVM = Module; +type Balances = pallet_balances::Pallet; +type EVM = Pallet; pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default() @@ -58,9 +59,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_balances::GenesisConfig::::default() .assimilate_storage(&mut t) .unwrap(); - crate::GenesisConfig { accounts } - .assimilate_storage::(&mut t) - .unwrap(); + GenesisBuild::::assimilate_storage(&crate::GenesisConfig { accounts }, &mut t).unwrap(); t.into() }