difftreelog
refactor(rmrk-proxy) better decoding
in: master
3 files changed
pallets/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))
});
pallets/proxy-rmrk-core/src/misc.rsdiffbeforeafterboth1use super::*;1use super::*;2use codec::{Encode, Decode};2use codec::{Encode, Decode, Error};3use derivative::Derivative;435#[macro_export]4#[macro_export]6macro_rules! map_common_err_to_proxy {5macro_rules! map_common_err_to_proxy {15 };14 };16}15}171617// Utilize the RmrkCore pallet for access to Runtime errors.18pub trait RmrkDecode<T: Decode + Default, S> {18pub trait RmrkDecode<T: Decode, S> {19 fn decode_or_default(&self) -> T;19 fn decode(&self) -> Result<T, Error>;20}20}212122// todo fail if unwrap doesn't work23impl<T: Decode + Default, S> RmrkDecode<T, S> for BoundedVec<u8, S> {22impl<T: Decode, S> RmrkDecode<T, S> for BoundedVec<u8, S> {24 fn decode_or_default(&self) -> T {23 fn decode(&self) -> Result<T, Error> {25 let mut value = self.as_slice();24 let mut value = self.as_slice();262527 T::decode(&mut value).unwrap_or_default()26 T::decode(&mut value)28 }27 }29}28}302930// Utilize the RmrkCore pallet for access to Runtime errors.31pub trait RmrkRebind<T, S> {31pub trait RmrkRebind<T, S> {32 fn rebind(&self) -> BoundedVec<u8, S>;32 fn rebind(&self) -> Result<BoundedVec<u8, S>, Error>;33}33}343435// todo fail if unwrap doesn't work36impl<T, S> RmrkRebind<T, S> for BoundedVec<u8, T>35impl<T, S> RmrkRebind<T, S> for BoundedVec<u8, T>37where36where38 BoundedVec<u8, S>: TryFrom<Vec<u8>>,37 BoundedVec<u8, S>: TryFrom<Vec<u8>>,39{38{40 fn rebind(&self) -> BoundedVec<u8, S> {39 fn rebind(&self) -> Result<BoundedVec<u8, S>, Error> {41 BoundedVec::<u8, S>::try_from(self.clone().into_inner()).unwrap_or_default()40 BoundedVec::<u8, S>::try_from(self.clone().into_inner()).map_err(|_| "BoundedVec exceeds its limit".into())42 }41 }43}42}444349 Base,48 Base,50}49}515052// todo remove default?53#[derive(Encode, Decode, PartialEq, Eq, Derivative)]51#[derive(Encode, Decode, PartialEq, Eq)]54#[derivative(Default(bound = ""))]55pub enum NftType {52pub enum NftType {56 #[derivative(Default)]57 Regular,53 Regular,58 Resource,54 Resource,59 FixedPart,55 FixedPart,60 SlotPart,56 SlotPart,61 Theme,57 Theme,62}58}635964// todo remove default?65#[derive(Encode, Decode, PartialEq, Eq, Derivative)]60#[derive(Encode, Decode, PartialEq, Eq)]66#[derivative(Default(bound = ""))]67pub enum ResourceType {61pub enum ResourceType {68 #[derivative(Default)]69 Basic,62 Basic,70 Composable,63 Composable,71 Slot,64 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,