git.delta.rocks / unique-network / refs/commits / 2d71e7a206db

difftreelog

source

pallets/nft/src/eth/account.rs4.0 KiBsourcehistory
1use crate::Config;2use codec::{Encode, EncodeLike, Decode};3use sp_core::{H160, H256, crypto::AccountId32};4use core::cmp::Ordering;5#[cfg(feature = "std")]6use serde::{Serialize, Deserialize};7use pallet_evm::AddressMapping;8use sp_std::vec::Vec;9use sp_std::clone::Clone;1011pub trait CrossAccountId<AccountId>: 12    Encode + EncodeLike + Decode + 13    Clone + PartialEq + Ord + core::fmt::Debug // + 14    // Serialize + Deserialize<'static> 15{16    fn as_sub(&self) -> &AccountId;17    fn as_eth(&self) -> &H160;1819    fn from_sub(account: AccountId) -> Self;20    fn from_eth(account: H160) -> Self;21}2223#[derive(Eq)]24#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]25pub struct BasicCrossAccountId<T: Config> {26    /// If true - then ethereum is canonical encoding27    from_ethereum: bool,28    substrate: T::AccountId,29    ethereum: H160,30}3132impl<T: Config> core::fmt::Debug for BasicCrossAccountId<T> {33    fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {34        if self.from_ethereum {35            fmt.debug_tuple("CrossAccountId::Ethereum")36                .field(&self.ethereum)37                .finish()38        } else {39            fmt.debug_tuple("CrossAccountId::Substrate")40                .field(&self.substrate)41                .finish()42        }43    }44}4546impl<T: Config> PartialOrd for BasicCrossAccountId<T> {47    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {48        Some(self.substrate.cmp(&other.substrate))49    }50}5152impl<T: Config> Ord for BasicCrossAccountId<T> {53    fn cmp(&self, other: &Self) -> Ordering {54        self.partial_cmp(other).expect("substrate account is total ordered")55    }56}5758impl<T: Config> PartialEq for BasicCrossAccountId<T> {59    fn eq(&self, other: &Self) -> bool {60        if self.from_ethereum == other.from_ethereum {61            self.substrate == other.substrate && self.ethereum == other.ethereum62        } else if self.from_ethereum {63            // ethereum is canonical encoding, but we need to compare derived address64            self.substrate == other.substrate65        } else {66            self.ethereum == other.ethereum67        }68    }69}70impl<T: Config> Clone for BasicCrossAccountId<T> {71    fn clone(&self) -> Self {72        Self {73            from_ethereum: self.from_ethereum,74            substrate: self.substrate.clone(),75            ethereum: self.ethereum,76        }77    }78}79impl<T: Config> Encode for BasicCrossAccountId<T> {80    fn encode(&self) -> Vec<u8> {81        let as_result = if !self.from_ethereum {82            Ok(self.substrate.clone())83        } else {84            Err(self.ethereum)85        };86        as_result.encode()87    }88}89impl<T: Config> EncodeLike for BasicCrossAccountId<T> {}90impl<T: Config> Decode for BasicCrossAccountId<T> {91    fn decode<I>(input: &mut I) -> Result<Self, codec::Error>92        where I: codec::Input93    {94        Ok(match <Result<T::AccountId, H160>>::decode(input)? {95            Ok(s) => Self::from_sub(s),96            Err(e) => Self::from_eth(e),97        })98    }99}100impl<T: Config> CrossAccountId<T::AccountId> for BasicCrossAccountId<T> {101    fn as_sub(&self) -> &T::AccountId {102        &self.substrate103    }104    fn as_eth(&self) -> &H160 {105        &self.ethereum106    }107    fn from_sub(substrate: T::AccountId) -> Self {108        Self {109            ethereum: T::EvmBackwardsAddressMapping::from_account_id(substrate.clone()),110            substrate,111            from_ethereum: false,112        }113    }114    fn from_eth(ethereum: H160) -> Self {115        Self {116            ethereum,117            substrate: T::EvmAddressMapping::into_account_id(ethereum),118            from_ethereum: true,119        }120    }121}122123pub trait EvmBackwardsAddressMapping<AccountId> {124    fn from_account_id(account_id: AccountId) -> H160;125}126127/// Should have same mapping as EnsureAddressTruncated128pub struct MapBackwardsAddressTruncated;129impl EvmBackwardsAddressMapping<AccountId32> for MapBackwardsAddressTruncated {130    fn from_account_id(account_id: AccountId32) -> H160 {131        let mut out = [0; 20];132        out.copy_from_slice(&(account_id.as_ref() as &[u8])[0..20]);133        H160(out)134    }135}