1234567891011121314151617use core::{convert::TryInto, iter::IntoIterator};1819use frame_benchmarking::v2::*;20use pallet_common::{21 bench_init,22 benchmarking::{create_collection_raw, property_key, property_value},23};24use sp_std::prelude::*;25use up_data_structs::{26 budget::Unlimited, CollectionMode, PropertyPermission, MAX_ITEMS_PER_BATCH,27 MAX_PROPERTIES_PER_ITEM,28};2930use super::*;31use crate::{Config, Pallet, RefungibleHandle};3233const SEED: u32 = 1;3435fn create_max_item_data<T: Config>(36 users: impl IntoIterator<Item = (T::CrossAccountId, u128)>,37) -> CreateItemData<T> {38 CreateItemData::<T> {39 users: users40 .into_iter()41 .collect::<BTreeMap<_, _>>()42 .try_into()43 .unwrap(),44 properties: Default::default(),45 }46}4748fn create_max_item<T: Config>(49 collection: &RefungibleHandle<T>,50 sender: &T::CrossAccountId,51 users: impl IntoIterator<Item = (T::CrossAccountId, u128)>,52) -> Result<TokenId, DispatchError> {53 let data: CreateItemData<T> = create_max_item_data::<T>(users);54 <Pallet<T>>::create_item(collection, sender, data, &Unlimited)?;55 Ok(TokenId(<TokensMinted<T>>::get(collection.id)))56}5758fn create_collection<T: Config>(59 owner: T::CrossAccountId,60) -> Result<RefungibleHandle<T>, DispatchError> {61 create_collection_raw(62 owner,63 CollectionMode::ReFungible,64 |owner: T::CrossAccountId, data| <Pallet<T>>::init_collection(owner.clone(), owner, data),65 RefungibleHandle::cast,66 )67}6869#[benchmarks]70mod benchmarks {71 use super::*;7273 #[benchmark]74 fn create_item() -> Result<(), BenchmarkError> {75 bench_init! {76 owner: sub; collection: collection(owner);77 sender: cross_from_sub(owner); to: cross_sub;78 };7980 #[block]81 {82 create_max_item(&collection, &sender, [(to, 200)])?;83 }8485 Ok(())86 }8788 #[benchmark]89 fn create_multiple_items(b: Linear<0, MAX_ITEMS_PER_BATCH>) -> Result<(), BenchmarkError> {90 bench_init! {91 owner: sub; collection: collection(owner);92 sender: cross_from_sub(owner); to: cross_sub;93 };94 let data = (0..b)95 .map(|_| create_max_item_data::<T>([(to.clone(), 200)]))96 .collect();9798 #[block]99 {100 <Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?;101 }102103 Ok(())104 }105 #[benchmark]106 fn create_multiple_items_ex_multiple_items(107 b: Linear<0, MAX_ITEMS_PER_BATCH>,108 ) -> Result<(), BenchmarkError> {109 bench_init! {110 owner: sub; collection: collection(owner);111 sender: cross_from_sub(owner);112 };113 let data = (0..b)114 .map(|t| {115 bench_init!(to: cross_sub(t););116 create_max_item_data::<T>([(to, 200)])117 })118 .collect();119120 #[block]121 {122 <Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?;123 }124125 Ok(())126 }127128 #[benchmark]129 fn create_multiple_items_ex_multiple_owners(130 b: Linear<0, MAX_ITEMS_PER_BATCH>,131 ) -> Result<(), BenchmarkError> {132 bench_init! {133 owner: sub; collection: collection(owner);134 sender: cross_from_sub(owner);135 };136 let data = vec![create_max_item_data::<T>((0..b).map(|u| {137 bench_init!(to: cross_sub(u););138 (to, 200)139 }))];140141 #[block]142 {143 <Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?;144 }145146 Ok(())147 }148149 150 #[benchmark]151 fn burn_item_partial() -> Result<(), BenchmarkError> {152 bench_init! {153 owner: sub; collection: collection(owner);154 sender: cross_from_sub(owner); burner: cross_sub; another_owner: cross_sub;155 };156 let item = create_max_item(157 &collection,158 &sender,159 [(burner.clone(), 200), (another_owner, 200)],160 )?;161162 #[block]163 {164 <Pallet<T>>::burn(&collection, &burner, item, 200)?;165 }166167 Ok(())168 }169170 171 #[benchmark]172 fn burn_item_fully() -> Result<(), BenchmarkError> {173 bench_init! {174 owner: sub; collection: collection(owner);175 sender: cross_from_sub(owner); burner: cross_sub;176 };177 let item = create_max_item(&collection, &sender, [(burner.clone(), 200)])?;178179 #[block]180 {181 <Pallet<T>>::burn(&collection, &burner, item, 200)?;182 }183184 Ok(())185 }186187 #[benchmark]188 fn transfer_normal() -> Result<(), BenchmarkError> {189 bench_init! {190 owner: sub; collection: collection(owner);191 sender: cross_from_sub(owner); receiver: cross_sub;192 };193 let item = create_max_item(194 &collection,195 &sender,196 [(sender.clone(), 200), (receiver.clone(), 200)],197 )?;198199 #[block]200 {201 <Pallet<T>>::transfer(&collection, &sender, &receiver, item, 100, &Unlimited)?;202 }203204 Ok(())205 }206207 208 #[benchmark]209 fn transfer_creating() -> Result<(), BenchmarkError> {210 bench_init! {211 owner: sub; collection: collection(owner);212 sender: cross_from_sub(owner); receiver: cross_sub;213 };214 let item = create_max_item(&collection, &sender, [(sender.clone(), 200)])?;215216 #[block]217 {218 <Pallet<T>>::transfer(&collection, &sender, &receiver, item, 100, &Unlimited)?;219 }220221 Ok(())222 }223224 225 #[benchmark]226 fn transfer_removing() -> Result<(), BenchmarkError> {227 bench_init! {228 owner: sub; collection: collection(owner);229 sender: cross_from_sub(owner); receiver: cross_sub;230 };231 let item = create_max_item(232 &collection,233 &sender,234 [(sender.clone(), 200), (receiver.clone(), 200)],235 )?;236237 #[block]238 {239 <Pallet<T>>::transfer(&collection, &sender, &receiver, item, 200, &Unlimited)?;240 }241242 Ok(())243 }244245 246 #[benchmark]247 fn transfer_creating_removing() -> Result<(), BenchmarkError> {248 bench_init! {249 owner: sub; collection: collection(owner);250 sender: cross_from_sub(owner); receiver: cross_sub;251 };252 let item = create_max_item(&collection, &sender, [(sender.clone(), 200)])?;253254 #[block]255 {256 <Pallet<T>>::transfer(&collection, &sender, &receiver, item, 200, &Unlimited)?;257 }258259 Ok(())260 }261262 #[benchmark]263 fn approve() -> Result<(), BenchmarkError> {264 bench_init! {265 owner: sub; collection: collection(owner);266 owner: cross_from_sub; sender: cross_sub; spender: cross_sub;267 };268 let item = create_max_item(&collection, &owner, [(sender.clone(), 200)])?;269270 #[block]271 {272 <Pallet<T>>::set_allowance(&collection, &sender, &spender, item, 100)?;273 }274275 Ok(())276 }277278 #[benchmark]279 fn approve_from() -> Result<(), BenchmarkError> {280 bench_init! {281 owner: sub; collection: collection(owner);282 owner: cross_from_sub; sender: cross_sub; spender: cross_sub;283 };284 let owner_eth = T::CrossAccountId::from_eth(*sender.as_eth());285 let item = create_max_item(&collection, &owner, [(owner_eth.clone(), 200)])?;286287 #[block]288 {289 <Pallet<T>>::set_allowance_from(&collection, &sender, &owner_eth, &spender, item, 100)?;290 }291292 Ok(())293 }294295 #[benchmark]296 fn transfer_from_normal() -> Result<(), BenchmarkError> {297 bench_init! {298 owner: sub; collection: collection(owner);299 owner: cross_from_sub; sender: cross_sub; spender: cross_sub; receiver: cross_sub;300 };301 let item = create_max_item(302 &collection,303 &owner,304 [(sender.clone(), 200), (receiver.clone(), 200)],305 )?;306 <Pallet<T>>::set_allowance(&collection, &sender, &spender, item, 100)?;307308 #[block]309 {310 <Pallet<T>>::transfer_from(311 &collection,312 &spender,313 &sender,314 &receiver,315 item,316 100,317 &Unlimited,318 )?;319 }320321 Ok(())322 }323324 325 #[benchmark]326 fn transfer_from_creating() -> Result<(), BenchmarkError> {327 bench_init! {328 owner: sub; collection: collection(owner);329 owner: cross_from_sub; sender: cross_sub; spender: cross_sub; receiver: cross_sub;330 };331 let item = create_max_item(&collection, &owner, [(sender.clone(), 200)])?;332 <Pallet<T>>::set_allowance(&collection, &sender, &spender, item, 100)?;333334 #[block]335 {336 <Pallet<T>>::transfer_from(337 &collection,338 &spender,339 &sender,340 &receiver,341 item,342 100,343 &Unlimited,344 )?;345 }346347 Ok(())348 }349350 351 #[benchmark]352 fn transfer_from_removing() -> Result<(), BenchmarkError> {353 bench_init! {354 owner: sub; collection: collection(owner);355 owner: cross_from_sub; sender: cross_sub; spender: cross_sub; receiver: cross_sub;356 };357 let item = create_max_item(358 &collection,359 &owner,360 [(sender.clone(), 200), (receiver.clone(), 200)],361 )?;362 <Pallet<T>>::set_allowance(&collection, &sender, &spender, item, 200)?;363364 #[block]365 {366 <Pallet<T>>::transfer_from(367 &collection,368 &spender,369 &sender,370 &receiver,371 item,372 200,373 &Unlimited,374 )?;375 }376377 Ok(())378 }379380 381 #[benchmark]382 fn transfer_from_creating_removing() -> Result<(), BenchmarkError> {383 bench_init! {384 owner: sub; collection: collection(owner);385 owner: cross_from_sub; sender: cross_sub; spender: cross_sub; receiver: cross_sub;386 };387 let item = create_max_item(&collection, &owner, [(sender.clone(), 200)])?;388 <Pallet<T>>::set_allowance(&collection, &sender, &spender, item, 200)?;389390 #[block]391 {392 <Pallet<T>>::transfer_from(393 &collection,394 &spender,395 &sender,396 &receiver,397 item,398 200,399 &Unlimited,400 )?;401 }402403 Ok(())404 }405406 407 #[benchmark]408 fn burn_from() -> Result<(), BenchmarkError> {409 bench_init! {410 owner: sub; collection: collection(owner);411 owner: cross_from_sub; sender: cross_sub; burner: cross_sub;412 };413 let item = create_max_item(&collection, &owner, [(sender.clone(), 200)])?;414 <Pallet<T>>::set_allowance(&collection, &sender, &burner, item, 200)?;415416 #[block]417 {418 <Pallet<T>>::burn_from(&collection, &burner, &sender, item, 200, &Unlimited)?;419 }420421 Ok(())422 }423424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445446 447 448 449 450 451452 453 454 455 456 457 458 459460 461 462 463 464 465 466467 468 469 470 471 472 473 474 475 476 477 478 479 480 481482 483 484 485 486 487 488489 490 491 492 493 494 495 496 497 498499 #[benchmark]500 fn set_token_property_permissions(501 b: Linear<0, MAX_PROPERTIES_PER_ITEM>,502 ) -> Result<(), BenchmarkError> {503 bench_init! {504 owner: sub; collection: collection(owner);505 owner: cross_from_sub;506 };507 let perms = (0..b)508 .map(|k| PropertyKeyPermission {509 key: property_key(k as usize),510 permission: PropertyPermission {511 mutable: false,512 collection_admin: false,513 token_owner: false,514 },515 })516 .collect::<Vec<_>>();517518 #[block]519 {520 <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;521 }522523 Ok(())524 }525526 #[benchmark]527 fn set_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {528 bench_init! {529 owner: sub; collection: collection(owner);530 owner: cross_from_sub;531 };532 let perms = (0..b)533 .map(|k| PropertyKeyPermission {534 key: property_key(k as usize),535 permission: PropertyPermission {536 mutable: false,537 collection_admin: true,538 token_owner: true,539 },540 })541 .collect::<Vec<_>>();542 <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;543 let props = (0..b)544 .map(|k| Property {545 key: property_key(k as usize),546 value: property_value(),547 })548 .collect::<Vec<_>>();549 let item = create_max_item(&collection, &owner, [(owner.clone(), 200)])?;550551 #[block]552 {553 <Pallet<T>>::set_token_properties(554 &collection,555 &owner,556 item,557 props.into_iter(),558 &Unlimited,559 )?;560 }561562 Ok(())563 }564565 566 #[benchmark]567 fn init_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {568 569 570 571 572573 574 575 576 577 578 579 580 581 582 583 584585 #[block]586 {}587 588 589 590 591 592593 594 595 596 597 598 599600 601 602 603 604 605 606 607 608 609 610 611 612613 Ok(())614 }615616 #[benchmark]617 fn delete_token_properties(618 b: Linear<0, MAX_PROPERTIES_PER_ITEM>,619 ) -> Result<(), BenchmarkError> {620 bench_init! {621 owner: sub; collection: collection(owner);622 owner: cross_from_sub;623 };624 let perms = (0..b)625 .map(|k| PropertyKeyPermission {626 key: property_key(k as usize),627 permission: PropertyPermission {628 mutable: true,629 collection_admin: true,630 token_owner: true,631 },632 })633 .collect::<Vec<_>>();634 <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;635 let props = (0..b)636 .map(|k| Property {637 key: property_key(k as usize),638 value: property_value(),639 })640 .collect::<Vec<_>>();641 let item = create_max_item(&collection, &owner, [(owner.clone(), 200)])?;642 <Pallet<T>>::set_token_properties(643 &collection,644 &owner,645 item,646 props.into_iter(),647 &Unlimited,648 )?;649 let to_delete = (0..b).map(|k| property_key(k as usize)).collect::<Vec<_>>();650651 #[block]652 {653 <Pallet<T>>::delete_token_properties(654 &collection,655 &owner,656 item,657 to_delete.into_iter(),658 &Unlimited,659 )?;660 }661662 Ok(())663 }664665 #[benchmark]666 fn repartition_item() -> Result<(), BenchmarkError> {667 bench_init! {668 owner: sub; collection: collection(owner);669 sender: cross_from_sub(owner); owner: cross_sub;670 };671 let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;672673 #[block]674 {675 <Pallet<T>>::repartition(&collection, &owner, item, 200)?;676 }677678 Ok(())679 }680681 #[benchmark]682 fn token_owner() -> Result<(), BenchmarkError> {683 bench_init! {684 owner: sub; collection: collection(owner);685 sender: cross_from_sub(owner); owner: cross_sub;686 };687 let item = create_max_item(&collection, &sender, [(owner, 100)])?;688689 #[block]690 {691 <Pallet<T>>::token_owner(collection.id, item).unwrap();692 }693694 Ok(())695 }696697 #[benchmark]698 fn set_allowance_for_all() -> Result<(), BenchmarkError> {699 bench_init! {700 owner: sub; collection: collection(owner); owner: cross_from_sub;701 operator: cross_sub;702 };703704 #[block]705 {706 <Pallet<T>>::set_allowance_for_all(&collection, &owner, &operator, true)?;707 }708709 Ok(())710 }711712 #[benchmark]713 fn allowance_for_all() -> Result<(), BenchmarkError> {714 bench_init! {715 owner: sub; collection: collection(owner); owner: cross_from_sub;716 operator: cross_sub;717 };718719 #[block]720 {721 <Pallet<T>>::allowance_for_all(&collection, &owner, &operator);722 }723724 Ok(())725 }726727 #[benchmark]728 fn repair_item() -> Result<(), BenchmarkError> {729 bench_init! {730 owner: sub; collection: collection(owner);731 owner: cross_from_sub;732 };733 let item = create_max_item(&collection, &owner, [(owner.clone(), 100)])?;734735 #[block]736 {737 <Pallet<T>>::repair_item(&collection, item)?;738 }739740 Ok(())741 }742}