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 = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(162 self.collection_id,163 root_nft_id,164 );165166 for _ in 0..width {167 self.build::<T>(owner)?;168169 <Pallet<T>>::send(170 RawOrigin::Signed(owner.clone()).into(),171 self.collection_id,172 self.current_nft_id,173 root_owner.clone(),174 )?;175 }176177 Ok(root_nft_id)178 }179}180181benchmarks! {182 create_collection {183 let caller = account("caller", 0, SEED);184 <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());185 let metadata = create_data();186 let max = None;187 let symbol = create_data();188 }: _(RawOrigin::Signed(caller), metadata, max, symbol)189190 destroy_collection {191 let caller = account("caller", 0, SEED);192193 create_max_collection::<T>(&caller)?;194 let collection_id = 0;195 }: _(RawOrigin::Signed(caller), collection_id)196197 change_collection_issuer {198 let caller: T::AccountId = account("caller", 0, SEED);199200 create_max_collection::<T>(&caller)?;201 let collection_id = 0;202203 let new_owner: T::AccountId = account("new_owner", 0, SEED);204205 let new_owner_source = T::Lookup::unlookup(new_owner);206 }: _(RawOrigin::Signed(caller), collection_id, new_owner_source)207208 lock_collection {209 let caller: T::AccountId = account("caller", 0, SEED);210211 create_max_collection::<T>(&caller)?;212 let collection_id = 0;213 }: _(RawOrigin::Signed(caller), collection_id)214215 mint_nft {216 let caller: T::AccountId = account("caller", 0, SEED);217218 create_max_collection::<T>(&caller)?;219 let collection_id = 0;220 let owner = caller.clone();221222 let royalty_recipient = Some(caller.clone());223 let royalty_amount = Some(Permill::from_percent(25));224 let metadata = create_data();225 let transferable = true;226 }: _(227 RawOrigin::Signed(caller),228 owner,229 collection_id,230 royalty_recipient,231 royalty_amount,232 metadata,233 transferable234 )235236 burn_nft {237 let b in 0..200;238239 let caller: T::AccountId = account("caller", 0, SEED);240 create_max_collection::<T>(&caller)?;241 let collection_id = 0;242243 let mut nft_builder = NftBuilder::new(collection_id);244 let root_nft_id = nft_builder.build_wide_tree::<T>(&caller, b)?;245 let max_burns = b + 1;246 }: _(247 RawOrigin::Signed(caller),248 collection_id,249 root_nft_id,250 max_burns251 )252253 send {254 let caller: T::AccountId = account("caller", 0, SEED);255 create_max_collection::<T>(&caller)?;256 let collection_id = 0;257258 let mut nft_builder = NftBuilder::new(collection_id);259 let src_nft_id = nft_builder.build::<T>(&caller)?;260 let (_, target_nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 2)?;261 }: _(262 RawOrigin::Signed(caller),263 collection_id,264 src_nft_id,265 <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(collection_id, target_nft_id)266 )267268 accept_nft {269 let caller: T::AccountId = account("caller", 0, SEED);270 let sender: T::AccountId = account("sender", 0, SEED);271272 create_max_collection::<T>(&sender)?;273 let src_collection_id = 0;274275 create_max_collection::<T>(&caller)?;276 let target_collection_id = 1;277278 let mut src_nft_builder = NftBuilder::new(src_collection_id);279 let src_nft_id = src_nft_builder.build::<T>(&sender)?;280281 let mut target_nft_builder = NftBuilder::new(target_collection_id);282 let fake_target_nft_id = target_nft_builder.build::<T>(&caller)?;283 let (_, target_nft_id) = target_nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;284285 let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(286 target_collection_id,287 fake_target_nft_id288 );289290 let actual_new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(291 target_collection_id,292 target_nft_id293 );294295 <Pallet<T>>::send(296 RawOrigin::Signed(sender.clone()).into(),297 src_collection_id,298 src_nft_id,299 new_owner,300 )?;301 }: _(302 RawOrigin::Signed(caller),303 src_collection_id,304 src_nft_id,305 actual_new_owner306 )307308 reject_nft {309 let caller: T::AccountId = account("caller", 0, SEED);310 let sender: T::AccountId = account("sender", 0, SEED);311312 create_max_collection::<T>(&sender)?;313 let src_collection_id = 0;314315 create_max_collection::<T>(&caller)?;316 let target_collection_id = 1;317318 let mut src_nft_builder = NftBuilder::new(src_collection_id);319 let (src_root_nft_id, _) = src_nft_builder.build_tower::<T>(&sender, NESTING_BUDGET - 1)?;320321 let mut target_nft_builder = NftBuilder::new(target_collection_id);322 let target_nft_id = target_nft_builder.build::<T>(&caller)?;323324 let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::CollectionAndNftTuple(325 target_collection_id,326 target_nft_id327 );328329 <Pallet<T>>::send(330 RawOrigin::Signed(sender.clone()).into(),331 src_collection_id,332 src_root_nft_id,333 new_owner,334 )?;335 }: _(336 RawOrigin::Signed(caller),337 src_collection_id,338 src_root_nft_id339 )340341 set_property {342 let caller: T::AccountId = account("caller", 0, SEED);343 create_max_collection::<T>(&caller)?;344 let collection_id = 0;345346 let mut nft_builder = NftBuilder::new(collection_id);347 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;348349 let key = create_data();350 let value = create_data();351 }: _(352 RawOrigin::Signed(caller),353 collection_id,354 Some(nft_id),355 key,356 value357 )358359 set_priority {360 let caller: T::AccountId = account("caller", 0, SEED);361 create_max_collection::<T>(&caller)?;362 let collection_id = 0;363364 let mut nft_builder = NftBuilder::new(collection_id);365 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;366 let priorities = create_u32_array();367 }: _(368 RawOrigin::Signed(caller),369 collection_id,370 nft_id,371 priorities372 )373374 add_basic_resource {375 let caller: T::AccountId = account("caller", 0, SEED);376 <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());377378 create_max_collection::<T>(&caller)?;379 let collection_id = 0;380381 let mut nft_builder = NftBuilder::new(collection_id);382 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;383 let resource = create_basic_resource();384 }: _(385 RawOrigin::Signed(caller),386 collection_id,387 nft_id,388 resource389 )390391 add_composable_resource {392 let caller: T::AccountId = account("caller", 0, SEED);393 <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());394395 create_max_collection::<T>(&caller)?;396 let collection_id = 0;397398 let mut nft_builder = NftBuilder::new(collection_id);399 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;400 let resource = create_composable_resource();401 }: _(402 RawOrigin::Signed(caller),403 collection_id,404 nft_id,405 resource406 )407408 add_slot_resource {409 let caller: T::AccountId = account("caller", 0, SEED);410 <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());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_slot_resource();418 }: _(419 RawOrigin::Signed(caller),420 collection_id,421 nft_id,422 resource423 )424425 remove_resource {426 let caller: T::AccountId = account("caller", 0, SEED);427 <T as pallet_common::Config>::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());428429 create_max_collection::<T>(&caller)?;430 let collection_id = 0;431432 let mut nft_builder = NftBuilder::new(collection_id);433 let (_, nft_id) = nft_builder.build_tower::<T>(&caller, NESTING_BUDGET - 1)?;434 let resource = create_basic_resource();435436 <Pallet<T>>::add_basic_resource(437 RawOrigin::Signed(caller.clone()).into(),438 collection_id,439 nft_id,440 resource441 )?;442443 let resource_id = 1;444 }: _(445 RawOrigin::Signed(caller),446 collection_id,447 nft_id,448 resource_id449 )450451 accept_resource {452 let caller: T::AccountId = account("caller", 0, SEED);453 let admin: T::AccountId = account("admin", 0, SEED);454455 <T as pallet_common::Config>::Currency::deposit_creating(&admin, T::CollectionCreationPrice::get());456457 create_max_collection::<T>(&admin)?;458 let collection_id = 0;459460 let mut nft_builder = NftBuilder::new(collection_id);461 let root_nft_id = 1;462 let (_, nested_nft_id) = nft_builder.build_tower::<T>(&admin, NESTING_BUDGET - 1)?;463 let resource = create_basic_resource();464465 let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::AccountId(caller.clone());466467 <Pallet<T>>::send(468 RawOrigin::Signed(admin.clone()).into(),469 collection_id,470 root_nft_id,471 new_owner,472 )?;473474 <Pallet<T>>::add_basic_resource(475 RawOrigin::Signed(admin.clone()).into(),476 collection_id,477 nested_nft_id,478 resource479 )?;480481 let resource_id = 1;482 }: _(483 RawOrigin::Signed(caller),484 collection_id,485 nested_nft_id,486 resource_id487 )488489 accept_resource_removal {490 let caller: T::AccountId = account("caller", 0, SEED);491 let admin: T::AccountId = account("admin", 0, SEED);492493 <T as pallet_common::Config>::Currency::deposit_creating(&admin, T::CollectionCreationPrice::get());494495 create_max_collection::<T>(&admin)?;496 let collection_id = 0;497498 let mut nft_builder = NftBuilder::new(collection_id);499 let root_nft_id = 1;500 let (_, nested_nft_id) = nft_builder.build_tower::<T>(&admin, NESTING_BUDGET - 1)?;501 let resource = create_basic_resource();502503 <Pallet<T>>::add_basic_resource(504 RawOrigin::Signed(admin.clone()).into(),505 collection_id,506 nested_nft_id,507 resource508 )?;509510 let resource_id = 1;511512 let new_owner = <RmrkAccountIdOrCollectionNftTuple<T::AccountId>>::AccountId(caller.clone());513514 <Pallet<T>>::send(515 RawOrigin::Signed(admin.clone()).into(),516 collection_id,517 root_nft_id,518 new_owner,519 )?;520521 <Pallet<T>>::remove_resource(522 RawOrigin::Signed(admin).into(),523 collection_id,524 nested_nft_id,525 resource_id526 )?;527 }: _(528 RawOrigin::Signed(caller),529 collection_id,530 nested_nft_id,531 resource_id532 )533}