From d8de1b3c39fb096e2c23e05ea35530ffc71d81c4 Mon Sep 17 00:00:00 2001 From: Daniel Shiposha Date: Thu, 12 Jan 2023 13:17:02 +0000 Subject: [PATCH] fix: bulk properties set --- --- a/pallets/common/src/erc.rs +++ b/pallets/common/src/erc.rs @@ -125,7 +125,7 @@ .map(eth::Property::try_into) .collect::>>()?; - >::set_collection_properties(self, &caller, properties) + >::set_collection_properties(self, &caller, properties.into_iter()) .map_err(dispatch_to_evm::) } @@ -158,7 +158,8 @@ }) .collect::>>()?; - >::delete_collection_properties(self, &caller, keys).map_err(dispatch_to_evm::) + >::delete_collection_properties(self, &caller, keys.into_iter()) + .map_err(dispatch_to_evm::) } /// Get collection property. --- a/pallets/common/src/lib.rs +++ b/pallets/common/src/lib.rs @@ -1198,6 +1198,51 @@ Ok(()) } + fn modify_collection_properties( + collection: &CollectionHandle, + sender: &T::CrossAccountId, + properties_updates: impl Iterator)>, + ) -> DispatchResult { + collection.check_is_owner_or_admin(sender)?; + + let mut stored_properties = >::get(collection.id); + + for (key, value) in properties_updates { + match value { + Some(value) => { + stored_properties + .try_set(key.clone(), value) + .map_err(>::from)?; + + Self::deposit_event(Event::CollectionPropertySet(collection.id, key)); + >::deposit_log( + erc::CollectionHelpersEvents::CollectionChanged { + collection_id: eth::collection_id_to_address(collection.id), + } + .to_log(T::ContractAddress::get()), + ); + } + None => { + stored_properties.remove(&key).map_err(>::from)?; + + Self::deposit_event(Event::CollectionPropertyDeleted(collection.id, key)); + >::deposit_log( + erc::CollectionHelpersEvents::CollectionChanged { + collection_id: eth::collection_id_to_address(collection.id), + } + .to_log(T::ContractAddress::get()), + ); + } + } + } + + >::mutate(collection.id, |properties| { + *properties = stored_properties; + }); + + Ok(()) + } + /// Set collection property. /// /// * `collection` - Collection handler. @@ -1208,23 +1253,7 @@ sender: &T::CrossAccountId, property: Property, ) -> DispatchResult { - collection.check_is_owner_or_admin(sender)?; - - CollectionProperties::::try_mutate(collection.id, |properties| { - let property = property.clone(); - properties.try_set(property.key, property.value) - }) - .map_err(>::from)?; - - Self::deposit_event(Event::CollectionPropertySet(collection.id, property.key)); - >::deposit_log( - erc::CollectionHelpersEvents::CollectionChanged { - collection_id: eth::collection_id_to_address(collection.id), - } - .to_log(T::ContractAddress::get()), - ); - - Ok(()) + Self::set_collection_properties(collection, sender, [property].into_iter()) } /// Set a scoped collection property, where the scope is a special prefix @@ -1274,13 +1303,13 @@ pub fn set_collection_properties( collection: &CollectionHandle, sender: &T::CrossAccountId, - properties: Vec, + properties: impl Iterator, ) -> DispatchResult { - for property in properties { - Self::set_collection_property(collection, sender, property)?; - } - - Ok(()) + Self::modify_collection_properties( + collection, + sender, + properties.map(|property| (property.key, Some(property.value))), + ) } /// Delete collection property. @@ -1293,25 +1322,7 @@ sender: &T::CrossAccountId, property_key: PropertyKey, ) -> DispatchResult { - collection.check_is_owner_or_admin(sender)?; - - CollectionProperties::::try_mutate(collection.id, |properties| { - properties.remove(&property_key) - }) - .map_err(>::from)?; - - Self::deposit_event(Event::CollectionPropertyDeleted( - collection.id, - property_key, - )); - >::deposit_log( - erc::CollectionHelpersEvents::CollectionChanged { - collection_id: eth::collection_id_to_address(collection.id), - } - .to_log(T::ContractAddress::get()), - ); - - Ok(()) + Self::delete_collection_properties(collection, sender, [property_key].into_iter()) } /// Delete collection properties. @@ -1323,13 +1334,9 @@ pub fn delete_collection_properties( collection: &CollectionHandle, sender: &T::CrossAccountId, - property_keys: Vec, + property_keys: impl Iterator, ) -> DispatchResult { - for key in property_keys { - Self::delete_collection_property(collection, sender, key)?; - } - - Ok(()) + Self::modify_collection_properties(collection, sender, property_keys.map(|key| (key, None))) } /// Set collection propetry permission without any checks. --- a/pallets/fungible/src/lib.rs +++ b/pallets/fungible/src/lib.rs @@ -266,7 +266,7 @@ sender: &T::CrossAccountId, properties: Vec, ) -> DispatchResult { - >::set_collection_properties(collection, sender, properties) + >::set_collection_properties(collection, sender, properties.into_iter()) } /// Delete properties of the collection, associated with the provided keys. @@ -275,7 +275,11 @@ sender: &T::CrossAccountId, property_keys: Vec, ) -> DispatchResult { - >::delete_collection_properties(collection, sender, property_keys) + >::delete_collection_properties( + collection, + sender, + property_keys.into_iter(), + ) } /// Checks if collection has tokens. Return `true` if it has. --- a/pallets/nonfungible/src/lib.rs +++ b/pallets/nonfungible/src/lib.rs @@ -590,7 +590,7 @@ collection: &NonfungibleHandle, sender: &T::CrossAccountId, token_id: TokenId, - properties: impl Iterator)>, + properties_updates: impl Iterator)>, is_token_create: bool, nesting_budget: &dyn Budget, ) -> DispatchResult { @@ -614,15 +614,16 @@ }) }; - for (key, value) in properties { - let permission = >::property_permissions(collection.id) + let mut stored_properties = >::get((collection.id, token_id)); + let permissions = >::property_permissions(collection.id); + + for (key, value) in properties_updates { + let permission = permissions .get(&key) .cloned() .unwrap_or_else(PropertyPermission::none); - let is_property_exists = TokenProperties::::get((collection.id, token_id)) - .get(&key) - .is_some(); + let is_property_exists = stored_properties.get(&key).is_some(); match permission { PropertyPermission { mutable: false, .. } if is_property_exists => { @@ -649,10 +650,9 @@ match value { Some(value) => { - >::try_mutate((collection.id, token_id), |properties| { - properties.try_set(key.clone(), value) - }) - .map_err(>::from)?; + stored_properties + .try_set(key.clone(), value) + .map_err(>::from)?; >::deposit_event(CommonEvent::TokenPropertySet( collection.id, @@ -661,10 +661,9 @@ )); } None => { - >::try_mutate((collection.id, token_id), |properties| { - properties.remove(&key) - }) - .map_err(>::from)?; + stored_properties + .remove(&key) + .map_err(>::from)?; >::deposit_event(CommonEvent::TokenPropertyDeleted( collection.id, @@ -683,6 +682,10 @@ ); } + >::mutate((collection.id, token_id), |properties| { + *properties = stored_properties; + }); + Ok(()) } @@ -784,7 +787,7 @@ sender: &T::CrossAccountId, properties: Vec, ) -> DispatchResult { - >::set_collection_properties(collection, sender, properties) + >::set_collection_properties(collection, sender, properties.into_iter()) } /// Remove properties from the collection @@ -793,7 +796,11 @@ sender: &T::CrossAccountId, property_keys: Vec, ) -> DispatchResult { - >::delete_collection_properties(collection, sender, property_keys) + >::delete_collection_properties( + collection, + sender, + property_keys.into_iter(), + ) } /// Set property permissions for the token. --- a/pallets/refungible/src/lib.rs +++ b/pallets/refungible/src/lib.rs @@ -520,7 +520,7 @@ collection: &RefungibleHandle, sender: &T::CrossAccountId, token_id: TokenId, - properties: impl Iterator)>, + properties_updates: impl Iterator)>, is_token_create: bool, nesting_budget: &dyn Budget, ) -> DispatchResult { @@ -544,15 +544,16 @@ Ok(is_bundle_owner) }; - for (key, value) in properties { - let permission = >::property_permissions(collection.id) + let mut stored_properties = >::get((collection.id, token_id)); + let permissions = >::property_permissions(collection.id); + + for (key, value) in properties_updates { + let permission = permissions .get(&key) .cloned() .unwrap_or_else(PropertyPermission::none); - let is_property_exists = TokenProperties::::get((collection.id, token_id)) - .get(&key) - .is_some(); + let is_property_exists = stored_properties.get(&key).is_some(); match permission { PropertyPermission { mutable: false, .. } if is_property_exists => { @@ -578,10 +579,9 @@ match value { Some(value) => { - >::try_mutate((collection.id, token_id), |properties| { - properties.try_set(key.clone(), value) - }) - .map_err(>::from)?; + stored_properties + .try_set(key.clone(), value) + .map_err(>::from)?; >::deposit_event(CommonEvent::TokenPropertySet( collection.id, @@ -590,10 +590,9 @@ )); } None => { - >::try_mutate((collection.id, token_id), |properties| { - properties.remove(&key) - }) - .map_err(>::from)?; + stored_properties + .remove(&key) + .map_err(>::from)?; >::deposit_event(CommonEvent::TokenPropertyDeleted( collection.id, @@ -612,6 +611,10 @@ ); } + >::mutate((collection.id, token_id), |properties| { + *properties = stored_properties; + }); + Ok(()) } @@ -1353,7 +1356,7 @@ sender: &T::CrossAccountId, properties: Vec, ) -> DispatchResult { - >::set_collection_properties(collection, sender, properties) + >::set_collection_properties(collection, sender, properties.into_iter()) } pub fn delete_collection_properties( @@ -1361,7 +1364,11 @@ sender: &T::CrossAccountId, property_keys: Vec, ) -> DispatchResult { - >::delete_collection_properties(collection, sender, property_keys) + >::delete_collection_properties( + collection, + sender, + property_keys.into_iter(), + ) } pub fn set_token_property_permissions( --- a/pallets/unique/src/eth/mod.rs +++ b/pallets/unique/src/eth/mod.rs @@ -33,7 +33,6 @@ }; use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult}; use pallet_evm_coder_substrate::{dispatch_to_evm, SubstrateRecorder, WithRecorder}; -use sp_std::vec; use up_data_structs::{ CollectionDescription, CollectionMode, CollectionName, CollectionTokenPrefix, CreateCollectionData, @@ -316,13 +315,14 @@ >::set_collection_properties( &collection, &caller, - vec![up_data_structs::Property { + [up_data_structs::Property { key: key::base_uri(), value: base_uri .into_bytes() .try_into() .map_err(|_| "base uri is too large")?, - }], + }] + .into_iter(), ) .map_err(dispatch_to_evm::)?; } -- gitstuff