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 }265 }266267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288289 290 291 292 293 294295 296 297 298 299 300 301 302303 304 305 306 307 308 309310 311 312 313 314 315 316 317 318 319 320 321 322 323 324325 326 327 328 329 330 331332 333 334 335 336 337 338 339 340 341342 #[benchmark]343 fn set_token_property_permissions(344 b: Linear<0, MAX_PROPERTIES_PER_ITEM>,345 ) -> Result<(), BenchmarkError> {346 bench_init! {347 owner: sub; collection: collection(owner);348 owner: cross_from_sub;349 };350 let perms = (0..b)351 .map(|k| PropertyKeyPermission {352 key: property_key(k as usize),353 permission: PropertyPermission {354 mutable: false,355 collection_admin: false,356 token_owner: false,357 },358 })359 .collect::<Vec<_>>();360361 #[block]362 {363 <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;364 }365366 Ok(())367 }368369 #[benchmark]370 fn set_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {371 bench_init! {372 owner: sub; collection: collection(owner);373 owner: cross_from_sub;374 };375 let perms = (0..b)376 .map(|k| PropertyKeyPermission {377 key: property_key(k as usize),378 permission: PropertyPermission {379 mutable: false,380 collection_admin: true,381 token_owner: true,382 },383 })384 .collect::<Vec<_>>();385 <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;386 let props = (0..b)387 .map(|k| Property {388 key: property_key(k as usize),389 value: property_value(),390 })391 .collect::<Vec<_>>();392 let item = create_max_item(&collection, &owner, owner.clone())?;393394 #[block]395 {396 <Pallet<T>>::set_token_properties(397 &collection,398 &owner,399 item,400 props.into_iter(),401 &Unlimited,402 )?;403 }404405 Ok(())406 }407408 409 #[benchmark]410 fn init_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {411 412 413 414 415416 417 418 419 420 421 422 423 424 425 426 427 #[block]428 {}429 430 431 432 433 434 435 436437 438 439 440 441 442 443444 445 446 447 448 449 450 451 452 453454 Ok(())455 }456457 #[benchmark]458 fn delete_token_properties(459 b: Linear<0, MAX_PROPERTIES_PER_ITEM>,460 ) -> Result<(), BenchmarkError> {461 bench_init! {462 owner: sub; collection: collection(owner);463 owner: cross_from_sub;464 };465 let perms = (0..b)466 .map(|k| PropertyKeyPermission {467 key: property_key(k as usize),468 permission: PropertyPermission {469 mutable: true,470 collection_admin: true,471 token_owner: true,472 },473 })474 .collect::<Vec<_>>();475 <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;476 let props = (0..b)477 .map(|k| Property {478 key: property_key(k as usize),479 value: property_value(),480 })481 .collect::<Vec<_>>();482 let item = create_max_item(&collection, &owner, owner.clone())?;483 <Pallet<T>>::set_token_properties(484 &collection,485 &owner,486 item,487 props.into_iter(),488 &Unlimited,489 )?;490 let to_delete = (0..b).map(|k| property_key(k as usize)).collect::<Vec<_>>();491492 #[block]493 {494 <Pallet<T>>::delete_token_properties(495 &collection,496 &owner,497 item,498 to_delete.into_iter(),499 &Unlimited,500 )?;501 }502503 Ok(())504 }505506 #[benchmark]507 fn token_owner() -> Result<(), BenchmarkError> {508 bench_init! {509 owner: sub; collection: collection(owner);510 owner: cross_from_sub;511 };512 let item = create_max_item(&collection, &owner, owner.clone())?;513514 #[block]515 {516 collection.token_owner(item).unwrap();517 }518519 Ok(())520 }521522 #[benchmark]523 fn set_allowance_for_all() -> Result<(), BenchmarkError> {524 bench_init! {525 owner: sub; collection: collection(owner); owner: cross_from_sub;526 operator: cross_sub;527 };528529 #[block]530 {531 <Pallet<T>>::set_allowance_for_all(&collection, &owner, &operator, true)?;532 }533534 Ok(())535 }536537 #[benchmark]538 fn allowance_for_all() -> Result<(), BenchmarkError> {539 bench_init! {540 owner: sub; collection: collection(owner); owner: cross_from_sub;541 operator: cross_sub;542 };543544 #[block]545 {546 <Pallet<T>>::allowance_for_all(&collection, &owner, &operator);547 }548549 Ok(())550 }551552 #[benchmark]553 fn repair_item() -> Result<(), BenchmarkError> {554 bench_init! {555 owner: sub; collection: collection(owner);556 owner: cross_from_sub;557 };558 let item = create_max_item(&collection, &owner, owner.clone())?;559560 #[block]561 {562 <Pallet<T>>::repair_item(&collection, item)?;563 }564565 Ok(())566 }567}