git.delta.rocks / unique-network / refs/commits / c1189fc5c3c1

difftreelog

refactor(rmrk-proxy) better decoding

Fahrrader2022-06-02parent: #71b4dea.patch.diff
in: master

3 files changed

modifiedpallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-core/src/lib.rs
+++ b/pallets/proxy-rmrk-core/src/lib.rs
@@ -111,7 +111,7 @@
 		CorruptedCollectionType,
 		NftTypeEncodeError,
 		RmrkPropertyKeyIsTooLong,
-		RmrkPropertyValueIsTooLong, // todo utilize that in RPCs
+		RmrkPropertyValueIsTooLong,
 
 		/* RMRK compatible events */
 		CollectionNotEmpty,
@@ -518,7 +518,7 @@
 		Ok(scoped_key)
 	}
 
-	pub fn rmrk_property<E: Encode>(
+	pub fn rmrk_property<E: Encode>( // todo think about renaming this
 		rmrk_key: RmrkProperty,
 		value: &E,
 	) -> Result<Property, DispatchError> {
@@ -533,6 +533,21 @@
 
 		Ok(property)
 	}
+	
+	pub fn decode_property<D: Decode>(
+		vec: PropertyValue,
+	) -> Result<D, DispatchError> {
+		vec.decode().map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong.into())
+	}
+
+	pub fn rebind<L, S>(
+		vec: &BoundedVec<u8, L>,
+	) -> Result<BoundedVec<u8, S>, DispatchError> 
+	where 
+		BoundedVec<u8, S>: TryFrom<Vec<u8>> 
+	{
+		vec.rebind().map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong.into())
+	}
 
 	fn init_collection(
 		sender: T::CrossAccountId,
@@ -619,8 +634,7 @@
 		)?;
 
 		let resource_collection_id: CollectionId =
-			Self::get_nft_property(collection_id, token_id, ResourceCollection)?
-				.decode_or_default();
+			Self::get_nft_property_decoded(collection_id, token_id, ResourceCollection)?;
 		let resource_collection =
 			Self::get_typed_nft_collection(resource_collection_id, misc::CollectionType::Resource)?;
 
@@ -709,14 +723,19 @@
 		Ok(collection_property)
 	}
 
+	pub fn get_collection_property_decoded<V: Decode>(
+		collection_id: CollectionId,
+		key: RmrkProperty,
+	) -> Result<V, DispatchError> {
+		Self::decode_property(
+			Self::get_collection_property(collection_id, key)?
+		)
+	}
+
 	pub fn get_collection_type(
 		collection_id: CollectionId,
 	) -> Result<misc::CollectionType, DispatchError> {
-		let value = Self::get_collection_property(collection_id, CollectionType)?;
-
-		let mut value = value.as_slice();
-
-		misc::CollectionType::decode(&mut value)
+		Self::get_collection_property_decoded(collection_id, CollectionType)
 			.map_err(|_| <Error<T>>::CorruptedCollectionType.into())
 	}
 
@@ -749,12 +768,22 @@
 	) -> Result<PropertyValue, DispatchError> {
 		let nft_property = <PalletNft<T>>::token_properties((collection_id, nft_id))
 			.get(&Self::rmrk_property_key(key)?)
-			.ok_or(<Error<T>>::NoAvailableNftId)? // todo replace with better error
+			.ok_or(<Error<T>>::NoAvailableNftId)? // todo replace with better error?
 			.clone();
 
 		Ok(nft_property)
 	}
 
+	pub fn get_nft_property_decoded<V: Decode>(
+		collection_id: CollectionId,
+		nft_id: TokenId,
+		key: RmrkProperty,
+	) -> Result<V, DispatchError> {
+		Self::decode_property(
+			Self::get_nft_property(collection_id, nft_id, key)?
+		)
+	}
+
 	pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {
 		<TokenData<T>>::contains_key((collection_id, nft_id))
 	}
@@ -763,9 +792,8 @@
 		collection_id: CollectionId,
 		token_id: TokenId,
 	) -> Result<NftType, DispatchError> {
-		Ok(Self::get_nft_property(collection_id, token_id, TokenType)?.decode_or_default())
-		// todo throw error
-		// NftTypeEncodeError?
+		Self::get_nft_property_decoded(collection_id, token_id, TokenType)
+			.map_err(|_| <Error<T>>::NftTypeEncodeError.into())
 	}
 
 	pub fn ensure_nft_type(
@@ -814,18 +842,17 @@
 						let key: Key = key.try_into().ok()?;
 
 						let value = match token_id {
-							Some(token_id) => Self::get_nft_property(
+							Some(token_id) => Self::get_nft_property_decoded(
 								collection_id,
 								token_id,
 								UserProperty(key.as_ref()),
 							),
-							None => Self::get_collection_property(
+							None => Self::get_collection_property_decoded(
 								collection_id,
 								UserProperty(key.as_ref()),
 							),
 						}
-						.ok()?
-						.decode_or_default();
+						.ok()?;
 
 						Some(mapper(key, value))
 					})
@@ -862,7 +889,7 @@
 			let key = key.as_slice().strip_prefix(key_prefix.as_slice())?;
 
 			let key: Key = key.to_vec().try_into().ok()?;
-			let value: Value = value.decode_or_default();
+			let value: Value = value.decode().ok()?;
 
 			Some(mapper(key, value))
 		});
modifiedpallets/proxy-rmrk-core/src/misc.rsdiffbeforeafterboth
before · pallets/proxy-rmrk-core/src/misc.rs
1use super::*;2use codec::{Encode, Decode};3use derivative::Derivative;45#[macro_export]6macro_rules! map_common_err_to_proxy {7    (match $err:ident { $($common_err:ident => $proxy_err:ident),+ }) => {8        $(9            if $err == <CommonError<T>>::$common_err.into() {10                return <Error<T>>::$proxy_err.into()11            } else12        )+ {13            $err14        }15    };16}1718pub trait RmrkDecode<T: Decode + Default, S> {19	fn decode_or_default(&self) -> T;20}2122// todo fail if unwrap doesn't work23impl<T: Decode + Default, S> RmrkDecode<T, S> for BoundedVec<u8, S> {24	fn decode_or_default(&self) -> T {25		let mut value = self.as_slice();2627		T::decode(&mut value).unwrap_or_default()28	}29}3031pub trait RmrkRebind<T, S> {32	fn rebind(&self) -> BoundedVec<u8, S>;33}3435// todo fail if unwrap doesn't work36impl<T, S> RmrkRebind<T, S> for BoundedVec<u8, T>37where38	BoundedVec<u8, S>: TryFrom<Vec<u8>>,39{40	fn rebind(&self) -> BoundedVec<u8, S> {41		BoundedVec::<u8, S>::try_from(self.clone().into_inner()).unwrap_or_default()42	}43}4445#[derive(Encode, Decode, PartialEq, Eq)]46pub enum CollectionType {47	Regular,48	Resource,49	Base,50}5152// todo remove default?53#[derive(Encode, Decode, PartialEq, Eq, Derivative)]54#[derivative(Default(bound = ""))]55pub enum NftType {56	#[derivative(Default)]57	Regular,58	Resource,59	FixedPart,60	SlotPart,61	Theme,62}6364// todo remove default?65#[derive(Encode, Decode, PartialEq, Eq, Derivative)]66#[derivative(Default(bound = ""))]67pub enum ResourceType {68	#[derivative(Default)]69	Basic,70	Composable,71	Slot,72}
after · pallets/proxy-rmrk-core/src/misc.rs
1use super::*;2use codec::{Encode, Decode, Error};34#[macro_export]5macro_rules! map_common_err_to_proxy {6    (match $err:ident { $($common_err:ident => $proxy_err:ident),+ }) => {7        $(8            if $err == <CommonError<T>>::$common_err.into() {9                return <Error<T>>::$proxy_err.into()10            } else11        )+ {12            $err13        }14    };15}1617// Utilize the RmrkCore pallet for access to Runtime errors.18pub trait RmrkDecode<T: Decode, S> {19	fn decode(&self) -> Result<T, Error>;20}2122impl<T: Decode, S> RmrkDecode<T, S> for BoundedVec<u8, S> {23	fn decode(&self) -> Result<T, Error> {24		let mut value = self.as_slice();2526		T::decode(&mut value)27	}28}2930// Utilize the RmrkCore pallet for access to Runtime errors.31pub trait RmrkRebind<T, S> {32	fn rebind(&self) -> Result<BoundedVec<u8, S>, Error>;33}3435impl<T, S> RmrkRebind<T, S> for BoundedVec<u8, T>36where37	BoundedVec<u8, S>: TryFrom<Vec<u8>>,38{39	fn rebind(&self) -> Result<BoundedVec<u8, S>, Error> {40		BoundedVec::<u8, S>::try_from(self.clone().into_inner()).map_err(|_| "BoundedVec exceeds its limit".into())41	}42}4344#[derive(Encode, Decode, PartialEq, Eq)]45pub enum CollectionType {46	Regular,47	Resource,48	Base,49}5051#[derive(Encode, Decode, PartialEq, Eq)]52pub enum NftType {53	Regular,54	Resource,55	FixedPart,56	SlotPart,57	Theme,58}5960#[derive(Encode, Decode, PartialEq, Eq)]61pub enum ResourceType {62	Basic,63	Composable,64	Slot,65}
modifiedruntime/common/src/runtime_apis.rsdiffbeforeafterboth
--- a/runtime/common/src/runtime_apis.rs
+++ b/runtime/common/src/runtime_apis.rs
@@ -144,7 +144,7 @@
                 }
 
                 fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {
-                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, RmrkDecode, RmrkRebind}};
+                    use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType}};
 
                     let collection_id = RmrkCore::unique_collection_id(collection_id)?;
                     let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Regular) {
@@ -157,9 +157,9 @@
 
                     Ok(Some(RmrkCollectionInfo {
                         issuer: collection.owner.clone(),
-                        metadata: RmrkCore::get_collection_property(collection_id, RmrkProperty::Metadata)?.decode_or_default(),
+                        metadata: RmrkCore::get_collection_property_decoded(collection_id, RmrkProperty::Metadata)?,
                         max: collection.limits.token_limit,
-                        symbol: collection.token_prefix.rebind(),
+                        symbol: RmrkCore::rebind(&collection.token_prefix)?,
                         nfts_count
                     }))
                 }
@@ -185,9 +185,9 @@
 
                     Ok(Some(RmrkInstanceInfo {
                         owner: owner,
-                        royalty: RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::RoyaltyInfo)?.decode_or_default(),
-                        metadata: RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::Metadata)?.decode_or_default(),
-                        equipped: RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::Equipped)?.decode_or_default(),
+                        royalty: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::RoyaltyInfo)?,
+                        metadata: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Metadata)?,
+                        equipped: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Equipped)?,
                         pending: allowance.is_some(),
                     }))
                 }
@@ -281,8 +281,7 @@
                     let nft_id = TokenId(nft_id);
                     if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }
 
-                    let res_collection_id: CollectionId = RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::ResourceCollection)?
-                        .decode_or_default();
+                    let res_collection_id: CollectionId = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourceCollection)?;
                     let resource_collection = RmrkCore::get_typed_nft_collection(res_collection_id, CollectionType::Resource)?;
 
                     let resources = resource_collection
@@ -290,32 +289,31 @@
                         .iter()
                         .filter_map(|(res_id)| Some(RmrkResourceInfo {
                             id: res_id.0,
-                            pending: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::PendingResourceAccept).unwrap().decode_or_default(),
-                            pending_removal: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::PendingResourceRemoval).unwrap().decode_or_default(),
-                            resource: match RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::ResourceType).unwrap().decode_or_default() {
+                            pending: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceAccept).unwrap(),
+                            pending_removal: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceRemoval).unwrap(),
+                            resource: match RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::ResourceType).unwrap() {
                                 ResourceType::Basic => RmrkResourceTypes::Basic(RmrkBasicResource {
-                                    src: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Src).unwrap().decode_or_default(),
-                                    metadata: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap().decode_or_default(),
-                                    license: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::License).unwrap().decode_or_default(),
-                                    thumb: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap().decode_or_default(),
+                                    src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).unwrap(),
+                                    metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap(),
+                                    license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).unwrap(),
+                                    thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap(),
                                 }),
                                 ResourceType::Composable => RmrkResourceTypes::Composable(RmrkComposableResource {
-                                    parts: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Parts).unwrap().decode_or_default(),
-                                    base: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Base).unwrap().decode_or_default(),
-                                    src: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Src).unwrap().decode_or_default(),
-                                    metadata: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap().decode_or_default(),
-                                    license: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::License).unwrap().decode_or_default(),
-                                    thumb: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap().decode_or_default(),
+                                    parts: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Parts).unwrap(),
+                                    base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).unwrap(),
+                                    src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).unwrap(),
+                                    metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap(),
+                                    license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).unwrap(),
+                                    thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap(),
                                 }),
                                 ResourceType::Slot => RmrkResourceTypes::Slot(RmrkSlotResource {
-                                    base: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Base).unwrap().decode_or_default(),
-                                    src: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Src).unwrap().decode_or_default(),
-                                    metadata: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap().decode_or_default(),
-                                    slot: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Slot).unwrap().decode_or_default(),
-                                    license: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::License).unwrap().decode_or_default(),
-                                    thumb: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap().decode_or_default(),
+                                    base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).unwrap(),
+                                    src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).unwrap(),
+                                    metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap(),
+                                    slot: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Slot).unwrap(),
+                                    license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).unwrap(),
+                                    thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap(),
                                 }),
-                                // todo refactor :|
                             },
                         }))
                         .collect();
@@ -332,28 +330,26 @@
                     let nft_id = TokenId(nft_id);
                     if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }
 
-                    /*let resource_collection_id: CollectionId = RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::ResourceCollection)
-                        .unwrap()
-                        .decode_or_default();
+                    /*let resource_collection_id: CollectionId = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourceCollection)
+                        .unwrap();
                     if RmrkCore::ensure_collection_type(collection_id, CollectionType::Resource).is_err() { return Ok(Vec::new()); }
 
                     let resources = pallet_nonfungible::TokenProperties::<Runtime>::iter_prefix((resource_collection_id,))
                         .filter_map(|(resource_id, properties)| Some((
                             resource_id, // ResourceId property
-                            RmrkCore::get_nft_property(resource_collection_id, resource_id, RmrkProperty::Priority).unwrap().decode_or_default(),
+                            RmrkCore::get_nft_property_decoded(resource_collection_id, resource_id, RmrkProperty::Priority).unwrap(),
                         )))
                         .collect()
                         .sort_by_key(|(_, index)| *index)
                         .into_iter().map(|(resource_id, _)| resource_id)*/
-                    let priorities = RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::ResourcePriorities)?.decode_or_default();
-                    // todo let it simply be default here after removing default from decode
+                    let priorities = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourcePriorities)?;
 
                     Ok(priorities)
                 }
 
                 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {
                     use pallet_proxy_rmrk_core::{
-                        RmrkProperty, misc::{CollectionType, RmrkDecode, RmrkRebind},
+                        RmrkProperty, misc::{CollectionType},
                     };
 
                     let collection_id = RmrkCore::unique_collection_id(base_id)?;
@@ -364,8 +360,8 @@
 
                     Ok(Some(RmrkBaseInfo {
                         issuer: collection.owner.clone(),
-                        base_type: RmrkCore::get_collection_property(collection_id, RmrkProperty::BaseType)?.decode_or_default(),
-                        symbol: collection.token_prefix.rebind(),
+                        base_type: RmrkCore::get_collection_property_decoded(collection_id, RmrkProperty::BaseType)?,
+                        symbol: RmrkCore::rebind(&collection.token_prefix)?,
                     }))
                 }
 
@@ -382,15 +378,15 @@
 
                             match nft_type {
                                 NftType::FixedPart => Some(RmrkPartType::FixedPart(RmrkFixedPart {
-                                    id: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?.decode_or_default(),
-                                    src: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::Src).ok()?.decode_or_default(),
-                                    z: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::ZIndex).ok()?.decode_or_default(),
+                                    id: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?,
+                                    src: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::Src).ok()?,
+                                    z: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ZIndex).ok()?,
                                 })),
                                 NftType::SlotPart => Some(RmrkPartType::SlotPart(RmrkSlotPart {
-                                    id: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?.decode_or_default(),
-                                    src: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::Src).ok()?.decode_or_default(),
-                                    z: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::ZIndex).ok()?.decode_or_default(),
-                                    equippable: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::EquippableList).ok()?.decode_or_default(),
+                                    id: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?,
+                                    src: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::Src).ok()?,
+                                    z: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ZIndex).ok()?,
+                                    equippable: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::EquippableList).ok()?,
                                 })),
                                 _ => None
                             }
@@ -415,7 +411,7 @@
 
                             match nft_type {
                                 Theme => Some(
-                                    RmrkCore::get_nft_property(collection_id, *token_id, RmrkProperty::ThemeName).unwrap().decode_or_default()
+                                    RmrkCore::get_nft_property_decoded(collection_id, *token_id, RmrkProperty::ThemeName).unwrap()
                                 ),
                                 _ => None
                             }
@@ -441,9 +437,9 @@
                         .find_map(|token_id| {
                             RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Theme).ok()?;
 
-                            let name: RmrkString = RmrkCore::get_nft_property(
+                            let name: RmrkString = RmrkCore::get_nft_property_decoded(
                                 collection_id, token_id, RmrkProperty::ThemeName
-                            ).ok()?.decode_or_default();
+                            ).ok()?;
 
                             if name == theme_name {
                                 Some((name, token_id))
@@ -467,11 +463,11 @@
                         }
                     )?;
 
-                    let inherit = RmrkCore::get_nft_property(
+                    let inherit = RmrkCore::get_nft_property_decoded(
                         collection_id,
                         theme_id,
                         RmrkProperty::ThemeInherit
-                    )?.decode_or_default();
+                    )?;
 
                     let theme = RmrkTheme {
                         name,