1234567891011121314151617use core::marker::PhantomData;1819use sp_std::collections::btree_map::BTreeMap;20use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight, BoundedVec};21use up_data_structs::{TokenId, CustomDataLimit, CreateItemExData, CreateRefungibleExData};22use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};23use sp_runtime::DispatchError;24use sp_std::{vec::Vec, vec};2526use crate::{27 AccountBalance, Allowance, Balance, Config, Error, Owned, Pallet, RefungibleHandle,28 SelfWeightOf, TokenData, weights::WeightInfo, TokensMinted,29};3031macro_rules! max_weight_of {32 ($($method:ident ($($args:tt)*)),*) => {33 034 $(35 .max(<SelfWeightOf<T>>::$method($($args)*))36 )*37 };38}3940pub struct CommonWeights<T: Config>(PhantomData<T>);41impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {42 fn create_item() -> Weight {43 <SelfWeightOf<T>>::create_item()44 }4546 fn create_multiple_items(amount: u32) -> Weight {47 <SelfWeightOf<T>>::create_multiple_items(amount)48 }4950 fn create_multiple_items_ex(call: &CreateItemExData<T::CrossAccountId>) -> Weight {51 match call {52 CreateItemExData::RefungibleMultipleOwners(i) => {53 <SelfWeightOf<T>>::create_multiple_items_ex_multiple_owners(i.users.len() as u32)54 }55 CreateItemExData::RefungibleMultipleItems(i) => {56 <SelfWeightOf<T>>::create_multiple_items_ex_multiple_items(i.len() as u32)57 }58 _ => 0,59 }60 }6162 fn burn_item() -> Weight {63 max_weight_of!(burn_item_partial(), burn_item_fully())64 }6566 fn transfer() -> Weight {67 max_weight_of!(68 transfer_normal(),69 transfer_creating(),70 transfer_removing(),71 transfer_creating_removing()72 )73 }7475 fn approve() -> Weight {76 <SelfWeightOf<T>>::approve()77 }7879 fn transfer_from() -> Weight {80 max_weight_of!(81 transfer_from_normal(),82 transfer_from_creating(),83 transfer_from_removing(),84 transfer_from_creating_removing()85 )86 }8788 fn burn_from() -> Weight {89 <SelfWeightOf<T>>::burn_from()90 }9192 fn set_variable_metadata(bytes: u32) -> Weight {93 <SelfWeightOf<T>>::set_variable_metadata(bytes)94 }95}9697fn map_create_data<T: Config>(98 data: up_data_structs::CreateItemData,99 to: &T::CrossAccountId,100) -> Result<CreateRefungibleExData<T::CrossAccountId>, DispatchError> {101 match data {102 up_data_structs::CreateItemData::ReFungible(data) => Ok(CreateRefungibleExData {103 const_data: data.const_data,104 variable_data: data.variable_data,105 users: {106 let mut out = BTreeMap::new();107 out.insert(to.clone(), data.pieces);108 out.try_into().expect("limit > 0")109 },110 }),111 _ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),112 }113}114115impl<T: Config> CommonCollectionOperations<T> for RefungibleHandle<T> {116 fn create_item(117 &self,118 sender: T::CrossAccountId,119 to: T::CrossAccountId,120 data: up_data_structs::CreateItemData,121 ) -> DispatchResultWithPostInfo {122 with_weight(123 <Pallet<T>>::create_item(self, &sender, map_create_data::<T>(data, &to)?),124 <CommonWeights<T>>::create_item(),125 )126 }127128 fn create_multiple_items(129 &self,130 sender: T::CrossAccountId,131 to: T::CrossAccountId,132 data: Vec<up_data_structs::CreateItemData>,133 ) -> DispatchResultWithPostInfo {134 let data = data135 .into_iter()136 .map(|d| map_create_data::<T>(d, &to))137 .collect::<Result<Vec<_>, DispatchError>>()?;138139 let amount = data.len();140 with_weight(141 <Pallet<T>>::create_multiple_items(self, &sender, data),142 <CommonWeights<T>>::create_multiple_items(amount as u32),143 )144 }145146 fn create_multiple_items_ex(147 &self,148 sender: <T>::CrossAccountId,149 data: CreateItemExData<T::CrossAccountId>,150 ) -> DispatchResultWithPostInfo {151 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);152 let data = match data {153 CreateItemExData::RefungibleMultipleOwners(r) => vec![r],154 CreateItemExData::RefungibleMultipleItems(r)155 if r.iter().all(|i| i.users.len() == 1) =>156 {157 r.into_inner()158 }159 _ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),160 };161162 with_weight(163 <Pallet<T>>::create_multiple_items(self, &sender, data),164 weight,165 )166 }167168 fn burn_item(169 &self,170 sender: T::CrossAccountId,171 token: TokenId,172 amount: u128,173 ) -> DispatchResultWithPostInfo {174 with_weight(175 <Pallet<T>>::burn(self, &sender, token, amount),176 <CommonWeights<T>>::burn_item(),177 )178 }179180 fn transfer(181 &self,182 from: T::CrossAccountId,183 to: T::CrossAccountId,184 token: TokenId,185 amount: u128,186 ) -> DispatchResultWithPostInfo {187 with_weight(188 <Pallet<T>>::transfer(self, &from, &to, token, amount),189 <CommonWeights<T>>::transfer(),190 )191 }192193 fn approve(194 &self,195 sender: T::CrossAccountId,196 spender: T::CrossAccountId,197 token: TokenId,198 amount: u128,199 ) -> DispatchResultWithPostInfo {200 with_weight(201 <Pallet<T>>::set_allowance(self, &sender, &spender, token, amount),202 <CommonWeights<T>>::approve(),203 )204 }205206 fn transfer_from(207 &self,208 sender: T::CrossAccountId,209 from: T::CrossAccountId,210 to: T::CrossAccountId,211 token: TokenId,212 amount: u128,213 ) -> DispatchResultWithPostInfo {214 with_weight(215 <Pallet<T>>::transfer_from(self, &sender, &from, &to, token, amount),216 <CommonWeights<T>>::transfer_from(),217 )218 }219220 fn burn_from(221 &self,222 sender: T::CrossAccountId,223 from: T::CrossAccountId,224 token: TokenId,225 amount: u128,226 ) -> DispatchResultWithPostInfo {227 with_weight(228 <Pallet<T>>::burn_from(self, &sender, &from, token, amount),229 <CommonWeights<T>>::burn_from(),230 )231 }232233 fn set_variable_metadata(234 &self,235 sender: T::CrossAccountId,236 token: TokenId,237 data: BoundedVec<u8, CustomDataLimit>,238 ) -> DispatchResultWithPostInfo {239 let len = data.len();240 with_weight(241 <Pallet<T>>::set_variable_metadata(self, &sender, token, data),242 <CommonWeights<T>>::set_variable_metadata(len as u32),243 )244 }245246 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {247 <Owned<T>>::iter_prefix((self.id, account))248 .map(|(id, _)| id)249 .collect()250 }251252 fn token_exists(&self, token: TokenId) -> bool {253 <Pallet<T>>::token_exists(self, token)254 }255256 fn last_token_id(&self) -> TokenId {257 TokenId(<TokensMinted<T>>::get(self.id))258 }259260 fn token_owner(&self, _token: TokenId) -> Option<T::CrossAccountId> {261 None262 }263 fn const_metadata(&self, token: TokenId) -> Vec<u8> {264 <TokenData<T>>::get((self.id, token))265 .const_data266 .into_inner()267 }268 fn variable_metadata(&self, token: TokenId) -> Vec<u8> {269 <TokenData<T>>::get((self.id, token))270 .variable_data271 .into_inner()272 }273274 fn collection_tokens(&self) -> u32 {275 <Pallet<T>>::total_supply(self)276 }277278 fn account_balance(&self, account: T::CrossAccountId) -> u32 {279 <AccountBalance<T>>::get((self.id, account))280 }281282 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {283 <Balance<T>>::get((self.id, token, account))284 }285286 fn allowance(287 &self,288 sender: T::CrossAccountId,289 spender: T::CrossAccountId,290 token: TokenId,291 ) -> u128 {292 <Allowance<T>>::get((self.id, token, sender, spender))293 }294}