difftreelog
refactor iterate rmrk props, add rmrk proxy set_propertty
in: master
5 files changed
pallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth24use 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;272828pub use pallet::*;29pub use pallet::*;293085 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 }899690 #[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());296303297 Self::destroy_nft(304 Self::destroy_nft(306 Ok(())313 Ok(())307 }314 }315316 #[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);327328 let collection_id: CollectionId = rmrk_collection_id.into();329330 match maybe_nft_id {331 Some(nft_id) => {332 let token_id: TokenId = nft_id.into();333334 Self::ensure_nft_owner(collection_id, token_id, &sender)?;335 Self::ensure_nft_type(collection_id, token_id, NftType::Regular)?;336337 <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::Regular348 )?;349350 Self::check_collection_owner(&collection, &sender)?;351352 <PalletCommon<T>>::set_scoped_collection_property(353 collection_id,354 PropertyScope::Rmrk,355 Self::rmrk_property(UserProperty(key.as_slice()), &value)?356 )?;357 }358 }359360 Self::deposit_event(361 Event::PropertySet {362 collection_id: rmrk_collection_id,363 maybe_nft_id,364 key,365 value366 }367 );368369 Ok(())370 }308 }371 }309}372}310373477540478 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);481544482 Ok(())545 Ok(())483 }546 }547548 pub fn ensure_nft_owner(549 collection_id: CollectionId,550 token_id: TokenId,551 possible_owner: &T::CrossAccountId552 ) -> DispatchResult {553 let token_data = <TokenData<T>>::get((collection_id, token_id))554 .ok_or(<Error<T>>::NoAvailableNftId)?;555556 ensure!(token_data.owner == *possible_owner, <Error<T>>::NoPermission);557558 Ok(())559 }484560485 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 where568 Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,569 Value: Decode + Default,570 Mapper: Fn(Key, Value) -> R571 {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()?;494576495 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();588502 key,589 Some(mapper(key, value))503 value504 };505506 Some(property)507 })590 })508 .collect();591 .collect();509592510 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();514597515 Ok(properties)598 Ok(properties)516 })599 })517 }600 }518601519 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 where608 Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,609 Value: Decode + Default,610 Mapper: Fn(Key, Value) -> R611 {523 let key_prefix = Self::rmrk_property_key(ThemeProperty(&RmrkString::default()))?;612 let key_prefix = Self::rmrk_property_key(UserProperty(b""))?;613614 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 };524618525 let properties = <PalletNft<T>>::token_properties((collection_id, token_id))619 let properties = properties526 .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())?;529623530 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();532626533 let property = RmrkThemeProperty {534 key,627 Some(mapper(key, value))535 value536 };537538 Some(property)539 });628 });540629541 Ok(properties)630 Ok(properties)pallets/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),
}
}
}
pallets/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
)?
)?;
primitives/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>>;
runtime/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,