Skip to content

Commit 87490ba

Browse files
dmitrylavrenovMOZGIII
authored andcommitted
Support external account provider (polkadot-evm#1329)
* Introduce account provider interface * Use AccountProvider logic at pallet-evm * Remove redundant ower type usage * Fix fmt * Fix clippy * Fix clippy * License at primitives/evm/src/account_provider.rs * Rename NativeSystemAccountProvider to FrameSystemAccountProvider * Formatting corrcetions at account_provider.rs --------- Co-authored-by: MOZGIII <[email protected]>
1 parent cd6bca1 commit 87490ba

File tree

13 files changed

+148
-46
lines changed

13 files changed

+148
-46
lines changed

frame/ethereum/src/mock.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ impl BalanceConverter for SubtensorEvmBalanceConverter {
194194
}
195195

196196
impl pallet_evm::Config for Test {
197+
type AccountProvider = pallet_evm::FrameSystemAccountProvider<Self>;
197198
type FeeCalculator = FixedGasPrice;
198199
type BalanceConverter = SubtensorEvmBalanceConverter;
199200
type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;

frame/evm/precompile/dispatch/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ impl<T, DispatchValidator, DecodeLimit> Precompile for Dispatch<T, DispatchValid
5454
where
5555
T: pallet_evm::Config,
5656
T::RuntimeCall: Dispatchable<PostInfo = PostDispatchInfo> + GetDispatchInfo + Decode,
57-
<T::RuntimeCall as Dispatchable>::RuntimeOrigin: From<Option<T::AccountId>>,
58-
DispatchValidator: DispatchValidateT<T::AccountId, T::RuntimeCall>,
57+
<T::RuntimeCall as Dispatchable>::RuntimeOrigin: From<Option<pallet_evm::AccountIdOf<T>>>,
58+
DispatchValidator: DispatchValidateT<pallet_evm::AccountIdOf<T>, T::RuntimeCall>,
5959
DecodeLimit: Get<u32>,
6060
{
6161
fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult {

frame/evm/precompile/dispatch/src/mock.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ parameter_types! {
170170
pub SuicideQuickClearLimit: u32 = 0;
171171
}
172172
impl pallet_evm::Config for Test {
173+
type AccountProvider = pallet_evm::FrameSystemAccountProvider<Self>;
173174
type FeeCalculator = FixedGasPrice;
174175
type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
175176
type WeightPerGas = WeightPerGas;

frame/evm/precompile/storage-cleaner/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ extern crate alloc;
2323

2424
use alloc::vec::Vec;
2525
use core::marker::PhantomData;
26-
use fp_evm::{PrecompileFailure, ACCOUNT_BASIC_PROOF_SIZE, ACCOUNT_STORAGE_PROOF_SIZE};
26+
use fp_evm::{
27+
AccountProvider, PrecompileFailure, ACCOUNT_BASIC_PROOF_SIZE, ACCOUNT_STORAGE_PROOF_SIZE,
28+
};
2729
use pallet_evm::AddressMapping;
2830
use precompile_utils::{prelude::*, EvmResult};
2931
use sp_core::H160;
@@ -200,7 +202,7 @@ where
200202
pallet_evm::Suicided::<Runtime>::remove(address);
201203

202204
let account_id = Runtime::AddressMapping::into_account_id(address);
203-
let _ = frame_system::Pallet::<Runtime>::dec_sufficients(&account_id);
205+
Runtime::AccountProvider::remove_account(&account_id);
204206
}
205207
}
206208

frame/evm/precompile/storage-cleaner/src/mock.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ impl BalanceConverter for SubtensorEvmBalanceConverter {
160160

161161
impl pallet_evm::Config for Runtime {
162162
type BalanceConverter = SubtensorEvmBalanceConverter;
163+
type AccountProvider = pallet_evm::FrameSystemAccountProvider<Self>;
163164
type FeeCalculator = ();
164165
type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
165166
type WeightPerGas = WeightPerGas;

frame/evm/src/lib.rs

Lines changed: 61 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,10 @@ use sp_runtime::{
102102
use fp_account::AccountId20;
103103
use fp_evm::GenesisAccount;
104104
pub use fp_evm::{
105-
Account, CallInfo, CreateInfo, ExecutionInfoV2 as ExecutionInfo, FeeCalculator,
106-
IsPrecompileResult, LinearCostPrecompile, Log, Precompile, PrecompileFailure, PrecompileHandle,
107-
PrecompileOutput, PrecompileResult, PrecompileSet, TransactionValidationError, Vicinity,
105+
Account, AccountProvider, CallInfo, CreateInfo, ExecutionInfoV2 as ExecutionInfo,
106+
FeeCalculator, IsPrecompileResult, LinearCostPrecompile, Log, Precompile, PrecompileFailure,
107+
PrecompileHandle, PrecompileOutput, PrecompileResult, PrecompileSet,
108+
TransactionValidationError, Vicinity,
108109
};
109110

110111
pub use self::{
@@ -125,6 +126,9 @@ pub mod pallet {
125126

126127
#[pallet::config]
127128
pub trait Config: frame_system::Config {
129+
/// Account info provider.
130+
type AccountProvider: AccountProvider;
131+
128132
/// Calculator for current gas price.
129133
type FeeCalculator: FeeCalculator;
130134

@@ -140,12 +144,12 @@ pub mod pallet {
140144
/// Allow the origin to call on behalf of given address.
141145
type CallOrigin: EnsureAddressOrigin<Self::RuntimeOrigin>;
142146
/// Allow the origin to withdraw on behalf of given address.
143-
type WithdrawOrigin: EnsureAddressOrigin<Self::RuntimeOrigin, Success = Self::AccountId>;
147+
type WithdrawOrigin: EnsureAddressOrigin<Self::RuntimeOrigin, Success = AccountIdOf<Self>>;
144148

145149
/// Mapping from address to account id.
146-
type AddressMapping: AddressMapping<Self::AccountId>;
150+
type AddressMapping: AddressMapping<AccountIdOf<Self>>;
147151
/// Currency type for withdraw and balance storage.
148-
type Currency: Currency<Self::AccountId> + Inspect<Self::AccountId>;
152+
type Currency: Currency<AccountIdOf<Self>> + Inspect<AccountIdOf<Self>>;
149153

150154
/// The overarching event type.
151155
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
@@ -585,7 +589,7 @@ pub mod pallet {
585589
MAX_ACCOUNT_NONCE,
586590
UniqueSaturatedInto::<usize>::unique_saturated_into(account.nonce),
587591
) {
588-
frame_system::Pallet::<T>::inc_account_nonce(&account_id);
592+
T::AccountProvider::inc_account_nonce(&account_id);
589593
}
590594

591595
let _ = T::Currency::deposit_creating(
@@ -625,13 +629,14 @@ pub mod pallet {
625629
pub type DisableWhitelistCheck<T: Config> = StorageValue<_, bool, ValueQuery>;
626630
}
627631

632+
/// Utility alias for easy access to the [`AccountProvider::AccountId`] type from a given config.
633+
pub type AccountIdOf<T> = <<T as Config>::AccountProvider as AccountProvider>::AccountId;
634+
628635
/// Type alias for currency balance.
629-
pub type BalanceOf<T> =
630-
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
636+
pub type BalanceOf<T> = <<T as Config>::Currency as Currency<AccountIdOf<T>>>::Balance;
631637

632638
/// Type alias for negative imbalance during fees
633-
type NegativeImbalanceOf<C, T> =
634-
<C as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;
639+
type NegativeImbalanceOf<C, T> = <C as Currency<AccountIdOf<T>>>::NegativeImbalance;
635640

636641
#[derive(
637642
Debug,
@@ -869,7 +874,7 @@ impl<T: Config> Pallet<T> {
869874
// In theory, we can always have pre-EIP161 contracts, so we
870875
// make sure the account nonce is at least one.
871876
let account_id = T::AddressMapping::into_account_id(*address);
872-
frame_system::Pallet::<T>::inc_account_nonce(&account_id);
877+
T::AccountProvider::inc_account_nonce(&account_id);
873878
}
874879

875880
<AccountCodes<T>>::remove(address);
@@ -884,7 +889,7 @@ impl<T: Config> Pallet<T> {
884889
<Suicided<T>>::remove(address);
885890

886891
let account_id = T::AddressMapping::into_account_id(*address);
887-
let _ = frame_system::Pallet::<T>::dec_sufficients(&account_id);
892+
T::AccountProvider::remove_account(&account_id);
888893
}
889894
KillStorageResult::SomeRemaining(_) => (),
890895
}
@@ -907,7 +912,7 @@ impl<T: Config> Pallet<T> {
907912

908913
if !<AccountCodes<T>>::contains_key(address) {
909914
let account_id = T::AddressMapping::into_account_id(address);
910-
let _ = frame_system::Pallet::<T>::inc_sufficients(&account_id);
915+
T::AccountProvider::create_account(&account_id);
911916
}
912917

913918
// Update metadata.
@@ -947,7 +952,7 @@ impl<T: Config> Pallet<T> {
947952
/// Get the account basic in EVM format.
948953
pub fn account_basic(address: &H160) -> (Account, frame_support::weights::Weight) {
949954
let account_id = T::AddressMapping::into_account_id(*address);
950-
let nonce = frame_system::Pallet::<T>::account_nonce(&account_id);
955+
let nonce = T::AccountProvider::account_nonce(&account_id);
951956
let balance =
952957
T::Currency::reducible_balance(&account_id, Preservation::Preserve, Fortitude::Polite);
953958
let balance_sub =
@@ -1007,17 +1012,13 @@ pub struct EVMCurrencyAdapter<C, OU>(core::marker::PhantomData<(C, OU)>);
10071012
impl<T, C, OU> OnChargeEVMTransaction<T> for EVMCurrencyAdapter<C, OU>
10081013
where
10091014
T: Config,
1010-
C: Currency<<T as frame_system::Config>::AccountId>,
1011-
C::PositiveImbalance: Imbalance<
1012-
<C as Currency<<T as frame_system::Config>::AccountId>>::Balance,
1013-
Opposite = C::NegativeImbalance,
1014-
>,
1015-
C::NegativeImbalance: Imbalance<
1016-
<C as Currency<<T as frame_system::Config>::AccountId>>::Balance,
1017-
Opposite = C::PositiveImbalance,
1018-
>,
1015+
C: Currency<AccountIdOf<T>>,
1016+
C::PositiveImbalance:
1017+
Imbalance<<C as Currency<AccountIdOf<T>>>::Balance, Opposite = C::NegativeImbalance>,
1018+
C::NegativeImbalance:
1019+
Imbalance<<C as Currency<AccountIdOf<T>>>::Balance, Opposite = C::PositiveImbalance>,
10191020
OU: OnUnbalanced<NegativeImbalanceOf<C, T>>,
1020-
U256: UniqueSaturatedInto<<C as Currency<<T as frame_system::Config>::AccountId>>::Balance>,
1021+
U256: UniqueSaturatedInto<<C as Currency<AccountIdOf<T>>>::Balance>,
10211022
{
10221023
// Kept type as Option to satisfy bound of Default
10231024
type LiquidityInfo = Option<NegativeImbalanceOf<C, T>>;
@@ -1122,12 +1123,12 @@ pub struct EVMFungibleAdapter<F, OU>(core::marker::PhantomData<(F, OU)>);
11221123
impl<T, F, OU> OnChargeEVMTransaction<T> for EVMFungibleAdapter<F, OU>
11231124
where
11241125
T: Config,
1125-
F: Balanced<T::AccountId>,
1126-
OU: OnUnbalanced<Credit<T::AccountId, F>>,
1127-
U256: UniqueSaturatedInto<<F as Inspect<<T as frame_system::Config>::AccountId>>::Balance>,
1126+
F: Balanced<AccountIdOf<T>>,
1127+
OU: OnUnbalanced<Credit<AccountIdOf<T>, F>>,
1128+
U256: UniqueSaturatedInto<<F as Inspect<AccountIdOf<T>>>::Balance>,
11281129
{
11291130
// Kept type as Option to satisfy bound of Default
1130-
type LiquidityInfo = Option<Credit<T::AccountId, F>>;
1131+
type LiquidityInfo = Option<Credit<AccountIdOf<T>, F>>;
11311132

11321133
fn withdraw_fee(who: &H160, fee: EvmBalance) -> Result<Self::LiquidityInfo, Error<T>> {
11331134
if fee.0.is_zero() {
@@ -1169,13 +1170,13 @@ where
11691170
.saturating_sub(corrected_fee_sub.0.unique_saturated_into());
11701171
// refund to the account that paid the fees.
11711172
let refund_imbalance = F::deposit(&account_id, refund_amount, Precision::BestEffort)
1172-
.unwrap_or_else(|_| Debt::<T::AccountId, F>::zero());
1173+
.unwrap_or_else(|_| Debt::<AccountIdOf<T>, F>::zero());
11731174

11741175
// merge the imbalance caused by paying the fees and refunding parts of it again.
11751176
let adjusted_paid = paid
11761177
.offset(refund_imbalance)
11771178
.same()
1178-
.unwrap_or_else(|_| Credit::<T::AccountId, F>::zero());
1179+
.unwrap_or_else(|_| Credit::<AccountIdOf<T>, F>::zero());
11791180

11801181
// Convert base fee into substrate balance
11811182
let base_fee_sub = T::BalanceConverter::into_substrate_balance(base_fee)
@@ -1203,13 +1204,11 @@ where
12031204
impl<T> OnChargeEVMTransaction<T> for ()
12041205
where
12051206
T: Config,
1206-
T::Currency: Balanced<T::AccountId>,
1207-
U256: UniqueSaturatedInto<
1208-
<<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance,
1209-
>,
1207+
T::Currency: Balanced<AccountIdOf<T>>,
1208+
U256: UniqueSaturatedInto<<<T as Config>::Currency as Inspect<AccountIdOf<T>>>::Balance>,
12101209
{
12111210
// Kept type as Option to satisfy bound of Default
1212-
type LiquidityInfo = Option<Credit<T::AccountId, T::Currency>>;
1211+
type LiquidityInfo = Option<Credit<AccountIdOf<T>, T::Currency>>;
12131212

12141213
fn withdraw_fee(who: &H160, fee: EvmBalance) -> Result<Self::LiquidityInfo, Error<T>> {
12151214
EVMFungibleAdapter::<T::Currency, ()>::withdraw_fee(who, fee)
@@ -1251,6 +1250,32 @@ impl<T> OnCreate<T> for Tuple {
12511250
}
12521251
}
12531252

1253+
/// EVM account provider based on the [`frame_system`] accounts.
1254+
///
1255+
/// Uses standard Substrate accounts system to hold EVM accounts.
1256+
pub struct FrameSystemAccountProvider<T>(core::marker::PhantomData<T>);
1257+
1258+
impl<T: frame_system::Config> AccountProvider for FrameSystemAccountProvider<T> {
1259+
type AccountId = T::AccountId;
1260+
type Nonce = T::Nonce;
1261+
1262+
fn account_nonce(who: &Self::AccountId) -> Self::Nonce {
1263+
frame_system::Pallet::<T>::account_nonce(who)
1264+
}
1265+
1266+
fn inc_account_nonce(who: &Self::AccountId) {
1267+
frame_system::Pallet::<T>::inc_account_nonce(who)
1268+
}
1269+
1270+
fn create_account(who: &Self::AccountId) {
1271+
let _ = frame_system::Pallet::<T>::inc_sufficients(who);
1272+
}
1273+
1274+
fn remove_account(who: &Self::AccountId) {
1275+
let _ = frame_system::Pallet::<T>::dec_sufficients(who);
1276+
}
1277+
}
1278+
12541279
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
12551280
pub struct SubstrateBalance(U256);
12561281

frame/evm/src/mock.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ use sp_runtime::{
3030
};
3131

3232
use crate::{
33-
BalanceConverter, EnsureAddressNever, EnsureAddressRoot, EvmBalance, FeeCalculator, IdentityAddressMapping, IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult, PrecompileSet, SubstrateBalance
33+
BalanceConverter, EnsureAddressNever, EnsureAddressRoot, EvmBalance, FeeCalculator,
34+
IdentityAddressMapping, IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult,
35+
PrecompileSet, SubstrateBalance,
3436
};
3537

3638
frame_support::construct_runtime! {
@@ -170,6 +172,7 @@ impl BalanceConverter for SubtensorEvmBalanceConverter {
170172

171173
impl crate::Config for Test {
172174
type BalanceConverter = SubtensorEvmBalanceConverter;
175+
type AccountProvider = crate::FrameSystemAccountProvider<Self>;
173176
type FeeCalculator = FixedGasPrice;
174177
type GasWeightMapping = crate::FixedGasWeightMapping<Self>;
175178
type WeightPerGas = WeightPerGas;

frame/evm/src/runner/stack.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ use fp_evm::{
4747
};
4848

4949
use crate::{
50-
runner::Runner as RunnerT, AccountCodes, AccountCodesMetadata, AccountStorages, AddressMapping, BalanceConverter, BalanceOf, BlockHashMapping, Config, Error, Event, EvmBalance, FeeCalculator, OnChargeEVMTransaction, OnCreate, Pallet, RunnerError
50+
runner::Runner as RunnerT, AccountCodes, AccountCodesMetadata, AccountProvider,
51+
AccountStorages, AddressMapping, BalanceConverter, BalanceOf, BlockHashMapping, Config, Error,
52+
Event, EvmBalance, FeeCalculator, OnChargeEVMTransaction, OnCreate, Pallet, RunnerError,
5153
};
5254

5355
#[cfg(feature = "forbid-evm-reentrancy")]
@@ -860,7 +862,7 @@ where
860862

861863
fn inc_nonce(&mut self, address: H160) -> Result<(), ExitError> {
862864
let account_id = T::AddressMapping::into_account_id(address);
863-
frame_system::Pallet::<T>::inc_account_nonce(&account_id);
865+
T::AccountProvider::inc_account_nonce(&account_id);
864866
Ok(())
865867
}
866868

@@ -925,8 +927,9 @@ where
925927
let target = T::AddressMapping::into_account_id(transfer.target);
926928

927929
// Adjust decimals
928-
let value_sub = T::BalanceConverter::into_substrate_balance(EvmBalance::new(transfer.value))
929-
.ok_or(ExitError::OutOfFund)?;
930+
let value_sub =
931+
T::BalanceConverter::into_substrate_balance(EvmBalance::new(transfer.value))
932+
.ok_or(ExitError::OutOfFund)?;
930933

931934
T::Currency::transfer(
932935
&source,

precompiles/src/precompile_set.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1085,7 +1085,7 @@ impl<R: pallet_evm::Config, P: PrecompileSetFragment> PrecompileSetBuilder<R, P>
10851085
}
10861086

10871087
/// Return the list of mapped addresses contained in this PrecompileSet.
1088-
pub fn used_addresses() -> impl Iterator<Item = R::AccountId> {
1088+
pub fn used_addresses() -> impl Iterator<Item = pallet_evm::AccountIdOf<R>> {
10891089
Self::used_addresses_h160().map(R::AddressMapping::into_account_id)
10901090
}
10911091

precompiles/tests-external/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ impl BalanceConverter for SubtensorEvmBalanceConverter {
266266

267267
impl pallet_evm::Config for Runtime {
268268
type BalanceConverter = SubtensorEvmBalanceConverter;
269+
type AccountProvider = pallet_evm::FrameSystemAccountProvider<Self>;
269270
type FeeCalculator = ();
270271
type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
271272
type WeightPerGas = WeightPerGas;

0 commit comments

Comments
 (0)