git.delta.rocks / unique-network / refs/commits / 376ee6b104f8

difftreelog

source

pallets/refungible/src/common.rs10.7 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, RefungibleExtensions, 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		// Error82		083	}8485	fn delete_token_properties(_amount: u32) -> Weight {86		// Error87		088	}8990	fn set_token_property_permissions(_amount: u32) -> Weight {91		// Error92		093	}9495	fn transfer() -> Weight {96		max_weight_of!(97			transfer_normal(),98			transfer_creating(),99			transfer_removing(),100			transfer_creating_removing()101		)102	}103104	fn approve() -> Weight {105		<SelfWeightOf<T>>::approve()106	}107108	fn transfer_from() -> Weight {109		max_weight_of!(110			transfer_from_normal(),111			transfer_from_creating(),112			transfer_from_removing(),113			transfer_from_creating_removing()114		)115	}116117	fn burn_from() -> Weight {118		<SelfWeightOf<T>>::burn_from()119	}120121	fn burn_recursively_self_raw() -> Weight {122		// Read to get total balance123		Self::burn_item() + T::DbWeight::get().reads(1)124	}125	fn burn_recursively_breadth_raw(_amount: u32) -> Weight {126		// Refungible token can't have children127		0128	}129}130131fn map_create_data<T: Config>(132	data: up_data_structs::CreateItemData,133	to: &T::CrossAccountId,134) -> Result<CreateRefungibleExData<T::CrossAccountId>, DispatchError> {135	match data {136		up_data_structs::CreateItemData::ReFungible(data) => Ok(CreateRefungibleExData {137			const_data: data.const_data,138			users: {139				let mut out = BTreeMap::new();140				out.insert(to.clone(), data.pieces);141				out.try_into().expect("limit > 0")142			},143		}),144		_ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),145	}146}147148/// Implementation of `CommonCollectionOperations` for `RefungibleHandle`. It wraps Refungible Pallete149/// methods and adds weight info.150impl<T: Config> CommonCollectionOperations<T> for RefungibleHandle<T> {151	fn create_item(152		&self,153		sender: T::CrossAccountId,154		to: T::CrossAccountId,155		data: up_data_structs::CreateItemData,156		nesting_budget: &dyn Budget,157	) -> DispatchResultWithPostInfo {158		with_weight(159			<Pallet<T>>::create_item(160				self,161				&sender,162				map_create_data::<T>(data, &to)?,163				nesting_budget,164			),165			<CommonWeights<T>>::create_item(),166		)167	}168169	fn create_multiple_items(170		&self,171		sender: T::CrossAccountId,172		to: T::CrossAccountId,173		data: Vec<up_data_structs::CreateItemData>,174		nesting_budget: &dyn Budget,175	) -> DispatchResultWithPostInfo {176		let weight = <CommonWeights<T>>::create_multiple_items(&data);177		let data = data178			.into_iter()179			.map(|d| map_create_data::<T>(d, &to))180			.collect::<Result<Vec<_>, DispatchError>>()?;181182		with_weight(183			<Pallet<T>>::create_multiple_items(self, &sender, data, nesting_budget),184			weight,185		)186	}187188	fn create_multiple_items_ex(189		&self,190		sender: <T>::CrossAccountId,191		data: CreateItemExData<T::CrossAccountId>,192		nesting_budget: &dyn Budget,193	) -> DispatchResultWithPostInfo {194		let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);195		let data = match data {196			CreateItemExData::RefungibleMultipleOwners(r) => vec![r],197			CreateItemExData::RefungibleMultipleItems(r)198				if r.iter().all(|i| i.users.len() == 1) =>199			{200				r.into_inner()201			}202			_ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),203		};204205		with_weight(206			<Pallet<T>>::create_multiple_items(self, &sender, data, nesting_budget),207			weight,208		)209	}210211	fn burn_item(212		&self,213		sender: T::CrossAccountId,214		token: TokenId,215		amount: u128,216	) -> DispatchResultWithPostInfo {217		with_weight(218			<Pallet<T>>::burn(self, &sender, token, amount),219			<CommonWeights<T>>::burn_item(),220		)221	}222223	fn burn_item_recursively(224		&self,225		sender: T::CrossAccountId,226		token: TokenId,227		self_budget: &dyn Budget,228		_breadth_budget: &dyn Budget,229	) -> DispatchResultWithPostInfo {230		ensure!(self_budget.consume(), <StructureError<T>>::DepthLimit,);231		with_weight(232			<Pallet<T>>::burn(233				self,234				&sender,235				token,236				<Balance<T>>::get((self.id, token, &sender)),237			),238			<CommonWeights<T>>::burn_recursively_self_raw(),239		)240	}241242	fn transfer(243		&self,244		from: T::CrossAccountId,245		to: T::CrossAccountId,246		token: TokenId,247		amount: u128,248		nesting_budget: &dyn Budget,249	) -> DispatchResultWithPostInfo {250		with_weight(251			<Pallet<T>>::transfer(self, &from, &to, token, amount, nesting_budget),252			<CommonWeights<T>>::transfer(),253		)254	}255256	fn approve(257		&self,258		sender: T::CrossAccountId,259		spender: T::CrossAccountId,260		token: TokenId,261		amount: u128,262	) -> DispatchResultWithPostInfo {263		with_weight(264			<Pallet<T>>::set_allowance(self, &sender, &spender, token, amount),265			<CommonWeights<T>>::approve(),266		)267	}268269	fn transfer_from(270		&self,271		sender: T::CrossAccountId,272		from: T::CrossAccountId,273		to: T::CrossAccountId,274		token: TokenId,275		amount: u128,276		nesting_budget: &dyn Budget,277	) -> DispatchResultWithPostInfo {278		with_weight(279			<Pallet<T>>::transfer_from(self, &sender, &from, &to, token, amount, nesting_budget),280			<CommonWeights<T>>::transfer_from(),281		)282	}283284	fn burn_from(285		&self,286		sender: T::CrossAccountId,287		from: T::CrossAccountId,288		token: TokenId,289		amount: u128,290		nesting_budget: &dyn Budget,291	) -> DispatchResultWithPostInfo {292		with_weight(293			<Pallet<T>>::burn_from(self, &sender, &from, token, amount, nesting_budget),294			<CommonWeights<T>>::burn_from(),295		)296	}297298	fn set_collection_properties(299		&self,300		_sender: T::CrossAccountId,301		_property: Vec<Property>,302	) -> DispatchResultWithPostInfo {303		fail!(<Error<T>>::SettingPropertiesNotAllowed)304	}305306	fn delete_collection_properties(307		&self,308		_sender: &T::CrossAccountId,309		_property_keys: Vec<PropertyKey>,310	) -> DispatchResultWithPostInfo {311		fail!(<Error<T>>::SettingPropertiesNotAllowed)312	}313314	fn set_token_properties(315		&self,316		_sender: T::CrossAccountId,317		_token_id: TokenId,318		_property: Vec<Property>,319		_nesting_budget: &dyn Budget,320	) -> DispatchResultWithPostInfo {321		fail!(<Error<T>>::SettingPropertiesNotAllowed)322	}323324	fn set_token_property_permissions(325		&self,326		_sender: &T::CrossAccountId,327		_property_permissions: Vec<PropertyKeyPermission>,328	) -> DispatchResultWithPostInfo {329		fail!(<Error<T>>::SettingPropertiesNotAllowed)330	}331332	fn delete_token_properties(333		&self,334		_sender: T::CrossAccountId,335		_token_id: TokenId,336		_property_keys: Vec<PropertyKey>,337		_nesting_budget: &dyn Budget,338	) -> DispatchResultWithPostInfo {339		fail!(<Error<T>>::SettingPropertiesNotAllowed)340	}341342	fn check_nesting(343		&self,344		_sender: <T>::CrossAccountId,345		_from: (CollectionId, TokenId),346		_under: TokenId,347		_nesting_budget: &dyn Budget,348	) -> sp_runtime::DispatchResult {349		fail!(<Error<T>>::RefungibleDisallowsNesting)350	}351352	fn nest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}353354	fn unnest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}355356	fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {357		<Owned<T>>::iter_prefix((self.id, account))358			.map(|(id, _)| id)359			.collect()360	}361362	fn collection_tokens(&self) -> Vec<TokenId> {363		<TokenData<T>>::iter_prefix((self.id,))364			.map(|(id, _)| id)365			.collect()366	}367368	fn token_exists(&self, token: TokenId) -> bool {369		<Pallet<T>>::token_exists(self, token)370	}371372	fn last_token_id(&self) -> TokenId {373		TokenId(<TokensMinted<T>>::get(self.id))374	}375376	fn token_owner(&self, _token: TokenId) -> Option<T::CrossAccountId> {377		None378	}379380	fn token_property(&self, _token_id: TokenId, _key: &PropertyKey) -> Option<PropertyValue> {381		None382	}383384	fn token_properties(385		&self,386		_token_id: TokenId,387		_keys: Option<Vec<PropertyKey>>,388	) -> Vec<Property> {389		Vec::new()390	}391392	fn total_supply(&self) -> u32 {393		<Pallet<T>>::total_supply(self)394	}395396	fn account_balance(&self, account: T::CrossAccountId) -> u32 {397		<AccountBalance<T>>::get((self.id, account))398	}399400	fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {401		<Balance<T>>::get((self.id, token, account))402	}403404	fn allowance(405		&self,406		sender: T::CrossAccountId,407		spender: T::CrossAccountId,408		token: TokenId,409	) -> u128 {410		<Allowance<T>>::get((self.id, token, sender, spender))411	}412413	fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>> {414		Some(self)415	}416417	fn total_pieces(&self, token: TokenId) -> Option<u128> {418		<Pallet<T>>::total_pieces(self.id, token)419	}420}421422impl<T: Config> RefungibleExtensions<T> for RefungibleHandle<T> {423	fn repartition(424		&self,425		owner: &T::CrossAccountId,426		token: TokenId,427		amount: u128,428	) -> DispatchResultWithPostInfo {429		with_weight(430			<Pallet<T>>::repartition(self, owner, token, amount),431			<SelfWeightOf<T>>::repartition_item(),432		)433	}434}