difftreelog
feat(rmrk) benchmark reject_nft
in: master
3 files changed
pallets/proxy-rmrk-core/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/benchmarking.rs
+++ b/pallets/proxy-rmrk-core/src/benchmarking.rs
@@ -104,6 +104,10 @@
}
}
+ fn current_nft_id(&self) -> RmrkNftId {
+ self.current_nft_id
+ }
+
fn build<T: Config>(&mut self, owner: &T::AccountId) -> Result<RmrkNftId, DispatchError> {
create_max_nft::<T>(owner, self.collection_id)?;
self.current_nft_id += 1;
@@ -115,10 +119,11 @@
&mut self,
owner: &T::AccountId,
height: u32,
- ) -> Result<RmrkNftId, DispatchError> {
+ ) -> Result<(RmrkNftId, RmrkNftId), DispatchError> {
self.build::<T>(owner)?;
- let mut prev_nft_id = self.current_nft_id;
+ let root_nft_id = self.current_nft_id;
+ let mut prev_nft_id = root_nft_id;
for _ in 0..height {
self.build::<T>(owner)?;
@@ -141,7 +146,7 @@
let deepest_nft_id = self.current_nft_id;
- Ok(deepest_nft_id)
+ Ok((root_nft_id, deepest_nft_id))
}
}
@@ -207,7 +212,7 @@
let mut nft_builder = NftBuilder::new(collection_id);
let src_nft_id = nft_builder.build::<T>(&caller)?;
- let target_nft_id = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 2)?;
+ let (_, target_nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 2)?;
}: _(
RawOrigin::Signed(caller),
collection_id,
@@ -230,7 +235,7 @@
let mut target_nft_builder = NftBuilder::new(target_collection_id);
let fake_target_nft_id = target_nft_builder.build::<T>(&caller)?;
- let target_nft_id = target_nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
+ let (_, target_nft_id) = target_nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(
target_collection_id,
@@ -255,13 +260,46 @@
actual_new_owner
)
+ reject_nft {
+ let caller: T::AccountId = account("caller", 0, SEED);
+ let sender: T::AccountId = account("sender", 0, SEED);
+
+ create_max_collection::<T>(&sender)?;
+ let src_collection_id = 0;
+
+ create_max_collection::<T>(&caller)?;
+ let target_collection_id = 1;
+
+ let mut src_nft_builder = NftBuilder::new(src_collection_id);
+ let (src_root_nft_id, _) = src_nft_builder.build_tower::<T>(&sender, NESTING_BUDGET - 1)?;
+
+ let mut target_nft_builder = NftBuilder::new(target_collection_id);
+ let target_nft_id = target_nft_builder.build::<T>(&caller)?;
+
+ let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(
+ target_collection_id,
+ target_nft_id
+ );
+
+ <Pallet<T>>::send(
+ RawOrigin::Signed(sender.clone()).into(),
+ src_collection_id,
+ src_root_nft_id,
+ new_owner,
+ )?;
+ }: _(
+ RawOrigin::Signed(caller),
+ src_collection_id,
+ src_root_nft_id
+ )
+
set_property {
let caller: T::AccountId = account("caller", 0, SEED);
create_max_collection::<T>(&caller)?;
let collection_id = 0;
let mut nft_builder = NftBuilder::new(collection_id);
- let nft_id = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
+ let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
let key = create_data();
let value = create_data();
@@ -279,7 +317,7 @@
let collection_id = 0;
let mut nft_builder = NftBuilder::new(collection_id);
- let nft_id = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
+ let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
let priorities = create_u32_array();
}: _(
RawOrigin::Signed(caller),
@@ -296,7 +334,7 @@
let collection_id = 0;
let mut nft_builder = NftBuilder::new(collection_id);
- let nft_id = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
+ let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
let resource = create_basic_resource();
}: _(
RawOrigin::Signed(caller),
@@ -313,7 +351,7 @@
let collection_id = 0;
let mut nft_builder = NftBuilder::new(collection_id);
- let nft_id = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
+ let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
let resource = create_composable_resource();
}: _(
RawOrigin::Signed(caller),
@@ -330,7 +368,7 @@
let collection_id = 0;
let mut nft_builder = NftBuilder::new(collection_id);
- let nft_id = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
+ let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
let resource = create_slot_resource();
}: _(
RawOrigin::Signed(caller),
@@ -347,7 +385,7 @@
let collection_id = 0;
let mut nft_builder = NftBuilder::new(collection_id);
- let nft_id = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
+ let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;
let resource = create_basic_resource();
<Pallet<T>>::add_basic_resource(
@@ -376,7 +414,7 @@
let mut nft_builder = NftBuilder::new(collection_id);
let root_nft_id = 1;
- let nested_nft_id = nft_builder.build_tower::<T>(&admin, NESTING_BUDGET - 1)?;
+ let (_, nested_nft_id) = nft_builder.build_tower::<T>(&admin, NESTING_BUDGET - 1)?;
let resource = create_basic_resource();
let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::AccountId(caller.clone());
@@ -414,7 +452,7 @@
let mut nft_builder = NftBuilder::new(collection_id);
let root_nft_id = 1;
- let nested_nft_id = nft_builder.build_tower::<T>(&admin, NESTING_BUDGET - 1)?;
+ let (_, nested_nft_id) = nft_builder.build_tower::<T>(&admin, NESTING_BUDGET - 1)?;
let resource = create_basic_resource();
<Pallet<T>>::add_basic_resource(
pallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617#![cfg_attr(not(feature = "std"), no_std)]1819use frame_support::{pallet_prelude::*, transactional, BoundedVec, dispatch::DispatchResult};20use frame_system::{pallet_prelude::*, ensure_signed};21use sp_runtime::{DispatchError, Permill, traits::StaticLookup};22use sp_std::vec::Vec;23use up_data_structs::{*, mapping::TokenAddressMapping};24use pallet_common::{25 Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations,26};27use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle, TokenData};28use pallet_structure::{Pallet as PalletStructure, Error as StructureError};29use pallet_evm::account::CrossAccountId;30use core::convert::AsRef;3132pub use pallet::*;3334#[cfg(feature = "runtime-benchmarks")]35pub mod benchmarking;36pub mod misc;37pub mod property;38pub mod weights;3940pub type SelfWeightOf<T> = <T as Config>::WeightInfo;4142use weights::WeightInfo;43use misc::*;44pub use property::*;4546use RmrkProperty::*;4748pub const NESTING_BUDGET: u32 = 5;4950#[frame_support::pallet]51pub mod pallet {52 use super::*;53 use pallet_evm::account;5455 #[pallet::config]56 pub trait Config:57 frame_system::Config + pallet_common::Config + pallet_nonfungible::Config + account::Config58 {59 type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;60 type WeightInfo: WeightInfo;61 }6263 #[pallet::storage]64 #[pallet::getter(fn collection_index)]65 pub type CollectionIndex<T: Config> = StorageValue<_, RmrkCollectionId, ValueQuery>;6667 #[pallet::storage]68 pub type UniqueCollectionId<T: Config> =69 StorageMap<_, Twox64Concat, RmrkCollectionId, CollectionId, ValueQuery>;7071 #[pallet::pallet]72 #[pallet::generate_store(pub(super) trait Store)]73 pub struct Pallet<T>(_);7475 #[pallet::event]76 #[pallet::generate_deposit(pub(super) fn deposit_event)]77 pub enum Event<T: Config> {78 CollectionCreated {79 issuer: T::AccountId,80 collection_id: RmrkCollectionId,81 },82 CollectionDestroyed {83 issuer: T::AccountId,84 collection_id: RmrkCollectionId,85 },86 IssuerChanged {87 old_issuer: T::AccountId,88 new_issuer: T::AccountId,89 collection_id: RmrkCollectionId,90 },91 CollectionLocked {92 issuer: T::AccountId,93 collection_id: RmrkCollectionId,94 },95 NftMinted {96 owner: T::AccountId,97 collection_id: RmrkCollectionId,98 nft_id: RmrkNftId,99 },100 NFTBurned {101 owner: T::AccountId,102 nft_id: RmrkNftId,103 },104 NFTSent {105 sender: T::AccountId,106 recipient: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,107 collection_id: RmrkCollectionId,108 nft_id: RmrkNftId,109 approval_required: bool,110 },111 NFTAccepted {112 sender: T::AccountId,113 recipient: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,114 collection_id: RmrkCollectionId,115 nft_id: RmrkNftId,116 },117 NFTRejected {118 sender: T::AccountId,119 collection_id: RmrkCollectionId,120 nft_id: RmrkNftId,121 },122 PropertySet {123 collection_id: RmrkCollectionId,124 maybe_nft_id: Option<RmrkNftId>,125 key: RmrkKeyString,126 value: RmrkValueString,127 },128 ResourceAdded {129 nft_id: RmrkNftId,130 resource_id: RmrkResourceId,131 },132 ResourceRemoval {133 nft_id: RmrkNftId,134 resource_id: RmrkResourceId,135 },136 ResourceAccepted {137 nft_id: RmrkNftId,138 resource_id: RmrkResourceId,139 },140 ResourceRemovalAccepted {141 nft_id: RmrkNftId,142 resource_id: RmrkResourceId,143 },144 PrioritySet {145 collection_id: RmrkCollectionId,146 nft_id: RmrkNftId,147 },148 }149150 #[pallet::error]151 pub enum Error<T> {152 /* Unique-specific events */153 CorruptedCollectionType,154 NftTypeEncodeError,155 RmrkPropertyKeyIsTooLong,156 RmrkPropertyValueIsTooLong,157 UnableToDecodeRmrkData,158159 /* RMRK compatible events */160 CollectionNotEmpty,161 NoAvailableCollectionId,162 NoAvailableNftId,163 CollectionUnknown,164 NoPermission,165 NonTransferable,166 CollectionFullOrLocked,167 ResourceDoesntExist,168 CannotSendToDescendentOrSelf,169 CannotAcceptNonOwnedNft,170 CannotRejectNonOwnedNft,171 ResourceNotPending,172 }173174 #[pallet::call]175 impl<T: Config> Pallet<T> {176 /// Create a collection177 #[transactional]178 #[pallet::weight(<SelfWeightOf<T>>::create_collection())]179 pub fn create_collection(180 origin: OriginFor<T>,181 metadata: RmrkString,182 max: Option<u32>,183 symbol: RmrkCollectionSymbol,184 ) -> DispatchResult {185 let sender = ensure_signed(origin)?;186187 let limits = CollectionLimits {188 owner_can_transfer: Some(false),189 token_limit: max,190 ..Default::default()191 };192193 let data = CreateCollectionData {194 limits: Some(limits),195 token_prefix: symbol196 .into_inner()197 .try_into()198 .map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,199 permissions: Some(CollectionPermissions {200 nesting: Some(NestingPermissions {201 token_owner: true,202 admin: false,203 restricted: None,204205 permissive: false,206 }),207 ..Default::default()208 }),209 ..Default::default()210 };211212 let unique_collection_id = Self::init_collection(213 T::CrossAccountId::from_sub(sender.clone()),214 data,215 [216 Self::rmrk_property(Metadata, &metadata)?,217 Self::rmrk_property(CollectionType, &misc::CollectionType::Regular)?,218 ]219 .into_iter(),220 )?;221 let rmrk_collection_id = <CollectionIndex<T>>::get();222223 <UniqueCollectionId<T>>::insert(rmrk_collection_id, unique_collection_id);224225 <PalletCommon<T>>::set_scoped_collection_property(226 unique_collection_id,227 PropertyScope::Rmrk,228 Self::rmrk_property(RmrkInternalCollectionId, &rmrk_collection_id)?229 )?;230231 <CollectionIndex<T>>::mutate(|n| *n += 1);232233 Self::deposit_event(Event::CollectionCreated {234 issuer: sender,235 collection_id: rmrk_collection_id,236 });237238 Ok(())239 }240241 /// destroy collection242 #[transactional]243 #[pallet::weight(<SelfWeightOf<T>>::destroy_collection())]244 pub fn destroy_collection(245 origin: OriginFor<T>,246 collection_id: RmrkCollectionId,247 ) -> DispatchResult {248 let sender = ensure_signed(origin)?;249 let cross_sender = T::CrossAccountId::from_sub(sender.clone());250251 let collection = Self::get_typed_nft_collection(252 Self::unique_collection_id(collection_id)?,253 misc::CollectionType::Regular,254 )?;255 collection.check_is_external()?;256257 <PalletNft<T>>::destroy_collection(collection, &cross_sender)258 .map_err(Self::map_unique_err_to_proxy)?;259260 Self::deposit_event(Event::CollectionDestroyed {261 issuer: sender,262 collection_id,263 });264265 Ok(())266 }267268 /// Change the issuer of a collection269 ///270 /// Parameters:271 /// - `origin`: sender of the transaction272 /// - `collection_id`: collection id of the nft to change issuer of273 /// - `new_issuer`: Collection's new issuer274 #[transactional]275 #[pallet::weight(<SelfWeightOf<T>>::change_collection_issuer())]276 pub fn change_collection_issuer(277 origin: OriginFor<T>,278 collection_id: RmrkCollectionId,279 new_issuer: <T::Lookup as StaticLookup>::Source,280 ) -> DispatchResult {281 let sender = ensure_signed(origin)?;282283 let collection = Self::get_nft_collection(Self::unique_collection_id(collection_id)?)?;284 collection.check_is_external()?;285286 let new_issuer = T::Lookup::lookup(new_issuer)?;287288 Self::change_collection_owner(289 Self::unique_collection_id(collection_id)?,290 misc::CollectionType::Regular,291 sender.clone(),292 new_issuer.clone(),293 )?;294295 Self::deposit_event(Event::IssuerChanged {296 old_issuer: sender,297 new_issuer,298 collection_id,299 });300301 Ok(())302 }303304 /// lock collection305 #[transactional]306 #[pallet::weight(<SelfWeightOf<T>>::lock_collection())]307 pub fn lock_collection(308 origin: OriginFor<T>,309 collection_id: RmrkCollectionId,310 ) -> DispatchResult {311 let sender = ensure_signed(origin)?;312 let cross_sender = T::CrossAccountId::from_sub(sender.clone());313314 let collection = Self::get_typed_nft_collection(315 Self::unique_collection_id(collection_id)?,316 misc::CollectionType::Regular,317 )?;318 collection.check_is_external()?;319320 Self::check_collection_owner(&collection, &cross_sender)?;321322 let token_count = collection.total_supply();323324 let mut collection = collection.into_inner();325 collection.limits.token_limit = Some(token_count);326 collection.save()?;327328 Self::deposit_event(Event::CollectionLocked {329 issuer: sender,330 collection_id,331 });332333 Ok(())334 }335336 /// Mints an NFT in the specified collection337 /// Sets metadata and the royalty attribute338 ///339 /// Parameters:340 /// - `collection_id`: The class of the asset to be minted.341 /// - `nft_id`: The nft value of the asset to be minted.342 /// - `recipient`: Receiver of the royalty343 /// - `royalty`: Permillage reward from each trade for the Recipient344 /// - `metadata`: Arbitrary data about an nft, e.g. IPFS hash345 /// - `transferable`: Ability to transfer this NFT346 #[transactional]347 #[pallet::weight(<SelfWeightOf<T>>::mint_nft())]348 pub fn mint_nft(349 origin: OriginFor<T>,350 owner: T::AccountId,351 collection_id: RmrkCollectionId,352 recipient: Option<T::AccountId>,353 royalty_amount: Option<Permill>,354 metadata: RmrkString,355 transferable: bool,356 ) -> DispatchResult {357 let sender = ensure_signed(origin)?;358 let sender = T::CrossAccountId::from_sub(sender);359 let cross_owner = T::CrossAccountId::from_sub(owner.clone());360361 let collection = Self::get_typed_nft_collection(362 Self::unique_collection_id(collection_id)?,363 misc::CollectionType::Regular,364 )?;365 collection.check_is_external()?;366367 let royalty_info = royalty_amount.map(|amount| rmrk_traits::RoyaltyInfo {368 recipient: recipient.unwrap_or_else(|| owner.clone()),369 amount,370 });371372 let nft_id = Self::create_nft(373 &sender,374 &cross_owner,375 &collection,376 [377 Self::rmrk_property(TokenType, &NftType::Regular)?,378 Self::rmrk_property(Transferable, &transferable)?,379 Self::rmrk_property(PendingNftAccept, &false)?,380 Self::rmrk_property(RoyaltyInfo, &royalty_info)?,381 Self::rmrk_property(Metadata, &metadata)?,382 Self::rmrk_property(Equipped, &false)?,383 Self::rmrk_property(ResourceCollection, &None::<CollectionId>)?,384 Self::rmrk_property(ResourcePriorities, &<Vec<u8>>::new())?,385 ]386 .into_iter(),387 )388 .map_err(|err| match err {389 DispatchError::Arithmetic(_) => <Error<T>>::NoAvailableNftId.into(),390 err => Self::map_unique_err_to_proxy(err),391 })?;392393 Self::deposit_event(Event::NftMinted {394 owner,395 collection_id,396 nft_id: nft_id.0,397 });398399 Ok(())400 }401402 /// burn nft403 #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]404 #[transactional]405 pub fn burn_nft(406 origin: OriginFor<T>,407 collection_id: RmrkCollectionId,408 nft_id: RmrkNftId,409 max_burns: u32,410 ) -> DispatchResult {411 let sender = ensure_signed(origin)?;412 let cross_sender = T::CrossAccountId::from_sub(sender.clone());413414 let collection = Self::get_typed_nft_collection(415 Self::unique_collection_id(collection_id)?,416 misc::CollectionType::Regular,417 )?;418 collection.check_is_external()?;419420 Self::destroy_nft(421 cross_sender,422 Self::unique_collection_id(collection_id)?,423 nft_id.into(),424 max_burns,425 <Error<T>>::NoPermission,426 )427 .map_err(|err| Self::map_unique_err_to_proxy(err.error))?;428429 Self::deposit_event(Event::NFTBurned {430 owner: sender,431 nft_id,432 });433434 Ok(())435 }436437 /// Transfers a NFT from an Account or NFT A to another Account or NFT B438 ///439 /// Parameters:440 /// - `origin`: sender of the transaction441 /// - `rmrk_collection_id`: collection id of the nft to be transferred442 /// - `rmrk_nft_id`: nft id of the nft to be transferred443 /// - `new_owner`: new owner of the nft which can be either an account or a NFT444 #[transactional]445 #[pallet::weight(<SelfWeightOf<T>>::send())]446 pub fn send(447 origin: OriginFor<T>,448 rmrk_collection_id: RmrkCollectionId,449 rmrk_nft_id: RmrkNftId,450 new_owner: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,451 ) -> DispatchResult {452 let sender = ensure_signed(origin.clone())?;453 let cross_sender = T::CrossAccountId::from_sub(sender.clone());454455 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;456 let nft_id = rmrk_nft_id.into();457458 let collection =459 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;460 collection.check_is_external()?;461462 let token_data =463 <TokenData<T>>::get((collection_id, nft_id)).ok_or(<Error<T>>::NoAvailableNftId)?;464465 let from = token_data.owner;466467 ensure!(468 Self::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Transferable)?,469 <Error<T>>::NonTransferable470 );471472 ensure!(473 !Self::get_nft_property_decoded(474 collection_id,475 nft_id,476 RmrkProperty::PendingNftAccept477 )?,478 <Error<T>>::NoPermission479 );480481 let target_owner;482 let approval_required;483484 match new_owner {485 RmrkAccountIdOrCollectionNftTuple::AccountId(ref account_id) => {486 target_owner = T::CrossAccountId::from_sub(account_id.clone());487 approval_required = false;488 }489 RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(490 target_collection_id,491 target_nft_id,492 ) => {493 let target_collection_id = Self::unique_collection_id(target_collection_id)?;494495 let target_nft_budget = budget::Value::new(NESTING_BUDGET);496497 let target_nft_owner = <PalletStructure<T>>::get_checked_topmost_owner(498 target_collection_id,499 target_nft_id.into(),500 Some((collection_id, nft_id)),501 &target_nft_budget,502 )503 .map_err(Self::map_unique_err_to_proxy)?;504505 approval_required = cross_sender != target_nft_owner;506507 if approval_required {508 target_owner = target_nft_owner;509510 <PalletNft<T>>::set_scoped_token_property(511 collection.id,512 nft_id,513 PropertyScope::Rmrk,514 Self::rmrk_property(PendingNftAccept, &approval_required)?,515 )?;516 } else {517 target_owner = T::CrossTokenAddressMapping::token_to_address(518 target_collection_id,519 target_nft_id.into(),520 );521 }522 }523 }524525 let src_nft_budget = budget::Value::new(NESTING_BUDGET);526527 <PalletNft<T>>::transfer_from(528 &collection,529 &cross_sender,530 &from,531 &target_owner,532 nft_id,533 &src_nft_budget,534 )535 .map_err(Self::map_unique_err_to_proxy)?;536537 Self::deposit_event(Event::NFTSent {538 sender,539 recipient: new_owner,540 collection_id: rmrk_collection_id,541 nft_id: rmrk_nft_id,542 approval_required,543 });544545 Ok(())546 }547548 /// Accepts an NFT sent from another account to self or owned NFT549 ///550 /// Parameters:551 /// - `origin`: sender of the transaction552 /// - `rmrk_collection_id`: collection id of the nft to be accepted553 /// - `rmrk_nft_id`: nft id of the nft to be accepted554 /// - `new_owner`: either origin's account ID or origin-owned NFT, whichever the NFT was555 /// sent to556 #[transactional]557 #[pallet::weight(<SelfWeightOf<T>>::accept_nft())]558 pub fn accept_nft(559 origin: OriginFor<T>,560 rmrk_collection_id: RmrkCollectionId,561 rmrk_nft_id: RmrkNftId,562 new_owner: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,563 ) -> DispatchResult {564 let sender = ensure_signed(origin.clone())?;565 let cross_sender = T::CrossAccountId::from_sub(sender.clone());566567 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;568 let nft_id = rmrk_nft_id.into();569570 let collection =571 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;572 collection.check_is_external()?;573574 let new_cross_owner = match new_owner {575 RmrkAccountIdOrCollectionNftTuple::AccountId(ref account_id) => {576 T::CrossAccountId::from_sub(account_id.clone())577 }578 RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(579 target_collection_id,580 target_nft_id,581 ) => {582 let target_collection_id = Self::unique_collection_id(target_collection_id)?;583584 T::CrossTokenAddressMapping::token_to_address(585 target_collection_id,586 TokenId(target_nft_id),587 )588 }589 };590591 let budget = budget::Value::new(NESTING_BUDGET);592593 <PalletNft<T>>::transfer(594 &collection,595 &cross_sender,596 &new_cross_owner,597 nft_id,598 &budget,599 )600 .map_err(|err| {601 if err == <CommonError<T>>::UserIsNotAllowedToNest.into() {602 <Error<T>>::CannotAcceptNonOwnedNft.into()603 } else {604 Self::map_unique_err_to_proxy(err)605 }606 })?;607608 <PalletNft<T>>::set_scoped_token_property(609 collection.id,610 nft_id,611 PropertyScope::Rmrk,612 Self::rmrk_property(PendingNftAccept, &false)?,613 )?;614615 Self::deposit_event(Event::NFTAccepted {616 sender,617 recipient: new_owner,618 collection_id: rmrk_collection_id,619 nft_id: rmrk_nft_id,620 });621622 Ok(())623 }624625 /// Rejects an NFT sent from another account to self or owned NFT626 ///627 /// Parameters:628 /// - `origin`: sender of the transaction629 /// - `rmrk_collection_id`: collection id of the nft to be accepted630 /// - `rmrk_nft_id`: nft id of the nft to be accepted631 #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]632 #[transactional]633 pub fn reject_nft(634 origin: OriginFor<T>,635 rmrk_collection_id: RmrkCollectionId,636 rmrk_nft_id: RmrkNftId,637 ) -> DispatchResult {638 let sender = ensure_signed(origin)?;639 let cross_sender = T::CrossAccountId::from_sub(sender.clone());640641 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;642 let nft_id = rmrk_nft_id.into();643644 let collection =645 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;646 collection.check_is_external()?;647648 ensure!(649 Self::get_nft_property_decoded(650 collection_id,651 nft_id,652 RmrkProperty::PendingNftAccept653 )?,654 <Error<T>>::NoPermission655 );656657 Self::destroy_nft(658 cross_sender,659 collection_id,660 nft_id,661 NESTING_BUDGET,662 <Error<T>>::CannotRejectNonOwnedNft,663 )664 .map_err(|err| Self::map_unique_err_to_proxy(err.error))?;665666 Self::deposit_event(Event::NFTRejected {667 sender,668 collection_id: rmrk_collection_id,669 nft_id: rmrk_nft_id,670 });671672 Ok(())673 }674675 /// accept the addition of a new resource to an existing NFT676 #[transactional]677 #[pallet::weight(<SelfWeightOf<T>>::accept_resource())]678 pub fn accept_resource(679 origin: OriginFor<T>,680 rmrk_collection_id: RmrkCollectionId,681 rmrk_nft_id: RmrkNftId,682 rmrk_resource_id: RmrkResourceId,683 ) -> DispatchResult {684 let sender = ensure_signed(origin)?;685 let cross_sender = T::CrossAccountId::from_sub(sender);686687 let collection_id = Self::unique_collection_id(rmrk_collection_id)688 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;689 let collection =690 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;691 collection.check_is_external()?;692693 let nft_id = rmrk_nft_id.into();694 let resource_id = rmrk_resource_id.into();695696 let budget = budget::Value::new(NESTING_BUDGET);697698 let nft_owner =699 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)700 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;701702 let resource_collection_id: Option<CollectionId> =703 Self::get_nft_property_decoded(collection_id, nft_id, ResourceCollection)704 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;705706 let resource_collection_id =707 resource_collection_id.ok_or(<Error<T>>::ResourceDoesntExist)?;708709 let is_pending: bool = Self::get_nft_property_decoded(710 resource_collection_id,711 resource_id,712 PendingResourceAccept,713 )714 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;715716 ensure!(is_pending, <Error<T>>::ResourceNotPending);717718 ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);719720 <PalletNft<T>>::set_scoped_token_property(721 resource_collection_id,722 rmrk_resource_id.into(),723 PropertyScope::Rmrk,724 Self::rmrk_property(PendingResourceAccept, &false)?,725 )?;726727 Self::deposit_event(Event::<T>::ResourceAccepted {728 nft_id: rmrk_nft_id,729 resource_id: rmrk_resource_id,730 });731732 Ok(())733 }734735 /// accept the removal of a resource of an existing NFT736 #[transactional]737 #[pallet::weight(<SelfWeightOf<T>>::accept_resource_removal())]738 pub fn accept_resource_removal(739 origin: OriginFor<T>,740 rmrk_collection_id: RmrkCollectionId,741 rmrk_nft_id: RmrkNftId,742 rmrk_resource_id: RmrkResourceId,743 ) -> DispatchResult {744 let sender = ensure_signed(origin)?;745 let cross_sender = T::CrossAccountId::from_sub(sender);746747 let collection_id = Self::unique_collection_id(rmrk_collection_id)748 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;749 let collection =750 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;751 collection.check_is_external()?;752753 let nft_id = rmrk_nft_id.into();754 let resource_id = rmrk_resource_id.into();755756 let budget = budget::Value::new(NESTING_BUDGET);757758 let nft_owner =759 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)760 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;761762 ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);763764 let resource_collection_id: Option<CollectionId> =765 Self::get_nft_property_decoded(collection_id, nft_id, ResourceCollection)766 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;767768 let resource_collection_id =769 resource_collection_id.ok_or(<Error<T>>::ResourceDoesntExist)?;770771 let is_pending: bool = Self::get_nft_property_decoded(772 resource_collection_id,773 resource_id,774 PendingResourceRemoval,775 )776 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;777778 ensure!(is_pending, <Error<T>>::ResourceNotPending);779780 let resource_collection = Self::get_typed_nft_collection(781 resource_collection_id,782 misc::CollectionType::Resource,783 )?;784785 let resource_data = <TokenData<T>>::get((resource_collection_id, resource_id))786 .ok_or(<Error<T>>::ResourceDoesntExist)?;787788 let resource_owner = resource_data.owner;789790 <PalletNft<T>>::burn(791 &resource_collection,792 &resource_owner,793 rmrk_resource_id.into(),794 )795 .map_err(Self::map_unique_err_to_proxy)?;796797 Self::deposit_event(Event::<T>::ResourceRemovalAccepted {798 nft_id: rmrk_nft_id,799 resource_id: rmrk_resource_id,800 });801802 Ok(())803 }804805 /// set a custom value on an NFT806 #[transactional]807 #[pallet::weight(<SelfWeightOf<T>>::set_property())]808 pub fn set_property(809 origin: OriginFor<T>,810 #[pallet::compact] rmrk_collection_id: RmrkCollectionId,811 maybe_nft_id: Option<RmrkNftId>,812 key: RmrkKeyString,813 value: RmrkValueString,814 ) -> DispatchResult {815 let sender = ensure_signed(origin)?;816 let sender = T::CrossAccountId::from_sub(sender);817818 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;819 let collection =820 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;821 collection.check_is_external()?;822823 let budget = budget::Value::new(NESTING_BUDGET);824825 match maybe_nft_id {826 Some(nft_id) => {827 let token_id: TokenId = nft_id.into();828829 Self::ensure_nft_type(collection_id, token_id, NftType::Regular)?;830 Self::ensure_nft_owner(collection_id, token_id, &sender, &budget)?;831832 <PalletNft<T>>::set_scoped_token_property(833 collection_id,834 token_id,835 PropertyScope::Rmrk,836 Self::rmrk_property(UserProperty(key.as_slice()), &value)?,837 )?;838 }839 None => {840 let collection = Self::get_typed_nft_collection(841 collection_id,842 misc::CollectionType::Regular,843 )?;844845 Self::check_collection_owner(&collection, &sender)?;846847 <PalletCommon<T>>::set_scoped_collection_property(848 collection_id,849 PropertyScope::Rmrk,850 Self::rmrk_property(UserProperty(key.as_slice()), &value)?,851 )?;852 }853 }854855 Self::deposit_event(Event::PropertySet {856 collection_id: rmrk_collection_id,857 maybe_nft_id,858 key,859 value,860 });861862 Ok(())863 }864865 /// set a different order of resource priority866 #[transactional]867 #[pallet::weight(<SelfWeightOf<T>>::set_priority())]868 pub fn set_priority(869 origin: OriginFor<T>,870 rmrk_collection_id: RmrkCollectionId,871 rmrk_nft_id: RmrkNftId,872 priorities: BoundedVec<RmrkResourceId, RmrkMaxPriorities>,873 ) -> DispatchResult {874 let sender = ensure_signed(origin)?;875 let sender = T::CrossAccountId::from_sub(sender);876877 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;878 let nft_id = rmrk_nft_id.into();879880 let collection =881 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;882 collection.check_is_external()?;883884 let budget = budget::Value::new(NESTING_BUDGET);885886 Self::ensure_nft_type(collection_id, nft_id, NftType::Regular)?;887 Self::ensure_nft_owner(collection_id, nft_id, &sender, &budget)?;888889 <PalletNft<T>>::set_scoped_token_property(890 collection_id,891 nft_id,892 PropertyScope::Rmrk,893 Self::rmrk_property(ResourcePriorities, &priorities.into_inner())?,894 )?;895896 Self::deposit_event(Event::<T>::PrioritySet {897 collection_id: rmrk_collection_id,898 nft_id: rmrk_nft_id,899 });900901 Ok(())902 }903904 /// Create basic resource905 #[transactional]906 #[pallet::weight(<SelfWeightOf<T>>::add_basic_resource())]907 pub fn add_basic_resource(908 origin: OriginFor<T>,909 rmrk_collection_id: RmrkCollectionId,910 nft_id: RmrkNftId,911 resource: RmrkBasicResource,912 ) -> DispatchResult {913 let sender = ensure_signed(origin.clone())?;914915 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;916 let collection =917 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;918 collection.check_is_external()?;919920 let resource_id = Self::resource_add(921 sender,922 collection_id,923 nft_id.into(),924 [925 Self::rmrk_property(TokenType, &NftType::Resource)?,926 Self::rmrk_property(ResourceType, &misc::ResourceType::Basic)?,927 Self::rmrk_property(Src, &resource.src)?,928 Self::rmrk_property(Metadata, &resource.metadata)?,929 Self::rmrk_property(License, &resource.license)?,930 Self::rmrk_property(Thumb, &resource.thumb)?,931 ]932 .into_iter(),933 )?;934935 Self::deposit_event(Event::ResourceAdded {936 nft_id,937 resource_id,938 });939 Ok(())940 }941942 /// Create composable resource943 #[transactional]944 #[pallet::weight(<SelfWeightOf<T>>::add_composable_resource())]945 pub fn add_composable_resource(946 origin: OriginFor<T>,947 rmrk_collection_id: RmrkCollectionId,948 nft_id: RmrkNftId,949 resource: RmrkComposableResource,950 ) -> DispatchResult {951 let sender = ensure_signed(origin.clone())?;952953 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;954 let collection =955 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;956 collection.check_is_external()?;957958 let resource_id = Self::resource_add(959 sender,960 collection_id,961 nft_id.into(),962 [963 Self::rmrk_property(TokenType, &NftType::Resource)?,964 Self::rmrk_property(ResourceType, &misc::ResourceType::Composable)?,965 Self::rmrk_property(Parts, &resource.parts)?,966 Self::rmrk_property(Base, &resource.base)?,967 Self::rmrk_property(Src, &resource.src)?,968 Self::rmrk_property(Metadata, &resource.metadata)?,969 Self::rmrk_property(License, &resource.license)?,970 Self::rmrk_property(Thumb, &resource.thumb)?,971 ]972 .into_iter(),973 )?;974975 Self::deposit_event(Event::ResourceAdded {976 nft_id,977 resource_id,978 });979 Ok(())980 }981982 /// Create slot resource983 #[transactional]984 #[pallet::weight(<SelfWeightOf<T>>::add_slot_resource())]985 pub fn add_slot_resource(986 origin: OriginFor<T>,987 rmrk_collection_id: RmrkCollectionId,988 nft_id: RmrkNftId,989 resource: RmrkSlotResource,990 ) -> DispatchResult {991 let sender = ensure_signed(origin.clone())?;992993 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;994 let collection =995 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;996 collection.check_is_external()?;997998 let resource_id = Self::resource_add(999 sender,1000 collection_id,1001 nft_id.into(),1002 [1003 Self::rmrk_property(TokenType, &NftType::Resource)?,1004 Self::rmrk_property(ResourceType, &misc::ResourceType::Slot)?,1005 Self::rmrk_property(Base, &resource.base)?,1006 Self::rmrk_property(Src, &resource.src)?,1007 Self::rmrk_property(Metadata, &resource.metadata)?,1008 Self::rmrk_property(Slot, &resource.slot)?,1009 Self::rmrk_property(License, &resource.license)?,1010 Self::rmrk_property(Thumb, &resource.thumb)?,1011 ]1012 .into_iter(),1013 )?;10141015 Self::deposit_event(Event::ResourceAdded {1016 nft_id,1017 resource_id,1018 });1019 Ok(())1020 }10211022 /// remove resource1023 #[transactional]1024 #[pallet::weight(<SelfWeightOf<T>>::remove_resource())]1025 pub fn remove_resource(1026 origin: OriginFor<T>,1027 rmrk_collection_id: RmrkCollectionId,1028 nft_id: RmrkNftId,1029 resource_id: RmrkResourceId,1030 ) -> DispatchResult {1031 let sender = ensure_signed(origin.clone())?;10321033 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1034 let collection =1035 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1036 collection.check_is_external()?;10371038 Self::resource_remove(sender, collection_id, nft_id.into(), resource_id.into())?;10391040 Self::deposit_event(Event::ResourceRemoval {1041 nft_id,1042 resource_id,1043 });1044 Ok(())1045 }1046 }1047}10481049impl<T: Config> Pallet<T> {1050 pub fn rmrk_property_key(rmrk_key: RmrkProperty) -> Result<PropertyKey, DispatchError> {1051 let key = rmrk_key.to_key::<T>()?;10521053 let scoped_key = PropertyScope::Rmrk1054 .apply(key)1055 .map_err(|_| <Error<T>>::RmrkPropertyKeyIsTooLong)?;10561057 Ok(scoped_key)1058 }10591060 // todo think about renaming these1061 pub fn rmrk_property<E: Encode>(1062 rmrk_key: RmrkProperty,1063 value: &E,1064 ) -> Result<Property, DispatchError> {1065 let key = rmrk_key.to_key::<T>()?;10661067 let value = value1068 .encode()1069 .try_into()1070 .map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong)?;10711072 let property = Property { key, value };10731074 Ok(property)1075 }10761077 pub fn decode_property<D: Decode>(vec: PropertyValue) -> Result<D, DispatchError> {1078 vec.decode()1079 .map_err(|_| <Error<T>>::UnableToDecodeRmrkData.into())1080 }10811082 pub fn rebind<L, S>(vec: &BoundedVec<u8, L>) -> Result<BoundedVec<u8, S>, DispatchError>1083 where1084 BoundedVec<u8, S>: TryFrom<Vec<u8>>,1085 {1086 vec.rebind()1087 .map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong.into())1088 }10891090 fn init_collection(1091 sender: T::CrossAccountId,1092 data: CreateCollectionData<T::AccountId>,1093 properties: impl Iterator<Item = Property>,1094 ) -> Result<CollectionId, DispatchError> {1095 let collection_id = <PalletNft<T>>::init_collection(sender, data, true);10961097 if let Err(DispatchError::Arithmetic(_)) = &collection_id {1098 return Err(<Error<T>>::NoAvailableCollectionId.into());1099 }11001101 <PalletCommon<T>>::set_scoped_collection_properties(1102 collection_id?,1103 PropertyScope::Rmrk,1104 properties,1105 )?;11061107 collection_id1108 }11091110 pub fn create_nft(1111 sender: &T::CrossAccountId,1112 owner: &T::CrossAccountId,1113 collection: &NonfungibleHandle<T>,1114 properties: impl Iterator<Item = Property>,1115 ) -> Result<TokenId, DispatchError> {1116 let data = CreateNftExData {1117 properties: BoundedVec::default(),1118 owner: owner.clone(),1119 };11201121 let budget = budget::Value::new(NESTING_BUDGET);11221123 <PalletNft<T>>::create_item(collection, sender, data, &budget)?;11241125 let nft_id = <PalletNft<T>>::current_token_id(collection.id);11261127 <PalletNft<T>>::set_scoped_token_properties(1128 collection.id,1129 nft_id,1130 PropertyScope::Rmrk,1131 properties,1132 )?;11331134 Ok(nft_id)1135 }11361137 fn destroy_nft(1138 sender: T::CrossAccountId,1139 collection_id: CollectionId,1140 token_id: TokenId,1141 max_burns: u32,1142 error_if_not_owned: Error<T>,1143 ) -> DispatchResultWithPostInfo {1144 let collection =1145 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;11461147 let token_data =1148 <TokenData<T>>::get((collection_id, token_id)).ok_or(<Error<T>>::NoAvailableNftId)?;11491150 let from = token_data.owner;11511152 let owner_check_budget = budget::Value::new(NESTING_BUDGET);11531154 ensure!(1155 <PalletStructure<T>>::check_indirectly_owned(1156 sender.clone(),1157 collection_id,1158 token_id,1159 None,1160 &owner_check_budget1161 )?,1162 error_if_not_owned,1163 );11641165 let burns_budget = budget::Value::new(max_burns);1166 let breadth_budget = budget::Value::new(max_burns);11671168 <PalletNft<T>>::burn_recursively(1169 &collection,1170 &from,1171 token_id,1172 &burns_budget,1173 &breadth_budget,1174 )1175 }11761177 fn resource_add(1178 sender: T::AccountId,1179 collection_id: CollectionId,1180 token_id: TokenId,1181 resource_properties: impl Iterator<Item = Property>,1182 ) -> Result<RmrkResourceId, DispatchError> {1183 let collection =1184 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1185 ensure!(collection.owner == sender, Error::<T>::NoPermission);11861187 let sender = T::CrossAccountId::from_sub(sender);1188 let budget = budget::Value::new(NESTING_BUDGET);11891190 let nft_owner = <PalletStructure<T>>::find_topmost_owner(collection_id, token_id, &budget)1191 .map_err(Self::map_unique_err_to_proxy)?;11921193 let pending = sender != nft_owner;11941195 let resource_collection_id: Option<CollectionId> =1196 Self::get_nft_property_decoded(collection_id, token_id, ResourceCollection)?;11971198 let resource_collection_id = match resource_collection_id {1199 Some(id) => id,1200 None => {1201 let resource_collection_id = Self::init_collection(1202 sender.clone(),1203 CreateCollectionData {1204 ..Default::default()1205 },1206 [Self::rmrk_property(1207 CollectionType,1208 &misc::CollectionType::Resource,1209 )?]1210 .into_iter(),1211 )?;12121213 <PalletNft<T>>::set_scoped_token_property(1214 collection_id,1215 token_id,1216 PropertyScope::Rmrk,1217 Self::rmrk_property(ResourceCollection, &Some(resource_collection_id))?,1218 )?;12191220 resource_collection_id1221 }1222 };12231224 let resource_collection =1225 Self::get_typed_nft_collection(resource_collection_id, misc::CollectionType::Resource)?;12261227 // todo probably add extra connections to bases, slots, etc., when RMRK starts to use them12281229 let resource_id = Self::create_nft(1230 &sender,1231 &nft_owner,1232 &resource_collection,1233 resource_properties.chain(1234 [1235 Self::rmrk_property(PendingResourceAccept, &pending)?,1236 Self::rmrk_property(PendingResourceRemoval, &false)?,1237 ]1238 .into_iter(),1239 ),1240 )1241 .map_err(|err| match err {1242 DispatchError::Arithmetic(_) => <Error<T>>::NoAvailableNftId.into(),1243 err => Self::map_unique_err_to_proxy(err),1244 })?;12451246 Ok(resource_id.0)1247 }12481249 fn resource_remove(1250 sender: T::AccountId,1251 collection_id: CollectionId,1252 nft_id: TokenId,1253 resource_id: TokenId,1254 ) -> DispatchResult {1255 let collection =1256 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1257 ensure!(collection.owner == sender, Error::<T>::NoPermission);12581259 let resource_collection_id: Option<CollectionId> =1260 Self::get_nft_property_decoded(collection_id, nft_id, ResourceCollection)?;12611262 let resource_collection_id =1263 resource_collection_id.ok_or(Error::<T>::ResourceDoesntExist)?;12641265 let resource_collection =1266 Self::get_typed_nft_collection(resource_collection_id, misc::CollectionType::Resource)?;1267 ensure!(1268 <PalletNft<T>>::token_exists(&resource_collection, resource_id),1269 Error::<T>::ResourceDoesntExist1270 );12711272 let budget = up_data_structs::budget::Value::new(NESTING_BUDGET);1273 let topmost_owner =1274 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)?;12751276 let sender = T::CrossAccountId::from_sub(sender);1277 if topmost_owner == sender {1278 <PalletNft<T>>::burn(&resource_collection, &sender, resource_id)1279 .map_err(Self::map_unique_err_to_proxy)?;1280 } else {1281 <PalletNft<T>>::set_scoped_token_property(1282 resource_collection_id,1283 resource_id,1284 PropertyScope::Rmrk,1285 Self::rmrk_property(PendingResourceRemoval, &true)?,1286 )?;1287 }12881289 Ok(())1290 }12911292 fn change_collection_owner(1293 collection_id: CollectionId,1294 collection_type: misc::CollectionType,1295 sender: T::AccountId,1296 new_owner: T::AccountId,1297 ) -> DispatchResult {1298 let collection = Self::get_typed_nft_collection(collection_id, collection_type)?;1299 Self::check_collection_owner(&collection, &T::CrossAccountId::from_sub(sender))?;13001301 let mut collection = collection.into_inner();13021303 collection.owner = new_owner;1304 collection.save()1305 }13061307 fn check_collection_owner(1308 collection: &NonfungibleHandle<T>,1309 account: &T::CrossAccountId,1310 ) -> DispatchResult {1311 collection1312 .check_is_owner(account)1313 .map_err(Self::map_unique_err_to_proxy)1314 }13151316 pub fn last_collection_idx() -> RmrkCollectionId {1317 <CollectionIndex<T>>::get()1318 }13191320 pub fn unique_collection_id(1321 rmrk_collection_id: RmrkCollectionId,1322 ) -> Result<CollectionId, DispatchError> {1323 <UniqueCollectionId<T>>::try_get(rmrk_collection_id)1324 .map_err(|_| <Error<T>>::CollectionUnknown.into())1325 }13261327 pub fn rmrk_collection_id(1328 unique_collection_id: CollectionId,1329 ) -> Result<RmrkCollectionId, DispatchError> {1330 Self::get_collection_property_decoded(1331 unique_collection_id,1332 RmrkInternalCollectionId1333 )1334 }13351336 pub fn get_nft_collection(1337 collection_id: CollectionId,1338 ) -> Result<NonfungibleHandle<T>, DispatchError> {1339 let collection = <CollectionHandle<T>>::try_get(collection_id)1340 .map_err(|_| <Error<T>>::CollectionUnknown)?;13411342 match collection.mode {1343 CollectionMode::NFT => Ok(NonfungibleHandle::cast(collection)),1344 _ => Err(<Error<T>>::CollectionUnknown.into()),1345 }1346 }13471348 pub fn collection_exists(collection_id: CollectionId) -> bool {1349 <CollectionHandle<T>>::try_get(collection_id).is_ok()1350 }13511352 pub fn get_collection_property(1353 collection_id: CollectionId,1354 key: RmrkProperty,1355 ) -> Result<PropertyValue, DispatchError> {1356 let collection_property = <PalletCommon<T>>::collection_properties(collection_id)1357 .get(&Self::rmrk_property_key(key)?)1358 .ok_or(<Error<T>>::CollectionUnknown)?1359 .clone();13601361 Ok(collection_property)1362 }13631364 pub fn get_collection_property_decoded<V: Decode>(1365 collection_id: CollectionId,1366 key: RmrkProperty,1367 ) -> Result<V, DispatchError> {1368 Self::decode_property(Self::get_collection_property(collection_id, key)?)1369 }13701371 pub fn get_collection_type(1372 collection_id: CollectionId,1373 ) -> Result<misc::CollectionType, DispatchError> {1374 Self::get_collection_property_decoded(collection_id, CollectionType)1375 .map_err(|_| <Error<T>>::CorruptedCollectionType.into())1376 }13771378 pub fn ensure_collection_type(1379 collection_id: CollectionId,1380 collection_type: misc::CollectionType,1381 ) -> DispatchResult {1382 let actual_type = Self::get_collection_type(collection_id)?;1383 ensure!(1384 actual_type == collection_type,1385 <CommonError<T>>::NoPermission1386 );13871388 Ok(())1389 }13901391 pub fn get_typed_nft_collection(1392 collection_id: CollectionId,1393 collection_type: misc::CollectionType,1394 ) -> Result<NonfungibleHandle<T>, DispatchError> {1395 Self::ensure_collection_type(collection_id, collection_type)?;13961397 Self::get_nft_collection(collection_id)1398 }13991400 pub fn get_typed_nft_collection_mapped(1401 rmrk_collection_id: RmrkCollectionId,1402 collection_type: misc::CollectionType,1403 ) -> Result<(NonfungibleHandle<T>, CollectionId), DispatchError> {1404 let unique_collection_id = match collection_type {1405 misc::CollectionType::Regular => Self::unique_collection_id(rmrk_collection_id)?,1406 _ => rmrk_collection_id.into(),1407 };14081409 let collection = Self::get_typed_nft_collection(unique_collection_id, collection_type)?;14101411 Ok((collection, unique_collection_id))1412 }14131414 pub fn get_nft_property(1415 collection_id: CollectionId,1416 nft_id: TokenId,1417 key: RmrkProperty,1418 ) -> Result<PropertyValue, DispatchError> {1419 let nft_property = <PalletNft<T>>::token_properties((collection_id, nft_id))1420 .get(&Self::rmrk_property_key(key)?)1421 .ok_or(<Error<T>>::NoAvailableNftId)? // todo replace with better error?1422 .clone();14231424 Ok(nft_property)1425 }14261427 pub fn get_nft_property_decoded<V: Decode>(1428 collection_id: CollectionId,1429 nft_id: TokenId,1430 key: RmrkProperty,1431 ) -> Result<V, DispatchError> {1432 Self::decode_property(Self::get_nft_property(collection_id, nft_id, key)?)1433 }14341435 pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {1436 <TokenData<T>>::contains_key((collection_id, nft_id))1437 }14381439 pub fn get_nft_type(1440 collection_id: CollectionId,1441 token_id: TokenId,1442 ) -> Result<NftType, DispatchError> {1443 Self::get_nft_property_decoded(collection_id, token_id, TokenType)1444 .map_err(|_| <Error<T>>::NoAvailableNftId.into())1445 }14461447 pub fn ensure_nft_type(1448 collection_id: CollectionId,1449 token_id: TokenId,1450 nft_type: NftType,1451 ) -> DispatchResult {1452 let actual_type = Self::get_nft_type(collection_id, token_id)?;1453 ensure!(actual_type == nft_type, <Error<T>>::NoPermission);14541455 Ok(())1456 }14571458 pub fn ensure_nft_owner(1459 collection_id: CollectionId,1460 token_id: TokenId,1461 possible_owner: &T::CrossAccountId,1462 nesting_budget: &dyn budget::Budget,1463 ) -> DispatchResult {1464 let is_owned = <PalletStructure<T>>::check_indirectly_owned(1465 possible_owner.clone(),1466 collection_id,1467 token_id,1468 None,1469 nesting_budget,1470 )1471 .map_err(Self::map_unique_err_to_proxy)?;14721473 ensure!(is_owned, <Error<T>>::NoPermission);14741475 Ok(())1476 }14771478 pub fn filter_user_properties<Key, Value, R, Mapper>(1479 collection_id: CollectionId,1480 token_id: Option<TokenId>,1481 filter_keys: Option<Vec<RmrkPropertyKey>>,1482 mapper: Mapper,1483 ) -> Result<Vec<R>, DispatchError>1484 where1485 Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,1486 Value: Decode + Default,1487 Mapper: Fn(Key, Value) -> R,1488 {1489 filter_keys1490 .map(|keys| {1491 let properties = keys1492 .into_iter()1493 .filter_map(|key| {1494 let key: Key = key.try_into().ok()?;14951496 let value = match token_id {1497 Some(token_id) => Self::get_nft_property_decoded(1498 collection_id,1499 token_id,1500 UserProperty(key.as_ref()),1501 ),1502 None => Self::get_collection_property_decoded(1503 collection_id,1504 UserProperty(key.as_ref()),1505 ),1506 }1507 .ok()?;15081509 Some(mapper(key, value))1510 })1511 .collect();15121513 Ok(properties)1514 })1515 .unwrap_or_else(|| {1516 let properties =1517 Self::iterate_user_properties(collection_id, token_id, mapper)?.collect();15181519 Ok(properties)1520 })1521 }15221523 pub fn iterate_user_properties<Key, Value, R, Mapper>(1524 collection_id: CollectionId,1525 token_id: Option<TokenId>,1526 mapper: Mapper,1527 ) -> Result<impl Iterator<Item = R>, DispatchError>1528 where1529 Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,1530 Value: Decode + Default,1531 Mapper: Fn(Key, Value) -> R,1532 {1533 let key_prefix = Self::rmrk_property_key(UserProperty(b""))?;15341535 let properties = match token_id {1536 Some(token_id) => <PalletNft<T>>::token_properties((collection_id, token_id)),1537 None => <PalletCommon<T>>::collection_properties(collection_id),1538 };15391540 let properties = properties.into_iter().filter_map(move |(key, value)| {1541 let key = key.as_slice().strip_prefix(key_prefix.as_slice())?;15421543 let key: Key = key.to_vec().try_into().ok()?;1544 let value: Value = value.decode().ok()?;15451546 Some(mapper(key, value))1547 });15481549 Ok(properties)1550 }15511552 fn map_unique_err_to_proxy(err: DispatchError) -> DispatchError {1553 map_unique_err_to_proxy! {1554 match err {1555 CommonError::NoPermission => NoPermission,1556 CommonError::CollectionTokenLimitExceeded => CollectionFullOrLocked,1557 CommonError::PublicMintingNotAllowed => NoPermission,1558 CommonError::TokenNotFound => NoAvailableNftId,1559 CommonError::ApprovedValueTooLow => NoPermission,1560 CommonError::CantDestroyNotEmptyCollection => CollectionNotEmpty,1561 StructureError::TokenNotFound => NoAvailableNftId,1562 StructureError::OuroborosDetected => CannotSendToDescendentOrSelf,1563 }1564 }1565 }1566}pallets/proxy-rmrk-core/src/weights.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/weights.rs
+++ b/pallets/proxy-rmrk-core/src/weights.rs
@@ -40,6 +40,7 @@
fn mint_nft() -> Weight;
fn send() -> Weight;
fn accept_nft() -> Weight;
+ fn reject_nft() -> Weight;
fn set_property() -> Weight;
fn set_priority() -> Weight;
fn add_basic_resource() -> Weight;
@@ -61,11 +62,10 @@
// Storage: Common CollectionProperties (r:0 w:1)
// Storage: Common CollectionById (r:0 w:1)
// Storage: RmrkCore UniqueCollectionId (r:0 w:1)
- // Storage: RmrkCore RmrkInernalCollectionId (r:0 w:1)
fn create_collection() -> Weight {
- (40_146_000 as Weight)
+ (40_456_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
- .saturating_add(T::DbWeight::get().writes(9 as Weight))
+ .saturating_add(T::DbWeight::get().writes(8 as Weight))
}
// Storage: RmrkCore UniqueCollectionId (r:1 w:0)
// Storage: Common CollectionProperties (r:1 w:1)
@@ -76,7 +76,7 @@
// Storage: Nonfungible TokensBurnt (r:0 w:1)
// Storage: Common AdminAmount (r:0 w:1)
fn destroy_collection() -> Weight {
- (44_905_000 as Weight)
+ (43_812_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
.saturating_add(T::DbWeight::get().writes(6 as Weight))
}
@@ -84,7 +84,7 @@
// Storage: Common CollectionById (r:1 w:1)
// Storage: Common CollectionProperties (r:1 w:0)
fn change_collection_issuer() -> Weight {
- (22_502_000 as Weight)
+ (22_032_000 as Weight)
.saturating_add(T::DbWeight::get().reads(3 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
@@ -94,7 +94,7 @@
// Storage: Nonfungible TokensMinted (r:1 w:0)
// Storage: Nonfungible TokensBurnt (r:1 w:0)
fn lock_collection() -> Weight {
- (23_705_000 as Weight)
+ (23_314_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
@@ -107,7 +107,7 @@
// Storage: Nonfungible TokenData (r:0 w:1)
// Storage: Nonfungible Owned (r:0 w:1)
fn mint_nft() -> Weight {
- (40_727_000 as Weight)
+ (40_075_000 as Weight)
.saturating_add(T::DbWeight::get().reads(6 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
}
@@ -121,7 +121,7 @@
// Storage: Nonfungible TokenChildren (r:0 w:1)
// Storage: Nonfungible Owned (r:0 w:2)
fn send() -> Weight {
- (73_288_000 as Weight)
+ (71_474_000 as Weight)
.saturating_add(T::DbWeight::get().reads(12 as Weight))
.saturating_add(T::DbWeight::get().writes(6 as Weight))
}
@@ -135,17 +135,32 @@
// Storage: Nonfungible TokenChildren (r:0 w:1)
// Storage: Nonfungible Owned (r:0 w:2)
fn accept_nft() -> Weight {
- (81_985_000 as Weight)
+ (79_890_000 as Weight)
.saturating_add(T::DbWeight::get().reads(15 as Weight))
.saturating_add(T::DbWeight::get().writes(7 as Weight))
}
// Storage: RmrkCore UniqueCollectionId (r:1 w:0)
// Storage: Common CollectionProperties (r:1 w:0)
// Storage: Common CollectionById (r:1 w:0)
+ // Storage: Nonfungible TokenProperties (r:1 w:5)
+ // Storage: Nonfungible TokenData (r:5 w:5)
+ // Storage: Nonfungible TokenChildren (r:9 w:4)
+ // Storage: Nonfungible TokensBurnt (r:1 w:1)
+ // Storage: Nonfungible AccountBalance (r:5 w:5)
+ // Storage: Nonfungible Allowance (r:5 w:0)
+ // Storage: Nonfungible Owned (r:0 w:5)
+ fn reject_nft() -> Weight {
+ (236_754_000 as Weight)
+ .saturating_add(T::DbWeight::get().reads(29 as Weight))
+ .saturating_add(T::DbWeight::get().writes(25 as Weight))
+ }
+ // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
+ // Storage: Common CollectionProperties (r:1 w:0)
+ // Storage: Common CollectionById (r:1 w:0)
// Storage: Nonfungible TokenProperties (r:1 w:1)
// Storage: Nonfungible TokenData (r:5 w:0)
fn set_property() -> Weight {
- (50_535_000 as Weight)
+ (48_370_000 as Weight)
.saturating_add(T::DbWeight::get().reads(9 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
@@ -155,7 +170,7 @@
// Storage: Nonfungible TokenProperties (r:1 w:1)
// Storage: Nonfungible TokenData (r:5 w:0)
fn set_priority() -> Weight {
- (49_443_000 as Weight)
+ (47_128_000 as Weight)
.saturating_add(T::DbWeight::get().reads(9 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
@@ -172,7 +187,7 @@
// Storage: Nonfungible Owned (r:0 w:1)
// Storage: Common CollectionPropertyPermissions (r:0 w:1)
fn add_basic_resource() -> Weight {
- (104_226_000 as Weight)
+ (101_501_000 as Weight)
.saturating_add(T::DbWeight::get().reads(16 as Weight))
.saturating_add(T::DbWeight::get().writes(12 as Weight))
}
@@ -189,7 +204,7 @@
// Storage: Nonfungible Owned (r:0 w:1)
// Storage: Common CollectionPropertyPermissions (r:0 w:1)
fn add_composable_resource() -> Weight {
- (105_197_000 as Weight)
+ (103_004_000 as Weight)
.saturating_add(T::DbWeight::get().reads(16 as Weight))
.saturating_add(T::DbWeight::get().writes(12 as Weight))
}
@@ -206,7 +221,7 @@
// Storage: Nonfungible Owned (r:0 w:1)
// Storage: Common CollectionPropertyPermissions (r:0 w:1)
fn add_slot_resource() -> Weight {
- (105_899_000 as Weight)
+ (102_613_000 as Weight)
.saturating_add(T::DbWeight::get().reads(16 as Weight))
.saturating_add(T::DbWeight::get().writes(12 as Weight))
}
@@ -221,7 +236,7 @@
// Storage: Nonfungible Allowance (r:1 w:0)
// Storage: Nonfungible Owned (r:0 w:1)
fn remove_resource() -> Weight {
- (82_997_000 as Weight)
+ (82_084_000 as Weight)
.saturating_add(T::DbWeight::get().reads(16 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
}
@@ -231,7 +246,7 @@
// Storage: Nonfungible TokenData (r:5 w:0)
// Storage: Nonfungible TokenProperties (r:2 w:1)
fn accept_resource() -> Weight {
- (56_848_000 as Weight)
+ (56_426_000 as Weight)
.saturating_add(T::DbWeight::get().reads(10 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
@@ -246,7 +261,7 @@
// Storage: Nonfungible Allowance (r:1 w:0)
// Storage: Nonfungible Owned (r:0 w:1)
fn accept_resource_removal() -> Weight {
- (86_303_000 as Weight)
+ (85_631_000 as Weight)
.saturating_add(T::DbWeight::get().reads(17 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
}
@@ -262,11 +277,10 @@
// Storage: Common CollectionProperties (r:0 w:1)
// Storage: Common CollectionById (r:0 w:1)
// Storage: RmrkCore UniqueCollectionId (r:0 w:1)
- // Storage: RmrkCore RmrkInernalCollectionId (r:0 w:1)
fn create_collection() -> Weight {
- (40_146_000 as Weight)
+ (40_456_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
- .saturating_add(RocksDbWeight::get().writes(9 as Weight))
+ .saturating_add(RocksDbWeight::get().writes(8 as Weight))
}
// Storage: RmrkCore UniqueCollectionId (r:1 w:0)
// Storage: Common CollectionProperties (r:1 w:1)
@@ -277,7 +291,7 @@
// Storage: Nonfungible TokensBurnt (r:0 w:1)
// Storage: Common AdminAmount (r:0 w:1)
fn destroy_collection() -> Weight {
- (44_905_000 as Weight)
+ (43_812_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(6 as Weight))
}
@@ -285,7 +299,7 @@
// Storage: Common CollectionById (r:1 w:1)
// Storage: Common CollectionProperties (r:1 w:0)
fn change_collection_issuer() -> Weight {
- (22_502_000 as Weight)
+ (22_032_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(3 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
@@ -295,7 +309,7 @@
// Storage: Nonfungible TokensMinted (r:1 w:0)
// Storage: Nonfungible TokensBurnt (r:1 w:0)
fn lock_collection() -> Weight {
- (23_705_000 as Weight)
+ (23_314_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
@@ -308,7 +322,7 @@
// Storage: Nonfungible TokenData (r:0 w:1)
// Storage: Nonfungible Owned (r:0 w:1)
fn mint_nft() -> Weight {
- (40_727_000 as Weight)
+ (40_075_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(6 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
}
@@ -322,7 +336,7 @@
// Storage: Nonfungible TokenChildren (r:0 w:1)
// Storage: Nonfungible Owned (r:0 w:2)
fn send() -> Weight {
- (73_288_000 as Weight)
+ (71_474_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(12 as Weight))
.saturating_add(RocksDbWeight::get().writes(6 as Weight))
}
@@ -336,17 +350,32 @@
// Storage: Nonfungible TokenChildren (r:0 w:1)
// Storage: Nonfungible Owned (r:0 w:2)
fn accept_nft() -> Weight {
- (81_985_000 as Weight)
+ (79_890_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(15 as Weight))
.saturating_add(RocksDbWeight::get().writes(7 as Weight))
}
// Storage: RmrkCore UniqueCollectionId (r:1 w:0)
// Storage: Common CollectionProperties (r:1 w:0)
// Storage: Common CollectionById (r:1 w:0)
+ // Storage: Nonfungible TokenProperties (r:1 w:5)
+ // Storage: Nonfungible TokenData (r:5 w:5)
+ // Storage: Nonfungible TokenChildren (r:9 w:4)
+ // Storage: Nonfungible TokensBurnt (r:1 w:1)
+ // Storage: Nonfungible AccountBalance (r:5 w:5)
+ // Storage: Nonfungible Allowance (r:5 w:0)
+ // Storage: Nonfungible Owned (r:0 w:5)
+ fn reject_nft() -> Weight {
+ (236_754_000 as Weight)
+ .saturating_add(RocksDbWeight::get().reads(29 as Weight))
+ .saturating_add(RocksDbWeight::get().writes(25 as Weight))
+ }
+ // Storage: RmrkCore UniqueCollectionId (r:1 w:0)
+ // Storage: Common CollectionProperties (r:1 w:0)
+ // Storage: Common CollectionById (r:1 w:0)
// Storage: Nonfungible TokenProperties (r:1 w:1)
// Storage: Nonfungible TokenData (r:5 w:0)
fn set_property() -> Weight {
- (50_535_000 as Weight)
+ (48_370_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(9 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
@@ -356,7 +385,7 @@
// Storage: Nonfungible TokenProperties (r:1 w:1)
// Storage: Nonfungible TokenData (r:5 w:0)
fn set_priority() -> Weight {
- (49_443_000 as Weight)
+ (47_128_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(9 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
@@ -373,7 +402,7 @@
// Storage: Nonfungible Owned (r:0 w:1)
// Storage: Common CollectionPropertyPermissions (r:0 w:1)
fn add_basic_resource() -> Weight {
- (104_226_000 as Weight)
+ (101_501_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(16 as Weight))
.saturating_add(RocksDbWeight::get().writes(12 as Weight))
}
@@ -390,7 +419,7 @@
// Storage: Nonfungible Owned (r:0 w:1)
// Storage: Common CollectionPropertyPermissions (r:0 w:1)
fn add_composable_resource() -> Weight {
- (105_197_000 as Weight)
+ (103_004_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(16 as Weight))
.saturating_add(RocksDbWeight::get().writes(12 as Weight))
}
@@ -407,7 +436,7 @@
// Storage: Nonfungible Owned (r:0 w:1)
// Storage: Common CollectionPropertyPermissions (r:0 w:1)
fn add_slot_resource() -> Weight {
- (105_899_000 as Weight)
+ (102_613_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(16 as Weight))
.saturating_add(RocksDbWeight::get().writes(12 as Weight))
}
@@ -422,7 +451,7 @@
// Storage: Nonfungible Allowance (r:1 w:0)
// Storage: Nonfungible Owned (r:0 w:1)
fn remove_resource() -> Weight {
- (82_997_000 as Weight)
+ (82_084_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(16 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
}
@@ -432,7 +461,7 @@
// Storage: Nonfungible TokenData (r:5 w:0)
// Storage: Nonfungible TokenProperties (r:2 w:1)
fn accept_resource() -> Weight {
- (56_848_000 as Weight)
+ (56_426_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(10 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
@@ -447,7 +476,7 @@
// Storage: Nonfungible Allowance (r:1 w:0)
// Storage: Nonfungible Owned (r:0 w:1)
fn accept_resource_removal() -> Weight {
- (86_303_000 as Weight)
+ (85_631_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(17 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
}