1234567891011121314151617use core::marker::PhantomData;1819use sp_std::collections::btree_map::BTreeMap;20use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight, BoundedVec};21use up_data_structs::{22 TokenId, CustomDataLimit, CreateItemExData, CreateRefungibleExData, budget::Budget,23};24use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};25use sp_runtime::DispatchError;26use sp_std::{vec::Vec, vec};2728use crate::{29 AccountBalance, Allowance, Balance, Config, Error, Owned, Pallet, RefungibleHandle,30 SelfWeightOf, TokenData, weights::WeightInfo, TokensMinted,31};3233macro_rules! max_weight_of {34 ($($method:ident ($($args:tt)*)),*) => {35 036 $(37 .max(<SelfWeightOf<T>>::$method($($args)*))38 )*39 };40}4142pub struct CommonWeights<T: Config>(PhantomData<T>);43impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {44 fn create_item() -> Weight {45 <SelfWeightOf<T>>::create_item()46 }4748 fn create_multiple_items(amount: u32) -> Weight {49 <SelfWeightOf<T>>::create_multiple_items(amount)50 }5152 fn create_multiple_items_ex(call: &CreateItemExData<T::CrossAccountId>) -> Weight {53 match call {54 CreateItemExData::RefungibleMultipleOwners(i) => {55 <SelfWeightOf<T>>::create_multiple_items_ex_multiple_owners(i.users.len() as u32)56 }57 CreateItemExData::RefungibleMultipleItems(i) => {58 <SelfWeightOf<T>>::create_multiple_items_ex_multiple_items(i.len() as u32)59 }60 _ => 0,61 }62 }6364 fn burn_item() -> Weight {65 max_weight_of!(burn_item_partial(), burn_item_fully())66 }6768 fn transfer() -> Weight {69 max_weight_of!(70 transfer_normal(),71 transfer_creating(),72 transfer_removing(),73 transfer_creating_removing()74 )75 }7677 fn approve() -> Weight {78 <SelfWeightOf<T>>::approve()79 }8081 fn transfer_from() -> Weight {82 max_weight_of!(83 transfer_from_normal(),84 transfer_from_creating(),85 transfer_from_removing(),86 transfer_from_creating_removing()87 )88 }8990 fn burn_from() -> Weight {91 <SelfWeightOf<T>>::burn_from()92 }9394 fn set_variable_metadata(bytes: u32) -> Weight {95 <SelfWeightOf<T>>::set_variable_metadata(bytes)96 }97}9899fn map_create_data<T: Config>(100 data: up_data_structs::CreateItemData,101 to: &T::CrossAccountId,102) -> Result<CreateRefungibleExData<T::CrossAccountId>, DispatchError> {103 match data {104 up_data_structs::CreateItemData::ReFungible(data) => Ok(CreateRefungibleExData {105 const_data: data.const_data,106 variable_data: data.variable_data,107 users: {108 let mut out = BTreeMap::new();109 out.insert(to.clone(), data.pieces);110 out.try_into().expect("limit > 0")111 },112 }),113 _ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),114 }115}116117impl<T: Config> CommonCollectionOperations<T> for RefungibleHandle<T> {118 fn create_item(119 &self,120 sender: T::CrossAccountId,121 to: T::CrossAccountId,122 data: up_data_structs::CreateItemData,123 ) -> DispatchResultWithPostInfo {124 with_weight(125 <Pallet<T>>::create_item(self, &sender, map_create_data::<T>(data, &to)?),126 <CommonWeights<T>>::create_item(),127 )128 }129130 fn create_multiple_items(131 &self,132 sender: T::CrossAccountId,133 to: T::CrossAccountId,134 data: Vec<up_data_structs::CreateItemData>,135 ) -> DispatchResultWithPostInfo {136 let data = data137 .into_iter()138 .map(|d| map_create_data::<T>(d, &to))139 .collect::<Result<Vec<_>, DispatchError>>()?;140141 let amount = data.len();142 with_weight(143 <Pallet<T>>::create_multiple_items(self, &sender, data),144 <CommonWeights<T>>::create_multiple_items(amount as u32),145 )146 }147148 fn create_multiple_items_ex(149 &self,150 sender: <T>::CrossAccountId,151 data: CreateItemExData<T::CrossAccountId>,152 ) -> DispatchResultWithPostInfo {153 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);154 let data = match data {155 CreateItemExData::RefungibleMultipleOwners(r) => vec![r],156 CreateItemExData::RefungibleMultipleItems(r)157 if r.iter().all(|i| i.users.len() == 1) =>158 {159 r.into_inner()160 }161 _ => fail!(<Error<T>>::NotRefungibleDataUsedToMintFungibleCollectionToken),162 };163164 with_weight(165 <Pallet<T>>::create_multiple_items(self, &sender, data),166 weight,167 )168 }169170 fn burn_item(171 &self,172 sender: T::CrossAccountId,173 token: TokenId,174 amount: u128,175 ) -> DispatchResultWithPostInfo {176 with_weight(177 <Pallet<T>>::burn(self, &sender, token, amount),178 <CommonWeights<T>>::burn_item(),179 )180 }181182 fn transfer(183 &self,184 from: T::CrossAccountId,185 to: T::CrossAccountId,186 token: TokenId,187 amount: u128,188 ) -> DispatchResultWithPostInfo {189 with_weight(190 <Pallet<T>>::transfer(self, &from, &to, token, amount),191 <CommonWeights<T>>::transfer(),192 )193 }194195 fn approve(196 &self,197 sender: T::CrossAccountId,198 spender: T::CrossAccountId,199 token: TokenId,200 amount: u128,201 ) -> DispatchResultWithPostInfo {202 with_weight(203 <Pallet<T>>::set_allowance(self, &sender, &spender, token, amount),204 <CommonWeights<T>>::approve(),205 )206 }207208 fn transfer_from(209 &self,210 sender: T::CrossAccountId,211 from: T::CrossAccountId,212 to: T::CrossAccountId,213 token: TokenId,214 amount: u128,215 nesting_budget: &dyn Budget,216 ) -> DispatchResultWithPostInfo {217 with_weight(218 <Pallet<T>>::transfer_from(self, &sender, &from, &to, token, amount, nesting_budget),219 <CommonWeights<T>>::transfer_from(),220 )221 }222223 fn burn_from(224 &self,225 sender: T::CrossAccountId,226 from: T::CrossAccountId,227 token: TokenId,228 amount: u128,229 nesting_budget: &dyn Budget,230 ) -> DispatchResultWithPostInfo {231 with_weight(232 <Pallet<T>>::burn_from(self, &sender, &from, token, amount, nesting_budget),233 <CommonWeights<T>>::burn_from(),234 )235 }236237 fn set_variable_metadata(238 &self,239 sender: T::CrossAccountId,240 token: TokenId,241 data: BoundedVec<u8, CustomDataLimit>,242 ) -> DispatchResultWithPostInfo {243 let len = data.len();244 with_weight(245 <Pallet<T>>::set_variable_metadata(self, &sender, token, data),246 <CommonWeights<T>>::set_variable_metadata(len as u32),247 )248 }249250 fn nest_token(251 &self,252 _sender: <T>::CrossAccountId,253 _from: (up_data_structs::CollectionId, TokenId),254 _under: TokenId,255 ) -> sp_runtime::DispatchResult {256 fail!(<Error<T>>::RefungibleDisallowsNesting)257 }258259 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {260 <Owned<T>>::iter_prefix((self.id, account))261 .map(|(id, _)| id)262 .collect()263 }264265 fn token_exists(&self, token: TokenId) -> bool {266 <Pallet<T>>::token_exists(self, token)267 }268269 fn last_token_id(&self) -> TokenId {270 TokenId(<TokensMinted<T>>::get(self.id))271 }272273 fn token_owner(&self, _token: TokenId) -> Option<T::CrossAccountId> {274 None275 }276 fn const_metadata(&self, token: TokenId) -> Vec<u8> {277 <TokenData<T>>::get((self.id, token))278 .const_data279 .into_inner()280 }281 fn variable_metadata(&self, token: TokenId) -> Vec<u8> {282 <TokenData<T>>::get((self.id, token))283 .variable_data284 .into_inner()285 }286287 fn collection_tokens(&self) -> u32 {288 <Pallet<T>>::total_supply(self)289 }290291 fn account_balance(&self, account: T::CrossAccountId) -> u32 {292 <AccountBalance<T>>::get((self.id, account))293 }294295 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {296 <Balance<T>>::get((self.id, token, account))297 }298299 fn allowance(300 &self,301 sender: T::CrossAccountId,302 spender: T::CrossAccountId,303 token: TokenId,304 ) -> u128 {305 <Allowance<T>>::get((self.id, token, sender, spender))306 }307}