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.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.rsdiffbeforeafterboth144 }144 }145145146 fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {146 fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {147 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, RmrkDecode, RmrkRebind}};147 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType}};148148149 let collection_id = RmrkCore::unique_collection_id(collection_id)?;149 let collection_id = RmrkCore::unique_collection_id(collection_id)?;150 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Regular) {150 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Regular) {157157158 Ok(Some(RmrkCollectionInfo {158 Ok(Some(RmrkCollectionInfo {159 issuer: collection.owner.clone(),159 issuer: collection.owner.clone(),160 metadata: RmrkCore::get_collection_property(collection_id, RmrkProperty::Metadata)?.decode_or_default(),160 metadata: RmrkCore::get_collection_property_decoded(collection_id, RmrkProperty::Metadata)?,161 max: collection.limits.token_limit,161 max: collection.limits.token_limit,162 symbol: collection.token_prefix.rebind(),162 symbol: RmrkCore::rebind(&collection.token_prefix)?,163 nfts_count163 nfts_count164 }))164 }))165 }165 }185185186 Ok(Some(RmrkInstanceInfo {186 Ok(Some(RmrkInstanceInfo {187 owner: owner,187 owner: owner,188 royalty: RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::RoyaltyInfo)?.decode_or_default(),188 royalty: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::RoyaltyInfo)?,189 metadata: RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::Metadata)?.decode_or_default(),189 metadata: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Metadata)?,190 equipped: RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::Equipped)?.decode_or_default(),190 equipped: RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Equipped)?,191 pending: allowance.is_some(),191 pending: allowance.is_some(),192 }))192 }))193 }193 }281 let nft_id = TokenId(nft_id);281 let nft_id = TokenId(nft_id);282 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }282 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }283283284 let res_collection_id: CollectionId = RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::ResourceCollection)?284 let res_collection_id: CollectionId = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourceCollection)?;285 .decode_or_default();286 let resource_collection = RmrkCore::get_typed_nft_collection(res_collection_id, CollectionType::Resource)?;285 let resource_collection = RmrkCore::get_typed_nft_collection(res_collection_id, CollectionType::Resource)?;287286288 let resources = resource_collection287 let resources = resource_collection289 .collection_tokens()288 .collection_tokens()290 .iter()289 .iter()291 .filter_map(|(res_id)| Some(RmrkResourceInfo {290 .filter_map(|(res_id)| Some(RmrkResourceInfo {292 id: res_id.0,291 id: res_id.0,293 pending: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::PendingResourceAccept).unwrap().decode_or_default(),292 pending: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceAccept).unwrap(),294 pending_removal: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::PendingResourceRemoval).unwrap().decode_or_default(),293 pending_removal: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceRemoval).unwrap(),295 resource: match RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::ResourceType).unwrap().decode_or_default() {294 resource: match RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::ResourceType).unwrap() {296 ResourceType::Basic => RmrkResourceTypes::Basic(RmrkBasicResource {295 ResourceType::Basic => RmrkResourceTypes::Basic(RmrkBasicResource {297 src: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Src).unwrap().decode_or_default(),296 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).unwrap(),298 metadata: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap().decode_or_default(),297 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap(),299 license: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::License).unwrap().decode_or_default(),298 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).unwrap(),300 thumb: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap().decode_or_default(),299 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap(),301 }),300 }),302 ResourceType::Composable => RmrkResourceTypes::Composable(RmrkComposableResource {301 ResourceType::Composable => RmrkResourceTypes::Composable(RmrkComposableResource {303 parts: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Parts).unwrap().decode_or_default(),302 parts: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Parts).unwrap(),304 base: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Base).unwrap().decode_or_default(),303 base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).unwrap(),305 src: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Src).unwrap().decode_or_default(),304 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).unwrap(),306 metadata: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap().decode_or_default(),305 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap(),307 license: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::License).unwrap().decode_or_default(),306 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).unwrap(),308 thumb: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap().decode_or_default(),307 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap(),309 }),308 }),310 ResourceType::Slot => RmrkResourceTypes::Slot(RmrkSlotResource {309 ResourceType::Slot => RmrkResourceTypes::Slot(RmrkSlotResource {311 base: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Base).unwrap().decode_or_default(),310 base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).unwrap(),312 src: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Src).unwrap().decode_or_default(),311 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).unwrap(),313 metadata: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap().decode_or_default(),312 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).unwrap(),314 slot: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Slot).unwrap().decode_or_default(),313 slot: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Slot).unwrap(),315 license: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::License).unwrap().decode_or_default(),314 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).unwrap(),316 thumb: RmrkCore::get_nft_property(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap().decode_or_default(),315 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).unwrap(),317 }),316 }),318 // todo refactor :|319 },317 },320 }))318 }))321 .collect();319 .collect();332 let nft_id = TokenId(nft_id);330 let nft_id = TokenId(nft_id);333 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }331 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }334332335 /*let resource_collection_id: CollectionId = RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::ResourceCollection)333 /*let resource_collection_id: CollectionId = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourceCollection)336 .unwrap()334 .unwrap();337 .decode_or_default();335 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Resource).is_err() { return Ok(Vec::new()); }338 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Resource).is_err() { return Ok(Vec::new()); }336339337 let resources = pallet_nonfungible::TokenProperties::<Runtime>::iter_prefix((resource_collection_id,))340 let resources = pallet_nonfungible::TokenProperties::<Runtime>::iter_prefix((resource_collection_id,))338 .filter_map(|(resource_id, properties)| Some((341 .filter_map(|(resource_id, properties)| Some((339 resource_id, // ResourceId property342 resource_id, // ResourceId property340 RmrkCore::get_nft_property_decoded(resource_collection_id, resource_id, RmrkProperty::Priority).unwrap(),343 RmrkCore::get_nft_property(resource_collection_id, resource_id, RmrkProperty::Priority).unwrap().decode_or_default(),341 )))344 )))342 .collect()345 .collect()343 .sort_by_key(|(_, index)| *index)346 .sort_by_key(|(_, index)| *index)344 .into_iter().map(|(resource_id, _)| resource_id)*/347 .into_iter().map(|(resource_id, _)| resource_id)*/348 let priorities = RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::ResourcePriorities)?.decode_or_default();345 let priorities = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourcePriorities)?;349 // todo let it simply be default here after removing default from decode350346351 Ok(priorities)347 Ok(priorities)352 }348 }353349354 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {350 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {355 use pallet_proxy_rmrk_core::{351 use pallet_proxy_rmrk_core::{356 RmrkProperty, misc::{CollectionType, RmrkDecode, RmrkRebind},352 RmrkProperty, misc::{CollectionType},357 };353 };358354359 let collection_id = RmrkCore::unique_collection_id(base_id)?;355 let collection_id = RmrkCore::unique_collection_id(base_id)?;364360365 Ok(Some(RmrkBaseInfo {361 Ok(Some(RmrkBaseInfo {366 issuer: collection.owner.clone(),362 issuer: collection.owner.clone(),367 base_type: RmrkCore::get_collection_property(collection_id, RmrkProperty::BaseType)?.decode_or_default(),363 base_type: RmrkCore::get_collection_property_decoded(collection_id, RmrkProperty::BaseType)?,368 symbol: collection.token_prefix.rebind(),364 symbol: RmrkCore::rebind(&collection.token_prefix)?,369 }))365 }))370 }366 }371367382378383 match nft_type {379 match nft_type {384 NftType::FixedPart => Some(RmrkPartType::FixedPart(RmrkFixedPart {380 NftType::FixedPart => Some(RmrkPartType::FixedPart(RmrkFixedPart {385 id: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?.decode_or_default(),381 id: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?,386 src: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::Src).ok()?.decode_or_default(),382 src: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::Src).ok()?,387 z: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::ZIndex).ok()?.decode_or_default(),383 z: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ZIndex).ok()?,388 })),384 })),389 NftType::SlotPart => Some(RmrkPartType::SlotPart(RmrkSlotPart {385 NftType::SlotPart => Some(RmrkPartType::SlotPart(RmrkSlotPart {390 id: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?.decode_or_default(),386 id: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ExternalPartId).ok()?,391 src: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::Src).ok()?.decode_or_default(),387 src: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::Src).ok()?,392 z: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::ZIndex).ok()?.decode_or_default(),388 z: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::ZIndex).ok()?,393 equippable: RmrkCore::get_nft_property(collection_id, token_id, RmrkProperty::EquippableList).ok()?.decode_or_default(),389 equippable: RmrkCore::get_nft_property_decoded(collection_id, token_id, RmrkProperty::EquippableList).ok()?,394 })),390 })),395 _ => None391 _ => None396 }392 }415411416 match nft_type {412 match nft_type {417 Theme => Some(413 Theme => Some(418 RmrkCore::get_nft_property(collection_id, *token_id, RmrkProperty::ThemeName).unwrap().decode_or_default()414 RmrkCore::get_nft_property_decoded(collection_id, *token_id, RmrkProperty::ThemeName).unwrap()419 ),415 ),420 _ => None416 _ => None421 }417 }441 .find_map(|token_id| {437 .find_map(|token_id| {442 RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Theme).ok()?;438 RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Theme).ok()?;443439444 let name: RmrkString = RmrkCore::get_nft_property(440 let name: RmrkString = RmrkCore::get_nft_property_decoded(445 collection_id, token_id, RmrkProperty::ThemeName441 collection_id, token_id, RmrkProperty::ThemeName446 ).ok()?.decode_or_default();442 ).ok()?;447443448 if name == theme_name {444 if name == theme_name {449 Some((name, token_id))445 Some((name, token_id))467 }463 }468 )?;464 )?;469465470 let inherit = RmrkCore::get_nft_property(466 let inherit = RmrkCore::get_nft_property_decoded(471 collection_id,467 collection_id,472 theme_id,468 theme_id,473 RmrkProperty::ThemeInherit469 RmrkProperty::ThemeInherit474 )?.decode_or_default();470 )?;475471476 let theme = RmrkTheme {472 let theme = RmrkTheme {477 name,473 name,