1234567891011121314151617use frame_benchmarking::v2::{account, benchmarks, BenchmarkError};18use pallet_common::{19 bench_init,20 benchmarking::{create_collection_raw, property_key, property_value},21 CommonCollectionOperations,22};23use sp_std::prelude::*;24use up_data_structs::{25 budget::Unlimited, CollectionMode, PropertyPermission, MAX_ITEMS_PER_BATCH,26 MAX_PROPERTIES_PER_ITEM,27};2829use super::*;30use crate::{Config, NonfungibleHandle, Pallet};3132const SEED: u32 = 1;3334fn create_max_item_data<T: Config>(owner: T::CrossAccountId) -> CreateItemData<T> {35 CreateItemData::<T> {36 owner,37 properties: Default::default(),38 }39}40fn create_max_item<T: Config>(41 collection: &NonfungibleHandle<T>,42 sender: &T::CrossAccountId,43 owner: T::CrossAccountId,44) -> Result<TokenId, DispatchError> {45 <Pallet<T>>::create_item(46 collection,47 sender,48 create_max_item_data::<T>(owner),49 &Unlimited,50 )?;51 Ok(TokenId(<TokensMinted<T>>::get(collection.id)))52}5354fn create_collection<T: Config>(55 owner: T::CrossAccountId,56) -> Result<NonfungibleHandle<T>, DispatchError> {57 create_collection_raw(58 owner,59 CollectionMode::NFT,60 |owner: T::CrossAccountId, data| <Pallet<T>>::init_collection(owner.clone(), owner, data),61 NonfungibleHandle::cast,62 )63}6465#[benchmarks]66mod benchmarks {67 use super::*;6869 #[benchmark]70 fn create_item() -> Result<(), BenchmarkError> {71 bench_init! {72 owner: sub; collection: collection(owner);73 sender: cross_from_sub(owner); to: cross_sub;74 };7576 #[block]77 {78 create_max_item(&collection, &sender, to)?;79 }8081 Ok(())82 }8384 #[benchmark]85 fn create_multiple_items(b: Linear<0, MAX_ITEMS_PER_BATCH>) -> Result<(), BenchmarkError> {86 bench_init! {87 owner: sub; collection: collection(owner);88 sender: cross_from_sub(owner); to: cross_sub;89 };90 let data = (0..b)91 .map(|_| create_max_item_data::<T>(to.clone()))92 .collect();9394 #[block]95 {96 <Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?;97 }9899 Ok(())100 }101102 #[benchmark]103 fn create_multiple_items_ex(b: Linear<0, MAX_ITEMS_PER_BATCH>) -> Result<(), BenchmarkError> {104 bench_init! {105 owner: sub; collection: collection(owner);106 sender: cross_from_sub(owner);107 };108 let data = (0..b)109 .map(|i| {110 bench_init!(to: cross_sub(i););111 create_max_item_data::<T>(to)112 })113 .collect();114115 #[block]116 {117 <Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?;118 }119120 Ok(())121 }122123 #[benchmark]124 fn burn_item() -> Result<(), BenchmarkError> {125 bench_init! {126 owner: sub; collection: collection(owner);127 sender: cross_from_sub(owner); burner: cross_sub;128 };129 let item = create_max_item(&collection, &sender, burner.clone())?;130131 #[block]132 {133 <Pallet<T>>::burn(&collection, &burner, item)?;134 }135136 Ok(())137 }138139 #[benchmark]140 fn burn_recursively_self_raw() -> Result<(), BenchmarkError> {141 bench_init! {142 owner: sub; collection: collection(owner);143 sender: cross_from_sub(owner); burner: cross_sub;144 };145 let item = create_max_item(&collection, &sender, burner.clone())?;146147 #[block]148 {149 <Pallet<T>>::burn_recursively(&collection, &burner, item, &Unlimited, &Unlimited)?;150 }151152 Ok(())153 }154155 #[benchmark]156 fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(157 b: Linear<0, 200>,158 ) -> Result<(), BenchmarkError> {159 bench_init! {160 owner: sub; collection: collection(owner);161 sender: cross_from_sub(owner); burner: cross_sub;162 };163 let item = create_max_item(&collection, &sender, burner.clone())?;164 for _ in 0..b {165 create_max_item(166 &collection,167 &sender,168 T::CrossTokenAddressMapping::token_to_address(collection.id, item),169 )?;170 }171172 #[block]173 {174 <Pallet<T>>::burn_recursively(&collection, &burner, item, &Unlimited, &Unlimited)?;175 }176177 Ok(())178 }179180 #[benchmark]181 fn transfer_raw() -> Result<(), BenchmarkError> {182 bench_init! {183 owner: sub; collection: collection(owner);184 owner: cross_from_sub; sender: cross_sub; receiver: cross_sub;185 };186 let item = create_max_item(&collection, &owner, sender.clone())?;187188 #[block]189 {190 <Pallet<T>>::transfer(&collection, &sender, &receiver, item, &Unlimited)?;191 }192193 Ok(())194 }195196 #[benchmark]197 fn approve() -> Result<(), BenchmarkError> {198 bench_init! {199 owner: sub; collection: collection(owner);200 owner: cross_from_sub; sender: cross_sub; spender: cross_sub;201 };202 let item = create_max_item(&collection, &owner, sender.clone())?;203204 #[block]205 {206 <Pallet<T>>::set_allowance(&collection, &sender, item, Some(&spender))?;207 }208209 Ok(())210 }211212 #[benchmark]213 fn approve_from() -> Result<(), BenchmarkError> {214 bench_init! {215 owner: sub; collection: collection(owner);216 owner: cross_from_sub; sender: cross_sub; spender: cross_sub;217 };218 let owner_eth = T::CrossAccountId::from_eth(*sender.as_eth());219 let item = create_max_item(&collection, &owner, owner_eth.clone())?;220221 #[block]222 {223 <Pallet<T>>::set_allowance_from(224 &collection,225 &sender,226 &owner_eth,227 item,228 Some(&spender),229 )?;230 }231232 Ok(())233 }234235 #[benchmark]236 fn check_allowed_raw() -> Result<(), BenchmarkError> {237 bench_init! {238 owner: sub; collection: collection(owner);239 owner: cross_from_sub; sender: cross_sub; spender: cross_sub;240 };241 let item = create_max_item(&collection, &owner, sender.clone())?;242 <Pallet<T>>::set_allowance(&collection, &sender, item, Some(&spender))?;243244 #[block]245 {246 <Pallet<T>>::check_allowed(&collection, &spender, &sender, item, &Unlimited)?;247 }248249 Ok(())250 }251252 #[benchmark]253 fn burn_from() -> Result<(), BenchmarkError> {254 bench_init! {255 owner: sub; collection: collection(owner);256 owner: cross_from_sub; sender: cross_sub; burner: cross_sub;257 };258 let item = create_max_item(&collection, &owner, sender.clone())?;259 <Pallet<T>>::set_allowance(&collection, &sender, item, Some(&burner))?;260261 #[block]262 {263 <Pallet<T>>::burn_from(&collection, &burner, &sender, item, &Unlimited)?;264 }265266 Ok(())267 }268269 #[benchmark]270 fn set_token_property_permissions(271 b: Linear<0, MAX_PROPERTIES_PER_ITEM>,272 ) -> Result<(), BenchmarkError> {273 bench_init! {274 owner: sub; collection: collection(owner);275 owner: cross_from_sub;276 };277 let perms = (0..b)278 .map(|k| PropertyKeyPermission {279 key: property_key(k as usize),280 permission: PropertyPermission {281 mutable: false,282 collection_admin: false,283 token_owner: false,284 },285 })286 .collect::<Vec<_>>();287288 #[block]289 {290 <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;291 }292293 Ok(())294 }295296 #[benchmark]297 fn set_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {298 bench_init! {299 owner: sub; collection: collection(owner);300 owner: cross_from_sub;301 };302 let perms = (0..b)303 .map(|k| PropertyKeyPermission {304 key: property_key(k as usize),305 permission: PropertyPermission {306 mutable: false,307 collection_admin: true,308 token_owner: true,309 },310 })311 .collect::<Vec<_>>();312 <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;313 let props = (0..b)314 .map(|k| Property {315 key: property_key(k as usize),316 value: property_value(),317 })318 .collect::<Vec<_>>();319 let item = create_max_item(&collection, &owner, owner.clone())?;320321 #[block]322 {323 <Pallet<T>>::set_token_properties(324 &collection,325 &owner,326 item,327 props.into_iter(),328 &Unlimited,329 )?;330 }331332 Ok(())333 }334335 336 #[benchmark]337 fn init_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {338 339 340 341 342343 344 345 346 347 348 349 350 351 352 353 354 #[block]355 {}356 357 358 359 360 361 362 363364 365 366 367 368 369 370371 372 373 374 375 376 377 378 379 380381 Ok(())382 }383384 #[benchmark]385 fn delete_token_properties(386 b: Linear<0, MAX_PROPERTIES_PER_ITEM>,387 ) -> Result<(), BenchmarkError> {388 bench_init! {389 owner: sub; collection: collection(owner);390 owner: cross_from_sub;391 };392 let perms = (0..b)393 .map(|k| PropertyKeyPermission {394 key: property_key(k as usize),395 permission: PropertyPermission {396 mutable: true,397 collection_admin: true,398 token_owner: true,399 },400 })401 .collect::<Vec<_>>();402 <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;403 let props = (0..b)404 .map(|k| Property {405 key: property_key(k as usize),406 value: property_value(),407 })408 .collect::<Vec<_>>();409 let item = create_max_item(&collection, &owner, owner.clone())?;410 <Pallet<T>>::set_token_properties(411 &collection,412 &owner,413 item,414 props.into_iter(),415 &Unlimited,416 )?;417 let to_delete = (0..b).map(|k| property_key(k as usize)).collect::<Vec<_>>();418419 #[block]420 {421 <Pallet<T>>::delete_token_properties(422 &collection,423 &owner,424 item,425 to_delete.into_iter(),426 &Unlimited,427 )?;428 }429430 Ok(())431 }432433 #[benchmark]434 fn token_owner() -> Result<(), BenchmarkError> {435 bench_init! {436 owner: sub; collection: collection(owner);437 owner: cross_from_sub;438 };439 let item = create_max_item(&collection, &owner, owner.clone())?;440441 #[block]442 {443 collection.token_owner(item).unwrap();444 }445446 Ok(())447 }448449 #[benchmark]450 fn set_allowance_for_all() -> Result<(), BenchmarkError> {451 bench_init! {452 owner: sub; collection: collection(owner); owner: cross_from_sub;453 operator: cross_sub;454 };455456 #[block]457 {458 <Pallet<T>>::set_allowance_for_all(&collection, &owner, &operator, true)?;459 }460461 Ok(())462 }463464 #[benchmark]465 fn allowance_for_all() -> Result<(), BenchmarkError> {466 bench_init! {467 owner: sub; collection: collection(owner); owner: cross_from_sub;468 operator: cross_sub;469 };470471 #[block]472 {473 <Pallet<T>>::allowance_for_all(&collection, &owner, &operator);474 }475476 Ok(())477 }478479 #[benchmark]480 fn repair_item() -> Result<(), BenchmarkError> {481 bench_init! {482 owner: sub; collection: collection(owner);483 owner: cross_from_sub;484 };485 let item = create_max_item(&collection, &owner, owner.clone())?;486487 #[block]488 {489 <Pallet<T>>::repair_item(&collection, item)?;490 }491492 Ok(())493 }494}