1234567891011121314151617use frame_benchmarking::v2::{account, benchmarks, BenchmarkError};18use pallet_common::{19 bench_init,20 benchmarking::{create_collection_raw, property_key, property_value},21};22use sp_std::prelude::*;23use up_data_structs::{24 budget::Unlimited, CollectionMode, PropertyPermission, MAX_ITEMS_PER_BATCH,25 MAX_PROPERTIES_PER_ITEM,26};2728use super::*;29use crate::{Config, NonfungibleHandle, Pallet};3031const SEED: u32 = 1;3233fn create_max_item_data<T: Config>(owner: T::CrossAccountId) -> CreateItemData<T> {34 CreateItemData::<T> {35 owner,36 properties: Default::default(),37 }38}39fn create_max_item<T: Config>(40 collection: &NonfungibleHandle<T>,41 sender: &T::CrossAccountId,42 owner: T::CrossAccountId,43) -> Result<TokenId, DispatchError> {44 <Pallet<T>>::create_item(45 collection,46 sender,47 create_max_item_data::<T>(owner),48 &Unlimited,49 )?;50 Ok(TokenId(<TokensMinted<T>>::get(collection.id)))51}5253fn create_collection<T: Config>(54 owner: T::CrossAccountId,55) -> Result<NonfungibleHandle<T>, DispatchError> {56 create_collection_raw(57 owner,58 CollectionMode::NFT,59 |owner: T::CrossAccountId, data| <Pallet<T>>::init_collection(owner.clone(), owner, data),60 NonfungibleHandle::cast,61 )62}6364#[benchmarks]65mod benchmarks {66 use super::*;6768 #[benchmark]69 fn create_item() -> Result<(), BenchmarkError> {70 bench_init! {71 owner: sub; collection: collection(owner);72 sender: cross_from_sub(owner); to: cross_sub;73 };7475 #[block]76 {77 create_max_item(&collection, &sender, to)?;78 }7980 Ok(())81 }8283 #[benchmark]84 fn create_multiple_items(b: Linear<0, MAX_ITEMS_PER_BATCH>) -> Result<(), BenchmarkError> {85 bench_init! {86 owner: sub; collection: collection(owner);87 sender: cross_from_sub(owner); to: cross_sub;88 };89 let data = (0..b)90 .map(|_| create_max_item_data::<T>(to.clone()))91 .collect();9293 #[block]94 {95 <Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?;96 }9798 Ok(())99 }100101 #[benchmark]102 fn create_multiple_items_ex(b: Linear<0, MAX_ITEMS_PER_BATCH>) -> Result<(), BenchmarkError> {103 bench_init! {104 owner: sub; collection: collection(owner);105 sender: cross_from_sub(owner);106 };107 let data = (0..b)108 .map(|i| {109 bench_init!(to: cross_sub(i););110 create_max_item_data::<T>(to)111 })112 .collect();113114 #[block]115 {116 <Pallet<T>>::create_multiple_items(&collection, &sender, data, &Unlimited)?;117 }118119 Ok(())120 }121122 #[benchmark]123 fn burn_item() -> Result<(), BenchmarkError> {124 bench_init! {125 owner: sub; collection: collection(owner);126 sender: cross_from_sub(owner); burner: cross_sub;127 };128 let item = create_max_item(&collection, &sender, burner.clone())?;129130 #[block]131 {132 <Pallet<T>>::burn(&collection, &burner, item)?;133 }134135 Ok(())136 }137138 #[benchmark]139 fn transfer_raw() -> Result<(), BenchmarkError> {140 bench_init! {141 owner: sub; collection: collection(owner);142 owner: cross_from_sub; sender: cross_sub; receiver: cross_sub;143 };144 let item = create_max_item(&collection, &owner, sender.clone())?;145146 #[block]147 {148 <Pallet<T>>::transfer(&collection, &sender, &receiver, item, &Unlimited)?;149 }150151 Ok(())152 }153154 #[benchmark]155 fn approve() -> Result<(), BenchmarkError> {156 bench_init! {157 owner: sub; collection: collection(owner);158 owner: cross_from_sub; sender: cross_sub; spender: cross_sub;159 };160 let item = create_max_item(&collection, &owner, sender.clone())?;161162 #[block]163 {164 <Pallet<T>>::set_allowance(&collection, &sender, item, Some(&spender))?;165 }166167 Ok(())168 }169170 #[benchmark]171 fn approve_from() -> Result<(), BenchmarkError> {172 bench_init! {173 owner: sub; collection: collection(owner);174 owner: cross_from_sub; sender: cross_sub; spender: cross_sub;175 };176 let owner_eth = T::CrossAccountId::from_eth(*sender.as_eth());177 let item = create_max_item(&collection, &owner, owner_eth.clone())?;178179 #[block]180 {181 <Pallet<T>>::set_allowance_from(182 &collection,183 &sender,184 &owner_eth,185 item,186 Some(&spender),187 )?;188 }189190 Ok(())191 }192193 #[benchmark]194 fn check_allowed_raw() -> Result<(), BenchmarkError> {195 bench_init! {196 owner: sub; collection: collection(owner);197 owner: cross_from_sub; sender: cross_sub; spender: cross_sub;198 };199 let item = create_max_item(&collection, &owner, sender.clone())?;200 <Pallet<T>>::set_allowance(&collection, &sender, item, Some(&spender))?;201202 #[block]203 {204 <Pallet<T>>::check_allowed(&collection, &spender, &sender, item, &Unlimited)?;205 }206207 Ok(())208 }209210 #[benchmark]211 fn burn_from() -> Result<(), BenchmarkError> {212 bench_init! {213 owner: sub; collection: collection(owner);214 owner: cross_from_sub; sender: cross_sub; burner: cross_sub;215 };216 let item = create_max_item(&collection, &owner, sender.clone())?;217 <Pallet<T>>::set_allowance(&collection, &sender, item, Some(&burner))?;218219 #[block]220 {221 <Pallet<T>>::burn_from(&collection, &burner, &sender, item, &Unlimited)?;222 }223224 Ok(())225 }226227 #[benchmark]228 fn load_token_properties() -> Result<(), BenchmarkError> {229 bench_init! {230 owner: sub; collection: collection(owner);231 owner: cross_from_sub;232 };233234 let item = create_max_item(&collection, &owner, owner.clone())?;235236 #[block]237 {238 pallet_common::BenchmarkPropertyWriter::<T>::load_token_properties(&collection, item);239 }240241 Ok(())242 }243244 #[benchmark]245 fn write_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {246 bench_init! {247 owner: sub; collection: collection(owner);248 owner: cross_from_sub;249 };250251 let perms = (0..b)252 .map(|k| PropertyKeyPermission {253 key: property_key(k as usize),254 permission: PropertyPermission {255 mutable: false,256 collection_admin: true,257 token_owner: true,258 },259 })260 .collect::<Vec<_>>();261 <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;262 let props = (0..b)263 .map(|k| Property {264 key: property_key(k as usize),265 value: property_value(),266 })267 .collect::<Vec<_>>();268 let item = create_max_item(&collection, &owner, owner.clone())?;269270 let lazy_collection_info =271 pallet_common::BenchmarkPropertyWriter::<T>::load_collection_info(&collection, &owner);272273 #[block]274 {275 let mut property_writer =276 pallet_common::BenchmarkPropertyWriter::new(&collection, lazy_collection_info);277278 property_writer.write_token_properties(279 item,280 props.into_iter(),281 crate::erc::ERC721TokenEvent::TokenChanged {282 token_id: item.into(),283 }284 .to_log(T::ContractAddress::get()),285 )?;286 }287288 Ok(())289 }290291 #[benchmark]292 fn set_token_property_permissions(293 b: Linear<0, MAX_PROPERTIES_PER_ITEM>,294 ) -> Result<(), BenchmarkError> {295 bench_init! {296 owner: sub; collection: collection(owner);297 owner: cross_from_sub;298 };299 let perms = (0..b)300 .map(|k| PropertyKeyPermission {301 key: property_key(k as usize),302 permission: PropertyPermission {303 mutable: false,304 collection_admin: false,305 token_owner: false,306 },307 })308 .collect::<Vec<_>>();309310 #[block]311 {312 <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;313 }314315 Ok(())316 }317318 #[benchmark]319 fn set_allowance_for_all() -> Result<(), BenchmarkError> {320 bench_init! {321 owner: sub; collection: collection(owner); owner: cross_from_sub;322 operator: cross_sub;323 };324325 #[block]326 {327 <Pallet<T>>::set_allowance_for_all(&collection, &owner, &operator, true)?;328 }329330 Ok(())331 }332333 #[benchmark]334 fn allowance_for_all() -> Result<(), BenchmarkError> {335 bench_init! {336 owner: sub; collection: collection(owner); owner: cross_from_sub;337 operator: cross_sub;338 };339340 #[block]341 {342 <Pallet<T>>::allowance_for_all(&collection, &owner, &operator);343 }344345 Ok(())346 }347348 #[benchmark]349 fn repair_item() -> Result<(), BenchmarkError> {350 bench_init! {351 owner: sub; collection: collection(owner);352 owner: cross_from_sub;353 };354 let item = create_max_item(&collection, &owner, owner.clone())?;355356 #[block]357 {358 <Pallet<T>>::repair_item(&collection, item)?;359 }360361 Ok(())362 }363}