1234567891011121314151617use core::marker::PhantomData;1819use frame_support::{20 dispatch::DispatchResultWithPostInfo, ensure, fail, traits::Get, weights::Weight,21};22use pallet_common::{23 weights::WeightInfo as _, with_weight, CommonCollectionOperations, CommonWeightInfo,24 RefungibleExtensions, SelfWeightOf as PalletCommonWeightOf,25};26use pallet_structure::Error as StructureError;27use sp_runtime::{ArithmeticError, DispatchError};28use sp_std::{vec, vec::Vec};29use up_data_structs::{30 budget::Budget, CollectionId, CreateItemData, CreateItemExData, Property, PropertyKey,31 PropertyKeyPermission, PropertyValue, TokenId, TokenOwnerError,32};3334use crate::{35 weights::WeightInfo, Allowance, Balance, Config, Error, FungibleHandle, Pallet, SelfWeightOf,36 TotalSupply,37};3839pub struct CommonWeights<T: Config>(PhantomData<T>);40impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {41 fn create_multiple_items(_data: &[CreateItemData]) -> Weight {42 43 <SelfWeightOf<T>>::create_item()44 }4546 fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {47 match data {48 CreateItemExData::Fungible(f) => {49 <SelfWeightOf<T>>::create_multiple_items_ex(f.len() as u32)50 }51 _ => Weight::zero(),52 }53 }5455 fn burn_item() -> Weight {56 <SelfWeightOf<T>>::burn_item()57 }5859 fn set_collection_properties(amount: u32) -> Weight {60 <pallet_common::SelfWeightOf<T>>::set_collection_properties(amount)61 }6263 fn delete_collection_properties(amount: u32) -> Weight {64 <pallet_common::SelfWeightOf<T>>::delete_collection_properties(amount)65 }6667 fn set_token_properties(_amount: u32) -> Weight {68 69 Weight::zero()70 }7172 fn delete_token_properties(_amount: u32) -> Weight {73 74 Weight::zero()75 }7677 fn set_token_property_permissions(_amount: u32) -> Weight {78 79 Weight::zero()80 }8182 fn transfer() -> Weight {83 <SelfWeightOf<T>>::transfer_raw() + <PalletCommonWeightOf<T>>::check_accesslist() * 284 }8586 fn approve() -> Weight {87 <SelfWeightOf<T>>::approve()88 }8990 fn approve_from() -> Weight {91 <SelfWeightOf<T>>::approve_from()92 }9394 fn transfer_from() -> Weight {95 Self::transfer()96 + <SelfWeightOf<T>>::check_allowed_raw()97 + <SelfWeightOf<T>>::set_allowance_unchecked_raw()98 }99100 fn burn_from() -> Weight {101 <SelfWeightOf<T>>::burn_from()102 }103104 fn burn_recursively_self_raw() -> Weight {105 106 Self::burn_item() + T::DbWeight::get().reads(1)107 }108109 fn burn_recursively_breadth_raw(_amount: u32) -> Weight {110 111 Weight::zero()112 }113114 fn token_owner() -> Weight {115 Weight::zero()116 }117118 fn set_allowance_for_all() -> Weight {119 Weight::zero()120 }121122 fn force_repair_item() -> Weight {123 Weight::zero()124 }125}126127128129impl<T: Config> CommonCollectionOperations<T> for FungibleHandle<T> {130 fn create_item(131 &self,132 sender: T::CrossAccountId,133 to: T::CrossAccountId,134 data: up_data_structs::CreateItemData,135 nesting_budget: &dyn Budget,136 ) -> DispatchResultWithPostInfo {137 match &data {138 up_data_structs::CreateItemData::Fungible(fungible_data) => with_weight(139 <Pallet<T>>::create_item(self, &sender, (to, fungible_data.value), nesting_budget),140 <CommonWeights<T>>::create_item(&data),141 ),142 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),143 }144 }145146 fn create_multiple_items(147 &self,148 sender: T::CrossAccountId,149 to: T::CrossAccountId,150 data: Vec<up_data_structs::CreateItemData>,151 nesting_budget: &dyn Budget,152 ) -> DispatchResultWithPostInfo {153 let mut sum: u128 = 0;154 for data in &data {155 match &data {156 up_data_structs::CreateItemData::Fungible(data) => {157 sum = sum158 .checked_add(data.value)159 .ok_or(ArithmeticError::Overflow)?;160 }161 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),162 }163 }164165 with_weight(166 <Pallet<T>>::create_item(self, &sender, (to, sum), nesting_budget),167 <CommonWeights<T>>::create_multiple_items(&data),168 )169 }170171 fn create_multiple_items_ex(172 &self,173 sender: <T>::CrossAccountId,174 data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,175 nesting_budget: &dyn Budget,176 ) -> DispatchResultWithPostInfo {177 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);178 let data = match data {179 up_data_structs::CreateItemExData::Fungible(f) => f,180 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),181 };182183 with_weight(184 <Pallet<T>>::create_multiple_items(self, &sender, data.into_inner(), nesting_budget),185 weight,186 )187 }188189 fn burn_item(190 &self,191 sender: T::CrossAccountId,192 token: TokenId,193 amount: u128,194 ) -> DispatchResultWithPostInfo {195 ensure!(196 token == TokenId::default(),197 <Error<T>>::FungibleItemsHaveNoId198 );199200 with_weight(201 <Pallet<T>>::burn(self, &sender, amount),202 <CommonWeights<T>>::burn_item(),203 )204 }205206 fn burn_item_recursively(207 &self,208 sender: T::CrossAccountId,209 token: TokenId,210 self_budget: &dyn Budget,211 _breadth_budget: &dyn Budget,212 ) -> DispatchResultWithPostInfo {213 214 ensure!(215 token == TokenId::default(),216 <Error<T>>::FungibleItemsHaveNoId217 );218 ensure!(self_budget.consume(), <StructureError<T>>::DepthLimit,);219220 with_weight(221 <Pallet<T>>::burn(self, &sender, <Balance<T>>::get((self.id, &sender))),222 <CommonWeights<T>>::burn_recursively_self_raw(),223 )224 }225226 fn transfer(227 &self,228 from: T::CrossAccountId,229 to: T::CrossAccountId,230 token: TokenId,231 amount: u128,232 nesting_budget: &dyn Budget,233 ) -> DispatchResultWithPostInfo {234 ensure!(235 token == TokenId::default(),236 <Error<T>>::FungibleItemsHaveNoId237 );238239 <Pallet<T>>::transfer(self, &from, &to, amount, nesting_budget)240 }241242 fn approve(243 &self,244 sender: T::CrossAccountId,245 spender: T::CrossAccountId,246 token: TokenId,247 amount: u128,248 ) -> DispatchResultWithPostInfo {249 ensure!(250 token == TokenId::default(),251 <Error<T>>::FungibleItemsHaveNoId252 );253254 with_weight(255 <Pallet<T>>::set_allowance(self, &sender, &spender, amount),256 <CommonWeights<T>>::approve(),257 )258 }259260 fn approve_from(261 &self,262 sender: T::CrossAccountId,263 from: T::CrossAccountId,264 to: T::CrossAccountId,265 token: TokenId,266 amount: u128,267 ) -> DispatchResultWithPostInfo {268 ensure!(269 token == TokenId::default(),270 <Error<T>>::FungibleItemsHaveNoId271 );272273 with_weight(274 <Pallet<T>>::set_allowance_from(self, &sender, &from, &to, amount),275 <CommonWeights<T>>::approve_from(),276 )277 }278279 fn transfer_from(280 &self,281 sender: T::CrossAccountId,282 from: T::CrossAccountId,283 to: T::CrossAccountId,284 token: TokenId,285 amount: u128,286 nesting_budget: &dyn Budget,287 ) -> DispatchResultWithPostInfo {288 ensure!(289 token == TokenId::default(),290 <Error<T>>::FungibleItemsHaveNoId291 );292293 <Pallet<T>>::transfer_from(self, &sender, &from, &to, amount, nesting_budget)294 }295296 fn burn_from(297 &self,298 sender: T::CrossAccountId,299 from: T::CrossAccountId,300 token: TokenId,301 amount: u128,302 nesting_budget: &dyn Budget,303 ) -> DispatchResultWithPostInfo {304 ensure!(305 token == TokenId::default(),306 <Error<T>>::FungibleItemsHaveNoId307 );308309 with_weight(310 <Pallet<T>>::burn_from(self, &sender, &from, amount, nesting_budget),311 <CommonWeights<T>>::burn_from(),312 )313 }314315 fn set_collection_properties(316 &self,317 sender: T::CrossAccountId,318 properties: Vec<Property>,319 ) -> DispatchResultWithPostInfo {320 let weight = <CommonWeights<T>>::set_collection_properties(properties.len() as u32);321322 with_weight(323 <Pallet<T>>::set_collection_properties(self, &sender, properties),324 weight,325 )326 }327328 fn delete_collection_properties(329 &self,330 sender: &T::CrossAccountId,331 property_keys: Vec<PropertyKey>,332 ) -> DispatchResultWithPostInfo {333 let weight = <CommonWeights<T>>::delete_collection_properties(property_keys.len() as u32);334335 with_weight(336 <Pallet<T>>::delete_collection_properties(self, sender, property_keys),337 weight,338 )339 }340341 fn set_token_properties(342 &self,343 _sender: T::CrossAccountId,344 _token_id: TokenId,345 _property: Vec<Property>,346 _nesting_budget: &dyn Budget,347 ) -> DispatchResultWithPostInfo {348 fail!(<Error<T>>::SettingPropertiesNotAllowed)349 }350351 fn set_token_property_permissions(352 &self,353 _sender: &T::CrossAccountId,354 _property_permissions: Vec<PropertyKeyPermission>,355 ) -> DispatchResultWithPostInfo {356 fail!(<Error<T>>::SettingPropertiesNotAllowed)357 }358359 fn delete_token_properties(360 &self,361 _sender: T::CrossAccountId,362 _token_id: TokenId,363 _property_keys: Vec<PropertyKey>,364 _nesting_budget: &dyn Budget,365 ) -> DispatchResultWithPostInfo {366 fail!(<Error<T>>::SettingPropertiesNotAllowed)367 }368369 fn get_token_properties_raw(370 &self,371 _token_id: TokenId,372 ) -> Option<up_data_structs::TokenProperties> {373 374 None375 }376377 fn set_token_properties_raw(&self, _token_id: TokenId, _map: up_data_structs::TokenProperties) {378 379 }380381 fn check_nesting(382 &self,383 _sender: <T>::CrossAccountId,384 _from: (CollectionId, TokenId),385 _under: TokenId,386 _nesting_budget: &dyn Budget,387 ) -> sp_runtime::DispatchResult {388 fail!(<Error<T>>::FungibleDisallowsNesting)389 }390391 fn nest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}392393 fn unnest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}394395 fn collection_tokens(&self) -> Vec<TokenId> {396 vec![TokenId::default()]397 }398399 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {400 if <Balance<T>>::get((self.id, account)) != 0 {401 vec![TokenId::default()]402 } else {403 vec![]404 }405 }406407 fn token_exists(&self, token: TokenId) -> bool {408 token == TokenId::default()409 }410411 fn last_token_id(&self) -> TokenId {412 TokenId::default()413 }414415 fn token_owner(&self, _token: TokenId) -> Result<T::CrossAccountId, TokenOwnerError> {416 Err(TokenOwnerError::MultipleOwners)417 }418419 fn check_token_indirect_owner(420 &self,421 _token: TokenId,422 _maybe_owner: &T::CrossAccountId,423 _nesting_budget: &dyn Budget,424 ) -> Result<bool, DispatchError> {425 Ok(false)426 }427428 429 fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId> {430 <Pallet<T>>::token_owners(self.id, token).unwrap_or_default()431 }432433 fn token_property(&self, _token_id: TokenId, _key: &PropertyKey) -> Option<PropertyValue> {434 None435 }436437 fn token_properties(438 &self,439 _token_id: TokenId,440 _keys: Option<Vec<PropertyKey>>,441 ) -> Vec<Property> {442 Vec::new()443 }444445 fn total_supply(&self) -> u32 {446 1447 }448449 fn account_balance(&self, account: T::CrossAccountId) -> u32 {450 if <Balance<T>>::get((self.id, account)) != 0 {451 1452 } else {453 0454 }455 }456457 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {458 if token != TokenId::default() {459 return 0;460 }461 <Balance<T>>::get((self.id, account))462 }463464 fn allowance(465 &self,466 sender: T::CrossAccountId,467 spender: T::CrossAccountId,468 token: TokenId,469 ) -> u128 {470 if token != TokenId::default() {471 return 0;472 }473 <Allowance<T>>::get((self.id, sender, spender))474 }475476 fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>> {477 None478 }479480 fn total_pieces(&self, token: TokenId) -> Option<u128> {481 if token != TokenId::default() {482 return None;483 }484 <TotalSupply<T>>::try_get(self.id).ok()485 }486487 fn set_allowance_for_all(488 &self,489 _owner: T::CrossAccountId,490 _operator: T::CrossAccountId,491 _approve: bool,492 ) -> DispatchResultWithPostInfo {493 fail!(<Error<T>>::SettingAllowanceForAllNotAllowed)494 }495496 fn allowance_for_all(&self, _owner: T::CrossAccountId, _operator: T::CrossAccountId) -> bool {497 false498 }499500 501 fn repair_item(&self, _token: TokenId) -> DispatchResultWithPostInfo {502 fail!(<Error<T>>::FungibleTokensAreAlwaysValid)503 }504}