git.delta.rocks / unique-network / refs/commits / 5c5d937f9f7f

difftreelog

refactor iterate rmrk props, add rmrk proxy set_propertty

Daniel Shiposha2022-05-25parent: #aab4f30.patch.diff
in: master

5 files changed

modifiedpallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth
24use pallet_common::{Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations};24use pallet_common::{Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations};
25use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle, TokenData};25use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle, TokenData};
26use pallet_evm::account::CrossAccountId;26use pallet_evm::account::CrossAccountId;
27use core::convert::AsRef;
2728
28pub use pallet::*;29pub use pallet::*;
2930
85 owner: T::AccountId,86 owner: T::AccountId,
86 nft_id: RmrkNftId,87 nft_id: RmrkNftId,
87 },88 },
89 PropertySet {
90 collection_id: RmrkCollectionId,
91 maybe_nft_id: Option<RmrkNftId>,
92 key: RmrkKeyString,
93 value: RmrkValueString,
94 },
88 }95 }
8996
90 #[pallet::error]97 #[pallet::error]
291 collection_id: RmrkCollectionId,298 collection_id: RmrkCollectionId,
292 nft_id: RmrkNftId,299 nft_id: RmrkNftId,
293 ) -> DispatchResult {300 ) -> DispatchResult {
294 let sender = ensure_signed(origin.clone())?;301 let sender = ensure_signed(origin)?;
295 let cross_sender = T::CrossAccountId::from_sub(sender.clone());302 let cross_sender = T::CrossAccountId::from_sub(sender.clone());
296303
297 Self::destroy_nft(304 Self::destroy_nft(
306 Ok(())313 Ok(())
307 }314 }
315
316 #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
317 #[transactional]
318 pub fn set_property(
319 origin: OriginFor<T>,
320 #[pallet::compact] rmrk_collection_id: RmrkCollectionId,
321 maybe_nft_id: Option<RmrkNftId>,
322 key: RmrkKeyString,
323 value: RmrkValueString,
324 ) -> DispatchResult {
325 let sender = ensure_signed(origin)?;
326 let sender = T::CrossAccountId::from_sub(sender);
327
328 let collection_id: CollectionId = rmrk_collection_id.into();
329
330 match maybe_nft_id {
331 Some(nft_id) => {
332 let token_id: TokenId = nft_id.into();
333
334 Self::ensure_nft_owner(collection_id, token_id, &sender)?;
335 Self::ensure_nft_type(collection_id, token_id, NftType::Regular)?;
336
337 <PalletNft<T>>::set_scoped_token_property(
338 collection_id,
339 token_id,
340 PropertyScope::Rmrk,
341 Self::rmrk_property(UserProperty(key.as_slice()), &value)?
342 )?;
343 },
344 None => {
345 let collection = Self::get_typed_nft_collection(
346 collection_id,
347 misc::CollectionType::Regular
348 )?;
349
350 Self::check_collection_owner(&collection, &sender)?;
351
352 <PalletCommon<T>>::set_scoped_collection_property(
353 collection_id,
354 PropertyScope::Rmrk,
355 Self::rmrk_property(UserProperty(key.as_slice()), &value)?
356 )?;
357 }
358 }
359
360 Self::deposit_event(
361 Event::PropertySet {
362 collection_id: rmrk_collection_id,
363 maybe_nft_id,
364 key,
365 value
366 }
367 );
368
369 Ok(())
370 }
308 }371 }
309}372}
310373
477540
478 pub fn ensure_nft_type(collection_id: CollectionId, token_id: TokenId, nft_type: NftType) -> DispatchResult {541 pub fn ensure_nft_type(collection_id: CollectionId, token_id: TokenId, nft_type: NftType) -> DispatchResult {
479 let actual_type = Self::get_nft_type(collection_id, token_id)?;542 let actual_type = Self::get_nft_type(collection_id, token_id)?;
480 ensure!(actual_type == nft_type, <CommonError<T>>::NoPermission);543 ensure!(actual_type == nft_type, <Error<T>>::NoPermission);
481544
482 Ok(())545 Ok(())
483 }546 }
547
548 pub fn ensure_nft_owner(
549 collection_id: CollectionId,
550 token_id: TokenId,
551 possible_owner: &T::CrossAccountId
552 ) -> DispatchResult {
553 let token_data = <TokenData<T>>::get((collection_id, token_id))
554 .ok_or(<Error<T>>::NoAvailableNftId)?;
555
556 ensure!(token_data.owner == *possible_owner, <Error<T>>::NoPermission);
557
558 Ok(())
559 }
484560
485 pub fn filter_theme_properties(561 pub fn filter_user_properties<Key, Value, R, Mapper>(
486 collection_id: CollectionId,562 collection_id: CollectionId,
487 token_id: TokenId,563 token_id: Option<TokenId>,
488 filter_keys: Option<Vec<RmrkPropertyKey>>564 filter_keys: Option<Vec<RmrkPropertyKey>>,
565 mapper: Mapper,
489 ) -> Result<Vec<RmrkThemeProperty>, DispatchError> {566 ) -> Result<Vec<R>, DispatchError>
567 where
568 Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,
569 Value: Decode + Default,
570 Mapper: Fn(Key, Value) -> R
571 {
490 filter_keys.map(|keys| {572 filter_keys.map(|keys| {
491 let properties = keys.into_iter()573 let properties = keys.into_iter()
492 .filter_map(|key| {574 .filter_map(|key| {
493 let key: RmrkString = key.try_into().ok()?;575 let key: Key = key.try_into().ok()?;
494576
495 let value = Self::get_nft_property(577 let value = match token_id {
578 Some(token_id) => Self::get_nft_property(
496 collection_id,579 collection_id,
497 token_id,580 token_id,
498 ThemeProperty(&key)581 UserProperty(key.as_ref())
499 ).ok()?.decode_or_default();582 ),
500583 None => Self::get_collection_property(
501 let property = RmrkThemeProperty {584 collection_id,
585 UserProperty(key.as_ref())
586 )
587 }.ok()?.decode_or_default();
588
502 key,589 Some(mapper(key, value))
503 value
504 };
505
506 Some(property)
507 })590 })
508 .collect();591 .collect();
509592
510 Ok(properties)593 Ok(properties)
511 }).unwrap_or_else(|| {594 }).unwrap_or_else(|| {
512 let properties = Self::iterate_theme_properties(collection_id, token_id)?595 let properties = Self::iterate_user_properties(collection_id, token_id, mapper)?
513 .collect();596 .collect();
514597
515 Ok(properties)598 Ok(properties)
516 })599 })
517 }600 }
518601
519 pub fn iterate_theme_properties(602 pub fn iterate_user_properties<Key, Value, R, Mapper>(
520 collection_id: CollectionId,603 collection_id: CollectionId,
521 token_id: TokenId604 token_id: Option<TokenId>,
605 mapper: Mapper,
522 ) -> Result<impl Iterator<Item=RmrkThemeProperty>, DispatchError> {606 ) -> Result<impl Iterator<Item=R>, DispatchError>
607 where
608 Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,
609 Value: Decode + Default,
610 Mapper: Fn(Key, Value) -> R
611 {
523 let key_prefix = Self::rmrk_property_key(ThemeProperty(&RmrkString::default()))?;612 let key_prefix = Self::rmrk_property_key(UserProperty(b""))?;
613
614 let properties = match token_id {
615 Some(token_id) => <PalletNft<T>>::token_properties((collection_id, token_id)),
616 None => <PalletCommon<T>>::collection_properties(collection_id)
617 };
524618
525 let properties = <PalletNft<T>>::token_properties((collection_id, token_id))619 let properties = properties
526 .into_iter()620 .into_iter()
527 .filter_map(move |(key, value)| {621 .filter_map(move |(key, value)| {
528 let key = key.as_slice().strip_prefix(key_prefix.as_slice())?;622 let key = key.as_slice().strip_prefix(key_prefix.as_slice())?;
529623
530 let key: RmrkString = key.to_vec().try_into().ok()?;624 let key: Key = key.to_vec().try_into().ok()?;
531 let value: RmrkString = value.decode_or_default();625 let value: Value = value.decode_or_default();
532626
533 let property = RmrkThemeProperty {
534 key,627 Some(mapper(key, value))
535 value
536 };
537
538 Some(property)
539 });628 });
540629
541 Ok(properties)630 Ok(properties)
modifiedpallets/proxy-rmrk-core/src/property.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-core/src/property.rs
+++ b/pallets/proxy-rmrk-core/src/property.rs
@@ -23,8 +23,8 @@
     EquippableList,
     ZIndex,
     ThemeName,
-    ThemeProperty(&'r RmrkString),
     ThemeInherit,
+    UserProperty(&'r [u8]),
 }
 
 impl<'r> RmrkProperty<'r> {
@@ -66,8 +66,8 @@
             Self::EquippableList => key!("equippable-list"),
             Self::ZIndex => key!("z-index"),
             Self::ThemeName => key!("theme-name"),
-            Self::ThemeProperty(name) => key!("theme-property-", name),
             Self::ThemeInherit => key!("theme-inherit"),
+            Self::UserProperty(name) => key!("userprop-", name),
         }
     }
 }
modifiedpallets/proxy-rmrk-equip/src/lib.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-equip/src/lib.rs
+++ b/pallets/proxy-rmrk-equip/src/lib.rs
@@ -185,7 +185,7 @@
                     token_id,
                     PropertyScope::Rmrk,
                     <PalletCore<T>>::rmrk_property(
-                        ThemeProperty(&property.key),
+                        UserProperty(property.key.as_slice()),
                         &property.value
                     )?
                 )?;
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -934,8 +934,9 @@
 	RmrkString,
 	BoundedVec<RmrkPartId, RmrkPartsLimit>,
 >;
-pub type RmrkPropertyInfo =
-	PropertyInfo<BoundedVec<u8, RmrkKeyLimit>, BoundedVec<u8, RmrkValueLimit>>;
+pub type RmrkKeyString = BoundedVec<u8, RmrkKeyLimit>;
+pub type RmrkValueString = BoundedVec<u8, RmrkValueLimit>;
+pub type RmrkPropertyInfo = PropertyInfo<RmrkKeyString, RmrkValueString>;
 pub type RmrkBaseInfo<AccountId> = BaseInfo<AccountId, RmrkString>;
 pub type RmrkPartType =
 	PartType<RmrkString, BoundedVec<RmrkCollectionId, RmrkMaxCollectionsEquippablePerPart>>;
modifiedruntime/common/src/runtime_apis.rsdiffbeforeafterboth
--- a/runtime/common/src/runtime_apis.rs
+++ b/runtime/common/src/runtime_apis.rs
@@ -232,78 +232,47 @@
                 }
 
                 fn collection_properties(collection_id: RmrkCollectionId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
-                    use pallet_proxy_rmrk_core::misc::RmrkDecode;
+                    use pallet_proxy_rmrk_core::misc::CollectionType;
 
                     let collection_id = CollectionId(collection_id);
-                    if !RmrkCore::collection_exists(collection_id) { return Ok(Vec::new()); }
-
-                    let properties = Common::collection_properties(collection_id);
-
-                    // todo repeated code
-                    return Ok(match filter_keys {
-                        Some(keys) => {
-                            let keys = Common::bytes_keys_to_property_keys(keys)?;
-                            let properties = keys
-                                .into_iter()
-                                .filter_map(|key| {
-                                    properties.get(&key).map(|value| RmrkPropertyInfo {
-                                        key: key.decode_or_default(),
-                                        value: value.decode_or_default(),
-                                    })
-                                })
-                                .collect();
+                    if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() {
+                        return Ok(Vec::new());
+                    }
 
-                            properties
-                        }
-                        None => {
-                            properties
-                                .into_iter()
-                                .filter_map(|(key, value)| Some(RmrkPropertyInfo {
-                                    key: key.decode_or_default(),
-                                    value: value.decode_or_default(),
-                                }))
-                                .collect()
+                    let properties = RmrkCore::filter_user_properties(
+                        collection_id,
+                        /* token_id = */ None,
+                        filter_keys,
+                        |key, value| RmrkPropertyInfo {
+                            key,
+                            value
                         }
-                    });
+                    )?;
+
+                    Ok(properties)
                 }
 
                 fn nft_properties(collection_id: RmrkCollectionId, nft_id: RmrkNftId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
-                    use frame_support::BoundedVec;
-                    use pallet_proxy_rmrk_core::misc::RmrkDecode;
+                    use pallet_proxy_rmrk_core::misc::NftType;
 
                     let collection_id = CollectionId(collection_id);
                     let token_id = TokenId(nft_id);
-                    if !RmrkCore::nft_exists(collection_id, token_id) { return Ok(Vec::new()); }
 
-		            let properties = Nonfungible::token_properties((collection_id, token_id));
-                    // todo look into this usage of pallet_nonfungible
+                    if RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Regular).is_err() {
+                        return Ok(Vec::new());
+                    }
 
-                    // todo displace to a function? redundant code piece with collection props
-                    return Ok(match filter_keys {
-                        Some(keys) => {
-                            let keys = Common::bytes_keys_to_property_keys(keys)?;
-                            let properties = keys
-                                .into_iter()
-                                .filter_map(|key| {
-                                    properties.get(&key).map(|value| RmrkPropertyInfo {
-                                        key: key.decode_or_default(),
-                                        value: value.decode_or_default(),
-                                    })
-                                })
-                                .collect();
+		            let properties = RmrkCore::filter_user_properties(
+                        collection_id,
+                        Some(token_id),
+                        filter_keys,
+                        |key, value| RmrkPropertyInfo {
+                            key,
+                            value
+                        }
+                    )?;
 
-                            properties
-                        }
-                        None => {
-                            properties
-                                .into_iter()
-                                .filter_map(|(key, value)| Some(RmrkPropertyInfo {
-                                    key: key.decode_or_default(),
-                                    value: value.decode_or_default(),
-                                }))
-                                .collect()
-                        }
-                    });
+                    Ok(properties)
                 }
 
                 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
@@ -436,7 +405,15 @@
                         None => return Ok(None)
                     };
 
-                    let properties = RmrkCore::filter_theme_properties(collection_id, theme_id, filter_keys)?;
+                    let properties = RmrkCore::filter_user_properties(
+                        collection_id,
+                        Some(theme_id),
+                        filter_keys,
+                        |key, value| RmrkThemeProperty {
+                            key,
+                            value
+                        }
+                    )?;
 
                     let inherit = RmrkCore::get_nft_property(
                         collection_id,