difftreelog
fix(rmrk) include pending children into nft_children RPC
in: master
3 files changed
pallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth20 pallet_prelude::*,21 transactional,22 BoundedVec,23 dispatch::DispatchResult,24};20use frame_system::{pallet_prelude::*, ensure_signed};25use frame_system::{pallet_prelude::*, ensure_signed};21use sp_runtime::{DispatchError, Permill, traits::StaticLookup};26use sp_runtime::{DispatchError, Permill, traits::StaticLookup};22use sp_std::vec::Vec;27use sp_std::{vec::Vec, collections::btree_set::BTreeSet};23use up_data_structs::{*, mapping::TokenAddressMapping};28use up_data_structs::{*, mapping::TokenAddressMapping};24use pallet_common::{29use pallet_common::{25 Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations,30 Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations,485349pub const NESTING_BUDGET: u32 = 5;54pub const NESTING_BUDGET: u32 = 5;5556type PendingTarget = (CollectionId, TokenId);57type PendingChild = (RmrkCollectionId, RmrkNftId);58type PendingChildrenMap = BTreeSet<PendingChild>;505951#[frame_support::pallet]60#[frame_support::pallet]52pub mod pallet {61pub mod pallet {383 [392 [384 Self::rmrk_property(TokenType, &NftType::Regular)?,393 Self::rmrk_property(TokenType, &NftType::Regular)?,385 Self::rmrk_property(Transferable, &transferable)?,394 Self::rmrk_property(Transferable, &transferable)?,386 Self::rmrk_property(PendingNftAccept, &false)?,395 Self::rmrk_property(PendingNftAccept, &None::<PendingTarget>)?,387 Self::rmrk_property(RoyaltyInfo, &royalty_info)?,396 Self::rmrk_property(RoyaltyInfo, &royalty_info)?,388 Self::rmrk_property(Metadata, &metadata)?,397 Self::rmrk_property(Metadata, &metadata)?,389 Self::rmrk_property(Equipped, &false)?,398 Self::rmrk_property(Equipped, &false)?,390 Self::rmrk_property(ResourcePriorities, &<Vec<u8>>::new())?,399 Self::rmrk_property(ResourcePriorities, &<Vec<u8>>::new())?,391 Self::rmrk_property(NextResourceId, &(0 as RmrkResourceId))?,400 Self::rmrk_property(NextResourceId, &(0 as RmrkResourceId))?,401 Self::rmrk_property(PendingChildren, &PendingChildrenMap::new())?,392 ]402 ]393 .into_iter(),403 .into_iter(),394 )404 )483 );493 );484494485 ensure!(495 ensure!(486 !Self::get_nft_property_decoded(496 Self::get_nft_property_decoded::<Option<PendingTarget>>(487 collection_id,497 collection_id,488 nft_id,498 nft_id,489 RmrkProperty::PendingNftAccept499 RmrkProperty::PendingNftAccept490 )?,500 )?.is_none(),491 <Error<T>>::NoPermission501 <Error<T>>::NoPermission492 );502 );493503524 collection.id,534 collection.id,525 nft_id,535 nft_id,526 PropertyScope::Rmrk,536 PropertyScope::Rmrk,527 Self::rmrk_property(PendingNftAccept, &approval_required)?,537 Self::rmrk_property::<Option<PendingTarget>>(538 PendingNftAccept,539 &Some((target_collection_id, target_nft_id.into()))540 )?,528 )?;541 )?;542543 Self::insert_pending_child(544 (target_collection_id, target_nft_id.into()),545 (rmrk_collection_id, rmrk_nft_id),546 )?;529 } else {547 } else {530 target_owner = T::CrossTokenAddressMapping::token_to_address(548 target_owner = T::CrossTokenAddressMapping::token_to_address(531 target_collection_id,549 target_collection_id,618 }636 }619 })?;637 })?;638639 let pending_target = Self::get_nft_property_decoded::<Option<PendingTarget>>(640 collection_id,641 nft_id,642 RmrkProperty::PendingNftAccept643 )?;644645 if let Some(pending_target) = pending_target {646 Self::remove_pending_child(pending_target, (rmrk_collection_id, rmrk_nft_id))?;620647621 <PalletNft<T>>::set_scoped_token_property(648 <PalletNft<T>>::set_scoped_token_property(622 collection.id,649 collection.id,623 nft_id,650 nft_id,624 PropertyScope::Rmrk,651 PropertyScope::Rmrk,625 Self::rmrk_property(PendingNftAccept, &false)?,652 Self::rmrk_property(PendingNftAccept, &None::<PendingTarget>)?,626 )?;653 )?;654 }627655628 Self::deposit_event(Event::NFTAccepted {656 Self::deposit_event(Event::NFTAccepted {629 sender,657 sender,663 <Error<T>>::NoAvailableNftId691 <Error<T>>::NoAvailableNftId664 );692 );665693666 ensure!(694667 Self::get_nft_property_decoded(695 let pending_target = Self::get_nft_property_decoded::<Option<PendingTarget>>(668 collection_id,696 collection_id,669 nft_id,697 nft_id,670 RmrkProperty::PendingNftAccept698 RmrkProperty::PendingNftAccept671 )?,699 )?;672 <Error<T>>::CannotRejectNonPendingNft700673 );701 match pending_target {702 Some(pending_target) => Self::remove_pending_child(pending_target, (rmrk_collection_id, rmrk_nft_id))?,703 None => return Err(<Error<T>>::CannotRejectNonPendingNft.into()),704 }674705675 Self::destroy_nft(706 Self::destroy_nft(676 cross_sender,707 cross_sender,1147 )1178 )1148 }1179 }11801181 fn insert_pending_child(1182 target: (CollectionId, TokenId),1183 child: (RmrkCollectionId, RmrkNftId),1184 ) -> DispatchResult {1185 Self::mutate_pending_child(target, |pending_children| {1186 pending_children.insert(child);1187 })1188 }11891190 fn remove_pending_child(1191 target: (CollectionId, TokenId),1192 child: (RmrkCollectionId, RmrkNftId),1193 ) -> DispatchResult {1194 Self::mutate_pending_child(target, |pending_children| {1195 pending_children.remove(&child);1196 })1197 }11981199 fn mutate_pending_child(1200 (target_collection_id, target_nft_id): (CollectionId, TokenId),1201 f: impl FnOnce(&mut PendingChildrenMap),1202 ) -> DispatchResult {1203 <PalletNft<T>>::try_mutate_token_aux_property(1204 target_collection_id,1205 target_nft_id,1206 PropertyScope::Rmrk,1207 Self::rmrk_property_key(PendingChildren)?,1208 |pending_children| -> DispatchResult {1209 let mut map = match pending_children {1210 Some(map) => Self::decode_property(map)?,1211 None => PendingChildrenMap::new(),1212 };12131214 f(&mut map);12151216 *pending_children = Some(Self::encode_property(&map)?);12171218 Ok(())1219 },1220 )1221 }12221223 fn iterate_pending_children(collection_id: CollectionId, nft_id: TokenId) -> Result<impl Iterator<Item=PendingChild>, DispatchError> {1224 let property = <PalletNft<T>>::token_aux_property((1225 collection_id,1226 nft_id,1227 PropertyScope::Rmrk,1228 Self::rmrk_property_key(PendingChildren)?1229 ));12301231 let pending_children = match property {1232 Some(map) => Self::decode_property(&map)?,1233 None => PendingChildrenMap::new(),1234 };12351236 Ok(pending_children.into_iter())1237 }114912381150 fn acquire_next_resource_id(1239 fn acquire_next_resource_id(1151 collection_id: CollectionId,1240 collection_id: CollectionId,1526 Value: Decode + Default,1615 Value: Decode + Default,1527 Mapper: Fn(Key, Value) -> R,1616 Mapper: Fn(Key, Value) -> R,1528 {1617 {1529 let key_prefix = Self::rmrk_property_key(UserProperty(b""))?;15301531 let properties = match token_id {1618 let properties = match token_id {1532 Some(token_id) => <PalletNft<T>>::token_properties((collection_id, token_id)),1619 Some(token_id) => <PalletNft<T>>::token_properties((collection_id, token_id)),1533 None => <PalletCommon<T>>::collection_properties(collection_id),1620 None => <PalletCommon<T>>::collection_properties(collection_id),1534 };1621 };153516221536 let properties = properties.into_iter().filter_map(move |(key, value)| {1623 let properties = properties.into_iter().filter_map(move |(key, value)| {1537 let key = key.as_slice().strip_prefix(key_prefix.as_slice())?;1624 let key = strip_key_prefix(&key, USER_PROPERTY_PREFIX)?;153816251539 let key: Key = key.to_vec().try_into().ok()?;1626 let key: Key = key.to_vec().try_into().ok()?;1540 let value: Value = value.decode().ok()?;1627 let value: Value = value.decode().ok()?;pallets/proxy-rmrk-core/src/property.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/property.rs
+++ b/pallets/proxy-rmrk-core/src/property.rs
@@ -15,9 +15,11 @@
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
use super::*;
+use up_data_structs::PropertyScope;
use core::convert::AsRef;
-const RESOURCE_ID_PREFIX: &str = "rsid-";
+pub const RESOURCE_ID_PREFIX: &str = "rsid-";
+pub const USER_PROPERTY_PREFIX: &str = "userprop-";
pub enum RmrkProperty<'r> {
Metadata,
@@ -31,6 +33,7 @@
NextResourceId,
ResourceId(RmrkResourceId),
PendingNftAccept,
+ PendingChildren,
Parts,
Base,
Src,
@@ -73,6 +76,7 @@
Self::NextResourceId => key!("next-resource-id"),
Self::ResourceId(id) => key!(RESOURCE_ID_PREFIX, id.to_le_bytes()),
Self::PendingNftAccept => key!("pending-nft-accept"),
+ Self::PendingChildren => key!("pending-children"),
Self::Parts => key!("parts"),
Self::Base => key!("base"),
Self::Src => key!("src"),
@@ -83,7 +87,19 @@
Self::ZIndex => key!("z-index"),
Self::ThemeName => key!("theme-name"),
Self::ThemeInherit => key!("theme-inherit"),
- Self::UserProperty(name) => key!("userprop-", name),
+ Self::UserProperty(name) => key!(USER_PROPERTY_PREFIX, name),
}
}
}
+
+pub fn strip_key_prefix(key: &PropertyKey, prefix: &str) -> Option<PropertyKey> {
+ let key_prefix = PropertyKey::try_from(prefix.as_bytes().to_vec()).ok()?;
+ let key_prefix = PropertyScope::Rmrk.apply(key_prefix).ok()?;
+
+ key.as_slice().strip_prefix(key_prefix.as_slice())?
+ .to_vec().try_into().ok()
+}
+
+pub fn is_valid_key_prefix(key: &PropertyKey, prefix: &str) -> bool {
+ strip_key_prefix(key, prefix).is_some()
+}
pallets/proxy-rmrk-core/src/rpc.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/rpc.rs
+++ b/pallets/proxy-rmrk-core/src/rpc.rs
@@ -132,17 +132,6 @@
Ok(
pallet_nonfungible::TokenChildren::<T>::iter_prefix((collection_id, nft_id))
.filter_map(|((child_collection, child_token), _)| {
- let is_pending = <Pallet<T>>::get_nft_property_decoded(
- child_collection,
- child_token,
- RmrkProperty::PendingNftAccept,
- )
- .ok()?;
-
- if is_pending {
- return None;
- }
-
let rmrk_child_collection =
<Pallet<T>>::rmrk_collection_id(child_collection).ok()?;
@@ -151,6 +140,13 @@
nft_id: child_token.0,
})
})
+ .chain(
+ <Pallet<T>>::iterate_pending_children(collection_id, nft_id)?
+ .map(|(child_collection, child_nft_id)| RmrkNftChild {
+ collection_id: child_collection,
+ nft_id: child_nft_id,
+ })
+ )
.collect(),
)
}
@@ -224,7 +220,11 @@
nft_id,
PropertyScope::Rmrk,
)
- .filter_map(|(_, value)| {
+ .filter_map(|(key, value)| {
+ if !is_valid_key_prefix(&key, RESOURCE_ID_PREFIX) {
+ return None;
+ }
+
let resource_info: RmrkResourceInfo = <Pallet<T>>::decode_property(&value).ok()?;
Some(resource_info)