difftreelog
refactor(rmrk-proxy) better decoding
in: master
3 files changed
pallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth111 CorruptedCollectionType,111 CorruptedCollectionType,112 NftTypeEncodeError,112 NftTypeEncodeError,113 RmrkPropertyKeyIsTooLong,113 RmrkPropertyKeyIsTooLong,114 RmrkPropertyValueIsTooLong, // todo utilize that in RPCs114 RmrkPropertyValueIsTooLong,115115116 /* RMRK compatible events */116 /* RMRK compatible events */117 CollectionNotEmpty,117 CollectionNotEmpty,518 Ok(scoped_key)518 Ok(scoped_key)519 }519 }520520521 pub fn rmrk_property<E: Encode>(521 pub fn rmrk_property<E: Encode>( // todo think about renaming this522 rmrk_key: RmrkProperty,522 rmrk_key: RmrkProperty,523 value: &E,523 value: &E,524 ) -> Result<Property, DispatchError> {524 ) -> Result<Property, DispatchError> {534 Ok(property)534 Ok(property)535 }535 }536 537 pub fn decode_property<D: Decode>(538 vec: PropertyValue,539 ) -> Result<D, DispatchError> {540 vec.decode().map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong.into())541 }542543 pub fn rebind<L, S>(544 vec: &BoundedVec<u8, L>,545 ) -> Result<BoundedVec<u8, S>, DispatchError> 546 where 547 BoundedVec<u8, S>: TryFrom<Vec<u8>> 548 {549 vec.rebind().map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong.into())550 }536551537 fn init_collection(552 fn init_collection(538 sender: T::CrossAccountId,553 sender: T::CrossAccountId,619 )?;634 )?;620635621 let resource_collection_id: CollectionId =636 let resource_collection_id: CollectionId =622 Self::get_nft_property(collection_id, token_id, ResourceCollection)?637 Self::get_nft_property_decoded(collection_id, token_id, ResourceCollection)?;623 .decode_or_default();624 let resource_collection =638 let resource_collection =625 Self::get_typed_nft_collection(resource_collection_id, misc::CollectionType::Resource)?;639 Self::get_typed_nft_collection(resource_collection_id, misc::CollectionType::Resource)?;626640709 Ok(collection_property)723 Ok(collection_property)710 }724 }725726 pub fn get_collection_property_decoded<V: Decode>(727 collection_id: CollectionId,728 key: RmrkProperty,729 ) -> Result<V, DispatchError> {730 Self::decode_property(731 Self::get_collection_property(collection_id, key)?732 )733 }711734712 pub fn get_collection_type(735 pub fn get_collection_type(713 collection_id: CollectionId,736 collection_id: CollectionId,714 ) -> Result<misc::CollectionType, DispatchError> {737 ) -> Result<misc::CollectionType, DispatchError> {715 let value = Self::get_collection_property(collection_id, CollectionType)?;738 Self::get_collection_property_decoded(collection_id, CollectionType)716717 let mut value = value.as_slice();718719 misc::CollectionType::decode(&mut value)720 .map_err(|_| <Error<T>>::CorruptedCollectionType.into())739 .map_err(|_| <Error<T>>::CorruptedCollectionType.into())721 }740 }722741723 pub fn ensure_collection_type(742 pub fn ensure_collection_type(749 ) -> Result<PropertyValue, DispatchError> {768 ) -> Result<PropertyValue, DispatchError> {750 let nft_property = <PalletNft<T>>::token_properties((collection_id, nft_id))769 let nft_property = <PalletNft<T>>::token_properties((collection_id, nft_id))751 .get(&Self::rmrk_property_key(key)?)770 .get(&Self::rmrk_property_key(key)?)752 .ok_or(<Error<T>>::NoAvailableNftId)? // todo replace with better error771 .ok_or(<Error<T>>::NoAvailableNftId)? // todo replace with better error?753 .clone();772 .clone();754773755 Ok(nft_property)774 Ok(nft_property)756 }775 }776777 pub fn get_nft_property_decoded<V: Decode>(778 collection_id: CollectionId,779 nft_id: TokenId,780 key: RmrkProperty,781 ) -> Result<V, DispatchError> {782 Self::decode_property(783 Self::get_nft_property(collection_id, nft_id, key)?784 )785 }757786758 pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {787 pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {759 <TokenData<T>>::contains_key((collection_id, nft_id))788 <TokenData<T>>::contains_key((collection_id, nft_id))763 collection_id: CollectionId,792 collection_id: CollectionId,764 token_id: TokenId,793 token_id: TokenId,765 ) -> Result<NftType, DispatchError> {794 ) -> Result<NftType, DispatchError> {766 Ok(Self::get_nft_property(collection_id, token_id, TokenType)?.decode_or_default())795 Self::get_nft_property_decoded(collection_id, token_id, TokenType)767 // todo throw error796 .map_err(|_| <Error<T>>::NftTypeEncodeError.into())768 // NftTypeEncodeError?769 }797 }770798771 pub fn ensure_nft_type(799 pub fn ensure_nft_type(814 let key: Key = key.try_into().ok()?;842 let key: Key = key.try_into().ok()?;815843816 let value = match token_id {844 let value = match token_id {817 Some(token_id) => Self::get_nft_property(845 Some(token_id) => Self::get_nft_property_decoded(818 collection_id,846 collection_id,819 token_id,847 token_id,820 UserProperty(key.as_ref()),848 UserProperty(key.as_ref()),821 ),849 ),822 None => Self::get_collection_property(850 None => Self::get_collection_property_decoded(823 collection_id,851 collection_id,824 UserProperty(key.as_ref()),852 UserProperty(key.as_ref()),825 ),853 ),826 }854 }827 .ok()?828 .decode_or_default();855 .ok()?;829856830 Some(mapper(key, value))857 Some(mapper(key, value))831 })858 })862 let key = key.as_slice().strip_prefix(key_prefix.as_slice())?;889 let key = key.as_slice().strip_prefix(key_prefix.as_slice())?;863890864 let key: Key = key.to_vec().try_into().ok()?;891 let key: Key = key.to_vec().try_into().ok()?;865 let value: Value = value.decode_or_default();892 let value: Value = value.decode().ok()?;866893867 Some(mapper(key, value))894 Some(mapper(key, value))868 });895 });pallets/proxy-rmrk-core/src/misc.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/misc.rs
+++ b/pallets/proxy-rmrk-core/src/misc.rs
@@ -1,6 +1,5 @@
use super::*;
-use codec::{Encode, Decode};
-use derivative::Derivative;
+use codec::{Encode, Decode, Error};
#[macro_export]
macro_rules! map_common_err_to_proxy {
@@ -15,30 +14,30 @@
};
}
-pub trait RmrkDecode<T: Decode + Default, S> {
- fn decode_or_default(&self) -> T;
+// Utilize the RmrkCore pallet for access to Runtime errors.
+pub trait RmrkDecode<T: Decode, S> {
+ fn decode(&self) -> Result<T, Error>;
}
-// todo fail if unwrap doesn't work
-impl<T: Decode + Default, S> RmrkDecode<T, S> for BoundedVec<u8, S> {
- fn decode_or_default(&self) -> T {
+impl<T: Decode, S> RmrkDecode<T, S> for BoundedVec<u8, S> {
+ fn decode(&self) -> Result<T, Error> {
let mut value = self.as_slice();
- T::decode(&mut value).unwrap_or_default()
+ T::decode(&mut value)
}
}
+// Utilize the RmrkCore pallet for access to Runtime errors.
pub trait RmrkRebind<T, S> {
- fn rebind(&self) -> BoundedVec<u8, S>;
+ fn rebind(&self) -> Result<BoundedVec<u8, S>, Error>;
}
-// todo fail if unwrap doesn't work
impl<T, S> RmrkRebind<T, S> for BoundedVec<u8, T>
where
BoundedVec<u8, S>: TryFrom<Vec<u8>>,
{
- fn rebind(&self) -> BoundedVec<u8, S> {
- BoundedVec::<u8, S>::try_from(self.clone().into_inner()).unwrap_or_default()
+ fn rebind(&self) -> Result<BoundedVec<u8, S>, Error> {
+ BoundedVec::<u8, S>::try_from(self.clone().into_inner()).map_err(|_| "BoundedVec exceeds its limit".into())
}
}
@@ -49,11 +48,8 @@
Base,
}
-// todo remove default?
-#[derive(Encode, Decode, PartialEq, Eq, Derivative)]
-#[derivative(Default(bound = ""))]
+#[derive(Encode, Decode, PartialEq, Eq)]
pub enum NftType {
- #[derivative(Default)]
Regular,
Resource,
FixedPart,
@@ -61,11 +57,8 @@
Theme,
}
-// todo remove default?
-#[derive(Encode, Decode, PartialEq, Eq, Derivative)]
-#[derivative(Default(bound = ""))]
+#[derive(Encode, Decode, PartialEq, Eq)]
pub enum ResourceType {
- #[derivative(Default)]
Basic,
Composable,
Slot,
runtime/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,