1234567891011121314151617use core::marker::PhantomData;1819use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, traits::Get};20use up_data_structs::{TokenId, CollectionId, CreateItemExData, budget::Budget, CreateItemData};21use pallet_common::{22 CommonCollectionOperations, CommonWeightInfo, RefungibleExtensions, with_weight,23 weights::WeightInfo as _,24};25use pallet_structure::Error as StructureError;26use sp_runtime::ArithmeticError;27use sp_std::{vec::Vec, vec};28use up_data_structs::{Property, PropertyKey, PropertyValue, PropertyKeyPermission};2930use crate::{31 Allowance, TotalSupply, Balance, Config, Error, FungibleHandle, Pallet, SelfWeightOf,32 weights::WeightInfo,33};3435pub struct CommonWeights<T: Config>(PhantomData<T>);36impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {37 fn create_item() -> Weight {38 <SelfWeightOf<T>>::create_item()39 }4041 fn create_multiple_items(_data: &[CreateItemData]) -> Weight {42 43 Self::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()84 }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 <SelfWeightOf<T>>::transfer_from()96 }9798 fn burn_from() -> Weight {99 <SelfWeightOf<T>>::burn_from()100 }101102 fn burn_recursively_self_raw() -> Weight {103 104 Self::burn_item() + T::DbWeight::get().reads(1)105 }106107 fn burn_recursively_breadth_raw(_amount: u32) -> Weight {108 109 Weight::zero()110 }111112 fn token_owner() -> Weight {113 Weight::zero()114 }115116 fn set_allowance_for_all() -> Weight {117 Weight::zero()118 }119120 fn force_repair_item() -> Weight {121 Weight::zero()122 }123}124125126127impl<T: Config> CommonCollectionOperations<T> for FungibleHandle<T> {128 fn mode(&self) -> up_data_structs::CollectionMode {129 self.0.mode()130 }131132 fn create_item(133 &self,134 sender: T::CrossAccountId,135 to: T::CrossAccountId,136 data: up_data_structs::CreateItemData,137 nesting_budget: &dyn Budget,138 ) -> DispatchResultWithPostInfo {139 match data {140 up_data_structs::CreateItemData::Fungible(data) => with_weight(141 <Pallet<T>>::create_item(self, &sender, (to, data.value), nesting_budget),142 <CommonWeights<T>>::create_item(),143 ),144 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),145 }146 }147148 fn create_multiple_items(149 &self,150 sender: T::CrossAccountId,151 to: T::CrossAccountId,152 data: Vec<up_data_structs::CreateItemData>,153 nesting_budget: &dyn Budget,154 ) -> DispatchResultWithPostInfo {155 let mut sum: u128 = 0;156 for data in data {157 match data {158 up_data_structs::CreateItemData::Fungible(data) => {159 sum = sum160 .checked_add(data.value)161 .ok_or(ArithmeticError::Overflow)?;162 }163 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),164 }165 }166167 with_weight(168 <Pallet<T>>::create_item(self, &sender, (to, sum), nesting_budget),169 <CommonWeights<T>>::create_item(),170 )171 }172173 fn create_multiple_items_ex(174 &self,175 sender: <T>::CrossAccountId,176 data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,177 nesting_budget: &dyn Budget,178 ) -> DispatchResultWithPostInfo {179 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);180 let data = match data {181 up_data_structs::CreateItemExData::Fungible(f) => f,182 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),183 };184185 with_weight(186 <Pallet<T>>::create_multiple_items(self, &sender, data.into_inner(), nesting_budget),187 weight,188 )189 }190191 fn burn_item(192 &self,193 sender: T::CrossAccountId,194 token: TokenId,195 amount: u128,196 ) -> DispatchResultWithPostInfo {197 ensure!(198 token == TokenId::default(),199 <Error<T>>::FungibleItemsHaveNoId200 );201202 with_weight(203 <Pallet<T>>::burn(self, &sender, amount),204 <CommonWeights<T>>::burn_item(),205 )206 }207208 fn burn_item_recursively(209 &self,210 sender: T::CrossAccountId,211 token: TokenId,212 self_budget: &dyn Budget,213 _breadth_budget: &dyn Budget,214 ) -> DispatchResultWithPostInfo {215 216 ensure!(217 token == TokenId::default(),218 <Error<T>>::FungibleItemsHaveNoId219 );220 ensure!(self_budget.consume(), <StructureError<T>>::DepthLimit,);221222 with_weight(223 <Pallet<T>>::burn(self, &sender, <Balance<T>>::get((self.id, &sender))),224 <CommonWeights<T>>::burn_recursively_self_raw(),225 )226 }227228 fn transfer(229 &self,230 from: T::CrossAccountId,231 to: T::CrossAccountId,232 token: TokenId,233 amount: u128,234 nesting_budget: &dyn Budget,235 ) -> DispatchResultWithPostInfo {236 ensure!(237 token == TokenId::default(),238 <Error<T>>::FungibleItemsHaveNoId239 );240241 with_weight(242 <Pallet<T>>::transfer(self, &from, &to, amount, nesting_budget),243 <CommonWeights<T>>::transfer(),244 )245 }246247 fn approve(248 &self,249 sender: T::CrossAccountId,250 spender: T::CrossAccountId,251 token: TokenId,252 amount: u128,253 ) -> DispatchResultWithPostInfo {254 ensure!(255 token == TokenId::default(),256 <Error<T>>::FungibleItemsHaveNoId257 );258259 with_weight(260 <Pallet<T>>::set_allowance(self, &sender, &spender, amount),261 <CommonWeights<T>>::approve(),262 )263 }264265 fn approve_from(266 &self,267 sender: T::CrossAccountId,268 from: T::CrossAccountId,269 to: T::CrossAccountId,270 token: TokenId,271 amount: u128,272 ) -> DispatchResultWithPostInfo {273 ensure!(274 token == TokenId::default(),275 <Error<T>>::FungibleItemsHaveNoId276 );277278 with_weight(279 <Pallet<T>>::set_allowance_from(self, &sender, &from, &to, amount),280 <CommonWeights<T>>::approve_from(),281 )282 }283284 fn transfer_from(285 &self,286 sender: T::CrossAccountId,287 from: T::CrossAccountId,288 to: T::CrossAccountId,289 token: TokenId,290 amount: u128,291 nesting_budget: &dyn Budget,292 ) -> DispatchResultWithPostInfo {293 ensure!(294 token == TokenId::default(),295 <Error<T>>::FungibleItemsHaveNoId296 );297298 with_weight(299 <Pallet<T>>::transfer_from(self, &sender, &from, &to, amount, nesting_budget),300 <CommonWeights<T>>::transfer_from(),301 )302 }303304 fn burn_from(305 &self,306 sender: T::CrossAccountId,307 from: T::CrossAccountId,308 token: TokenId,309 amount: u128,310 nesting_budget: &dyn Budget,311 ) -> DispatchResultWithPostInfo {312 ensure!(313 token == TokenId::default(),314 <Error<T>>::FungibleItemsHaveNoId315 );316317 with_weight(318 <Pallet<T>>::burn_from(self, &sender, &from, amount, nesting_budget),319 <CommonWeights<T>>::burn_from(),320 )321 }322323 fn set_collection_properties(324 &self,325 sender: T::CrossAccountId,326 properties: Vec<Property>,327 ) -> DispatchResultWithPostInfo {328 let weight = <CommonWeights<T>>::set_collection_properties(properties.len() as u32);329330 with_weight(331 <Pallet<T>>::set_collection_properties(self, &sender, properties),332 weight,333 )334 }335336 fn delete_collection_properties(337 &self,338 sender: &T::CrossAccountId,339 property_keys: Vec<PropertyKey>,340 ) -> DispatchResultWithPostInfo {341 let weight = <CommonWeights<T>>::delete_collection_properties(property_keys.len() as u32);342343 with_weight(344 <Pallet<T>>::delete_collection_properties(self, sender, property_keys),345 weight,346 )347 }348349 fn set_token_properties(350 &self,351 _sender: T::CrossAccountId,352 _token_id: TokenId,353 _property: Vec<Property>,354 _nesting_budget: &dyn Budget,355 ) -> DispatchResultWithPostInfo {356 fail!(<Error<T>>::SettingPropertiesNotAllowed)357 }358359 fn set_token_property_permissions(360 &self,361 _sender: &T::CrossAccountId,362 _property_permissions: Vec<PropertyKeyPermission>,363 ) -> DispatchResultWithPostInfo {364 fail!(<Error<T>>::SettingPropertiesNotAllowed)365 }366367 fn delete_token_properties(368 &self,369 _sender: T::CrossAccountId,370 _token_id: TokenId,371 _property_keys: Vec<PropertyKey>,372 _nesting_budget: &dyn Budget,373 ) -> DispatchResultWithPostInfo {374 fail!(<Error<T>>::SettingPropertiesNotAllowed)375 }376377 fn check_nesting(378 &self,379 _sender: <T>::CrossAccountId,380 _from: (CollectionId, TokenId),381 _under: TokenId,382 _nesting_budget: &dyn Budget,383 ) -> sp_runtime::DispatchResult {384 fail!(<Error<T>>::FungibleDisallowsNesting)385 }386387 fn nest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}388389 fn unnest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}390391 fn collection_tokens(&self) -> Vec<TokenId> {392 vec![TokenId::default()]393 }394395 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {396 if <Balance<T>>::get((self.id, account)) != 0 {397 vec![TokenId::default()]398 } else {399 vec![]400 }401 }402403 fn token_exists(&self, token: TokenId) -> bool {404 token == TokenId::default()405 }406407 fn last_token_id(&self) -> TokenId {408 TokenId::default()409 }410411 fn token_owner(&self, _token: TokenId) -> Option<T::CrossAccountId> {412 None413 }414415 416 fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId> {417 <Pallet<T>>::token_owners(self.id, token).unwrap_or_default()418 }419420 fn token_property(&self, _token_id: TokenId, _key: &PropertyKey) -> Option<PropertyValue> {421 None422 }423424 fn token_properties(425 &self,426 _token_id: TokenId,427 _keys: Option<Vec<PropertyKey>>,428 ) -> Vec<Property> {429 Vec::new()430 }431432 fn total_supply(&self) -> u32 {433 1434 }435436 fn account_balance(&self, account: T::CrossAccountId) -> u32 {437 if <Balance<T>>::get((self.id, account)) != 0 {438 1439 } else {440 0441 }442 }443444 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {445 if token != TokenId::default() {446 return 0;447 }448 <Balance<T>>::get((self.id, account))449 }450451 fn allowance(452 &self,453 sender: T::CrossAccountId,454 spender: T::CrossAccountId,455 token: TokenId,456 ) -> u128 {457 if token != TokenId::default() {458 return 0;459 }460 <Allowance<T>>::get((self.id, sender, spender))461 }462463 fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>> {464 None465 }466467 fn total_pieces(&self, token: TokenId) -> Option<u128> {468 if token != TokenId::default() {469 return None;470 }471 <TotalSupply<T>>::try_get(self.id).ok()472 }473474 fn set_allowance_for_all(475 &self,476 _owner: T::CrossAccountId,477 _operator: T::CrossAccountId,478 _approve: bool,479 ) -> DispatchResultWithPostInfo {480 fail!(<Error<T>>::SettingAllowanceForAllNotAllowed)481 }482483 fn allowance_for_all(&self, _owner: T::CrossAccountId, _operator: T::CrossAccountId) -> bool {484 false485 }486487 488 fn repair_item(&self, _token: TokenId) -> DispatchResultWithPostInfo {489 fail!(<Error<T>>::FungibleTokensAreAlwaysValid)490 }491}