difftreelog
refactor use modify_token_properties
in: master
4 files changed
pallets/nonfungible/src/common.rsdiffbeforeafterboth229 self,229 self,230 &sender,230 &sender,231 token_id,231 token_id,232 properties,232 properties.into_iter(),233 false,233 false,234 nesting_budget,234 nesting_budget,235 ),235 ),251 self,251 self,252 &sender,252 &sender,253 token_id,253 token_id,254 property_keys,254 property_keys.into_iter(),255 nesting_budget,255 nesting_budget,256 ),256 ),257 weight,257 weight,pallets/nonfungible/src/erc.rsdiffbeforeafterboth373738use crate::{38use crate::{39 AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData, TokensMinted,39 AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData, TokensMinted,40 SelfWeightOf, weights::WeightInfo, TokenProperties, property_guard::*,40 SelfWeightOf, weights::WeightInfo, TokenProperties,41};41};424243#[solidity_interface(name = "TokenProperties")]43#[solidity_interface(name = "TokenProperties")]82 .map_err(|_| "key too long")?;82 .map_err(|_| "key too long")?;83 let value = value.try_into().map_err(|_| "value too long")?;83 let value = value.try_into().map_err(|_| "value too long")?;848485 let is_token_create = false;86 let nesting_budget = self85 let nesting_budget = self87 .recorder86 .recorder88 .weight_calls_budget(<StructureWeight<T>>::find_parent());87 .weight_calls_budget(<StructureWeight<T>>::find_parent());8990 let mut guard = PropertyGuard::new(PropertyGuardData {91 sender: &caller,92 collection: self,93 token_id: TokenId(token_id),94 is_token_create,95 nesting_budget: &nesting_budget,96 });978898 <Pallet<T>>::set_token_property(Property { key, value }, &mut guard)89 <Pallet<T>>::set_token_property(90 self,91 &caller,92 TokenId(token_id),93 Property { key, value },94 &nesting_budget,95 )99 .map_err(dispatch_to_evm::<T>)96 .map_err(dispatch_to_evm::<T>)100 }97 }106 .try_into()103 .try_into()107 .map_err(|_| "key too long")?;104 .map_err(|_| "key too long")?;108105109 let is_token_create = false;110 let nesting_budget = self106 let nesting_budget = self111 .recorder107 .recorder112 .weight_calls_budget(<StructureWeight<T>>::find_parent());108 .weight_calls_budget(<StructureWeight<T>>::find_parent());113114 let mut guard = PropertyGuard::new(PropertyGuardData {115 sender: &caller,116 collection: self,117 token_id: TokenId(token_id),118 is_token_create,119 nesting_budget: &nesting_budget,120 });121109122 <Pallet<T>>::delete_token_property(key, &mut guard).map_err(dispatch_to_evm::<T>)110 <Pallet<T>>::delete_token_property(self, &caller, TokenId(token_id), key, &nesting_budget)111 .map_err(dispatch_to_evm::<T>)123 }112 }124113pallets/nonfungible/src/lib.rsdiffbeforeafterboth28use up_data_structs::{28use up_data_structs::{29 AccessMode, CollectionId, CustomDataLimit, TokenId, CreateCollectionData, CreateNftExData,29 AccessMode, CollectionId, CustomDataLimit, TokenId, CreateCollectionData, CreateNftExData,30 mapping::TokenAddressMapping, budget::Budget, Property, PropertyPermission, PropertyKey,30 mapping::TokenAddressMapping, budget::Budget, Property, PropertyPermission, PropertyKey,31 PropertyKeyPermission, Properties, PropertyScope, TrySetProperty, TokenChild, AuxPropertyValue,31 PropertyValue, PropertyKeyPermission, Properties, PropertyScope, TrySetProperty, TokenChild,32 AuxPropertyValue,32};33};33use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};34use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};52pub mod erc;53pub mod erc;53pub mod weights;54pub mod weights;5455mod property_guard;5657use property_guard::*;585559pub type CreateItemData<T> = CreateNftExData<<T as pallet_evm::account::Config>::CrossAccountId>;56pub type CreateItemData<T> = CreateNftExData<<T as pallet_evm::account::Config>::CrossAccountId>;60pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;57pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;89 NonfungibleItemsHaveNoAmount,86 NonfungibleItemsHaveNoAmount,90 /// Unable to burn NFT with children87 /// Unable to burn NFT with children91 CantBurnNftWithChildren,88 CantBurnNftWithChildren,89 /// Unable to create an empty property90 UnableToCreateEmptyProperty,92 }91 }939294 #[pallet::config]93 #[pallet::config]488 })487 })489 }488 }490491 pub fn set_token_property(492 property: Property,493 guard: &mut PropertyGuard<'_, T>,494 ) -> DispatchResult {495 Self::check_token_change_permission(&property.key, guard)?;496497 <TokenProperties<T>>::try_mutate((guard.collection.id, guard.token_id), |properties| {498 let property = property.clone();499 properties.try_set(property.key, property.value)500 })501 .map_err(<CommonError<T>>::from)?;502503 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertySet(504 guard.collection.id,505 guard.token_id,506 property.key,507 ));508509 Ok(())510 }511489512 #[transactional]490 #[transactional]513 pub fn set_token_properties(491 fn modify_token_properties(514 collection: &NonfungibleHandle<T>,492 collection: &NonfungibleHandle<T>,515 sender: &T::CrossAccountId,493 sender: &T::CrossAccountId,516 token_id: TokenId,494 token_id: TokenId,517 properties: Vec<Property>,495 properties: impl Iterator<Item = (PropertyKey, Option<PropertyValue>)>,518 is_token_create: bool,496 is_token_create: bool,519 nesting_budget: &dyn Budget,497 nesting_budget: &dyn Budget,520 ) -> DispatchResult {498 ) -> DispatchResult {521 let mut guard = PropertyGuard::new(PropertyGuardData {499 let mut collection_admin_result = None;522 sender,523 collection,524 token_id,525 is_token_create,526 nesting_budget,527 });528529 for property in properties {530 Self::set_token_property(property, &mut guard)?;531 }532533 Ok(())534 }535536 pub fn delete_token_property(537 property_key: PropertyKey,538 guard: &mut PropertyGuard<'_, T>,500 let mut token_owner_result = None;539 ) -> DispatchResult {501502 let mut check_collection_admin = || {503 *collection_admin_result540 Self::check_token_change_permission(&property_key, guard)?;504 .get_or_insert_with(|| collection.check_is_owner_or_admin(sender))541505 };506507 let mut check_token_owner = || {508 *token_owner_result.get_or_insert_with(|| {542 <TokenProperties<T>>::try_mutate((guard.collection.id, guard.token_id), |properties| {509 let is_owned = <PalletStructure<T>>::check_indirectly_owned(510 sender.clone(),511 collection.id,512 token_id,513 None,514 nesting_budget,515 )?;516517 if is_owned {518 Ok(())519 } else {543 properties.remove(&property_key)520 Err(<CommonError<T>>::NoPermission.into())544 })521 }522 })545 .map_err(<CommonError<T>>::from)?;523 };546547 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertyDeleted(548 guard.collection.id,549 guard.token_id,550 property_key,551 ));552553 Ok(())554 }555524556 fn check_token_change_permission(525 for (key, value) in properties {557 property_key: &PropertyKey,558 guard: &mut PropertyGuard<'_, T>,559 ) -> DispatchResult {560 let permission = <PalletCommon<T>>::property_permissions(guard.collection.id)526 let permission = <PalletCommon<T>>::property_permissions(collection.id)561 .get(property_key)527 .get(&key)562 .cloned()528 .cloned()563 .unwrap_or_else(PropertyPermission::none);529 .unwrap_or_else(PropertyPermission::none);564530565 let is_property_exists = TokenProperties::<T>::get((guard.collection.id, guard.token_id))531 let is_property_exists = TokenProperties::<T>::get((collection.id, token_id))566 .get(property_key)532 .get(&key)567 .is_some();533 .is_some();568534569 match permission {535 match permission {570 PropertyPermission { mutable: false, .. } if is_property_exists => {536 PropertyPermission { mutable: false, .. } if is_property_exists => {571 Err(<CommonError<T>>::NoPermission.into())537 return Err(<CommonError<T>>::NoPermission.into());572 }538 }573539574 PropertyPermission {540 PropertyPermission {577 ..543 ..578 } => {544 } => {579 //TODO: investigate threats during public minting.545 //TODO: investigate threats during public minting.580 if guard.is_token_create && (collection_admin || token_owner) {546 if is_token_create && (collection_admin || token_owner) {547 if value.is_some() {581 return Ok(());548 return Ok(());582 }549 } else {550 return Err(<Error<T>>::UnableToCreateEmptyProperty.into());551 }552 }583553584 let mut check_result = Err(<CommonError<T>>::NoPermission.into());554 let mut check_result = Err(<CommonError<T>>::NoPermission.into());585555586 if collection_admin {556 if collection_admin {587 check_result = guard.check_collection_admin();557 check_result = check_collection_admin();588 }558 }589559590 if token_owner {560 if token_owner {591 check_result.or_else(|_| guard.check_token_owner())561 check_result = check_result.or_else(|_| check_token_owner())592 } else {562 }593 check_result563594 }564 check_result?;595 }565 }596 }566 }567568 match value {569 Some(value) => {570 <TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {571 properties.try_set(key.clone(), value)572 })573 .map_err(<CommonError<T>>::from)?;574575 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertySet(576 collection.id,577 token_id,578 key,579 ));580 }581 None => {582 <TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {583 properties.remove(&key)584 })585 .map_err(<CommonError<T>>::from)?;586587 <PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertyDeleted(588 collection.id,589 token_id,590 key,591 ));592 }593 }597 }594 }595596 Ok(())597 }598599 #[transactional]600 pub fn set_token_properties(601 collection: &NonfungibleHandle<T>,602 sender: &T::CrossAccountId,603 token_id: TokenId,604 properties: impl Iterator<Item = Property>,605 is_token_create: bool,606 nesting_budget: &dyn Budget,607 ) -> DispatchResult {608 Self::modify_token_properties(609 collection,610 sender,611 token_id,612 properties.map(|p| (p.key, Some(p.value))),613 is_token_create,614 nesting_budget,615 )616 }617618 pub fn set_token_property(619 collection: &NonfungibleHandle<T>,620 sender: &T::CrossAccountId,621 token_id: TokenId,622 property: Property,623 nesting_budget: &dyn Budget,624 ) -> DispatchResult {625 let is_token_create = false;626627 Self::set_token_properties(628 collection,629 sender,630 token_id,631 [property].into_iter(),632 is_token_create,633 nesting_budget,634 )635 }598636599 #[transactional]637 #[transactional]600 pub fn delete_token_properties(638 pub fn delete_token_properties(601 collection: &NonfungibleHandle<T>,639 collection: &NonfungibleHandle<T>,602 sender: &T::CrossAccountId,640 sender: &T::CrossAccountId,603 token_id: TokenId,641 token_id: TokenId,604 property_keys: Vec<PropertyKey>,642 property_keys: impl Iterator<Item = PropertyKey>,605 nesting_budget: &dyn Budget,643 nesting_budget: &dyn Budget,606 ) -> DispatchResult {644 ) -> DispatchResult {607 let is_token_create = false;645 let is_token_create = false;608646609 let mut guard = PropertyGuard::new(PropertyGuardData {647 Self::modify_token_properties(648 collection,610 sender,649 sender,611 collection,612 token_id,650 token_id,651 property_keys.into_iter().map(|key| (key, None)),613 is_token_create,652 is_token_create,614 nesting_budget,653 nesting_budget,615 });654 )616617 for key in property_keys {618 Self::delete_token_property(key, &mut guard)?;619 }620621 Ok(())622 }655 }656657 pub fn delete_token_property(658 collection: &NonfungibleHandle<T>,659 sender: &T::CrossAccountId,660 token_id: TokenId,661 property_key: PropertyKey,662 nesting_budget: &dyn Budget,663 ) -> DispatchResult {664 Self::delete_token_properties(665 collection,666 sender,667 token_id,668 [property_key].into_iter(),669 nesting_budget,670 )671 }623672624 pub fn set_collection_properties(673 pub fn set_collection_properties(625 collection: &NonfungibleHandle<T>,674 collection: &NonfungibleHandle<T>,829 collection,878 collection,830 sender,879 sender,831 TokenId(token),880 TokenId(token),832 data.properties.clone().into_inner(),881 data.properties.clone().into_iter(),833 true,882 true,834 nesting_budget,883 nesting_budget,835 ) {884 ) {pallets/nonfungible/src/property_guard.rsdiffbeforeafterbothno changes