1use core::marker::PhantomData;23use sp_std::collections::btree_map::BTreeMap;4use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight, BoundedVec};5use up_data_structs::{TokenId, CustomDataLimit, CreateItemExData, CreateRefungibleExData};6use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};7use sp_runtime::DispatchError;8use sp_std::{vec::Vec, vec};910use crate::{11 AccountBalance, Allowance, Balance, Config, Error, Owned, Pallet, RefungibleHandle,12 SelfWeightOf, TokenData, weights::WeightInfo, TokensMinted,13};1415macro_rules! max_weight_of {16 ($($method:ident ($($args:tt)*)),*) => {17 018 $(19 .max(<SelfWeightOf<T>>::$method($($args)*))20 )*21 };22}2324pub struct CommonWeights<T: Config>(PhantomData<T>);25impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {26 fn create_item() -> Weight {27 <SelfWeightOf<T>>::create_item()28 }2930 fn create_multiple_items(amount: u32) -> Weight {31 <SelfWeightOf<T>>::create_multiple_items(amount)32 }3334 fn create_multiple_items_ex(call: &CreateItemExData<T::CrossAccountId>) -> Weight {35 match call {36 CreateItemExData::RefungibleMultipleOwners(i) => {37 <SelfWeightOf<T>>::create_multiple_items_ex_multiple_owners(i.users.len() as u32)38 }39 CreateItemExData::RefungibleMultipleItems(i) => {40 <SelfWeightOf<T>>::create_multiple_items_ex_multiple_items(i.len() as u32)41 }42 _ => 0,43 }44 }4546 fn burn_item() -> Weight {47 max_weight_of!(burn_item_partial(), burn_item_fully())48 }4950 fn transfer() -> Weight {51 max_weight_of!(52 transfer_normal(),53 transfer_creating(),54 transfer_removing(),55 transfer_creating_removing()56 )57 }5859 fn approve() -> Weight {60 <SelfWeightOf<T>>::approve()61 }6263 fn transfer_from() -> Weight {64 max_weight_of!(65 transfer_from_normal(),66 transfer_from_creating(),67 transfer_from_removing(),68 transfer_from_creating_removing()69 )70 }7172 fn burn_from() -> Weight {73 <SelfWeightOf<T>>::burn_from()74 }7576 fn set_variable_metadata(bytes: u32) -> Weight {77 <SelfWeightOf<T>>::set_variable_metadata(bytes)78 }79}8081fn map_create_data<T: Config>(82 data: up_data_structs::CreateItemData,83 to: &T::CrossAccountId,84) -> Result<CreateRefungibleExData<T::CrossAccountId>, DispatchError> {85 match data {86 up_data_structs::CreateItemData::ReFungible(data) => Ok(CreateRefungibleExData {87 const_data: data.const_data,88 variable_data: data.variable_data,89 users: {90 let mut out = BTreeMap::new();91 out.insert(to.clone(), data.pieces);92 out.try_into().expect("limit > 0")93 },94 }),95 _ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),96 }97}9899impl<T: Config> CommonCollectionOperations<T> for RefungibleHandle<T> {100 fn create_item(101 &self,102 sender: T::CrossAccountId,103 to: T::CrossAccountId,104 data: up_data_structs::CreateItemData,105 ) -> DispatchResultWithPostInfo {106 with_weight(107 <Pallet<T>>::create_item(self, &sender, map_create_data::<T>(data, &to)?),108 <CommonWeights<T>>::create_item(),109 )110 }111112 fn create_multiple_items(113 &self,114 sender: T::CrossAccountId,115 to: T::CrossAccountId,116 data: Vec<up_data_structs::CreateItemData>,117 ) -> DispatchResultWithPostInfo {118 let data = data119 .into_iter()120 .map(|d| map_create_data::<T>(d, &to))121 .collect::<Result<Vec<_>, DispatchError>>()?;122123 let amount = data.len();124 with_weight(125 <Pallet<T>>::create_multiple_items(self, &sender, data),126 <CommonWeights<T>>::create_multiple_items(amount as u32),127 )128 }129130 fn create_multiple_items_ex(131 &self,132 sender: <T>::CrossAccountId,133 data: CreateItemExData<T::CrossAccountId>,134 ) -> DispatchResultWithPostInfo {135 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);136 let data = match data {137 CreateItemExData::RefungibleMultipleOwners(r) => vec![r],138 CreateItemExData::RefungibleMultipleItems(r)139 if r.iter().all(|i| i.users.len() == 1) =>140 {141 r.into_inner()142 }143 _ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),144 };145146 with_weight(147 <Pallet<T>>::create_multiple_items(self, &sender, data),148 weight,149 )150 }151152 fn burn_item(153 &self,154 sender: T::CrossAccountId,155 token: TokenId,156 amount: u128,157 ) -> DispatchResultWithPostInfo {158 with_weight(159 <Pallet<T>>::burn(self, &sender, token, amount),160 <CommonWeights<T>>::burn_item(),161 )162 }163164 fn transfer(165 &self,166 from: T::CrossAccountId,167 to: T::CrossAccountId,168 token: TokenId,169 amount: u128,170 ) -> DispatchResultWithPostInfo {171 with_weight(172 <Pallet<T>>::transfer(self, &from, &to, token, amount),173 <CommonWeights<T>>::transfer(),174 )175 }176177 fn approve(178 &self,179 sender: T::CrossAccountId,180 spender: T::CrossAccountId,181 token: TokenId,182 amount: u128,183 ) -> DispatchResultWithPostInfo {184 with_weight(185 <Pallet<T>>::set_allowance(self, &sender, &spender, token, amount),186 <CommonWeights<T>>::approve(),187 )188 }189190 fn transfer_from(191 &self,192 sender: T::CrossAccountId,193 from: T::CrossAccountId,194 to: T::CrossAccountId,195 token: TokenId,196 amount: u128,197 ) -> DispatchResultWithPostInfo {198 with_weight(199 <Pallet<T>>::transfer_from(self, &sender, &from, &to, token, amount),200 <CommonWeights<T>>::transfer_from(),201 )202 }203204 fn burn_from(205 &self,206 sender: T::CrossAccountId,207 from: T::CrossAccountId,208 token: TokenId,209 amount: u128,210 ) -> DispatchResultWithPostInfo {211 with_weight(212 <Pallet<T>>::burn_from(self, &sender, &from, token, amount),213 <CommonWeights<T>>::burn_from(),214 )215 }216217 fn set_variable_metadata(218 &self,219 sender: T::CrossAccountId,220 token: TokenId,221 data: BoundedVec<u8, CustomDataLimit>,222 ) -> DispatchResultWithPostInfo {223 let len = data.len();224 with_weight(225 <Pallet<T>>::set_variable_metadata(self, &sender, token, data),226 <CommonWeights<T>>::set_variable_metadata(len as u32),227 )228 }229230 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {231 <Owned<T>>::iter_prefix((self.id, account))232 .map(|(id, _)| id)233 .collect()234 }235236 fn token_exists(&self, token: TokenId) -> bool {237 <Pallet<T>>::token_exists(self, token)238 }239240 fn last_token_id(&self) -> TokenId {241 TokenId(<TokensMinted<T>>::get(self.id))242 }243244 fn token_owner(&self, _token: TokenId) -> Option<T::CrossAccountId> {245 None246 }247 fn const_metadata(&self, token: TokenId) -> Vec<u8> {248 <TokenData<T>>::get((self.id, token))249 .const_data250 .into_inner()251 }252 fn variable_metadata(&self, token: TokenId) -> Vec<u8> {253 <TokenData<T>>::get((self.id, token))254 .variable_data255 .into_inner()256 }257258 fn collection_tokens(&self) -> u32 {259 <Pallet<T>>::total_supply(self)260 }261262 fn account_balance(&self, account: T::CrossAccountId) -> u32 {263 <AccountBalance<T>>::get((self.id, account))264 }265266 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {267 <Balance<T>>::get((self.id, token, account))268 }269270 fn allowance(271 &self,272 sender: T::CrossAccountId,273 spender: T::CrossAccountId,274 token: TokenId,275 ) -> u128 {276 <Allowance<T>>::get((self.id, token, sender, spender))277 }278}