git.delta.rocks / unique-network / refs/commits / 442d14a2f734

difftreelog

fix mint_with_props_weight

Daniel Shiposha2023-10-13parent: #ae91353.patch.diff
in: master

2 files changed

modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
before · pallets/nonfungible/src/common.rs
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 frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};20use pallet_common::{21	weights::WeightInfo as _, with_weight, write_token_properties_total_weight,22	CommonCollectionOperations, CommonWeightInfo, RefungibleExtensions,23	SelfWeightOf as PalletCommonWeightOf,24};25use pallet_structure::Pallet as PalletStructure;26use sp_runtime::DispatchError;27use sp_std::{vec, vec::Vec};28use up_data_structs::{29	budget::Budget, CollectionId, CreateItemExData, Property, PropertyKey, PropertyKeyPermission,30	PropertyValue, TokenId, TokenOwnerError,31};3233use crate::{34	weights::WeightInfo, AccountBalance, Allowance, Config, CreateItemData, Error,35	NonfungibleHandle, Owned, Pallet, SelfWeightOf, TokenData, TokenProperties, TokensMinted,36};3738pub struct CommonWeights<T: Config>(PhantomData<T>);39impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {40	fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {41		match data {42			CreateItemExData::NFT(t) => mint_with_props_weight::<T>(43				<SelfWeightOf<T>>::create_multiple_items_ex(t.len() as u32),44				t.iter().map(|t| t.properties.len() as u32),45			),46			_ => Weight::zero(),47		}48	}4950	fn create_multiple_items(data: &[up_data_structs::CreateItemData]) -> Weight {51		mint_with_props_weight::<T>(52			<SelfWeightOf<T>>::create_multiple_items(data.len() as u32),53			data.iter().map(|t| match t {54				up_data_structs::CreateItemData::NFT(n) => n.properties.len() as u32,55				_ => 0,56			}),57		)58	}5960	fn burn_item() -> Weight {61		<SelfWeightOf<T>>::burn_item()62	}6364	fn set_collection_properties(amount: u32) -> Weight {65		<pallet_common::SelfWeightOf<T>>::set_collection_properties(amount)66	}6768	fn set_token_properties(amount: u32) -> Weight {69		write_token_properties_total_weight::<T, _>([amount].into_iter(), |amount| {70			<SelfWeightOf<T>>::load_token_properties()71				.saturating_add(<SelfWeightOf<T>>::write_token_properties(amount))72		})73	}7475	fn delete_token_properties(amount: u32) -> Weight {76		Self::set_token_properties(amount)77	}7879	fn set_token_property_permissions(amount: u32) -> Weight {80		<SelfWeightOf<T>>::set_token_property_permissions(amount)81	}8283	fn transfer() -> Weight {84		<SelfWeightOf<T>>::transfer_raw()85			.saturating_add(<PalletCommonWeightOf<T>>::check_accesslist().saturating_mul(2))86	}8788	fn approve() -> Weight {89		<SelfWeightOf<T>>::approve()90	}9192	fn approve_from() -> Weight {93		<SelfWeightOf<T>>::approve_from()94	}9596	fn transfer_from() -> Weight {97		Self::transfer().saturating_add(<SelfWeightOf<T>>::check_allowed_raw())98	}99100	fn burn_from() -> Weight {101		<SelfWeightOf<T>>::burn_from()102	}103104	fn set_allowance_for_all() -> Weight {105		<SelfWeightOf<T>>::set_allowance_for_all()106	}107108	fn force_repair_item() -> Weight {109		<SelfWeightOf<T>>::repair_item()110	}111}112113pub(crate) fn mint_with_props_weight<T: Config>(114	create_no_data_weight: Weight,115	tokens: impl Iterator<Item = u32> + Clone,116) -> Weight {117	create_no_data_weight.saturating_add(write_token_properties_total_weight::<T, _>(118		tokens,119		<SelfWeightOf<T>>::write_token_properties,120	))121}122123fn map_create_data<T: Config>(124	data: up_data_structs::CreateItemData,125	to: &T::CrossAccountId,126) -> Result<CreateItemData<T>, DispatchError> {127	match data {128		up_data_structs::CreateItemData::NFT(data) => Ok(CreateItemData::<T> {129			properties: data.properties,130			owner: to.clone(),131		}),132		_ => fail!(<Error<T>>::NotNonfungibleDataUsedToMintFungibleCollectionToken),133	}134}135136/// Implementation of `CommonCollectionOperations` for `NonfungibleHandle`. It wraps Nonfungible Pallete137/// methods and adds weight info.138impl<T: Config> CommonCollectionOperations<T> for NonfungibleHandle<T> {139	fn create_item(140		&self,141		sender: T::CrossAccountId,142		to: T::CrossAccountId,143		data: up_data_structs::CreateItemData,144		nesting_budget: &dyn Budget,145	) -> DispatchResultWithPostInfo {146		let weight = <CommonWeights<T>>::create_item(&data);147		with_weight(148			<Pallet<T>>::create_item(149				self,150				&sender,151				map_create_data::<T>(data, &to)?,152				nesting_budget,153			),154			weight,155		)156	}157158	fn create_multiple_items(159		&self,160		sender: T::CrossAccountId,161		to: T::CrossAccountId,162		data: Vec<up_data_structs::CreateItemData>,163		nesting_budget: &dyn Budget,164	) -> DispatchResultWithPostInfo {165		let weight = <CommonWeights<T>>::create_multiple_items(&data);166		let data = data167			.into_iter()168			.map(|d| map_create_data::<T>(d, &to))169			.collect::<Result<Vec<_>, DispatchError>>()?;170171		with_weight(172			<Pallet<T>>::create_multiple_items(self, &sender, data, nesting_budget),173			weight,174		)175	}176177	fn create_multiple_items_ex(178		&self,179		sender: <T>::CrossAccountId,180		data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,181		nesting_budget: &dyn Budget,182	) -> DispatchResultWithPostInfo {183		let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);184		let data = match data {185			up_data_structs::CreateItemExData::NFT(nft) => nft,186			_ => fail!(Error::<T>::NotNonfungibleDataUsedToMintFungibleCollectionToken),187		};188189		with_weight(190			<Pallet<T>>::create_multiple_items(self, &sender, data.into_inner(), nesting_budget),191			weight,192		)193	}194195	fn set_collection_properties(196		&self,197		sender: T::CrossAccountId,198		properties: Vec<Property>,199	) -> DispatchResultWithPostInfo {200		let weight = <CommonWeights<T>>::set_collection_properties(properties.len() as u32);201202		with_weight(203			<Pallet<T>>::set_collection_properties(self, &sender, properties),204			weight,205		)206	}207208	fn delete_collection_properties(209		&self,210		sender: &T::CrossAccountId,211		property_keys: Vec<PropertyKey>,212	) -> DispatchResultWithPostInfo {213		let weight = <CommonWeights<T>>::delete_collection_properties(property_keys.len() as u32);214215		with_weight(216			<Pallet<T>>::delete_collection_properties(self, sender, property_keys),217			weight,218		)219	}220221	fn set_token_properties(222		&self,223		sender: T::CrossAccountId,224		token_id: TokenId,225		properties: Vec<Property>,226		nesting_budget: &dyn Budget,227	) -> DispatchResultWithPostInfo {228		let weight = <CommonWeights<T>>::set_token_properties(properties.len() as u32);229230		with_weight(231			<Pallet<T>>::set_token_properties(232				self,233				&sender,234				token_id,235				properties.into_iter(),236				nesting_budget,237			),238			weight,239		)240	}241242	fn delete_token_properties(243		&self,244		sender: T::CrossAccountId,245		token_id: TokenId,246		property_keys: Vec<PropertyKey>,247		nesting_budget: &dyn Budget,248	) -> DispatchResultWithPostInfo {249		let weight = <CommonWeights<T>>::delete_token_properties(property_keys.len() as u32);250251		with_weight(252			<Pallet<T>>::delete_token_properties(253				self,254				&sender,255				token_id,256				property_keys.into_iter(),257				nesting_budget,258			),259			weight,260		)261	}262263	fn get_token_properties_raw(264		&self,265		token_id: TokenId,266	) -> Option<up_data_structs::TokenProperties> {267		<TokenProperties<T>>::get((self.id, token_id))268	}269270	fn set_token_properties_raw(&self, token_id: TokenId, map: up_data_structs::TokenProperties) {271		<TokenProperties<T>>::insert((self.id, token_id), map)272	}273274	fn set_token_property_permissions(275		&self,276		sender: &T::CrossAccountId,277		property_permissions: Vec<PropertyKeyPermission>,278	) -> DispatchResultWithPostInfo {279		let weight =280			<CommonWeights<T>>::set_token_property_permissions(property_permissions.len() as u32);281282		with_weight(283			<Pallet<T>>::set_token_property_permissions(self, sender, property_permissions),284			weight,285		)286	}287288	fn burn_item(289		&self,290		sender: T::CrossAccountId,291		token: TokenId,292		amount: u128,293	) -> DispatchResultWithPostInfo {294		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);295		if amount == 1 {296			with_weight(297				<Pallet<T>>::burn(self, &sender, token),298				<CommonWeights<T>>::burn_item(),299			)300		} else {301			<Pallet<T>>::check_token_immediate_ownership(self, token, &sender)?;302			Ok(().into())303		}304	}305306	fn transfer(307		&self,308		from: T::CrossAccountId,309		to: T::CrossAccountId,310		token: TokenId,311		amount: u128,312		nesting_budget: &dyn Budget,313	) -> DispatchResultWithPostInfo {314		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);315		if amount == 1 {316			<Pallet<T>>::transfer(self, &from, &to, token, nesting_budget)317		} else {318			<Pallet<T>>::check_token_immediate_ownership(self, token, &from)?;319			Ok(().into())320		}321	}322323	fn approve(324		&self,325		sender: T::CrossAccountId,326		spender: T::CrossAccountId,327		token: TokenId,328		amount: u128,329	) -> DispatchResultWithPostInfo {330		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);331332		with_weight(333			if amount == 1 {334				<Pallet<T>>::set_allowance(self, &sender, token, Some(&spender))335			} else {336				<Pallet<T>>::set_allowance(self, &sender, token, None)337			},338			<CommonWeights<T>>::approve(),339		)340	}341342	fn approve_from(343		&self,344		sender: T::CrossAccountId,345		from: T::CrossAccountId,346		to: T::CrossAccountId,347		token: TokenId,348		amount: u128,349	) -> DispatchResultWithPostInfo {350		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);351352		with_weight(353			if amount == 1 {354				<Pallet<T>>::set_allowance_from(self, &sender, &from, token, Some(&to))355			} else {356				<Pallet<T>>::set_allowance_from(self, &sender, &from, token, None)357			},358			<CommonWeights<T>>::approve_from(),359		)360	}361362	fn transfer_from(363		&self,364		sender: T::CrossAccountId,365		from: T::CrossAccountId,366		to: T::CrossAccountId,367		token: TokenId,368		amount: u128,369		nesting_budget: &dyn Budget,370	) -> DispatchResultWithPostInfo {371		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);372373		if amount == 1 {374			<Pallet<T>>::transfer_from(self, &sender, &from, &to, token, nesting_budget)375		} else {376			<Pallet<T>>::check_allowed(self, &sender, &from, token, nesting_budget)?;377378			Ok(().into())379		}380	}381382	fn burn_from(383		&self,384		sender: T::CrossAccountId,385		from: T::CrossAccountId,386		token: TokenId,387		amount: u128,388		nesting_budget: &dyn Budget,389	) -> DispatchResultWithPostInfo {390		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);391392		if amount == 1 {393			with_weight(394				<Pallet<T>>::burn_from(self, &sender, &from, token, nesting_budget),395				<CommonWeights<T>>::burn_from(),396			)397		} else {398			<Pallet<T>>::check_allowed(self, &sender, &from, token, nesting_budget)?;399400			Ok(().into())401		}402	}403404	fn check_nesting(405		&self,406		sender: T::CrossAccountId,407		from: (CollectionId, TokenId),408		under: TokenId,409		nesting_budget: &dyn Budget,410	) -> sp_runtime::DispatchResult {411		<Pallet<T>>::check_nesting(self, sender, from, under, nesting_budget)412	}413414	fn nest(&self, under: TokenId, to_nest: (CollectionId, TokenId)) {415		<Pallet<T>>::nest((self.id, under), to_nest);416	}417418	fn unnest(&self, under: TokenId, to_unnest: (CollectionId, TokenId)) {419		<Pallet<T>>::unnest((self.id, under), to_unnest);420	}421422	fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {423		<Owned<T>>::iter_prefix((self.id, account))424			.map(|(id, _)| id)425			.collect()426	}427428	fn collection_tokens(&self) -> Vec<TokenId> {429		<TokenData<T>>::iter_prefix((self.id,))430			.map(|(id, _)| id)431			.collect()432	}433434	fn token_exists(&self, token: TokenId) -> bool {435		<Pallet<T>>::token_exists(self, token)436	}437438	fn last_token_id(&self) -> TokenId {439		TokenId(<TokensMinted<T>>::get(self.id))440	}441442	fn token_owner(&self, token: TokenId) -> Result<T::CrossAccountId, TokenOwnerError> {443		<TokenData<T>>::get((self.id, token))444			.map(|t| t.owner)445			.ok_or(TokenOwnerError::NotFound)446	}447448	fn check_token_indirect_owner(449		&self,450		token: TokenId,451		maybe_owner: &T::CrossAccountId,452		nesting_budget: &dyn Budget,453	) -> Result<bool, DispatchError> {454		<PalletStructure<T>>::check_indirectly_owned(455			maybe_owner.clone(),456			self.id,457			token,458			None,459			nesting_budget,460		)461	}462463	/// Returns token owners.464	fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId> {465		self.token_owner(token).map_or_else(|_| vec![], |t| vec![t])466	}467468	fn token_property(&self, token_id: TokenId, key: &PropertyKey) -> Option<PropertyValue> {469		<Pallet<T>>::token_properties((self.id, token_id))?470			.get(key)471			.cloned()472	}473474	fn token_properties(&self, token_id: TokenId, keys: Option<Vec<PropertyKey>>) -> Vec<Property> {475		let Some(properties) = <Pallet<T>>::token_properties((self.id, token_id)) else {476			return vec![];477		};478479		keys.map(|keys| {480			keys.into_iter()481				.filter_map(|key| {482					properties.get(&key).map(|value| Property {483						key,484						value: value.clone(),485					})486				})487				.collect()488		})489		.unwrap_or_else(|| {490			properties491				.into_iter()492				.map(|(key, value)| Property { key, value })493				.collect()494		})495	}496497	fn total_supply(&self) -> u32 {498		<Pallet<T>>::total_supply(self)499	}500501	fn account_balance(&self, account: T::CrossAccountId) -> u32 {502		<AccountBalance<T>>::get((self.id, account))503	}504505	fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {506		if <TokenData<T>>::get((self.id, token))507			.map(|a| a.owner == account)508			.unwrap_or(false)509		{510			1511		} else {512			0513		}514	}515516	fn allowance(517		&self,518		sender: T::CrossAccountId,519		spender: T::CrossAccountId,520		token: TokenId,521	) -> u128 {522		if <TokenData<T>>::get((self.id, token))523			.map(|a| a.owner != sender)524			.unwrap_or(true)525		{526			0527		} else if <Allowance<T>>::get((self.id, token)) == Some(spender) {528			1529		} else {530			0531		}532	}533534	fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>> {535		None536	}537538	fn total_pieces(&self, token: TokenId) -> Option<u128> {539		if <TokenData<T>>::contains_key((self.id, token)) {540			Some(1)541		} else {542			None543		}544	}545546	fn set_allowance_for_all(547		&self,548		owner: T::CrossAccountId,549		operator: T::CrossAccountId,550		approve: bool,551	) -> DispatchResultWithPostInfo {552		with_weight(553			<Pallet<T>>::set_allowance_for_all(self, &owner, &operator, approve),554			<CommonWeights<T>>::set_allowance_for_all(),555		)556	}557558	fn allowance_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool {559		<Pallet<T>>::allowance_for_all(self, &owner, &operator)560	}561562	fn repair_item(&self, token: TokenId) -> DispatchResultWithPostInfo {563		with_weight(564			<Pallet<T>>::repair_item(self, token),565			<CommonWeights<T>>::force_repair_item(),566		)567	}568}
after · pallets/nonfungible/src/common.rs
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 frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};20use pallet_common::{21	weights::WeightInfo as _, with_weight, write_token_properties_total_weight,22	CommonCollectionOperations, CommonWeightInfo, RefungibleExtensions,23	SelfWeightOf as PalletCommonWeightOf,24};25use pallet_structure::Pallet as PalletStructure;26use sp_runtime::DispatchError;27use sp_std::{vec, vec::Vec};28use up_data_structs::{29	budget::Budget, CollectionId, CreateItemExData, Property, PropertyKey, PropertyKeyPermission,30	PropertyValue, TokenId, TokenOwnerError,31};3233use crate::{34	weights::WeightInfo, AccountBalance, Allowance, Config, CreateItemData, Error,35	NonfungibleHandle, Owned, Pallet, SelfWeightOf, TokenData, TokenProperties, TokensMinted,36};3738pub struct CommonWeights<T: Config>(PhantomData<T>);39impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {40	fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {41		match data {42			CreateItemExData::NFT(t) => mint_with_props_weight::<T>(43				<SelfWeightOf<T>>::create_multiple_items_ex(t.len() as u32),44				t.iter().map(|t| t.properties.len() as u32),45			),46			_ => Weight::zero(),47		}48	}4950	fn create_multiple_items(data: &[up_data_structs::CreateItemData]) -> Weight {51		mint_with_props_weight::<T>(52			<SelfWeightOf<T>>::create_multiple_items(data.len() as u32),53			data.iter().map(|t| match t {54				up_data_structs::CreateItemData::NFT(n) => n.properties.len() as u32,55				_ => 0,56			}),57		)58	}5960	fn burn_item() -> Weight {61		<SelfWeightOf<T>>::burn_item()62	}6364	fn set_collection_properties(amount: u32) -> Weight {65		<pallet_common::SelfWeightOf<T>>::set_collection_properties(amount)66	}6768	fn set_token_properties(amount: u32) -> Weight {69		write_token_properties_total_weight::<T, _>([amount].into_iter(), |amount| {70			<SelfWeightOf<T>>::load_token_properties()71				.saturating_add(<SelfWeightOf<T>>::write_token_properties(amount))72		})73	}7475	fn delete_token_properties(amount: u32) -> Weight {76		Self::set_token_properties(amount)77	}7879	fn set_token_property_permissions(amount: u32) -> Weight {80		<SelfWeightOf<T>>::set_token_property_permissions(amount)81	}8283	fn transfer() -> Weight {84		<SelfWeightOf<T>>::transfer_raw()85			.saturating_add(<PalletCommonWeightOf<T>>::check_accesslist().saturating_mul(2))86	}8788	fn approve() -> Weight {89		<SelfWeightOf<T>>::approve()90	}9192	fn approve_from() -> Weight {93		<SelfWeightOf<T>>::approve_from()94	}9596	fn transfer_from() -> Weight {97		Self::transfer().saturating_add(<SelfWeightOf<T>>::check_allowed_raw())98	}99100	fn burn_from() -> Weight {101		<SelfWeightOf<T>>::burn_from()102	}103104	fn set_allowance_for_all() -> Weight {105		<SelfWeightOf<T>>::set_allowance_for_all()106	}107108	fn force_repair_item() -> Weight {109		<SelfWeightOf<T>>::repair_item()110	}111}112113/// Weight of minting tokens with properties114/// * `create_no_data_weight` -- the weight of minting without properties115/// * `token_properties_nums` -- number of properties of each token116#[inline]117pub(crate) fn mint_with_props_weight<T: Config>(118	create_no_data_weight: Weight,119	token_properties_nums: impl Iterator<Item = u32> + Clone,120) -> Weight {121	create_no_data_weight.saturating_add(write_token_properties_total_weight::<T, _>(122		token_properties_nums,123		<SelfWeightOf<T>>::write_token_properties,124	))125}126127fn map_create_data<T: Config>(128	data: up_data_structs::CreateItemData,129	to: &T::CrossAccountId,130) -> Result<CreateItemData<T>, DispatchError> {131	match data {132		up_data_structs::CreateItemData::NFT(data) => Ok(CreateItemData::<T> {133			properties: data.properties,134			owner: to.clone(),135		}),136		_ => fail!(<Error<T>>::NotNonfungibleDataUsedToMintFungibleCollectionToken),137	}138}139140/// Implementation of `CommonCollectionOperations` for `NonfungibleHandle`. It wraps Nonfungible Pallete141/// methods and adds weight info.142impl<T: Config> CommonCollectionOperations<T> for NonfungibleHandle<T> {143	fn create_item(144		&self,145		sender: T::CrossAccountId,146		to: T::CrossAccountId,147		data: up_data_structs::CreateItemData,148		nesting_budget: &dyn Budget,149	) -> DispatchResultWithPostInfo {150		let weight = <CommonWeights<T>>::create_item(&data);151		with_weight(152			<Pallet<T>>::create_item(153				self,154				&sender,155				map_create_data::<T>(data, &to)?,156				nesting_budget,157			),158			weight,159		)160	}161162	fn create_multiple_items(163		&self,164		sender: T::CrossAccountId,165		to: T::CrossAccountId,166		data: Vec<up_data_structs::CreateItemData>,167		nesting_budget: &dyn Budget,168	) -> DispatchResultWithPostInfo {169		let weight = <CommonWeights<T>>::create_multiple_items(&data);170		let data = data171			.into_iter()172			.map(|d| map_create_data::<T>(d, &to))173			.collect::<Result<Vec<_>, DispatchError>>()?;174175		with_weight(176			<Pallet<T>>::create_multiple_items(self, &sender, data, nesting_budget),177			weight,178		)179	}180181	fn create_multiple_items_ex(182		&self,183		sender: <T>::CrossAccountId,184		data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,185		nesting_budget: &dyn Budget,186	) -> DispatchResultWithPostInfo {187		let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);188		let data = match data {189			up_data_structs::CreateItemExData::NFT(nft) => nft,190			_ => fail!(Error::<T>::NotNonfungibleDataUsedToMintFungibleCollectionToken),191		};192193		with_weight(194			<Pallet<T>>::create_multiple_items(self, &sender, data.into_inner(), nesting_budget),195			weight,196		)197	}198199	fn set_collection_properties(200		&self,201		sender: T::CrossAccountId,202		properties: Vec<Property>,203	) -> DispatchResultWithPostInfo {204		let weight = <CommonWeights<T>>::set_collection_properties(properties.len() as u32);205206		with_weight(207			<Pallet<T>>::set_collection_properties(self, &sender, properties),208			weight,209		)210	}211212	fn delete_collection_properties(213		&self,214		sender: &T::CrossAccountId,215		property_keys: Vec<PropertyKey>,216	) -> DispatchResultWithPostInfo {217		let weight = <CommonWeights<T>>::delete_collection_properties(property_keys.len() as u32);218219		with_weight(220			<Pallet<T>>::delete_collection_properties(self, sender, property_keys),221			weight,222		)223	}224225	fn set_token_properties(226		&self,227		sender: T::CrossAccountId,228		token_id: TokenId,229		properties: Vec<Property>,230		nesting_budget: &dyn Budget,231	) -> DispatchResultWithPostInfo {232		let weight = <CommonWeights<T>>::set_token_properties(properties.len() as u32);233234		with_weight(235			<Pallet<T>>::set_token_properties(236				self,237				&sender,238				token_id,239				properties.into_iter(),240				nesting_budget,241			),242			weight,243		)244	}245246	fn delete_token_properties(247		&self,248		sender: T::CrossAccountId,249		token_id: TokenId,250		property_keys: Vec<PropertyKey>,251		nesting_budget: &dyn Budget,252	) -> DispatchResultWithPostInfo {253		let weight = <CommonWeights<T>>::delete_token_properties(property_keys.len() as u32);254255		with_weight(256			<Pallet<T>>::delete_token_properties(257				self,258				&sender,259				token_id,260				property_keys.into_iter(),261				nesting_budget,262			),263			weight,264		)265	}266267	fn get_token_properties_raw(268		&self,269		token_id: TokenId,270	) -> Option<up_data_structs::TokenProperties> {271		<TokenProperties<T>>::get((self.id, token_id))272	}273274	fn set_token_properties_raw(&self, token_id: TokenId, map: up_data_structs::TokenProperties) {275		<TokenProperties<T>>::insert((self.id, token_id), map)276	}277278	fn set_token_property_permissions(279		&self,280		sender: &T::CrossAccountId,281		property_permissions: Vec<PropertyKeyPermission>,282	) -> DispatchResultWithPostInfo {283		let weight =284			<CommonWeights<T>>::set_token_property_permissions(property_permissions.len() as u32);285286		with_weight(287			<Pallet<T>>::set_token_property_permissions(self, sender, property_permissions),288			weight,289		)290	}291292	fn burn_item(293		&self,294		sender: T::CrossAccountId,295		token: TokenId,296		amount: u128,297	) -> DispatchResultWithPostInfo {298		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);299		if amount == 1 {300			with_weight(301				<Pallet<T>>::burn(self, &sender, token),302				<CommonWeights<T>>::burn_item(),303			)304		} else {305			<Pallet<T>>::check_token_immediate_ownership(self, token, &sender)?;306			Ok(().into())307		}308	}309310	fn transfer(311		&self,312		from: T::CrossAccountId,313		to: T::CrossAccountId,314		token: TokenId,315		amount: u128,316		nesting_budget: &dyn Budget,317	) -> DispatchResultWithPostInfo {318		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);319		if amount == 1 {320			<Pallet<T>>::transfer(self, &from, &to, token, nesting_budget)321		} else {322			<Pallet<T>>::check_token_immediate_ownership(self, token, &from)?;323			Ok(().into())324		}325	}326327	fn approve(328		&self,329		sender: T::CrossAccountId,330		spender: T::CrossAccountId,331		token: TokenId,332		amount: u128,333	) -> DispatchResultWithPostInfo {334		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);335336		with_weight(337			if amount == 1 {338				<Pallet<T>>::set_allowance(self, &sender, token, Some(&spender))339			} else {340				<Pallet<T>>::set_allowance(self, &sender, token, None)341			},342			<CommonWeights<T>>::approve(),343		)344	}345346	fn approve_from(347		&self,348		sender: T::CrossAccountId,349		from: T::CrossAccountId,350		to: T::CrossAccountId,351		token: TokenId,352		amount: u128,353	) -> DispatchResultWithPostInfo {354		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);355356		with_weight(357			if amount == 1 {358				<Pallet<T>>::set_allowance_from(self, &sender, &from, token, Some(&to))359			} else {360				<Pallet<T>>::set_allowance_from(self, &sender, &from, token, None)361			},362			<CommonWeights<T>>::approve_from(),363		)364	}365366	fn transfer_from(367		&self,368		sender: T::CrossAccountId,369		from: T::CrossAccountId,370		to: T::CrossAccountId,371		token: TokenId,372		amount: u128,373		nesting_budget: &dyn Budget,374	) -> DispatchResultWithPostInfo {375		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);376377		if amount == 1 {378			<Pallet<T>>::transfer_from(self, &sender, &from, &to, token, nesting_budget)379		} else {380			<Pallet<T>>::check_allowed(self, &sender, &from, token, nesting_budget)?;381382			Ok(().into())383		}384	}385386	fn burn_from(387		&self,388		sender: T::CrossAccountId,389		from: T::CrossAccountId,390		token: TokenId,391		amount: u128,392		nesting_budget: &dyn Budget,393	) -> DispatchResultWithPostInfo {394		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);395396		if amount == 1 {397			with_weight(398				<Pallet<T>>::burn_from(self, &sender, &from, token, nesting_budget),399				<CommonWeights<T>>::burn_from(),400			)401		} else {402			<Pallet<T>>::check_allowed(self, &sender, &from, token, nesting_budget)?;403404			Ok(().into())405		}406	}407408	fn check_nesting(409		&self,410		sender: T::CrossAccountId,411		from: (CollectionId, TokenId),412		under: TokenId,413		nesting_budget: &dyn Budget,414	) -> sp_runtime::DispatchResult {415		<Pallet<T>>::check_nesting(self, sender, from, under, nesting_budget)416	}417418	fn nest(&self, under: TokenId, to_nest: (CollectionId, TokenId)) {419		<Pallet<T>>::nest((self.id, under), to_nest);420	}421422	fn unnest(&self, under: TokenId, to_unnest: (CollectionId, TokenId)) {423		<Pallet<T>>::unnest((self.id, under), to_unnest);424	}425426	fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {427		<Owned<T>>::iter_prefix((self.id, account))428			.map(|(id, _)| id)429			.collect()430	}431432	fn collection_tokens(&self) -> Vec<TokenId> {433		<TokenData<T>>::iter_prefix((self.id,))434			.map(|(id, _)| id)435			.collect()436	}437438	fn token_exists(&self, token: TokenId) -> bool {439		<Pallet<T>>::token_exists(self, token)440	}441442	fn last_token_id(&self) -> TokenId {443		TokenId(<TokensMinted<T>>::get(self.id))444	}445446	fn token_owner(&self, token: TokenId) -> Result<T::CrossAccountId, TokenOwnerError> {447		<TokenData<T>>::get((self.id, token))448			.map(|t| t.owner)449			.ok_or(TokenOwnerError::NotFound)450	}451452	fn check_token_indirect_owner(453		&self,454		token: TokenId,455		maybe_owner: &T::CrossAccountId,456		nesting_budget: &dyn Budget,457	) -> Result<bool, DispatchError> {458		<PalletStructure<T>>::check_indirectly_owned(459			maybe_owner.clone(),460			self.id,461			token,462			None,463			nesting_budget,464		)465	}466467	/// Returns token owners.468	fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId> {469		self.token_owner(token).map_or_else(|_| vec![], |t| vec![t])470	}471472	fn token_property(&self, token_id: TokenId, key: &PropertyKey) -> Option<PropertyValue> {473		<Pallet<T>>::token_properties((self.id, token_id))?474			.get(key)475			.cloned()476	}477478	fn token_properties(&self, token_id: TokenId, keys: Option<Vec<PropertyKey>>) -> Vec<Property> {479		let Some(properties) = <Pallet<T>>::token_properties((self.id, token_id)) else {480			return vec![];481		};482483		keys.map(|keys| {484			keys.into_iter()485				.filter_map(|key| {486					properties.get(&key).map(|value| Property {487						key,488						value: value.clone(),489					})490				})491				.collect()492		})493		.unwrap_or_else(|| {494			properties495				.into_iter()496				.map(|(key, value)| Property { key, value })497				.collect()498		})499	}500501	fn total_supply(&self) -> u32 {502		<Pallet<T>>::total_supply(self)503	}504505	fn account_balance(&self, account: T::CrossAccountId) -> u32 {506		<AccountBalance<T>>::get((self.id, account))507	}508509	fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {510		if <TokenData<T>>::get((self.id, token))511			.map(|a| a.owner == account)512			.unwrap_or(false)513		{514			1515		} else {516			0517		}518	}519520	fn allowance(521		&self,522		sender: T::CrossAccountId,523		spender: T::CrossAccountId,524		token: TokenId,525	) -> u128 {526		if <TokenData<T>>::get((self.id, token))527			.map(|a| a.owner != sender)528			.unwrap_or(true)529		{530			0531		} else if <Allowance<T>>::get((self.id, token)) == Some(spender) {532			1533		} else {534			0535		}536	}537538	fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>> {539		None540	}541542	fn total_pieces(&self, token: TokenId) -> Option<u128> {543		if <TokenData<T>>::contains_key((self.id, token)) {544			Some(1)545		} else {546			None547		}548	}549550	fn set_allowance_for_all(551		&self,552		owner: T::CrossAccountId,553		operator: T::CrossAccountId,554		approve: bool,555	) -> DispatchResultWithPostInfo {556		with_weight(557			<Pallet<T>>::set_allowance_for_all(self, &owner, &operator, approve),558			<CommonWeights<T>>::set_allowance_for_all(),559		)560	}561562	fn allowance_for_all(&self, owner: T::CrossAccountId, operator: T::CrossAccountId) -> bool {563		<Pallet<T>>::allowance_for_all(self, &owner, &operator)564	}565566	fn repair_item(&self, token: TokenId) -> DispatchResultWithPostInfo {567		with_weight(568			<Pallet<T>>::repair_item(self, token),569			<CommonWeights<T>>::force_repair_item(),570		)571	}572}
modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -130,12 +130,16 @@
 	}
 }
 
+/// Weight of minting tokens with properties
+/// * `create_no_data_weight` -- the weight of minting without properties
+/// * `token_properties_nums` -- number of properties of each token
+#[inline]
 pub(crate) fn mint_with_props_weight<T: Config>(
 	create_no_data_weight: Weight,
-	tokens: impl Iterator<Item = u32> + Clone,
+	token_properties_nums: impl Iterator<Item = u32> + Clone,
 ) -> Weight {
 	create_no_data_weight.saturating_add(write_token_properties_total_weight::<T, _>(
-		tokens,
+		token_properties_nums,
 		<SelfWeightOf<T>>::write_token_properties,
 	))
 }