1234567891011121314151617use sp_std::vec;1819use frame_benchmarking::{benchmarks, account};20use frame_system::RawOrigin;21use frame_support::{22 traits::{Currency, Get},23 BoundedVec,24};25use sp_runtime::Permill;2627use up_data_structs::*;2829use super::*;3031const SEED: u32 = 1;3233fn create_data<S: Get<u32>>() -> BoundedVec<u8, S> {34 vec![b'A'; S::get() as usize].try_into().expect("size == S")35}3637fn create_u32_array<S: Get<u32>>() -> BoundedVec<u32, S> {38 vec![0; S::get() as usize].try_into().expect("size == S")39}4041fn create_basic_resource() -> RmrkBasicResource {42 RmrkBasicResource {43 src: Some(create_data()),44 metadata: Some(create_data()),45 license: Some(create_data()),46 thumb: Some(create_data()),47 }48}4950fn create_composable_resource() -> RmrkComposableResource {51 RmrkComposableResource {52 parts: create_u32_array(),53 base: 100,54 src: Some(create_data()),55 metadata: Some(create_data()),56 license: Some(create_data()),57 thumb: Some(create_data()),58 }59}6061fn create_slot_resource() -> RmrkSlotResource {62 RmrkSlotResource {63 base: 100,64 slot: 200,65 src: Some(create_data()),66 metadata: Some(create_data()),67 license: Some(create_data()),68 thumb: Some(create_data()),69 }70}7172fn create_max_resource_types_array<S: Get<u32>>(num: usize) -> BoundedVec<RmrkResourceTypes, S> {73 vec![RmrkResourceTypes::Composable(create_composable_resource()); num]74 .try_into()75 .expect("num <= S")76}7778fn create_max_collection<T: Config>(owner: &T::AccountId) -> DispatchResult {79 <T as pallet_common::Config>::Currency::deposit_creating(80 owner,81 T::CollectionCreationPrice::get(),82 );8384 let metadata = create_data();85 let max = None;86 let symbol = create_data();8788 <Pallet<T>>::create_collection(89 RawOrigin::Signed(owner.clone()).into(),90 metadata,91 max,92 symbol,93 )94}9596fn create_nft<T: Config>(owner: &T::AccountId, collection_id: RmrkCollectionId) -> DispatchResult {97 let royalty_recipient = Some(owner.clone());98 let royalty_amount = Some(Permill::from_percent(25));99 let metadata = create_data();100 let transferable = true;101102 <Pallet<T>>::mint_nft(103 RawOrigin::Signed(owner.clone()).into(),104 None,105 collection_id,106 royalty_recipient,107 royalty_amount,108 metadata,109 transferable,110 None,111 )112}113114struct NftBuilder {115 collection_id: RmrkCollectionId,116 current_nft_id: RmrkNftId,117}118119impl NftBuilder {120 fn new(collection_id: RmrkCollectionId) -> Self {121 Self {122 collection_id,123 current_nft_id: 0,124 }125 }126127 fn build<T: Config>(&mut self, owner: &T::AccountId) -> Result<RmrkNftId, DispatchError> {128 create_nft::<T>(owner, self.collection_id)?;129 self.current_nft_id += 1;130131 Ok(self.current_nft_id)132 }133134 fn build_tower<T: Config>(135 &mut self,136 owner: &T::AccountId,137 height: u32,138 ) -> Result<(RmrkNftId, RmrkNftId), DispatchError> {139 self.build::<T>(owner)?;140141 let root_nft_id = self.current_nft_id;142 let mut prev_nft_id = root_nft_id;143144 for _ in 0..height {145 self.build::<T>(owner)?;146147 let new_owner =148 <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(149 self.collection_id,150 prev_nft_id,151 );152153 <Pallet<T>>::send(154 RawOrigin::Signed(owner.clone()).into(),155 self.collection_id,156 self.current_nft_id,157 new_owner,158 )?;159160 prev_nft_id = self.current_nft_id;161 }162163 let deepest_nft_id = self.current_nft_id;164165 Ok((root_nft_id, deepest_nft_id))166 }167168 fn build_wide_tree<T: Config>(169 &mut self,170 owner: &T::AccountId,171 width: u32,172 ) -> Result<RmrkNftId, DispatchError> {173 self.build::<T>(owner)?;174175 let root_nft_id = self.current_nft_id;176177 let root_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(178 self.collection_id,179 root_nft_id,180 );181182 for _ in 0..width {183 self.build::<T>(owner)?;184185 <Pallet<T>>::send(186 RawOrigin::Signed(owner.clone()).into(),187 self.collection_id,188 self.current_nft_id,189 root_owner.clone(),190 )?;191 }192193 Ok(root_nft_id)194 }195}196197benchmarks! {198 create_collection {199 let caller = account("caller", 0, SEED);200 <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());201 let metadata = create_data();202 let max = None;203 let symbol = create_data();204 }: _(RawOrigin::Signed(caller), metadata, max, symbol)205206 destroy_collection {207 let caller = account("caller", 0, SEED);208209 create_max_collection::<T>(&caller)?;210 let collection_id = 0;211 }: _(RawOrigin::Signed(caller), collection_id)212213 change_collection_issuer {214 let caller: T::AccountId = account("caller", 0, SEED);215216 create_max_collection::<T>(&caller)?;217 let collection_id = 0;218219 let new_owner: T::AccountId = account("new_owner", 0, SEED);220221 let new_owner_source = T::Lookup::unlookup(new_owner);222 }: _(RawOrigin::Signed(caller), collection_id, new_owner_source)223224 lock_collection {225 let caller: T::AccountId = account("caller", 0, SEED);226227 create_max_collection::<T>(&caller)?;228 let collection_id = 0;229 }: _(RawOrigin::Signed(caller), collection_id)230231 mint_nft {232 let b in 0..100;233234 let caller: T::AccountId = account("caller", 0, SEED);235236 create_max_collection::<T>(&caller)?;237 let collection_id = 0;238 let owner = caller.clone();239240 let royalty_recipient = Some(caller.clone());241 let royalty_amount = Some(Permill::from_percent(25));242 let metadata = create_data();243 let transferable = true;244 }: _(245 RawOrigin::Signed(caller),246 None,247 collection_id,248 royalty_recipient,249 royalty_amount,250 metadata,251 transferable,252 Some(create_max_resource_types_array(b as usize))253 )254255 burn_nft {256 let b in 0..200;257258 let caller: T::AccountId = account("caller", 0, SEED);259 create_max_collection::<T>(&caller)?;260 let collection_id = 0;261262 let mut nft_builder = NftBuilder::new(collection_id);263 let root_nft_id = nft_builder.build_wide_tree::<T>(&caller, b)?;264 let max_burns = b + 1;265 }: _(266 RawOrigin::Signed(caller),267 collection_id,268 root_nft_id,269 max_burns270 )271272 send {273 let caller: T::AccountId = account("caller", 0, SEED);274 create_max_collection::<T>(&caller)?;275 let collection_id = 0;276277 let mut nft_builder = NftBuilder::new(collection_id);278 let src_nft_id = nft_builder.build::<T>(&caller)?;279 let (_, target_nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 2)?;280 }: _(281 RawOrigin::Signed(caller),282 collection_id,283 src_nft_id,284 <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(collection_id, target_nft_id)285 )286287 accept_nft {288 let caller: T::AccountId = account("caller", 0, SEED);289 let sender: T::AccountId = account("sender", 0, SEED);290291 create_max_collection::<T>(&sender)?;292 let src_collection_id = 0;293294 create_max_collection::<T>(&caller)?;295 let target_collection_id = 1;296297 let mut src_nft_builder = NftBuilder::new(src_collection_id);298 let src_nft_id = src_nft_builder.build::<T>(&sender)?;299300 let mut target_nft_builder = NftBuilder::new(target_collection_id);301 let fake_target_nft_id = target_nft_builder.build::<T>(&caller)?;302 let (_, target_nft_id) = target_nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;303304 let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(305 target_collection_id,306 fake_target_nft_id307 );308309 let actual_new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(310 target_collection_id,311 target_nft_id312 );313314 <Pallet<T>>::send(315 RawOrigin::Signed(sender.clone()).into(),316 src_collection_id,317 src_nft_id,318 new_owner,319 )?;320 }: _(321 RawOrigin::Signed(caller),322 src_collection_id,323 src_nft_id,324 actual_new_owner325 )326327 reject_nft {328 let caller: T::AccountId = account("caller", 0, SEED);329 let sender: T::AccountId = account("sender", 0, SEED);330331 create_max_collection::<T>(&sender)?;332 let src_collection_id = 0;333334 create_max_collection::<T>(&caller)?;335 let target_collection_id = 1;336337 let mut src_nft_builder = NftBuilder::new(src_collection_id);338 let (src_root_nft_id, _) = src_nft_builder.build_tower::<T>(&sender, NESTING_BUDGET - 1)?;339340 let mut target_nft_builder = NftBuilder::new(target_collection_id);341 let target_nft_id = target_nft_builder.build::<T>(&caller)?;342343 let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(344 target_collection_id,345 target_nft_id346 );347348 <Pallet<T>>::send(349 RawOrigin::Signed(sender.clone()).into(),350 src_collection_id,351 src_root_nft_id,352 new_owner,353 )?;354 }: _(355 RawOrigin::Signed(caller),356 src_collection_id,357 src_root_nft_id358 )359360 set_property {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)?;367368 let key = create_data();369 let value = create_data();370 }: _(371 RawOrigin::Signed(caller),372 collection_id,373 Some(nft_id),374 key,375 value376 )377378 set_priority {379 let caller: T::AccountId = account("caller", 0, SEED);380 create_max_collection::<T>(&caller)?;381 let collection_id = 0;382383 let mut nft_builder = NftBuilder::new(collection_id);384 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;385 let priorities = create_u32_array();386 }: _(387 RawOrigin::Signed(caller),388 collection_id,389 nft_id,390 priorities391 )392393 add_basic_resource {394 let caller: T::AccountId = account("caller", 0, SEED);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_basic_resource();402 }: _(403 RawOrigin::Signed(caller),404 collection_id,405 nft_id,406 resource407 )408409 add_composable_resource {410 let caller: T::AccountId = account("caller", 0, SEED);411412 create_max_collection::<T>(&caller)?;413 let collection_id = 0;414415 let mut nft_builder = NftBuilder::new(collection_id);416 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;417 let resource = create_composable_resource();418 }: _(419 RawOrigin::Signed(caller),420 collection_id,421 nft_id,422 resource423 )424425 add_slot_resource {426 let caller: T::AccountId = account("caller", 0, SEED);427428 create_max_collection::<T>(&caller)?;429 let collection_id = 0;430431 let mut nft_builder = NftBuilder::new(collection_id);432 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;433 let resource = create_slot_resource();434 }: _(435 RawOrigin::Signed(caller),436 collection_id,437 nft_id,438 resource439 )440441 remove_resource {442 let caller: T::AccountId = account("caller", 0, SEED);443444 create_max_collection::<T>(&caller)?;445 let collection_id = 0;446447 let mut nft_builder = NftBuilder::new(collection_id);448 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;449 let resource = create_basic_resource();450451 <Pallet<T>>::add_basic_resource(452 RawOrigin::Signed(caller.clone()).into(),453 collection_id,454 nft_id,455 resource456 )?;457458 let resource_id = 0;459 }: _(460 RawOrigin::Signed(caller),461 collection_id,462 nft_id,463 resource_id464 )465466 accept_resource {467 let caller: T::AccountId = account("caller", 0, SEED);468 let admin: T::AccountId = account("admin", 0, SEED);469470 create_max_collection::<T>(&admin)?;471 let collection_id = 0;472473 let mut nft_builder = NftBuilder::new(collection_id);474 let root_nft_id = 1;475 let (_, nested_nft_id) = nft_builder.build_tower::<T>(&admin, NESTING_BUDGET - 1)?;476 let resource = create_basic_resource();477478 let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::AccountId(caller.clone());479480 <Pallet<T>>::send(481 RawOrigin::Signed(admin.clone()).into(),482 collection_id,483 root_nft_id,484 new_owner,485 )?;486487 <Pallet<T>>::add_basic_resource(488 RawOrigin::Signed(admin.clone()).into(),489 collection_id,490 nested_nft_id,491 resource492 )?;493494 let resource_id = 0;495 }: _(496 RawOrigin::Signed(caller),497 collection_id,498 nested_nft_id,499 resource_id500 )501502 accept_resource_removal {503 let caller: T::AccountId = account("caller", 0, SEED);504 let admin: T::AccountId = account("admin", 0, SEED);505506 create_max_collection::<T>(&admin)?;507 let collection_id = 0;508509 let mut nft_builder = NftBuilder::new(collection_id);510 let root_nft_id = 1;511 let (_, nested_nft_id) = nft_builder.build_tower::<T>(&admin, NESTING_BUDGET - 1)?;512 let resource = create_basic_resource();513514 <Pallet<T>>::add_basic_resource(515 RawOrigin::Signed(admin.clone()).into(),516 collection_id,517 nested_nft_id,518 resource519 )?;520521 let resource_id = 0;522523 let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::AccountId(caller.clone());524525 <Pallet<T>>::send(526 RawOrigin::Signed(admin.clone()).into(),527 collection_id,528 root_nft_id,529 new_owner,530 )?;531532 <Pallet<T>>::remove_resource(533 RawOrigin::Signed(admin).into(),534 collection_id,535 nested_nft_id,536 resource_id537 )?;538 }: _(539 RawOrigin::Signed(caller),540 collection_id,541 nested_nft_id,542 resource_id543 )544}