git.delta.rocks / unique-network / refs/commits / 77688fbffa89

difftreelog

source

runtime/common/src/dispatch.rs5.1 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	budget::Budget,16};1718pub enum CollectionDispatchT<T>19where20	T: pallet_fungible::Config + pallet_nonfungible::Config + pallet_refungible::Config,21{22	Fungible(FungibleHandle<T>),23	Nonfungible(NonfungibleHandle<T>),24	Refungible(RefungibleHandle<T>),25}26impl<T> CollectionDispatch<T> for CollectionDispatchT<T>27where28	T: pallet_common::Config29		+ pallet_unique::Config30		+ pallet_fungible::Config31		+ pallet_nonfungible::Config32		+ pallet_refungible::Config,33{34	fn create(sender: T::AccountId, data: CreateCollectionData<T::AccountId>) -> DispatchResult {35		let _id = match data.mode {36			CollectionMode::NFT => <PalletNonfungible<T>>::init_collection(sender, data)?,37			CollectionMode::Fungible(decimal_points) => {38				// check params39				ensure!(40					decimal_points <= MAX_DECIMAL_POINTS,41					pallet_unique::Error::<T>::CollectionDecimalPointLimitExceeded42				);43				<PalletFungible<T>>::init_collection(sender, data)?44			}45			CollectionMode::ReFungible => <PalletRefungible<T>>::init_collection(sender, data)?,46		};47		Ok(())48	}4950	fn destroy(51		sender: T::CrossAccountId,52		collection: CollectionHandle<T>,53		nesting_budget: &dyn Budget,54	) -> DispatchResult {55		match collection.mode {56			CollectionMode::ReFungible => {57				PalletRefungible::destroy_collection(RefungibleHandle::cast(collection), &sender)?58			}59			CollectionMode::Fungible(_) => {60				PalletFungible::destroy_collection(FungibleHandle::cast(collection), &sender)?61			}62			CollectionMode::NFT => {63				PalletNonfungible::destroy_collection(64					NonfungibleHandle::cast(collection),65					&sender,66					nesting_budget,67				)?68			}69		}70		Ok(())71	}7273	fn dispatch(handle: CollectionHandle<T>) -> Self {74		match handle.mode {75			CollectionMode::Fungible(_) => Self::Fungible(FungibleHandle::cast(handle)),76			CollectionMode::NFT => Self::Nonfungible(NonfungibleHandle::cast(handle)),77			CollectionMode::ReFungible => Self::Refungible(RefungibleHandle::cast(handle)),78		}79	}8081	fn into_inner(self) -> CollectionHandle<T> {82		match self {83			Self::Fungible(f) => f.into_inner(),84			Self::Nonfungible(f) => f.into_inner(),85			Self::Refungible(f) => f.into_inner(),86		}87	}8889	fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {90		match self {91			Self::Fungible(h) => h,92			Self::Nonfungible(h) => h,93			Self::Refungible(h) => h,94		}95	}96}9798impl<T> pallet_evm::OnMethodCall<T> for CollectionDispatchT<T>99where100	T: pallet_common::Config101		+ pallet_unique::Config102		+ pallet_fungible::Config103		+ pallet_nonfungible::Config104		+ pallet_refungible::Config,105{106	fn is_reserved(target: &H160) -> bool {107		map_eth_to_id(target).is_some()108	}109	fn is_used(target: &H160) -> bool {110		map_eth_to_id(target)111			.map(<CollectionById<T>>::contains_key)112			.unwrap_or(false)113	}114	fn get_code(target: &H160) -> Option<Vec<u8>> {115		if let Some(collection_id) = map_eth_to_id(target) {116			let collection = <CollectionById<T>>::get(collection_id)?;117			Some(118				match collection.mode {119					CollectionMode::NFT => <NonfungibleHandle<T>>::CODE,120					CollectionMode::Fungible(_) => <FungibleHandle<T>>::CODE,121					CollectionMode::ReFungible => <RefungibleHandle<T>>::CODE,122				}123				.to_owned(),124			)125		} else if let Some((collection_id, _token_id)) =126			<T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(target)127		{128			let collection = <CollectionById<T>>::get(collection_id)?;129			if collection.mode != CollectionMode::ReFungible {130				return None;131			}132			// TODO: check token existence133			Some(<RefungibleTokenHandle<T>>::CODE.to_owned())134		} else {135			None136		}137	}138	fn call(139		source: &H160,140		target: &H160,141		gas_limit: u64,142		input: &[u8],143		value: U256,144	) -> Option<PrecompileResult> {145		if let Some(collection_id) = map_eth_to_id(target) {146			let collection = <CollectionHandle<T>>::new_with_gas_limit(collection_id, gas_limit)?;147			let dispatched = Self::dispatch(collection);148149			match dispatched {150				Self::Fungible(h) => h.call(source, input, value),151				Self::Nonfungible(h) => h.call(source, input, value),152				Self::Refungible(h) => h.call(source, input, value),153			}154		} else if let Some((collection_id, token_id)) =155			<T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(target)156		{157			let collection = <CollectionHandle<T>>::new_with_gas_limit(collection_id, gas_limit)?;158			if collection.mode != CollectionMode::ReFungible {159				return None;160			}161162			let handle = RefungibleHandle::cast(collection);163			// TODO: check token existence164			RefungibleTokenHandle(handle, token_id).call(source, input, value)165		} else {166			None167		}168	}169}