diff --git a/chain-extensions/types/unified-accounts/src/lib.rs b/chain-extensions/types/unified-accounts/src/lib.rs index 7371e3a9e0..c090ba32e8 100644 --- a/chain-extensions/types/unified-accounts/src/lib.rs +++ b/chain-extensions/types/unified-accounts/src/lib.rs @@ -39,8 +39,10 @@ pub enum Command { pub enum UnifiedAddress { /// The address fetched from the mappings and the account /// is unified + #[codec(index = 0)] Mapped(T), /// The default address associated with account as there /// is no mapping found and accounts are not unified + #[codec(index = 1)] Default(T), } diff --git a/chain-extensions/unified-accounts/src/lib.rs b/chain-extensions/unified-accounts/src/lib.rs index 57d73a9922..b4d1efda16 100644 --- a/chain-extensions/unified-accounts/src/lib.rs +++ b/chain-extensions/unified-accounts/src/lib.rs @@ -18,10 +18,7 @@ #![cfg_attr(not(feature = "std"), no_std)] -use astar_primitives::{ - ethereum_checked::AccountMapping, - evm::{EvmAddress, UnifiedAddressMapper}, -}; +use astar_primitives::evm::{EvmAddress, UnifiedAddressMapper}; use core::marker::PhantomData; use sp_runtime::DispatchError; @@ -29,13 +26,9 @@ use frame_support::DefaultNoBound; use pallet_contracts::chain_extension::{ ChainExtension, Environment, Ext, InitState, Result as DispatchResult, RetVal, }; -use pallet_evm::AddressMapping; use pallet_unified_accounts::WeightInfo; use parity_scale_codec::Encode; -pub use unified_accounts_chain_extension_types::{ - Command::{self, *}, - UnifiedAddress, -}; +pub use unified_accounts_chain_extension_types::Command::{self, *}; type UAWeight = ::WeightInfo; @@ -67,13 +60,8 @@ where // charge weight env.charge_weight(UAWeight::::to_h160_or_default())?; - let evm_address = if let Some(h160) = UA::to_h160(&account_id) { - UnifiedAddress::Mapped(h160) - } else { - UnifiedAddress::Default(T::DefaultNativeToEvm::into_h160(account_id)) - }; // write to buffer - evm_address.using_encoded(|r| env.write(r, false, None))?; + UA::to_h160_or_default(&account_id).using_encoded(|r| env.write(r, false, None))?; } GetNativeAddress => { let evm_address: EvmAddress = env.read_as()?; @@ -87,15 +75,9 @@ where // charge weight env.charge_weight(UAWeight::::to_account_id_or_default())?; - // read the storage item - let native_address = if let Some(native) = UA::to_account_id(&evm_address) { - UnifiedAddress::Mapped(native) - } else { - UnifiedAddress::Default(T::DefaultEvmToNative::into_account_id(evm_address)) - }; - // write to buffer - native_address.using_encoded(|r| env.write(r, false, None))?; + UA::to_account_id_or_default(&evm_address) + .using_encoded(|r| env.write(r, false, None))?; } }; Ok(RetVal::Converging(0)) diff --git a/pallets/unified-accounts/src/lib.rs b/pallets/unified-accounts/src/lib.rs index cb804d2f3b..8811159619 100644 --- a/pallets/unified-accounts/src/lib.rs +++ b/pallets/unified-accounts/src/lib.rs @@ -67,7 +67,7 @@ use astar_primitives::{ ethereum_checked::AccountMapping, - evm::{EvmAddress, UnifiedAddressMapper}, + evm::{EvmAddress, UnifiedAddress, UnifiedAddressMapper}, Balance, }; use frame_support::{ @@ -351,11 +351,12 @@ impl UnifiedAddressMapper for Pallet { EvmToNative::::get(evm_address) } - fn to_account_id_or_default(evm_address: &EvmAddress) -> T::AccountId { - EvmToNative::::get(evm_address).unwrap_or_else(|| { - // fallback to default account_id - T::DefaultEvmToNative::into_account_id(evm_address.clone()) - }) + fn to_account_id_or_default(evm_address: &EvmAddress) -> UnifiedAddress { + if let Some(native) = Self::to_account_id(&evm_address) { + UnifiedAddress::Mapped(native) + } else { + UnifiedAddress::Default(T::DefaultEvmToNative::into_account_id(evm_address.clone())) + } } fn to_default_account_id(evm_address: &EvmAddress) -> T::AccountId { @@ -366,11 +367,12 @@ impl UnifiedAddressMapper for Pallet { NativeToEvm::::get(account_id) } - fn to_h160_or_default(account_id: &T::AccountId) -> EvmAddress { - NativeToEvm::::get(account_id).unwrap_or_else(|| { - // fallback to default account_id - T::DefaultNativeToEvm::into_h160(account_id.clone()) - }) + fn to_h160_or_default(account_id: &T::AccountId) -> UnifiedAddress { + if let Some(h160) = Self::to_h160(&account_id) { + UnifiedAddress::Mapped(h160) + } else { + UnifiedAddress::Default(T::DefaultNativeToEvm::into_h160(account_id.clone())) + } } fn to_default_h160(account_id: &T::AccountId) -> EvmAddress { @@ -381,7 +383,7 @@ impl UnifiedAddressMapper for Pallet { /// AccountMapping wrapper implementation impl AccountMapping for Pallet { fn into_h160(account: T::AccountId) -> H160 { - >::to_h160_or_default(&account) + >::to_h160_or_default(&account).into_address() } } @@ -389,6 +391,7 @@ impl AccountMapping for Pallet { impl AddressMapping for Pallet { fn into_account_id(evm_address: H160) -> T::AccountId { >::to_account_id_or_default(&evm_address) + .into_address() } } @@ -415,7 +418,8 @@ impl StaticLookup for Pallet { MultiAddress::Address20(i) => Ok( >::to_account_id_or_default( &EvmAddress::from_slice(&i), - ), + ) + .into_address(), ), _ => Err(LookupError), } diff --git a/primitives/src/evm.rs b/primitives/src/evm.rs index 766f7bf7a8..9b1a5ae6ee 100644 --- a/primitives/src/evm.rs +++ b/primitives/src/evm.rs @@ -19,6 +19,8 @@ use crate::{AccountId, AssetId}; use frame_support::ensure; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; use sp_core::H160; use sp_std::marker::PhantomData; @@ -64,7 +66,7 @@ pub trait UnifiedAddressMapper { fn to_account_id(evm_address: &EvmAddress) -> Option; /// Gets the account id associated with given evm address. /// If no mapping exists, then return the default evm address. - fn to_account_id_or_default(evm_address: &EvmAddress) -> AccountId; + fn to_account_id_or_default(evm_address: &EvmAddress) -> UnifiedAddress; /// Gets the default account id which is associated with given evm address. fn to_default_account_id(evm_address: &EvmAddress) -> AccountId; @@ -72,7 +74,29 @@ pub trait UnifiedAddressMapper { fn to_h160(account_id: &AccountId) -> Option; /// Gets the evm address associated with given account id. /// If no mapping exists, then return the default account id. - fn to_h160_or_default(account_id: &AccountId) -> EvmAddress; + fn to_h160_or_default(account_id: &AccountId) -> UnifiedAddress; /// Gets the default evm address which is associated with given account id. fn to_default_h160(account_id: &AccountId) -> EvmAddress; } + +#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, TypeInfo)] +pub enum UnifiedAddress
{ + /// The address fetched from the mappings and the account + /// is unified + #[codec(index = 0)] + Mapped(Address), + /// The default address associated with account as there + /// is no mapping found and accounts are not unified + #[codec(index = 1)] + Default(Address), +} + +impl
UnifiedAddress
{ + /// Get the underlying address + pub fn into_address(self) -> Address { + match self { + Self::Default(a) => a, + Self::Mapped(a) => a, + } + } +} diff --git a/tests/integration/src/unified_accounts.rs b/tests/integration/src/unified_accounts.rs index 3029f4dbb5..d1ffa322af 100644 --- a/tests/integration/src/unified_accounts.rs +++ b/tests/integration/src/unified_accounts.rs @@ -17,9 +17,9 @@ // along with Astar. If not, see . use crate::setup::*; +use astar_primitives::evm::UnifiedAddress; use parity_scale_codec::Encode; use sp_io::hashing::keccak_256; -use unified_accounts_chain_extension_types::UnifiedAddress; const AU_CE_GETTER: &'static str = "au_ce_getters"; @@ -70,7 +70,7 @@ fn unified_accounts_chain_extension_works() { contract_id.clone(), [GET_H160_OR_DEFAULT.to_vec(), ALICE.encode()].concat() ), - UnifiedAddress::Default(UnifiedAccounts::to_h160_or_default(&ALICE)) + UnifiedAccounts::to_h160_or_default(&ALICE) ); // mapped native address should be None assert_eq!( @@ -88,7 +88,7 @@ fn unified_accounts_chain_extension_works() { contract_id.clone(), [GET_NATIVE_OR_DEFAULT.to_vec(), alith().encode()].concat() ), - UnifiedAddress::Default(UnifiedAccounts::to_account_id_or_default(&alith())) + UnifiedAccounts::to_account_id_or_default(&alith()) ); //