difftreelog
refactor share unq sponsoring code with evm
in: master
4 files changed
pallets/nft/src/eth/sponsoring.rsdiffbeforeafterboth--- a/pallets/nft/src/eth/sponsoring.rs
+++ b/pallets/nft/src/eth/sponsoring.rs
@@ -1,123 +1,64 @@
//! Implements EVM sponsoring logic via OnChargeEVMTransaction
-use crate::{Collection, Config, FungibleTransferBasket, NftTransferBasket};
+use crate::{Config, sponsorship::*};
use evm_coder::{Call, abi::AbiReader};
-use frame_support::{
- storage::{StorageDoubleMap},
-};
-use pallet_common::eth::map_eth_to_id;
+use pallet_common::{CollectionHandle, eth::map_eth_to_id};
use sp_core::H160;
use sp_std::prelude::*;
use up_sponsorship::SponsorshipHandler;
use core::marker::PhantomData;
use core::convert::TryInto;
-use nft_data_structs::{CollectionId, NFT_SPONSOR_TRANSFER_TIMEOUT, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT};
-use pallet_common::{
- CollectionById,
- account::{CrossAccountId, EvmBackwardsAddressMapping},
-};
+use nft_data_structs::TokenId;
+use up_evm_mapping::EvmBackwardsAddressMapping;
+use pallet_evm::AddressMapping;
use pallet_nonfungible::erc::{UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721Call};
use pallet_fungible::erc::{UniqueFungibleCall, ERC20Call};
-struct AnyError;
-
-fn try_sponsor<T: Config>(
- caller: &H160,
- collection_id: CollectionId,
- collection: &Collection<T>,
- call: &[u8],
-) -> Result<(), AnyError> {
- let (method_id, mut reader) = AbiReader::new_call(call).map_err(|_| AnyError)?;
- match &collection.mode {
- crate::CollectionMode::NFT => {
- let call: UniqueNFTCall = UniqueNFTCall::parse(method_id, &mut reader)
- .map_err(|_| AnyError)?
- .ok_or(AnyError)?;
- match call {
- UniqueNFTCall::ERC721UniqueExtensions(ERC721UniqueExtensionsCall::Transfer {
- token_id,
- ..
- })
- | UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, .. }) => {
- let token_id: u32 = token_id.try_into().map_err(|_| AnyError)?;
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let collection_limits = &collection.limits;
- let limit =
- collection_limits.sponsor_transfer_timeout(NFT_SPONSOR_TRANSFER_TIMEOUT);
-
- let mut sponsor = true;
- if <NftTransferBasket<T>>::contains_key(collection_id, token_id) {
- let last_tx_block = <NftTransferBasket<T>>::get(collection_id, token_id);
- let limit_time = last_tx_block + limit.into();
- if block_number <= limit_time {
- sponsor = false;
- }
+pub struct NftEthSponsorshipHandler<T: Config>(PhantomData<*const T>);
+impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for NftEthSponsorshipHandler<T> {
+ fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {
+ let collection_id = map_eth_to_id(&call.0)?;
+ let collection = <CollectionHandle<T>>::new(collection_id)?;
+ let sponsor = collection.sponsorship.sponsor()?.clone();
+ let sponsor =
+ <T as pallet_common::Config>::EvmBackwardsAddressMapping::from_account_id(sponsor);
+ let who = <T as pallet_common::Config>::EvmAddressMapping::into_account_id(*who);
+ let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?;
+ match &collection.mode {
+ crate::CollectionMode::NFT => {
+ let call = UniqueNFTCall::parse(method_id, &mut reader).ok()??;
+ match call {
+ UniqueNFTCall::ERC721UniqueExtensions(
+ ERC721UniqueExtensionsCall::Transfer { token_id, .. },
+ )
+ | UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, .. }) => {
+ let token_id: TokenId = token_id.try_into().ok()?;
+ withdraw_transfer::<T>(&collection, &who, &token_id).map(|()| sponsor)
}
- if sponsor {
- <NftTransferBasket<T>>::insert(collection_id, token_id, block_number);
- return Ok(());
+ UniqueNFTCall::ERC721(ERC721Call::Approve { token_id, .. }) => {
+ let token_id: TokenId = token_id.try_into().ok()?;
+ withdraw_approve::<T>(&collection, &who, &token_id).map(|()| sponsor)
}
+ _ => None,
}
- _ => {}
}
- }
- crate::CollectionMode::Fungible(_) => {
- let call: UniqueFungibleCall = UniqueFungibleCall::parse(method_id, &mut reader)
- .map_err(|_| AnyError)?
- .ok_or(AnyError)?;
- #[allow(clippy::single_match)]
- match call {
- UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {
- let who = T::CrossAccountId::from_eth(*caller);
- let collection_limits = &collection.limits;
- let limit = collection_limits
- .sponsor_transfer_timeout(FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT);
-
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let mut sponsored = true;
- if <FungibleTransferBasket<T>>::contains_key(collection_id, who.as_sub()) {
- let last_tx_block =
- <FungibleTransferBasket<T>>::get(collection_id, who.as_sub());
- let limit_time = last_tx_block + limit.into();
- if block_number <= limit_time {
- sponsored = false;
- }
- }
- if sponsored {
- <FungibleTransferBasket<T>>::insert(
- collection_id,
- who.as_sub(),
- block_number,
- );
- return Ok(());
+ crate::CollectionMode::Fungible(_) => {
+ let call = UniqueFungibleCall::parse(method_id, &mut reader).ok()??;
+ #[allow(clippy::single_match)]
+ match call {
+ UniqueFungibleCall::ERC20(
+ ERC20Call::Transfer { .. } | ERC20Call::TransferFrom { .. },
+ ) => withdraw_transfer::<T>(&collection, &who, &TokenId::default())
+ .map(|()| sponsor),
+ UniqueFungibleCall::ERC20(ERC20Call::Approve { .. }) => {
+ withdraw_approve::<T>(&collection, &who, &TokenId::default())
+ .map(|()| sponsor)
}
- }
- _ => {}
- }
- }
- _ => {}
- }
- Err(AnyError)
-}
-
-pub struct NftEthSponsorshipHandler<T: Config>(PhantomData<*const T>);
-impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for NftEthSponsorshipHandler<T> {
- fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {
- if let Some(collection_id) = map_eth_to_id(&call.0) {
- if let Some(collection) = <CollectionById<T>>::get(collection_id) {
- if !collection.sponsorship.confirmed() {
- return None;
- }
- if try_sponsor(who, collection_id, &collection, &call.1).is_ok() {
- return collection
- .sponsorship
- .sponsor()
- .cloned()
- .map(T::EvmBackwardsAddressMapping::from_account_id);
+ _ => None,
}
}
+ _ => None,
}
- None
}
}
pallets/nft/src/lib.rsdiffbeforeafterboth136 //#region Tokens transfer rate limit baskets136 //#region Tokens transfer rate limit baskets137 /// (Collection id (controlled?2), who created (real))137 /// (Collection id (controlled?2), who created (real))138 /// TODO: Off chain worker should remove from this map when collection gets removed138 /// TODO: Off chain worker should remove from this map when collection gets removed139 pub CreateItemBasket get(fn create_item_basket): map hasher(blake2_128_concat) (CollectionId, T::AccountId) => T::BlockNumber;139 pub CreateItemBasket get(fn create_item_basket): map hasher(blake2_128_concat) (CollectionId, T::AccountId) => Option<T::BlockNumber>;140 /// Collection id (controlled?2), token id (controlled?2)140 /// Collection id (controlled?2), token id (controlled?2)141 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => T::BlockNumber;141 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;142 /// Collection id (controlled?2), owning user (real)142 /// Collection id (controlled?2), owning user (real)143 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;143 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;144 /// Collection id (controlled?2), token id (controlled?2)144 /// Collection id (controlled?2), token id (controlled?2)145 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => T::BlockNumber;145 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): nmap hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;146 //#endregion146 //#endregion147147148 /// Variable metadata sponsoring148 /// Variable metadata sponsoring253253254 <NftTransferBasket<T>>::remove_prefix(collection_id, None);254 <NftTransferBasket<T>>::remove_prefix(collection_id, None);255 <FungibleTransferBasket<T>>::remove_prefix(collection_id, None);255 <FungibleTransferBasket<T>>::remove_prefix(collection_id, None);256 <ReFungibleTransferBasket<T>>::remove_prefix(collection_id, None);256 <ReFungibleTransferBasket<T>>::remove_prefix((collection_id,), None);257257258 <VariableMetaDataBasket<T>>::remove_prefix(collection_id, None);258 <VariableMetaDataBasket<T>>::remove_prefix(collection_id, None);259 <NftApproveBasket<T>>::remove_prefix(collection_id, None);259 <NftApproveBasket<T>>::remove_prefix(collection_id, None);pallets/nft/src/sponsorship.rsdiffbeforeafterboth--- a/pallets/nft/src/sponsorship.rs
+++ b/pallets/nft/src/sponsorship.rs
@@ -1,175 +1,167 @@
use crate::{
Config, Call, CreateItemBasket, VariableMetaDataBasket, ReFungibleTransferBasket,
- FungibleTransferBasket, NftTransferBasket, CreateItemData, CollectionMode,
+ FungibleTransferBasket, NftTransferBasket, CreateItemData, CollectionMode, NftApproveBasket,
+ FungibleApproveBasket, RefungibleApproveBasket,
};
use core::marker::PhantomData;
use up_sponsorship::SponsorshipHandler;
use frame_support::{
traits::{IsSubType},
- storage::{StorageMap, StorageDoubleMap},
+ storage::{StorageMap, StorageDoubleMap, StorageNMap},
};
use nft_data_structs::{
- TokenId, CollectionId, NFT_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionId, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, NFT_SPONSOR_TRANSFER_TIMEOUT,
+ REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, TokenId,
};
-use pallet_common::{CollectionById};
+use pallet_common::{CollectionHandle};
-pub struct NftSponsorshipHandler<T>(PhantomData<T>);
-impl<T: Config> NftSponsorshipHandler<T> {
- pub fn withdraw_create_item(
- who: &T::AccountId,
- collection_id: &CollectionId,
- _properties: &CreateItemData,
- ) -> Option<T::AccountId> {
- let collection = CollectionById::<T>::get(collection_id)?;
+pub fn withdraw_transfer<T: Config>(
+ collection: &CollectionHandle<T>,
+ who: &T::AccountId,
+ item_id: &TokenId,
+) -> Option<()> {
+ // sponsor timeout
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection
+ .limits
+ .sponsor_transfer_timeout(match collection.mode {
+ CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ });
- // sponsor timeout
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
-
- let limit = collection
- .limits
- .sponsor_transfer_timeout(match _properties {
- CreateItemData::NFT(_) => NFT_SPONSOR_TRANSFER_TIMEOUT,
- CreateItemData::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- CreateItemData::ReFungible(_) => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
- });
- if CreateItemBasket::<T>::contains_key((collection_id, &who)) {
- let last_tx_block = CreateItemBasket::<T>::get((collection_id, &who));
- let limit_time = last_tx_block + limit.into();
- if block_number <= limit_time {
- return None;
- }
+ let last_tx_block = match collection.mode {
+ CollectionMode::NFT => <NftTransferBasket<T>>::get(collection.id, item_id),
+ CollectionMode::Fungible(_) => <FungibleTransferBasket<T>>::get(collection.id, who),
+ CollectionMode::ReFungible => {
+ <ReFungibleTransferBasket<T>>::get((collection.id, item_id, who))
}
- CreateItemBasket::<T>::insert((collection_id, who.clone()), block_number);
+ };
- // check free create limit
- if collection.limits.sponsored_data_size() >= (_properties.data_size() as u32) {
- collection.sponsorship.sponsor().cloned()
- } else {
- None
+ if let Some(last_tx_block) = last_tx_block {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return None;
}
}
- pub fn withdraw_transfer(
- who: &T::AccountId,
- collection_id: &CollectionId,
- item_id: &TokenId,
- ) -> Option<T::AccountId> {
- let collection = CollectionById::<T>::get(collection_id)?;
+ match collection.mode {
+ CollectionMode::NFT => <NftTransferBasket<T>>::insert(collection.id, item_id, block_number),
+ CollectionMode::Fungible(_) => {
+ <FungibleTransferBasket<T>>::insert(collection.id, who, block_number)
+ }
+ CollectionMode::ReFungible => {
+ <ReFungibleTransferBasket<T>>::insert((collection.id, item_id, who), block_number)
+ }
+ };
- let mut sponsor_transfer = false;
- if collection.sponsorship.confirmed() {
- let collection_limits = collection.limits.clone();
- let collection_mode = collection.mode.clone();
+ Some(())
+}
- // sponsor timeout
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- sponsor_transfer = match collection_mode {
- CollectionMode::NFT => {
- // get correct limit
- let limit =
- collection_limits.sponsor_transfer_timeout(NFT_SPONSOR_TRANSFER_TIMEOUT);
+pub fn withdraw_create_item<T: Config>(
+ collection: &CollectionHandle<T>,
+ who: &T::AccountId,
+ _properties: &CreateItemData,
+) -> Option<()> {
+ if _properties.data_size() as u32 > collection.limits.sponsored_data_size() {
+ return None;
+ }
- let mut sponsored = true;
- if NftTransferBasket::<T>::contains_key(collection_id, item_id) {
- let last_tx_block = NftTransferBasket::<T>::get(collection_id, item_id);
- let limit_time = last_tx_block + limit.into();
- if block_number <= limit_time {
- sponsored = false;
- }
- }
- if sponsored {
- NftTransferBasket::<T>::insert(collection_id, item_id, block_number);
- }
+ // sponsor timeout
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection
+ .limits
+ .sponsor_transfer_timeout(match _properties {
+ CreateItemData::NFT(_) => NFT_SPONSOR_TRANSFER_TIMEOUT,
+ CreateItemData::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ CreateItemData::ReFungible(_) => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ });
- sponsored
- }
- CollectionMode::Fungible(_) => {
- // get correct limit
- let limit = collection_limits
- .sponsor_transfer_timeout(FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT);
+ if let Some(last_tx_block) = <CreateItemBasket<T>>::get((collection.id, &who)) {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return None;
+ }
+ }
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
- let mut sponsored = true;
- if FungibleTransferBasket::<T>::contains_key(collection_id, who) {
- let last_tx_block = FungibleTransferBasket::<T>::get(collection_id, who);
- let limit_time = last_tx_block + limit.into();
- if block_number <= limit_time {
- sponsored = false;
- }
- }
- if sponsored {
- FungibleTransferBasket::<T>::insert(collection_id, who, block_number);
- }
+ CreateItemBasket::<T>::insert((collection.id, who.clone()), block_number);
- sponsored
- }
- CollectionMode::ReFungible => {
- // get correct limit
- let limit = collection_limits
- .sponsor_transfer_timeout(REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT);
+ Some(())
+}
- let mut sponsored = true;
- if ReFungibleTransferBasket::<T>::contains_key(collection_id, item_id) {
- let last_tx_block =
- ReFungibleTransferBasket::<T>::get(collection_id, item_id);
- let limit_time = last_tx_block + limit.into();
- if block_number <= limit_time {
- sponsored = false;
- }
- }
- if sponsored {
- ReFungibleTransferBasket::<T>::insert(collection_id, item_id, block_number);
- }
+pub fn withdraw_set_variable_meta_data<T: Config>(
+ collection: &CollectionHandle<T>,
+ item_id: &TokenId,
+ data: &[u8],
+) -> Option<()> {
+ // Can't sponsor fungible collection, this tx will be rejected
+ // as invalid
+ if matches!(collection.mode, CollectionMode::Fungible(_)) {
+ return None;
+ }
+ if data.len() > collection.limits.sponsored_data_size() as usize {
+ return None;
+ }
- sponsored
- }
- };
- }
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection.limits.sponsored_data_rate_limit()?;
- if !sponsor_transfer {
- None
- } else {
- collection.sponsorship.sponsor().cloned()
+ if let Some(last_tx_block) = VariableMetaDataBasket::<T>::get(collection.id, item_id) {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return None;
}
}
- pub fn withdraw_set_variable_meta_data(
- collection_id: &CollectionId,
- item_id: &TokenId,
- data: &[u8],
- ) -> Option<T::AccountId> {
- let mut sponsor_metadata_changes = false;
+ <VariableMetaDataBasket<T>>::insert(collection.id, item_id, block_number);
- let collection = CollectionById::<T>::get(collection_id)?;
+ Some(())
+}
- if collection.sponsorship.confirmed() &&
- // Can't sponsor fungible collection, this tx will be rejected
- // as invalid
- !matches!(collection.mode, CollectionMode::Fungible(_)) &&
- data.len() <= collection.limits.sponsored_data_size() as usize
- {
- if let Some(rate_limit) = collection.limits.sponsored_data_rate_limit() {
- let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+pub fn withdraw_approve<T: Config>(
+ collection: &CollectionHandle<T>,
+ who: &T::AccountId,
+ item_id: &TokenId,
+) -> Option<()> {
+ // sponsor timeout
+ let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
+ let limit = collection.limits.sponsor_approve_timeout();
- if VariableMetaDataBasket::<T>::get(collection_id, item_id)
- .map(|last_block| block_number - last_block > rate_limit.into())
- .unwrap_or(true)
- {
- sponsor_metadata_changes = true;
- VariableMetaDataBasket::<T>::insert(collection_id, item_id, block_number);
- }
- }
+ let last_tx_block = match collection.mode {
+ CollectionMode::NFT => <NftApproveBasket<T>>::get(collection.id, item_id),
+ CollectionMode::Fungible(_) => <FungibleApproveBasket<T>>::get(collection.id, who),
+ CollectionMode::ReFungible => {
+ <RefungibleApproveBasket<T>>::get((collection.id, item_id, who))
}
+ };
- if !sponsor_metadata_changes {
- None
- } else {
- collection.sponsorship.sponsor().cloned()
+ if let Some(last_tx_block) = last_tx_block {
+ let timeout = last_tx_block + limit.into();
+ if block_number < timeout {
+ return None;
}
}
+
+ match collection.mode {
+ CollectionMode::NFT => <NftApproveBasket<T>>::insert(collection.id, item_id, block_number),
+ CollectionMode::Fungible(_) => {
+ <FungibleApproveBasket<T>>::insert(collection.id, who, block_number)
+ }
+ CollectionMode::ReFungible => {
+ <RefungibleApproveBasket<T>>::insert((collection.id, item_id, who), block_number)
+ }
+ };
+
+ Some(())
}
+fn load<T: Config>(id: CollectionId) -> Option<(T::AccountId, CollectionHandle<T>)> {
+ let collection = CollectionHandle::new(id)?;
+ let sponsor = collection.sponsorship.sponsor().cloned()?;
+ Some((sponsor, collection))
+}
+
+pub struct NftSponsorshipHandler<T>(PhantomData<T>);
impl<T, C> SponsorshipHandler<T::AccountId, C> for NftSponsorshipHandler<T>
where
T: Config,
@@ -181,17 +173,39 @@
collection_id,
data,
..
- } => Self::withdraw_create_item(who, collection_id, data),
+ } => {
+ let (sponsor, collection) = load(*collection_id)?;
+ withdraw_create_item::<T>(&collection, who, data).map(|()| sponsor)
+ }
Call::transfer {
collection_id,
item_id,
..
- } => Self::withdraw_transfer(who, collection_id, item_id),
+ }
+ | Call::transfer_from {
+ collection_id,
+ item_id,
+ ..
+ } => {
+ let (sponsor, collection) = load(*collection_id)?;
+ withdraw_transfer::<T>(&collection, who, item_id).map(|()| sponsor)
+ }
+ Call::approve {
+ collection_id,
+ item_id,
+ ..
+ } => {
+ let (sponsor, collection) = load(*collection_id)?;
+ withdraw_approve::<T>(&collection, who, item_id).map(|()| sponsor)
+ }
Call::set_variable_meta_data {
collection_id,
item_id,
data,
- } => Self::withdraw_set_variable_meta_data(collection_id, item_id, data),
+ } => {
+ let (sponsor, collection) = load(*collection_id)?;
+ withdraw_set_variable_meta_data::<T>(&collection, item_id, data).map(|()| sponsor)
+ }
_ => None,
}
}
primitives/evm-mapping/src/lib.rsdiffbeforeafterboth--- a/primitives/evm-mapping/src/lib.rs
+++ b/primitives/evm-mapping/src/lib.rs
@@ -4,9 +4,9 @@
use sp_core::H160;
/// Transforms substrate addresses to ethereum (Reverse of `EvmAddressMapping`)
-/// pallet_evm doesn't have this, as it only checks if eth address
+/// pallet_evm doesn't have this, as it only checks if eth address
/// is owned by substrate via `EnsureAddressOrigin` trait
-///
+///
/// This trait implementations shouldn't conflict with used `EnsureAddressOrigin`
pub trait EvmBackwardsAddressMapping<AccountId> {
fn from_account_id(account_id: AccountId) -> H160;