From aa3d2ae73e39126a2e097b34118a65b05e6da13c Mon Sep 17 00:00:00 2001 From: Daniel Shiposha Date: Wed, 04 May 2022 12:42:06 +0000 Subject: [PATCH] Add extrinsic: delete token property --- --- a/pallets/common/src/lib.rs +++ b/pallets/common/src/lib.rs @@ -294,6 +294,8 @@ TokenPropertySet(CollectionId, TokenId, Property), + TokenPropertyDeleted(CollectionId, TokenId, PropertyKey), + PropertyPermissionSet(CollectionId, PropertyKeyPermission), } @@ -738,10 +740,9 @@ ) -> DispatchResult { collection.check_is_owner_or_admin(sender)?; - CollectionProperties::::try_mutate( - collection.id, - |properties| properties.try_set_property(property.clone()) - )?; + CollectionProperties::::try_mutate(collection.id, |properties| { + properties.try_set_property(property.clone()) + })?; Self::deposit_event(Event::CollectionPropertySet(collection.id, property)); @@ -763,13 +764,16 @@ pub fn set_property_permission( collection: &CollectionHandle, sender: &T::CrossAccountId, - property_permission: PropertyKeyPermission + property_permission: PropertyKeyPermission, ) -> DispatchResult { collection.check_is_owner_or_admin(sender)?; let all_permissions = CollectionPropertyPermissions::::get(collection.id); let current_permission = all_permissions.get(&property_permission.key); - if matches![current_permission, Some(PropertyPermission::AdminConst | PropertyPermission::ItemOwnerConst)] { + if matches![ + current_permission, + Some(PropertyPermission::AdminConst | PropertyPermission::ItemOwnerConst) + ] { return Err(>::NoPermission.into()); } @@ -779,7 +783,10 @@ }) .map_err(|_| PropertiesError::PropertyLimitReached)?; - Self::deposit_event(Event::PropertyPermissionSet(collection.id, property_permission)); + Self::deposit_event(Event::PropertyPermissionSet( + collection.id, + property_permission, + )); Ok(()) } @@ -787,7 +794,7 @@ pub fn set_property_permissions( collection: &CollectionHandle, sender: &T::CrossAccountId, - property_permissions: Vec + property_permissions: Vec, ) -> DispatchResult { for prop_pemission in property_permissions { Self::set_property_permission(collection, sender, prop_pemission)?; @@ -950,6 +957,7 @@ fn burn_item() -> Weight; fn set_collection_properties(amount: u32) -> Weight; fn set_token_properties(amount: u32) -> Weight; + fn delete_token_properties(amount: u32) -> Weight; fn set_property_permissions(amount: u32) -> Weight; fn transfer() -> Weight; fn approve() -> Weight; @@ -996,6 +1004,12 @@ token_id: TokenId, property: Vec, ) -> DispatchResultWithPostInfo; + fn delete_token_properties( + &self, + sender: T::CrossAccountId, + token_id: TokenId, + property_keys: Vec, + ) -> DispatchResultWithPostInfo; fn set_property_permissions( &self, sender: &T::CrossAccountId, --- a/pallets/fungible/src/common.rs +++ b/pallets/fungible/src/common.rs @@ -21,7 +21,7 @@ use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight}; use sp_runtime::ArithmeticError; use sp_std::{vec::Vec, vec}; -use up_data_structs::{CustomDataLimit, Property, PropertyKeyPermission,}; +use up_data_structs::{CustomDataLimit, Property, PropertyKey, PropertyKeyPermission}; use crate::{ Allowance, Balance, Config, Error, FungibleHandle, Pallet, SelfWeightOf, weights::WeightInfo, @@ -58,6 +58,10 @@ >::set_token_properties(amount) } + fn delete_token_properties(amount: u32) -> Weight { + >::delete_token_properties(amount) + } + fn set_property_permissions(amount: u32) -> Weight { >::set_property_permissions(amount) } @@ -262,6 +266,15 @@ fail!(>::PropertiesNotAllowed) } + fn delete_token_properties( + &self, + _sender: T::CrossAccountId, + _token_id: TokenId, + _property_keys: Vec, + ) -> DispatchResultWithPostInfo { + fail!(>::PropertiesNotAllowed) + } + fn set_variable_metadata( &self, _sender: T::CrossAccountId, --- a/pallets/fungible/src/weights.rs +++ b/pallets/fungible/src/weights.rs @@ -37,6 +37,7 @@ fn burn_item() -> Weight; fn set_collection_properties(amount: u32) -> Weight; fn set_token_properties(amount: u32) -> Weight; + fn delete_token_properties(amount: u32) -> Weight; fn set_property_permissions(amount: u32) -> Weight; fn transfer() -> Weight; fn approve() -> Weight; @@ -73,17 +74,22 @@ .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn set_collection_properties(amount: u32) -> Weight { + fn set_collection_properties(_amount: u32) -> Weight { + // Error + 0 + } + + fn set_token_properties(_amount: u32) -> Weight { // Error 0 } - fn set_token_properties(amount: u32) -> Weight { + fn delete_token_properties(_amount: u32) -> Weight { // Error 0 } - fn set_property_permissions(amount: u32) -> Weight { + fn set_property_permissions(_amount: u32) -> Weight { // Error 0 } @@ -146,17 +152,22 @@ .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } - fn set_collection_properties(amount: u32) -> Weight { + fn set_collection_properties(_amount: u32) -> Weight { // Error 0 } - fn set_token_properties(amount: u32) -> Weight { + fn set_token_properties(_amount: u32) -> Weight { // Error 0 } - fn set_property_permissions(amount: u32) -> Weight { + fn delete_token_properties(_amount: u32) -> Weight { + // Error + 0 + } + + fn set_property_permissions(_amount: u32) -> Weight { // Error 0 } --- a/pallets/nonfungible/src/common.rs +++ b/pallets/nonfungible/src/common.rs @@ -18,7 +18,8 @@ use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, BoundedVec}; use up_data_structs::{ - TokenId, CustomDataLimit, CreateItemExData, CollectionId, budget::Budget, Property, PropertyKeyPermission, + TokenId, CustomDataLimit, CreateItemExData, CollectionId, budget::Budget, Property, + PropertyKey, PropertyKeyPermission, }; use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight}; use sp_runtime::DispatchError; @@ -58,6 +59,10 @@ >::set_token_properties(amount) } + fn delete_token_properties(amount: u32) -> Weight { + >::delete_token_properties(amount) + } + fn set_property_permissions(amount: u32) -> Weight { >::set_property_permissions(amount) } @@ -162,7 +167,7 @@ with_weight( >::set_collection_properties(self, &sender, properties), - weight + weight, ) } @@ -176,7 +181,21 @@ with_weight( >::set_token_properties(self, &sender, token_id, properties), - weight + weight, + ) + } + + fn delete_token_properties( + &self, + sender: T::CrossAccountId, + token_id: TokenId, + property_keys: Vec, + ) -> DispatchResultWithPostInfo { + let weight = >::delete_token_properties(property_keys.len() as u32); + + with_weight( + >::delete_token_properties(self, &sender, token_id, property_keys), + weight, ) } @@ -185,11 +204,12 @@ sender: &T::CrossAccountId, property_permissions: Vec, ) -> DispatchResultWithPostInfo { - let weight = >::set_property_permissions(property_permissions.len() as u32); + let weight = + >::set_property_permissions(property_permissions.len() as u32); with_weight( >::set_property_permissions(self, sender, property_permissions), - weight + weight, ) } --- a/pallets/nonfungible/src/lib.rs +++ b/pallets/nonfungible/src/lib.rs @@ -21,7 +21,7 @@ use up_data_structs::{ AccessMode, CollectionId, CustomDataLimit, TokenId, CreateCollectionData, CreateNftExData, mapping::TokenAddressMapping, NestingRule, budget::Budget, Property, PropertyPermission, - PropertyKeyPermission, + PropertyKey, PropertyKeyPermission, }; use pallet_evm::account::CrossAccountId; use pallet_common::{ @@ -261,8 +261,63 @@ token_id: TokenId, property: Property, ) -> DispatchResult { + Self::check_token_change_permission(collection, sender, token_id, &property.key)?; + + >::try_mutate((collection.id, token_id), |properties| { + properties.try_set_property(property.clone()) + })?; + + >::deposit_event(CommonEvent::TokenPropertySet( + collection.id, + token_id, + property, + )); + + Ok(()) + } + + pub fn set_token_properties( + collection: &NonfungibleHandle, + sender: &T::CrossAccountId, + token_id: TokenId, + properties: Vec, + ) -> DispatchResult { + for property in properties { + Self::set_token_property(collection, sender, token_id, property)?; + } + + Ok(()) + } + + pub fn delete_token_property( + collection: &NonfungibleHandle, + sender: &T::CrossAccountId, + token_id: TokenId, + property_key: PropertyKey, + ) -> DispatchResult { + Self::check_token_change_permission(collection, sender, token_id, &property_key)?; + + >::mutate((collection.id, token_id), |properties| { + properties.remove_property(&property_key); + }); + + >::deposit_event(CommonEvent::TokenPropertyDeleted( + collection.id, + token_id, + property_key, + )); + + Ok(()) + } + + fn check_token_change_permission( + collection: &NonfungibleHandle, + sender: &T::CrossAccountId, + token_id: TokenId, + property_key: &PropertyKey, + ) -> DispatchResult { let permission = >::property_permission(collection.id) - .get(&property.key) + .get(property_key) .map(|p| p.clone()) .unwrap_or(PropertyPermission::None); @@ -275,43 +330,29 @@ }; let is_property_exists = TokenProperties::::get((collection.id, token_id)) - .get_property(&property.key) + .get_property(property_key) .is_some(); match (permission, is_property_exists) { - (PropertyPermission::AdminConst, false) => { - collection.check_is_owner_or_admin(sender)? - } - (PropertyPermission::Admin, _) => collection.check_is_owner_or_admin(sender)?, - (PropertyPermission::ItemOwnerConst, false) => check_token_owner()?, - (PropertyPermission::ItemOwner, _) => check_token_owner()?, + (PropertyPermission::AdminConst, false) => collection.check_is_owner_or_admin(sender), + (PropertyPermission::Admin, _) => collection.check_is_owner_or_admin(sender), + (PropertyPermission::ItemOwnerConst, false) => check_token_owner(), + (PropertyPermission::ItemOwner, _) => check_token_owner(), (PropertyPermission::ItemOwnerOrAdmin, _) => { - check_token_owner().or(collection.check_is_owner_or_admin(sender))?; + check_token_owner().or(collection.check_is_owner_or_admin(sender)) } - _ => return Err(>::NoPermission.into()), + _ => Err(>::NoPermission.into()), } - - >::try_mutate((collection.id, token_id), |properties| { - properties.try_set_property(property.clone()) - })?; - - >::deposit_event(CommonEvent::TokenPropertySet( - collection.id, - token_id, - property, - )); - - Ok(()) } - pub fn set_token_properties( + pub fn delete_token_properties( collection: &NonfungibleHandle, sender: &T::CrossAccountId, token_id: TokenId, - properties: Vec, + property_keys: Vec, ) -> DispatchResult { - for property in properties { - Self::set_token_property(collection, sender, token_id, property)?; + for key in property_keys { + Self::delete_token_property(collection, sender, token_id, key)?; } Ok(()) @@ -328,13 +369,9 @@ pub fn set_property_permissions( collection: &CollectionHandle, sender: &T::CrossAccountId, - property_permissions: Vec + property_permissions: Vec, ) -> DispatchResult { - >::set_property_permissions( - collection, - sender, - property_permissions, - ) + >::set_property_permissions(collection, sender, property_permissions) } pub fn transfer( --- a/pallets/nonfungible/src/weights.rs +++ b/pallets/nonfungible/src/weights.rs @@ -38,6 +38,7 @@ fn burn_item() -> Weight; fn set_collection_properties(amount: u32) -> Weight; fn set_token_properties(amount: u32) -> Weight; + fn delete_token_properties(amount: u32) -> Weight; fn set_property_permissions(amount: u32) -> Weight; fn transfer() -> Weight; fn approve() -> Weight; @@ -104,6 +105,11 @@ (50_000_000 as Weight).saturating_mul(amount as Weight) } + fn delete_token_properties(amount: u32) -> Weight { + // TODO calculate appropriate weight + (50_000_000 as Weight).saturating_mul(amount as Weight) + } + fn set_property_permissions(amount: u32) -> Weight { // TODO calculate appropriate weight (50_000_000 as Weight).saturating_mul(amount as Weight) @@ -209,6 +215,11 @@ (50_000_000 as Weight).saturating_mul(amount as Weight) } + fn delete_token_properties(amount: u32) -> Weight { + // TODO calculate appropriate weight + (50_000_000 as Weight).saturating_mul(amount as Weight) + } + fn set_property_permissions(amount: u32) -> Weight { // TODO calculate appropriate weight (50_000_000 as Weight).saturating_mul(amount as Weight) --- a/pallets/refungible/src/common.rs +++ b/pallets/refungible/src/common.rs @@ -20,7 +20,7 @@ use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight, BoundedVec}; use up_data_structs::{ CollectionId, TokenId, CustomDataLimit, CreateItemExData, CreateRefungibleExData, - budget::Budget, Property, PropertyKeyPermission, + budget::Budget, Property, PropertyKey, PropertyKeyPermission, }; use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight}; use sp_runtime::DispatchError; @@ -74,6 +74,10 @@ >::set_token_properties(amount) } + fn delete_token_properties(amount: u32) -> Weight { + >::delete_token_properties(amount) + } + fn set_property_permissions(amount: u32) -> Weight { >::set_property_permissions(amount) } @@ -281,6 +285,15 @@ fail!(>::PropertiesNotAllowed) } + fn delete_token_properties( + &self, + _sender: T::CrossAccountId, + _token_id: TokenId, + _property_keys: Vec, + ) -> DispatchResultWithPostInfo { + fail!(>::PropertiesNotAllowed) + } + fn set_variable_metadata( &self, sender: T::CrossAccountId, --- a/pallets/refungible/src/weights.rs +++ b/pallets/refungible/src/weights.rs @@ -40,6 +40,7 @@ fn burn_item_fully() -> Weight; fn set_collection_properties(amount: u32) -> Weight; fn set_token_properties(amount: u32) -> Weight; + fn delete_token_properties(amount: u32) -> Weight; fn set_property_permissions(amount: u32) -> Weight; fn transfer_normal() -> Weight; fn transfer_creating() -> Weight; @@ -133,17 +134,22 @@ .saturating_add(T::DbWeight::get().writes(6 as Weight)) } - fn set_collection_properties(amount: u32) -> Weight { + fn set_collection_properties(_amount: u32) -> Weight { + // Error + 0 + } + + fn set_token_properties(_amount: u32) -> Weight { // Error 0 } - fn set_token_properties(amount: u32) -> Weight { + fn delete_token_properties(_amount: u32) -> Weight { // Error 0 } - fn set_property_permissions(amount: u32) -> Weight { + fn set_property_permissions(_amount: u32) -> Weight { // Error 0 } @@ -317,17 +323,22 @@ .saturating_add(RocksDbWeight::get().writes(6 as Weight)) } - fn set_collection_properties(amount: u32) -> Weight { + fn set_collection_properties(_amount: u32) -> Weight { // Error 0 } - fn set_token_properties(amount: u32) -> Weight { + fn set_token_properties(_amount: u32) -> Weight { // Error 0 } - fn set_property_permissions(amount: u32) -> Weight { + fn delete_token_properties(_amount: u32) -> Weight { + // Error + 0 + } + + fn set_property_permissions(_amount: u32) -> Weight { // Error 0 } --- a/pallets/unique/src/lib.rs +++ b/pallets/unique/src/lib.rs @@ -39,7 +39,7 @@ MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH, AccessMode, CreateItemData, CollectionLimits, CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission, CreateCollectionData, CustomDataLimit, - CreateItemExData, budget, CollectionField, Property, PropertyKeyPermission, + CreateItemExData, budget, CollectionField, Property, PropertyKey, PropertyKeyPermission, }; use pallet_evm::account::CrossAccountId; use pallet_common::{ @@ -723,6 +723,21 @@ dispatch_call::(collection_id, |d| d.set_token_properties(sender, token_id, properties)) } + #[weight = T::CommonWeightInfo::delete_token_properties(properties.len() as u32)] + #[transactional] + pub fn delete_token_properties( + origin, + collection_id: CollectionId, + token_id: TokenId, + properties: Vec + ) -> DispatchResultWithPostInfo { + ensure!(!properties.is_empty(), Error::::EmptyArgument); + + let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?); + + dispatch_call::(collection_id, |d| d.delete_token_properties(sender, token_id, properties)) + } + #[weight = T::CommonWeightInfo::set_property_permissions(property_permissions.len() as u32)] #[transactional] pub fn set_property_permissions( --- a/primitives/data-structs/src/lib.rs +++ b/primitives/data-structs/src/lib.rs @@ -720,6 +720,17 @@ Ok(()) } + pub fn remove_property(&mut self, key: &PropertyKey) { + let property = self.map.get(key); + + if let Some(value) = property { + let value_len = value.len() as u32; + + self.map.remove(key); + self.consumed_space -= value_len; + } + } + pub fn get_property(&self, key: &PropertyKey) -> Option<&PropertyValue> { self.map.get(key) } --- a/primitives/rpc/src/lib.rs +++ b/primitives/rpc/src/lib.rs @@ -16,9 +16,7 @@ #![cfg_attr(not(feature = "std"), no_std)] -use up_data_structs::{ - CollectionId, TokenId, RpcCollection, CollectionStats, CollectionLimits, Property, -}; +use up_data_structs::{CollectionId, TokenId, RpcCollection, CollectionStats, CollectionLimits}; use sp_std::vec::Vec; use codec::Decode; use sp_runtime::DispatchError; --- a/runtime/common/src/weights.rs +++ b/runtime/common/src/weights.rs @@ -62,6 +62,10 @@ dispatch_weight::() + max_weight_of!(set_token_properties(amount)) } + fn delete_token_properties(amount: u32) -> Weight { + dispatch_weight::() + max_weight_of!(delete_token_properties(amount)) + } + fn set_property_permissions(amount: u32) -> Weight { dispatch_weight::() + max_weight_of!(set_property_permissions(amount)) } -- gitstuff