git.delta.rocks / unique-network / refs/commits / 00a765656f26

difftreelog

source

pallets/refungible/src/common.rs10.0 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use core::marker::PhantomData;1819use sp_std::collections::btree_map::BTreeMap;20use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, traits::Get};21use up_data_structs::{22	CollectionId, TokenId, CreateItemExData, CreateRefungibleExData, budget::Budget, Property,23	PropertyKey, PropertyValue, PropertyKeyPermission, CreateItemData,24};25use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};26use pallet_structure::Error as StructureError;27use sp_runtime::DispatchError;28use sp_std::{vec::Vec, vec};2930use crate::{31	AccountBalance, Allowance, Balance, Config, Error, Owned, Pallet, RefungibleHandle,32	SelfWeightOf, TokenData, weights::WeightInfo, TokensMinted,33};3435macro_rules! max_weight_of {36	($($method:ident ($($args:tt)*)),*) => {37		038		$(39			.max(<SelfWeightOf<T>>::$method($($args)*))40		)*41	};42}4344pub struct CommonWeights<T: Config>(PhantomData<T>);45impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {46	fn create_item() -> Weight {47		<SelfWeightOf<T>>::create_item()48	}4950	fn create_multiple_items(data: &[CreateItemData]) -> Weight {51		<SelfWeightOf<T>>::create_multiple_items(data.len() as u32)52	}5354	fn create_multiple_items_ex(call: &CreateItemExData<T::CrossAccountId>) -> Weight {55		match call {56			CreateItemExData::RefungibleMultipleOwners(i) => {57				<SelfWeightOf<T>>::create_multiple_items_ex_multiple_owners(i.users.len() as u32)58			}59			CreateItemExData::RefungibleMultipleItems(i) => {60				<SelfWeightOf<T>>::create_multiple_items_ex_multiple_items(i.len() as u32)61			}62			_ => 0,63		}64	}6566	fn burn_item() -> Weight {67		max_weight_of!(burn_item_partial(), burn_item_fully())68	}6970	fn set_collection_properties(_amount: u32) -> Weight {71		// Error72		073	}7475	fn delete_collection_properties(_amount: u32) -> Weight {76		// Error77		078	}7980	fn set_token_properties(amount: u32) -> Weight {81		<SelfWeightOf<T>>::set_token_properties(amount)82	}8384	fn delete_token_properties(amount: u32) -> Weight {85		<SelfWeightOf<T>>::delete_token_properties(amount)86	}8788	fn set_property_permissions(amount: u32) -> Weight {89		<SelfWeightOf<T>>::set_property_permissions(amount)90	}9192	fn transfer() -> Weight {93		max_weight_of!(94			transfer_normal(),95			transfer_creating(),96			transfer_removing(),97			transfer_creating_removing()98		)99	}100101	fn approve() -> Weight {102		<SelfWeightOf<T>>::approve()103	}104105	fn transfer_from() -> Weight {106		max_weight_of!(107			transfer_from_normal(),108			transfer_from_creating(),109			transfer_from_removing(),110			transfer_from_creating_removing()111		)112	}113114	fn burn_from() -> Weight {115		<SelfWeightOf<T>>::burn_from()116	}117118	fn burn_recursively_self_raw() -> Weight {119		// Read to get total balance120		Self::burn_item() + T::DbWeight::get().reads(1)121	}122	fn burn_recursively_breadth_raw(_amount: u32) -> Weight {123		// Refungible token can't have children124		0125	}126}127128fn map_create_data<T: Config>(129	data: up_data_structs::CreateItemData,130	to: &T::CrossAccountId,131) -> Result<CreateRefungibleExData<T::CrossAccountId>, DispatchError> {132	match data {133		up_data_structs::CreateItemData::ReFungible(data) => Ok(CreateRefungibleExData {134			const_data: data.const_data,135			users: {136				let mut out = BTreeMap::new();137				out.insert(to.clone(), data.pieces);138				out.try_into().expect("limit > 0")139			},140		}),141		_ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),142	}143}144145impl<T: Config> CommonCollectionOperations<T> for RefungibleHandle<T> {146	fn create_item(147		&self,148		sender: T::CrossAccountId,149		to: T::CrossAccountId,150		data: up_data_structs::CreateItemData,151		nesting_budget: &dyn Budget,152	) -> DispatchResultWithPostInfo {153		with_weight(154			<Pallet<T>>::create_item(155				self,156				&sender,157				map_create_data::<T>(data, &to)?,158				nesting_budget,159			),160			<CommonWeights<T>>::create_item(),161		)162	}163164	fn create_multiple_items(165		&self,166		sender: T::CrossAccountId,167		to: T::CrossAccountId,168		data: Vec<up_data_structs::CreateItemData>,169		nesting_budget: &dyn Budget,170	) -> DispatchResultWithPostInfo {171		let weight = <CommonWeights<T>>::create_multiple_items(&data);172		let data = data173			.into_iter()174			.map(|d| map_create_data::<T>(d, &to))175			.collect::<Result<Vec<_>, DispatchError>>()?;176177		with_weight(178			<Pallet<T>>::create_multiple_items(self, &sender, data, nesting_budget),179			weight,180		)181	}182183	fn create_multiple_items_ex(184		&self,185		sender: <T>::CrossAccountId,186		data: CreateItemExData<T::CrossAccountId>,187		nesting_budget: &dyn Budget,188	) -> DispatchResultWithPostInfo {189		let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);190		let data = match data {191			CreateItemExData::RefungibleMultipleOwners(r) => vec![r],192			CreateItemExData::RefungibleMultipleItems(r)193				if r.iter().all(|i| i.users.len() == 1) =>194			{195				r.into_inner()196			}197			_ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),198		};199200		with_weight(201			<Pallet<T>>::create_multiple_items(self, &sender, data, nesting_budget),202			weight,203		)204	}205206	fn burn_item(207		&self,208		sender: T::CrossAccountId,209		token: TokenId,210		amount: u128,211	) -> DispatchResultWithPostInfo {212		with_weight(213			<Pallet<T>>::burn(self, &sender, token, amount),214			<CommonWeights<T>>::burn_item(),215		)216	}217218	fn burn_item_recursively(219		&self,220		sender: T::CrossAccountId,221		token: TokenId,222		self_budget: &dyn Budget,223		_breadth_budget: &dyn Budget,224	) -> DispatchResultWithPostInfo {225		ensure!(self_budget.consume(), <StructureError<T>>::DepthLimit,);226		with_weight(227			<Pallet<T>>::burn(228				self,229				&sender,230				token,231				<Balance<T>>::get((self.id, token, &sender)),232			),233			<CommonWeights<T>>::burn_recursively_self_raw(),234		)235	}236237	fn transfer(238		&self,239		from: T::CrossAccountId,240		to: T::CrossAccountId,241		token: TokenId,242		amount: u128,243		nesting_budget: &dyn Budget,244	) -> DispatchResultWithPostInfo {245		with_weight(246			<Pallet<T>>::transfer(self, &from, &to, token, amount, nesting_budget),247			<CommonWeights<T>>::transfer(),248		)249	}250251	fn approve(252		&self,253		sender: T::CrossAccountId,254		spender: T::CrossAccountId,255		token: TokenId,256		amount: u128,257	) -> DispatchResultWithPostInfo {258		with_weight(259			<Pallet<T>>::set_allowance(self, &sender, &spender, token, amount),260			<CommonWeights<T>>::approve(),261		)262	}263264	fn transfer_from(265		&self,266		sender: T::CrossAccountId,267		from: T::CrossAccountId,268		to: T::CrossAccountId,269		token: TokenId,270		amount: u128,271		nesting_budget: &dyn Budget,272	) -> DispatchResultWithPostInfo {273		with_weight(274			<Pallet<T>>::transfer_from(self, &sender, &from, &to, token, amount, nesting_budget),275			<CommonWeights<T>>::transfer_from(),276		)277	}278279	fn burn_from(280		&self,281		sender: T::CrossAccountId,282		from: T::CrossAccountId,283		token: TokenId,284		amount: u128,285		nesting_budget: &dyn Budget,286	) -> DispatchResultWithPostInfo {287		with_weight(288			<Pallet<T>>::burn_from(self, &sender, &from, token, amount, nesting_budget),289			<CommonWeights<T>>::burn_from(),290		)291	}292293	fn set_collection_properties(294		&self,295		_sender: T::CrossAccountId,296		_property: Vec<Property>,297	) -> DispatchResultWithPostInfo {298		fail!(<Error<T>>::SettingPropertiesNotAllowed)299	}300301	fn delete_collection_properties(302		&self,303		_sender: &T::CrossAccountId,304		_property_keys: Vec<PropertyKey>,305	) -> DispatchResultWithPostInfo {306		fail!(<Error<T>>::SettingPropertiesNotAllowed)307	}308309	fn set_token_properties(310		&self,311		_sender: T::CrossAccountId,312		_token_id: TokenId,313		_property: Vec<Property>,314	) -> DispatchResultWithPostInfo {315		fail!(<Error<T>>::SettingPropertiesNotAllowed)316	}317318	fn set_property_permissions(319		&self,320		_sender: &T::CrossAccountId,321		_property_permissions: Vec<PropertyKeyPermission>,322	) -> DispatchResultWithPostInfo {323		fail!(<Error<T>>::SettingPropertiesNotAllowed)324	}325326	fn delete_token_properties(327		&self,328		_sender: T::CrossAccountId,329		_token_id: TokenId,330		_property_keys: Vec<PropertyKey>,331	) -> DispatchResultWithPostInfo {332		fail!(<Error<T>>::SettingPropertiesNotAllowed)333	}334335	fn check_nesting(336		&self,337		_sender: <T>::CrossAccountId,338		_from: (CollectionId, TokenId),339		_under: TokenId,340		_budget: &dyn Budget,341	) -> sp_runtime::DispatchResult {342		fail!(<Error<T>>::RefungibleDisallowsNesting)343	}344345	fn nest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}346347	fn unnest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}348349	fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {350		<Owned<T>>::iter_prefix((self.id, account))351			.map(|(id, _)| id)352			.collect()353	}354355	fn collection_tokens(&self) -> Vec<TokenId> {356		<TokenData<T>>::iter_prefix((self.id,))357			.map(|(id, _)| id)358			.collect()359	}360361	fn token_exists(&self, token: TokenId) -> bool {362		<Pallet<T>>::token_exists(self, token)363	}364365	fn last_token_id(&self) -> TokenId {366		TokenId(<TokensMinted<T>>::get(self.id))367	}368369	fn token_owner(&self, _token: TokenId) -> Option<T::CrossAccountId> {370		None371	}372373	fn token_property(&self, _token_id: TokenId, _key: &PropertyKey) -> Option<PropertyValue> {374		None375	}376377	fn token_properties(378		&self,379		_token_id: TokenId,380		_keys: Option<Vec<PropertyKey>>,381	) -> Vec<Property> {382		Vec::new()383	}384385	fn total_supply(&self) -> u32 {386		<Pallet<T>>::total_supply(self)387	}388389	fn account_balance(&self, account: T::CrossAccountId) -> u32 {390		<AccountBalance<T>>::get((self.id, account))391	}392393	fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {394		<Balance<T>>::get((self.id, token, account))395	}396397	fn allowance(398		&self,399		sender: T::CrossAccountId,400		spender: T::CrossAccountId,401		token: TokenId,402	) -> u128 {403		<Allowance<T>>::get((self.id, token, sender, spender))404	}405}