git.delta.rocks / unique-network / refs/commits / 5c5d937f9f7f

difftreelog

source

runtime/common/src/dispatch.rs5.0 KiBsourcehistory
1use frame_support::{dispatch::DispatchResult, ensure};2use pallet_evm::PrecompileResult;3use sp_core::{H160, U256};4use sp_std::{borrow::ToOwned, vec::Vec};5use pallet_common::{6	CollectionById, CollectionHandle, CommonCollectionOperations, erc::CommonEvmHandler,7	eth::map_eth_to_id,8};9pub use pallet_common::dispatch::CollectionDispatch;10use pallet_fungible::{Pallet as PalletFungible, FungibleHandle};11use pallet_nonfungible::{Pallet as PalletNonfungible, NonfungibleHandle};12use pallet_refungible::{Pallet as PalletRefungible, RefungibleHandle, erc::RefungibleTokenHandle};13use up_data_structs::{14	CollectionMode, CreateCollectionData, MAX_DECIMAL_POINTS, mapping::TokenAddressMapping,15};1617pub enum CollectionDispatchT<T>18where19	T: pallet_fungible::Config + pallet_nonfungible::Config + pallet_refungible::Config,20{21	Fungible(FungibleHandle<T>),22	Nonfungible(NonfungibleHandle<T>),23	Refungible(RefungibleHandle<T>),24}25impl<T> CollectionDispatch<T> for CollectionDispatchT<T>26where27	T: pallet_common::Config28		+ pallet_unique::Config29		+ pallet_fungible::Config30		+ pallet_nonfungible::Config31		+ pallet_refungible::Config,32{33	fn create(sender: T::AccountId, data: CreateCollectionData<T::AccountId>) -> DispatchResult {34		let _id = match data.mode {35			CollectionMode::NFT => <PalletNonfungible<T>>::init_collection(sender, data)?,36			CollectionMode::Fungible(decimal_points) => {37				// check params38				ensure!(39					decimal_points <= MAX_DECIMAL_POINTS,40					pallet_unique::Error::<T>::CollectionDecimalPointLimitExceeded41				);42				<PalletFungible<T>>::init_collection(sender, data)?43			}44			CollectionMode::ReFungible => <PalletRefungible<T>>::init_collection(sender, data)?,45		};46		Ok(())47	}4849	fn destroy(sender: T::CrossAccountId, collection: CollectionHandle<T>) -> DispatchResult {50		match collection.mode {51			CollectionMode::ReFungible => {52				PalletRefungible::destroy_collection(RefungibleHandle::cast(collection), &sender)?53			}54			CollectionMode::Fungible(_) => {55				PalletFungible::destroy_collection(FungibleHandle::cast(collection), &sender)?56			}57			CollectionMode::NFT => {58				PalletNonfungible::destroy_collection(NonfungibleHandle::cast(collection), &sender)?59			}60		}61		Ok(())62	}6364	fn dispatch(handle: CollectionHandle<T>) -> Self {65		match handle.mode {66			CollectionMode::Fungible(_) => Self::Fungible(FungibleHandle::cast(handle)),67			CollectionMode::NFT => Self::Nonfungible(NonfungibleHandle::cast(handle)),68			CollectionMode::ReFungible => Self::Refungible(RefungibleHandle::cast(handle)),69		}70	}7172	fn into_inner(self) -> CollectionHandle<T> {73		match self {74			Self::Fungible(f) => f.into_inner(),75			Self::Nonfungible(f) => f.into_inner(),76			Self::Refungible(f) => f.into_inner(),77		}78	}7980	fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {81		match self {82			Self::Fungible(h) => h,83			Self::Nonfungible(h) => h,84			Self::Refungible(h) => h,85		}86	}87}8889impl<T> pallet_evm::OnMethodCall<T> for CollectionDispatchT<T>90where91	T: pallet_common::Config92		+ pallet_unique::Config93		+ pallet_fungible::Config94		+ pallet_nonfungible::Config95		+ pallet_refungible::Config,96{97	fn is_reserved(target: &H160) -> bool {98		map_eth_to_id(target).is_some()99	}100	fn is_used(target: &H160) -> bool {101		map_eth_to_id(target)102			.map(<CollectionById<T>>::contains_key)103			.unwrap_or(false)104	}105	fn get_code(target: &H160) -> Option<Vec<u8>> {106		if let Some(collection_id) = map_eth_to_id(target) {107			let collection = <CollectionById<T>>::get(collection_id)?;108			Some(109				match collection.mode {110					CollectionMode::NFT => <NonfungibleHandle<T>>::CODE,111					CollectionMode::Fungible(_) => <FungibleHandle<T>>::CODE,112					CollectionMode::ReFungible => <RefungibleHandle<T>>::CODE,113				}114				.to_owned(),115			)116		} else if let Some((collection_id, _token_id)) =117			<T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(target)118		{119			let collection = <CollectionById<T>>::get(collection_id)?;120			if collection.mode != CollectionMode::ReFungible {121				return None;122			}123			// TODO: check token existence124			Some(<RefungibleTokenHandle<T>>::CODE.to_owned())125		} else {126			None127		}128	}129	fn call(130		source: &H160,131		target: &H160,132		gas_limit: u64,133		input: &[u8],134		value: U256,135	) -> Option<PrecompileResult> {136		if let Some(collection_id) = map_eth_to_id(target) {137			let collection = <CollectionHandle<T>>::new_with_gas_limit(collection_id, gas_limit)?;138			let dispatched = Self::dispatch(collection);139140			match dispatched {141				Self::Fungible(h) => h.call(source, input, value),142				Self::Nonfungible(h) => h.call(source, input, value),143				Self::Refungible(h) => h.call(source, input, value),144			}145		} else if let Some((collection_id, token_id)) =146			<T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(target)147		{148			let collection = <CollectionHandle<T>>::new_with_gas_limit(collection_id, gas_limit)?;149			if collection.mode != CollectionMode::ReFungible {150				return None;151			}152153			let handle = RefungibleHandle::cast(collection);154			// TODO: check token existence155			RefungibleTokenHandle(handle, token_id).call(source, input, value)156		} else {157			None158		}159	}160}