Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frame/ethereum/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ impl AddressMapping<AccountId32> for HashedAddressMapping {
}

impl pallet_evm::Config for Test {
type AccountProvider = pallet_evm::NativeSystemAccountProvider<Self>;
type FeeCalculator = FixedGasPrice;
type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
type WeightPerGas = WeightPerGas;
Expand Down
2 changes: 1 addition & 1 deletion frame/evm/precompile/dispatch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl<T, DecodeLimit> Precompile for Dispatch<T, DecodeLimit>
where
T: pallet_evm::Config,
T::RuntimeCall: Dispatchable<PostInfo = PostDispatchInfo> + GetDispatchInfo + Decode,
<T::RuntimeCall as Dispatchable>::RuntimeOrigin: From<Option<T::AccountId>>,
<T::RuntimeCall as Dispatchable>::RuntimeOrigin: From<Option<<<T as pallet_evm::Config>::AccountProvider as pallet_evm::AccountProvider>::AccountId>>,
DecodeLimit: Get<u32>,
{
fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult {
Expand Down
5 changes: 3 additions & 2 deletions frame/evm/precompile/dispatch/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,15 @@ parameter_types! {
pub WeightPerGas: Weight = Weight::from_ref_time(20_000);
}
impl pallet_evm::Config for Test {
type AccountProvider = pallet_evm::NativeSystemAccountProvider<Self>;
type FeeCalculator = FixedGasPrice;
type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
type WeightPerGas = WeightPerGas;

type BlockHashMapping = pallet_evm::SubstrateBlockHashMapping<Self>;
type CallOrigin = EnsureAddressRoot<Self::AccountId>;
type CallOrigin = EnsureAddressRoot<<Self::AccountProvider as pallet_evm::AccountProvider>::AccountId>;

type WithdrawOrigin = EnsureAddressNever<Self::AccountId>;
type WithdrawOrigin = EnsureAddressNever<<Self::AccountProvider as pallet_evm::AccountProvider>::AccountId>;
type AddressMapping = IdentityAddressMapping;
type Currency = Balances;

Expand Down
81 changes: 63 additions & 18 deletions frame/evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ use frame_system::RawOrigin;
use impl_trait_for_tuples::impl_for_tuples;
use sp_core::{Hasher, H160, H256, U256};
use sp_runtime::{
traits::{BadOrigin, Saturating, UniqueSaturatedInto, Zero},
traits::{BadOrigin, Saturating, UniqueSaturatedInto, AtLeast32Bit, Zero},
AccountId32, DispatchErrorWithPostInfo,
};
use sp_std::{cmp::min, vec::Vec};
Expand Down Expand Up @@ -110,6 +110,9 @@ pub mod pallet {

#[pallet::config]
pub trait Config: frame_system::Config + pallet_timestamp::Config {
/// Account info provider.
type AccountProvider: AccountProvider;

/// Calculator for current gas price.
type FeeCalculator: FeeCalculator;

Expand All @@ -125,12 +128,12 @@ pub mod pallet {
/// Allow the origin to call on behalf of given address.
type CallOrigin: EnsureAddressOrigin<Self::RuntimeOrigin>;
/// Allow the origin to withdraw on behalf of given address.
type WithdrawOrigin: EnsureAddressOrigin<Self::RuntimeOrigin, Success = Self::AccountId>;
type WithdrawOrigin: EnsureAddressOrigin<Self::RuntimeOrigin, Success = <Self::AccountProvider as AccountProvider>::AccountId>;

/// Mapping from address to account id.
type AddressMapping: AddressMapping<Self::AccountId>;
type AddressMapping: AddressMapping<<Self::AccountProvider as AccountProvider>::AccountId>;
/// Currency type for withdraw and balance storage.
type Currency: Currency<Self::AccountId> + Inspect<Self::AccountId>;
type Currency: Currency<<Self::AccountProvider as AccountProvider>::AccountId> + Inspect<<Self::AccountProvider as AccountProvider>::AccountId>;

/// The overarching event type.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
Expand Down Expand Up @@ -486,7 +489,7 @@ pub mod pallet {
MAX_ACCOUNT_NONCE,
UniqueSaturatedInto::<usize>::unique_saturated_into(account.nonce),
) {
frame_system::Pallet::<T>::inc_account_nonce(&account_id);
T::AccountProvider::inc_account_nonce(&account_id);
}

T::Currency::deposit_creating(&account_id, account.balance.unique_saturated_into());
Expand All @@ -512,11 +515,11 @@ pub mod pallet {

/// Type alias for currency balance.
pub type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
<<T as Config>::Currency as Currency<<<T as Config>::AccountProvider as AccountProvider>::AccountId>>::Balance;

/// Type alias for negative imbalance during fees
type NegativeImbalanceOf<C, T> =
<C as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;
<C as Currency<<<T as Config>::AccountProvider as AccountProvider>::AccountId>>::NegativeImbalance;

pub trait EnsureAddressOrigin<OuterOrigin> {
/// Success return type.
Expand Down Expand Up @@ -690,7 +693,7 @@ impl<T: Config> Pallet<T> {
pub fn remove_account(address: &H160) {
if <AccountCodes<T>>::contains_key(address) {
let account_id = T::AddressMapping::into_account_id(*address);
let _ = frame_system::Pallet::<T>::dec_sufficients(&account_id);
T::AccountProvider::remove_account(&account_id);
}

<AccountCodes<T>>::remove(address);
Expand All @@ -706,7 +709,7 @@ impl<T: Config> Pallet<T> {

if !<AccountCodes<T>>::contains_key(address) {
let account_id = T::AddressMapping::into_account_id(address);
let _ = frame_system::Pallet::<T>::inc_sufficients(&account_id);
T::AccountProvider::create_account(&account_id);
}

<AccountCodes<T>>::insert(address, code);
Expand All @@ -716,7 +719,7 @@ impl<T: Config> Pallet<T> {
pub fn account_basic(address: &H160) -> (Account, frame_support::weights::Weight) {
let account_id = T::AddressMapping::into_account_id(*address);

let nonce = frame_system::Pallet::<T>::account_nonce(&account_id);
let nonce = T::AccountProvider::account_nonce(&account_id);
// keepalive `true` takes into account ExistentialDeposit as part of what's considered liquid balance.
let balance = T::Currency::reducible_balance(&account_id, true);

Expand Down Expand Up @@ -772,17 +775,17 @@ pub struct EVMCurrencyAdapter<C, OU>(sp_std::marker::PhantomData<(C, OU)>);
impl<T, C, OU> OnChargeEVMTransaction<T> for EVMCurrencyAdapter<C, OU>
where
T: Config,
C: Currency<<T as frame_system::Config>::AccountId>,
C: Currency<<<T as Config>::AccountProvider as AccountProvider>::AccountId>,
C::PositiveImbalance: Imbalance<
<C as Currency<<T as frame_system::Config>::AccountId>>::Balance,
<C as Currency<<<T as Config>::AccountProvider as AccountProvider>::AccountId>>::Balance,
Opposite = C::NegativeImbalance,
>,
C::NegativeImbalance: Imbalance<
<C as Currency<<T as frame_system::Config>::AccountId>>::Balance,
<C as Currency<<<T as Config>::AccountProvider as AccountProvider>::AccountId>>::Balance,
Opposite = C::PositiveImbalance,
>,
OU: OnUnbalanced<NegativeImbalanceOf<C, T>>,
U256: UniqueSaturatedInto<<C as Currency<<T as frame_system::Config>::AccountId>>::Balance>,
U256: UniqueSaturatedInto<<C as Currency<<<T as Config>::AccountProvider as AccountProvider>::AccountId>>::Balance>,
{
// Kept type as Option to satisfy bound of Default
type LiquidityInfo = Option<NegativeImbalanceOf<C, T>>;
Expand Down Expand Up @@ -866,10 +869,10 @@ where
impl<T> OnChargeEVMTransaction<T> for ()
where
T: Config,
<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::PositiveImbalance:
Imbalance<<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance, Opposite = <T::Currency as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance>,
<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance:
Imbalance<<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance, Opposite = <T::Currency as Currency<<T as frame_system::Config>::AccountId>>::PositiveImbalance>,
<T::Currency as Currency<<<T as Config>::AccountProvider as AccountProvider>::AccountId>>::PositiveImbalance:
Imbalance<<T::Currency as Currency<<<T as Config>::AccountProvider as AccountProvider>::AccountId>>::Balance, Opposite = <T::Currency as Currency<<<T as Config>::AccountProvider as AccountProvider>::AccountId>>::NegativeImbalance>,
<T::Currency as Currency<<<T as Config>::AccountProvider as AccountProvider>::AccountId>>::NegativeImbalance:
Imbalance<<T::Currency as Currency<<<T as Config>::AccountProvider as AccountProvider>::AccountId>>::Balance, Opposite = <T::Currency as Currency<<<T as Config>::AccountProvider as AccountProvider>::AccountId>>::PositiveImbalance>,
U256: UniqueSaturatedInto<BalanceOf<T>>,

{
Expand Down Expand Up @@ -913,3 +916,45 @@ impl<T> OnCreate<T> for Tuple {
)*)
}
}

/// The account provider interface.
///
/// Responsible for keeping account data records including their
/// indexes (the number of previous transactions associated with an account).
pub trait AccountProvider {
/// The user account identifier type.
type AccountId;
/// Account index (aka nonce) type.
type Index: AtLeast32Bit;

/// Creates a new account.
fn create_account(who: &Self::AccountId);
/// Removed an account.
fn remove_account(who: &Self::AccountId);
/// Return current account nonce value.
fn account_nonce(who: &Self::AccountId) -> Self::Index;
/// Increment account nonce value.
fn inc_account_nonce(who: &Self::AccountId);
}

pub struct NativeSystemAccountProvider<T>(sp_std::marker::PhantomData<T>);

impl<T: Config> AccountProvider for NativeSystemAccountProvider<T> {
type AccountId = <T as frame_system::Config>::AccountId;
type Index = <T as frame_system::Config>::Index;

fn account_nonce(who: &Self::AccountId) -> Self::Index {
frame_system::Pallet::<T>::account_nonce(&who)
}

fn inc_account_nonce(who: &Self::AccountId) {
frame_system::Pallet::<T>::inc_account_nonce(&who)
}

fn create_account(who: &Self::AccountId) {
let _ = frame_system::Pallet::<T>::inc_sufficients(&who);
}
fn remove_account(who: &Self::AccountId) {
let _ = frame_system::Pallet::<T>::dec_sufficients(&who);
}
}
5 changes: 3 additions & 2 deletions frame/evm/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,15 @@ parameter_types! {
pub MockPrecompiles: MockPrecompileSet = MockPrecompileSet;
}
impl crate::Config for Test {
type AccountProvider = crate::NativeSystemAccountProvider<Self>;
type FeeCalculator = FixedGasPrice;
type GasWeightMapping = crate::FixedGasWeightMapping<Self>;
type WeightPerGas = WeightPerGas;

type BlockHashMapping = crate::SubstrateBlockHashMapping<Self>;
type CallOrigin = EnsureAddressRoot<Self::AccountId>;
type CallOrigin = EnsureAddressRoot<<Self::AccountProvider as crate::AccountProvider>::AccountId>;

type WithdrawOrigin = EnsureAddressNever<Self::AccountId>;
type WithdrawOrigin = EnsureAddressNever<<Self::AccountProvider as crate::AccountProvider>::AccountId>;
type AddressMapping = IdentityAddressMapping;
type Currency = Balances;

Expand Down
4 changes: 2 additions & 2 deletions frame/evm/src/runner/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use crate::{
runner::Runner as RunnerT, AccountCodes, AccountStorages, AddressMapping, BalanceOf,
BlockHashMapping, Config, Error, Event, FeeCalculator, OnChargeEVMTransaction, OnCreate,
Pallet, RunnerError,
Pallet, RunnerError, AccountProvider
};
use evm::{
backend::Backend as BackendT,
Expand Down Expand Up @@ -721,7 +721,7 @@ where

fn inc_nonce(&mut self, address: H160) {
let account_id = T::AddressMapping::into_account_id(address);
frame_system::Pallet::<T>::inc_account_nonce(&account_id);
T::AccountProvider::inc_account_nonce(&account_id);
}

fn set_storage(&mut self, address: H160, index: H256, value: H256) {
Expand Down
1 change: 1 addition & 0 deletions template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ parameter_types! {
}

impl pallet_evm::Config for Runtime {
type AccountProvider = pallet_evm::NativeSystemAccountProvider<Self>;
type FeeCalculator = BaseFee;
type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
type WeightPerGas = WeightPerGas;
Expand Down