1use sp_std::vec;23use frame_benchmarking::{benchmarks, account};4use frame_system::RawOrigin;5use frame_support::{6 traits::{Currency, Get},7 BoundedVec,8};9use sp_runtime::Permill;1011use up_data_structs::*;1213use super::*;1415const SEED: u32 = 1;1617fn create_data<S: Get<u32>>() -> BoundedVec<u8, S> {18 vec![b'A'; S::get() as usize].try_into().expect("size == S")19}2021fn create_u32_array<S: Get<u32>>() -> BoundedVec<u32, S> {22 vec![0; S::get() as usize].try_into().expect("size == S")23}2425fn create_basic_resource() -> RmrkBasicResource {26 RmrkBasicResource {27 src: Some(create_data()),28 metadata: Some(create_data()),29 license: Some(create_data()),30 thumb: Some(create_data()),31 }32}3334fn create_composable_resource() -> RmrkComposableResource {35 RmrkComposableResource {36 parts: create_u32_array(),37 base: 100,38 src: Some(create_data()),39 metadata: Some(create_data()),40 license: Some(create_data()),41 thumb: Some(create_data()),42 }43}4445fn create_slot_resource() -> RmrkSlotResource {46 RmrkSlotResource {47 base: 100,48 slot: 200,49 src: Some(create_data()),50 metadata: Some(create_data()),51 license: Some(create_data()),52 thumb: Some(create_data()),53 }54}5556fn create_max_collection<T: Config>(owner: &T::AccountId) -> DispatchResult {57 <T as pallet_common::Config>::Currency::deposit_creating(58 owner,59 T::CollectionCreationPrice::get(),60 );6162 let metadata = create_data();63 let max = None;64 let symbol = create_data();6566 <Pallet<T>>::create_collection(67 RawOrigin::Signed(owner.clone()).into(),68 metadata,69 max,70 symbol,71 )72}7374fn create_max_nft<T: Config>(75 owner: &T::AccountId,76 collection_id: RmrkCollectionId,77) -> DispatchResult {78 let royalty_recipient = Some(owner.clone());79 let royalty_amount = Some(Permill::from_percent(25));80 let metadata = create_data();81 let transferable = true;8283 <Pallet<T>>::mint_nft(84 RawOrigin::Signed(owner.clone()).into(),85 owner.clone(),86 collection_id,87 royalty_recipient,88 royalty_amount,89 metadata,90 transferable,91 )92}9394struct NftBuilder {95 collection_id: RmrkCollectionId,96 current_nft_id: RmrkNftId,97}9899impl NftBuilder {100 fn new(collection_id: RmrkCollectionId) -> Self {101 Self {102 collection_id,103 current_nft_id: 0,104 }105 }106107 fn current_nft_id(&self) -> RmrkNftId {108 self.current_nft_id109 }110111 fn build<T: Config>(&mut self, owner: &T::AccountId) -> Result<RmrkNftId, DispatchError> {112 create_max_nft::<T>(owner, self.collection_id)?;113 self.current_nft_id += 1;114115 Ok(self.current_nft_id)116 }117118 fn build_tower<T: Config>(119 &mut self,120 owner: &T::AccountId,121 height: u32,122 ) -> Result<(RmrkNftId, RmrkNftId), DispatchError> {123 self.build::<T>(owner)?;124125 let root_nft_id = self.current_nft_id;126 let mut prev_nft_id = root_nft_id;127128 for _ in 0..height {129 self.build::<T>(owner)?;130131 let new_owner =132 <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(133 self.collection_id,134 prev_nft_id,135 );136137 <Pallet<T>>::send(138 RawOrigin::Signed(owner.clone()).into(),139 self.collection_id,140 self.current_nft_id,141 new_owner,142 )?;143144 prev_nft_id = self.current_nft_id;145 }146147 let deepest_nft_id = self.current_nft_id;148149 Ok((root_nft_id, deepest_nft_id))150 }151152 fn build_wide_tree<T: Config>(153 &mut self,154 owner: &T::AccountId,155 width: u32,156 ) -> Result<RmrkNftId, DispatchError> {157 self.build::<T>(owner)?;158159 let root_nft_id = self.current_nft_id;160161 let root_owner =162 <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(163 self.collection_id,164 root_nft_id,165 );166167 for _ in 0..width {168 self.build::<T>(owner)?;169170 <Pallet<T>>::send(171 RawOrigin::Signed(owner.clone()).into(),172 self.collection_id,173 self.current_nft_id,174 root_owner.clone(),175 )?;176 } 177178 Ok(root_nft_id)179 }180}181182benchmarks! {183 create_collection {184 let caller = account("caller", 0, SEED);185 <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());186 let metadata = create_data();187 let max = None;188 let symbol = create_data();189 }: _(RawOrigin::Signed(caller), metadata, max, symbol)190191 destroy_collection {192 let caller = account("caller", 0, SEED);193194 create_max_collection::<T>(&caller)?;195 let collection_id = 0;196 }: _(RawOrigin::Signed(caller), collection_id)197198 change_collection_issuer {199 let caller: T::AccountId = account("caller", 0, SEED);200201 create_max_collection::<T>(&caller)?;202 let collection_id = 0;203204 let new_owner: T::AccountId = account("new_owner", 0, SEED);205206 let new_owner_source = T::Lookup::unlookup(new_owner);207 }: _(RawOrigin::Signed(caller), collection_id, new_owner_source)208209 lock_collection {210 let caller: T::AccountId = account("caller", 0, SEED);211212 create_max_collection::<T>(&caller)?;213 let collection_id = 0;214 }: _(RawOrigin::Signed(caller), collection_id)215216 mint_nft {217 let caller: T::AccountId = account("caller", 0, SEED);218219 create_max_collection::<T>(&caller)?;220 let collection_id = 0;221 let owner = caller.clone();222223 let royalty_recipient = Some(caller.clone());224 let royalty_amount = Some(Permill::from_percent(25));225 let metadata = create_data();226 let transferable = true;227 }: _(228 RawOrigin::Signed(caller),229 owner,230 collection_id,231 royalty_recipient,232 royalty_amount,233 metadata,234 transferable235 )236237 burn_nft {238 let b in 0..200;239240 let caller: T::AccountId = account("caller", 0, SEED);241 create_max_collection::<T>(&caller)?;242 let collection_id = 0;243244 let mut nft_builder = NftBuilder::new(collection_id);245 let root_nft_id = nft_builder.build_wide_tree::<T>(&caller, b)?;246 let max_burns = b + 1;247 }: _(248 RawOrigin::Signed(caller),249 collection_id,250 root_nft_id,251 max_burns252 )253254 send {255 let caller: T::AccountId = account("caller", 0, SEED);256 create_max_collection::<T>(&caller)?;257 let collection_id = 0;258259 let mut nft_builder = NftBuilder::new(collection_id);260 let src_nft_id = nft_builder.build::<T>(&caller)?;261 let (_, target_nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 2)?;262 }: _(263 RawOrigin::Signed(caller),264 collection_id,265 src_nft_id,266 <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(collection_id, target_nft_id)267 )268269 accept_nft {270 let caller: T::AccountId = account("caller", 0, SEED);271 let sender: T::AccountId = account("sender", 0, SEED);272273 create_max_collection::<T>(&sender)?;274 let src_collection_id = 0;275276 create_max_collection::<T>(&caller)?;277 let target_collection_id = 1;278279 let mut src_nft_builder = NftBuilder::new(src_collection_id);280 let src_nft_id = src_nft_builder.build::<T>(&sender)?;281282 let mut target_nft_builder = NftBuilder::new(target_collection_id);283 let fake_target_nft_id = target_nft_builder.build::<T>(&caller)?;284 let (_, target_nft_id) = target_nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;285286 let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(287 target_collection_id,288 fake_target_nft_id289 );290291 let actual_new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(292 target_collection_id,293 target_nft_id294 );295296 <Pallet<T>>::send(297 RawOrigin::Signed(sender.clone()).into(),298 src_collection_id,299 src_nft_id,300 new_owner,301 )?;302 }: _(303 RawOrigin::Signed(caller),304 src_collection_id,305 src_nft_id,306 actual_new_owner307 )308309 reject_nft {310 let caller: T::AccountId = account("caller", 0, SEED);311 let sender: T::AccountId = account("sender", 0, SEED);312313 create_max_collection::<T>(&sender)?;314 let src_collection_id = 0;315316 create_max_collection::<T>(&caller)?;317 let target_collection_id = 1;318319 let mut src_nft_builder = NftBuilder::new(src_collection_id);320 let (src_root_nft_id, _) = src_nft_builder.build_tower::<T>(&sender, NESTING_BUDGET - 1)?;321322 let mut target_nft_builder = NftBuilder::new(target_collection_id);323 let target_nft_id = target_nft_builder.build::<T>(&caller)?;324325 let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(326 target_collection_id,327 target_nft_id328 );329330 <Pallet<T>>::send(331 RawOrigin::Signed(sender.clone()).into(),332 src_collection_id,333 src_root_nft_id,334 new_owner,335 )?;336 }: _(337 RawOrigin::Signed(caller),338 src_collection_id,339 src_root_nft_id340 )341342 set_property {343 let caller: T::AccountId = account("caller", 0, SEED);344 create_max_collection::<T>(&caller)?;345 let collection_id = 0;346347 let mut nft_builder = NftBuilder::new(collection_id);348 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;349350 let key = create_data();351 let value = create_data();352 }: _(353 RawOrigin::Signed(caller),354 collection_id,355 Some(nft_id),356 key,357 value358 )359360 set_priority {361 let caller: T::AccountId = account("caller", 0, SEED);362 create_max_collection::<T>(&caller)?;363 let collection_id = 0;364365 let mut nft_builder = NftBuilder::new(collection_id);366 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;367 let priorities = create_u32_array();368 }: _(369 RawOrigin::Signed(caller),370 collection_id,371 nft_id,372 priorities373 )374375 add_basic_resource {376 let caller: T::AccountId = account("caller", 0, SEED);377 <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());378379 create_max_collection::<T>(&caller)?;380 let collection_id = 0;381382 let mut nft_builder = NftBuilder::new(collection_id);383 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;384 let resource = create_basic_resource();385 }: _(386 RawOrigin::Signed(caller),387 collection_id,388 nft_id,389 resource390 )391392 add_composable_resource {393 let caller: T::AccountId = account("caller", 0, SEED);394 <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());395396 create_max_collection::<T>(&caller)?;397 let collection_id = 0;398399 let mut nft_builder = NftBuilder::new(collection_id);400 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;401 let resource = create_composable_resource();402 }: _(403 RawOrigin::Signed(caller),404 collection_id,405 nft_id,406 resource407 )408409 add_slot_resource {410 let caller: T::AccountId = account("caller", 0, SEED);411 <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());412413 create_max_collection::<T>(&caller)?;414 let collection_id = 0;415416 let mut nft_builder = NftBuilder::new(collection_id);417 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;418 let resource = create_slot_resource();419 }: _(420 RawOrigin::Signed(caller),421 collection_id,422 nft_id,423 resource424 )425426 remove_resource {427 let caller: T::AccountId = account("caller", 0, SEED);428 <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());429430 create_max_collection::<T>(&caller)?;431 let collection_id = 0;432433 let mut nft_builder = NftBuilder::new(collection_id);434 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;435 let resource = create_basic_resource();436437 <Pallet<T>>::add_basic_resource(438 RawOrigin::Signed(caller.clone()).into(),439 collection_id,440 nft_id,441 resource442 )?;443444 let resource_id = 1;445 }: _(446 RawOrigin::Signed(caller),447 collection_id,448 nft_id,449 resource_id450 )451452 accept_resource {453 let caller: T::AccountId = account("caller", 0, SEED);454 let admin: T::AccountId = account("admin", 0, SEED);455456 <T as pallet_common::Config>::Currency::deposit_creating(&admin, T::CollectionCreationPrice::get());457458 create_max_collection::<T>(&admin)?;459 let collection_id = 0;460461 let mut nft_builder = NftBuilder::new(collection_id);462 let root_nft_id = 1;463 let (_, nested_nft_id) = nft_builder.build_tower::<T>(&admin, NESTING_BUDGET - 1)?;464 let resource = create_basic_resource();465466 let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::AccountId(caller.clone());467468 <Pallet<T>>::send(469 RawOrigin::Signed(admin.clone()).into(),470 collection_id,471 root_nft_id,472 new_owner,473 )?;474475 <Pallet<T>>::add_basic_resource(476 RawOrigin::Signed(admin.clone()).into(),477 collection_id,478 nested_nft_id,479 resource480 )?;481482 let resource_id = 1;483 }: _(484 RawOrigin::Signed(caller),485 collection_id,486 nested_nft_id,487 resource_id488 )489490 accept_resource_removal {491 let caller: T::AccountId = account("caller", 0, SEED);492 let admin: T::AccountId = account("admin", 0, SEED);493494 <T as pallet_common::Config>::Currency::deposit_creating(&admin, T::CollectionCreationPrice::get());495496 create_max_collection::<T>(&admin)?;497 let collection_id = 0;498499 let mut nft_builder = NftBuilder::new(collection_id);500 let root_nft_id = 1;501 let (_, nested_nft_id) = nft_builder.build_tower::<T>(&admin, NESTING_BUDGET - 1)?;502 let resource = create_basic_resource();503504 <Pallet<T>>::add_basic_resource(505 RawOrigin::Signed(admin.clone()).into(),506 collection_id,507 nested_nft_id,508 resource509 )?;510511 let resource_id = 1;512513 let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::AccountId(caller.clone());514515 <Pallet<T>>::send(516 RawOrigin::Signed(admin.clone()).into(),517 collection_id,518 root_nft_id,519 new_owner,520 )?;521522 <Pallet<T>>::remove_resource(523 RawOrigin::Signed(admin).into(),524 collection_id,525 nested_nft_id,526 resource_id527 )?;528 }: _(529 RawOrigin::Signed(caller),530 collection_id,531 nested_nft_id,532 resource_id533 )534}