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 create_item(129 &self,130 sender: T::CrossAccountId,131 to: T::CrossAccountId,132 data: up_data_structs::CreateItemData,133 nesting_budget: &dyn Budget,134 ) -> DispatchResultWithPostInfo {135 match data {136 up_data_structs::CreateItemData::Fungible(data) => with_weight(137 <Pallet<T>>::create_item(self, &sender, (to, data.value), nesting_budget),138 <CommonWeights<T>>::create_item(),139 ),140 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),141 }142 }143144 fn create_multiple_items(145 &self,146 sender: T::CrossAccountId,147 to: T::CrossAccountId,148 data: Vec<up_data_structs::CreateItemData>,149 nesting_budget: &dyn Budget,150 ) -> DispatchResultWithPostInfo {151 let mut sum: u128 = 0;152 for data in data {153 match data {154 up_data_structs::CreateItemData::Fungible(data) => {155 sum = sum156 .checked_add(data.value)157 .ok_or(ArithmeticError::Overflow)?;158 }159 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),160 }161 }162163 with_weight(164 <Pallet<T>>::create_item(self, &sender, (to, sum), nesting_budget),165 <CommonWeights<T>>::create_item(),166 )167 }168169 fn create_multiple_items_ex(170 &self,171 sender: <T>::CrossAccountId,172 data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,173 nesting_budget: &dyn Budget,174 ) -> DispatchResultWithPostInfo {175 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);176 let data = match data {177 up_data_structs::CreateItemExData::Fungible(f) => f,178 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),179 };180181 with_weight(182 <Pallet<T>>::create_multiple_items(self, &sender, data.into_inner(), nesting_budget),183 weight,184 )185 }186187 fn burn_item(188 &self,189 sender: T::CrossAccountId,190 token: TokenId,191 amount: u128,192 ) -> DispatchResultWithPostInfo {193 ensure!(194 token == TokenId::default(),195 <Error<T>>::FungibleItemsHaveNoId196 );197198 with_weight(199 <Pallet<T>>::burn(self, &sender, amount),200 <CommonWeights<T>>::burn_item(),201 )202 }203204 fn burn_item_recursively(205 &self,206 sender: T::CrossAccountId,207 token: TokenId,208 self_budget: &dyn Budget,209 _breadth_budget: &dyn Budget,210 ) -> DispatchResultWithPostInfo {211 212 ensure!(213 token == TokenId::default(),214 <Error<T>>::FungibleItemsHaveNoId215 );216 ensure!(self_budget.consume(), <StructureError<T>>::DepthLimit,);217218 with_weight(219 <Pallet<T>>::burn(self, &sender, <Balance<T>>::get((self.id, &sender))),220 <CommonWeights<T>>::burn_recursively_self_raw(),221 )222 }223224 fn transfer(225 &self,226 from: T::CrossAccountId,227 to: T::CrossAccountId,228 token: TokenId,229 amount: u128,230 nesting_budget: &dyn Budget,231 ) -> DispatchResultWithPostInfo {232 ensure!(233 token == TokenId::default(),234 <Error<T>>::FungibleItemsHaveNoId235 );236237 with_weight(238 <Pallet<T>>::transfer(self, &from, &to, amount, nesting_budget),239 <CommonWeights<T>>::transfer(),240 )241 }242243 fn approve(244 &self,245 sender: T::CrossAccountId,246 spender: T::CrossAccountId,247 token: TokenId,248 amount: u128,249 ) -> DispatchResultWithPostInfo {250 ensure!(251 token == TokenId::default(),252 <Error<T>>::FungibleItemsHaveNoId253 );254255 with_weight(256 <Pallet<T>>::set_allowance(self, &sender, &spender, amount),257 <CommonWeights<T>>::approve(),258 )259 }260261 fn approve_from(262 &self,263 sender: T::CrossAccountId,264 from: T::CrossAccountId,265 to: T::CrossAccountId,266 token: TokenId,267 amount: u128,268 ) -> DispatchResultWithPostInfo {269 ensure!(270 token == TokenId::default(),271 <Error<T>>::FungibleItemsHaveNoId272 );273274 with_weight(275 <Pallet<T>>::set_allowance_from(self, &sender, &from, &to, amount),276 <CommonWeights<T>>::approve_from(),277 )278 }279280 fn transfer_from(281 &self,282 sender: T::CrossAccountId,283 from: T::CrossAccountId,284 to: T::CrossAccountId,285 token: TokenId,286 amount: u128,287 nesting_budget: &dyn Budget,288 ) -> DispatchResultWithPostInfo {289 ensure!(290 token == TokenId::default(),291 <Error<T>>::FungibleItemsHaveNoId292 );293294 with_weight(295 <Pallet<T>>::transfer_from(self, &sender, &from, &to, amount, nesting_budget),296 <CommonWeights<T>>::transfer_from(),297 )298 }299300 fn burn_from(301 &self,302 sender: T::CrossAccountId,303 from: T::CrossAccountId,304 token: TokenId,305 amount: u128,306 nesting_budget: &dyn Budget,307 ) -> DispatchResultWithPostInfo {308 ensure!(309 token == TokenId::default(),310 <Error<T>>::FungibleItemsHaveNoId311 );312313 with_weight(314 <Pallet<T>>::burn_from(self, &sender, &from, amount, nesting_budget),315 <CommonWeights<T>>::burn_from(),316 )317 }318319 fn set_collection_properties(320 &self,321 sender: T::CrossAccountId,322 properties: Vec<Property>,323 ) -> DispatchResultWithPostInfo {324 let weight = <CommonWeights<T>>::set_collection_properties(properties.len() as u32);325326 with_weight(327 <Pallet<T>>::set_collection_properties(self, &sender, properties),328 weight,329 )330 }331332 fn delete_collection_properties(333 &self,334 sender: &T::CrossAccountId,335 property_keys: Vec<PropertyKey>,336 ) -> DispatchResultWithPostInfo {337 let weight = <CommonWeights<T>>::delete_collection_properties(property_keys.len() as u32);338339 with_weight(340 <Pallet<T>>::delete_collection_properties(self, sender, property_keys),341 weight,342 )343 }344345 fn set_token_properties(346 &self,347 _sender: T::CrossAccountId,348 _token_id: TokenId,349 _property: Vec<Property>,350 _nesting_budget: &dyn Budget,351 ) -> DispatchResultWithPostInfo {352 fail!(<Error<T>>::SettingPropertiesNotAllowed)353 }354355 fn set_token_property_permissions(356 &self,357 _sender: &T::CrossAccountId,358 _property_permissions: Vec<PropertyKeyPermission>,359 ) -> DispatchResultWithPostInfo {360 fail!(<Error<T>>::SettingPropertiesNotAllowed)361 }362363 fn delete_token_properties(364 &self,365 _sender: T::CrossAccountId,366 _token_id: TokenId,367 _property_keys: Vec<PropertyKey>,368 _nesting_budget: &dyn Budget,369 ) -> DispatchResultWithPostInfo {370 fail!(<Error<T>>::SettingPropertiesNotAllowed)371 }372373 fn check_nesting(374 &self,375 _sender: <T>::CrossAccountId,376 _from: (CollectionId, TokenId),377 _under: TokenId,378 _nesting_budget: &dyn Budget,379 ) -> sp_runtime::DispatchResult {380 fail!(<Error<T>>::FungibleDisallowsNesting)381 }382383 fn nest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}384385 fn unnest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}386387 fn collection_tokens(&self) -> Vec<TokenId> {388 vec![TokenId::default()]389 }390391 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {392 if <Balance<T>>::get((self.id, account)) != 0 {393 vec![TokenId::default()]394 } else {395 vec![]396 }397 }398399 fn token_exists(&self, token: TokenId) -> bool {400 token == TokenId::default()401 }402403 fn last_token_id(&self) -> TokenId {404 TokenId::default()405 }406407 fn token_owner(&self, _token: TokenId) -> Option<T::CrossAccountId> {408 None409 }410411 412 fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId> {413 <Pallet<T>>::token_owners(self.id, token).unwrap_or_default()414 }415416 fn token_property(&self, _token_id: TokenId, _key: &PropertyKey) -> Option<PropertyValue> {417 None418 }419420 fn token_properties(421 &self,422 _token_id: TokenId,423 _keys: Option<Vec<PropertyKey>>,424 ) -> Vec<Property> {425 Vec::new()426 }427428 fn total_supply(&self) -> u32 {429 1430 }431432 fn account_balance(&self, account: T::CrossAccountId) -> u32 {433 if <Balance<T>>::get((self.id, account)) != 0 {434 1435 } else {436 0437 }438 }439440 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {441 if token != TokenId::default() {442 return 0;443 }444 <Balance<T>>::get((self.id, account))445 }446447 fn allowance(448 &self,449 sender: T::CrossAccountId,450 spender: T::CrossAccountId,451 token: TokenId,452 ) -> u128 {453 if token != TokenId::default() {454 return 0;455 }456 <Allowance<T>>::get((self.id, sender, spender))457 }458459 fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>> {460 None461 }462463 fn total_pieces(&self, token: TokenId) -> Option<u128> {464 if token != TokenId::default() {465 return None;466 }467 <TotalSupply<T>>::try_get(self.id).ok()468 }469470 fn set_allowance_for_all(471 &self,472 _owner: T::CrossAccountId,473 _operator: T::CrossAccountId,474 _approve: bool,475 ) -> DispatchResultWithPostInfo {476 fail!(<Error<T>>::SettingAllowanceForAllNotAllowed)477 }478479 fn allowance_for_all(&self, _owner: T::CrossAccountId, _operator: T::CrossAccountId) -> bool {480 false481 }482483 484 fn repair_item(&self, _token: TokenId) -> DispatchResultWithPostInfo {485 fail!(<Error<T>>::FungibleTokensAreAlwaysValid)486 }487}