difftreelog
fix EVM mint with properties, minor improvements
in: master
9 files changed
pallets/common/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/common/src/benchmarking.rs
+++ b/pallets/common/src/benchmarking.rs
@@ -29,9 +29,8 @@
use sp_std::{vec, vec::Vec};
use up_data_structs::{
AccessMode, CollectionId, CollectionMode, CollectionPermissions, CreateCollectionData,
- NestingPermissions, PropertiesPermissionMap, Property, PropertyKey, PropertyValue,
- MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_COLLECTION_NAME_LENGTH, MAX_PROPERTIES_PER_ITEM,
- MAX_TOKEN_PREFIX_LENGTH,
+ NestingPermissions, Property, PropertyKey, PropertyValue, MAX_COLLECTION_DESCRIPTION_LENGTH,
+ MAX_COLLECTION_NAME_LENGTH, MAX_PROPERTIES_PER_ITEM, MAX_TOKEN_PREFIX_LENGTH,
};
use crate::{BenchmarkPropertyWriter, CollectionHandle, Config, Pallet};
@@ -190,31 +189,6 @@
#[block]
{
<Pallet<T>>::set_collection_properties(&collection, &owner, props.into_iter())?;
- }
-
- Ok(())
- }
-
- #[benchmark]
- fn delete_collection_properties(
- b: Linear<0, MAX_PROPERTIES_PER_ITEM>,
- ) -> Result<(), BenchmarkError> {
- bench_init! {
- owner: sub; collection: collection(owner);
- owner: cross_from_sub;
- };
- let props = (0..b)
- .map(|p| Property {
- key: property_key(p as usize),
- value: property_value(),
- })
- .collect::<Vec<_>>();
- <Pallet<T>>::set_collection_properties(&collection, &owner, props.into_iter())?;
- let to_delete = (0..b).map(|p| property_key(p as usize)).collect::<Vec<_>>();
-
- #[block]
- {
- <Pallet<T>>::delete_collection_properties(&collection, &owner, to_delete.into_iter())?;
}
Ok(())
@@ -253,7 +227,7 @@
}
#[benchmark]
- fn init_token_properties_common() -> Result<(), BenchmarkError> {
+ fn property_writer_load_collection_info() -> Result<(), BenchmarkError> {
bench_init! {
owner: sub; collection: collection(owner);
sender: sub;
pallets/common/src/erc.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! This module contains the implementation of pallet methods for evm.1819pub use pallet_evm::{20 account::CrossAccountId, PrecompileHandle, PrecompileOutput, PrecompileResult,21};22use pallet_evm_coder_substrate::{23 abi::AbiType,24 dispatch_to_evm,25 execution::{Error, PreDispatch, Result},26 frontier_contract, solidity_interface,27 types::*,28 ToLog,29};30use sp_std::{vec, vec::Vec};31use up_data_structs::{32 CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property, SponsoringRateLimit,33 SponsorshipState,34};3536use crate::{37 eth, weights::WeightInfo, CollectionHandle, CollectionProperties, Config, Pallet, SelfWeightOf,38};3940frontier_contract! {41 macro_rules! CollectionHandle_result {...}42 impl<T: Config> Contract for CollectionHandle<T> {...}43}4445/// Events for ethereum collection helper.46#[derive(ToLog)]47pub enum CollectionHelpersEvents {48 /// The collection has been created.49 CollectionCreated {50 /// Collection owner.51 #[indexed]52 owner: Address,5354 /// Collection ID.55 #[indexed]56 collection_id: Address,57 },58 /// The collection has been destroyed.59 CollectionDestroyed {60 /// Collection ID.61 #[indexed]62 collection_id: Address,63 },64 /// The collection has been changed.65 CollectionChanged {66 /// Collection ID.67 #[indexed]68 collection_id: Address,69 },70}7172/// Does not always represent a full collection, for RFT it is either73/// collection (Implementing ERC721), or specific collection token (Implementing ERC20).74pub trait CommonEvmHandler {75 /// Raw compiled binary code of the contract stub76 const CODE: &'static [u8];7778 /// Call precompiled handle.79 fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult>;80}8182/// @title A contract that allows you to work with collections.83#[solidity_interface(name = Collection, enum(derive(PreDispatch)), enum_attr(weight))]84impl<T: Config> CollectionHandle<T>85where86 T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,87{88 /// Set collection property.89 ///90 /// @param key Property key.91 /// @param value Propery value.92 #[solidity(hide)]93 #[weight(<SelfWeightOf<T>>::set_collection_properties(1))]94 fn set_collection_property(&mut self, caller: Caller, key: String, value: Bytes) -> Result<()> {95 let caller = T::CrossAccountId::from_eth(caller);96 let key = <Vec<u8>>::from(key)97 .try_into()98 .map_err(|_| "key too large")?;99 let value = value.0.try_into().map_err(|_| "value too large")?;100101 <Pallet<T>>::set_collection_property(self, &caller, Property { key, value })102 .map_err(dispatch_to_evm::<T>)103 }104105 /// Set collection properties.106 ///107 /// @param properties Vector of properties key/value pair.108 #[weight(<SelfWeightOf<T>>::set_collection_properties(properties.len() as u32))]109 fn set_collection_properties(110 &mut self,111 caller: Caller,112 properties: Vec<eth::Property>,113 ) -> Result<()> {114 let caller = T::CrossAccountId::from_eth(caller);115116 let properties = properties117 .into_iter()118 .map(eth::Property::try_into)119 .collect::<Result<Vec<_>>>()?;120121 <Pallet<T>>::set_collection_properties(self, &caller, properties.into_iter())122 .map_err(dispatch_to_evm::<T>)123 }124125 /// Delete collection property.126 ///127 /// @param key Property key.128 #[solidity(hide)]129 #[weight(<SelfWeightOf<T>>::set_collection_properties(1))]130 fn delete_collection_property(&mut self, caller: Caller, key: String) -> Result<()> {131 let caller = T::CrossAccountId::from_eth(caller);132 let key = <Vec<u8>>::from(key)133 .try_into()134 .map_err(|_| "key too large")?;135136 <Pallet<T>>::delete_collection_property(self, &caller, key).map_err(dispatch_to_evm::<T>)137 }138139 /// Delete collection properties.140 ///141 /// @param keys Properties keys.142 #[weight(<SelfWeightOf<T>>::set_collection_properties(keys.len() as u32))]143 fn delete_collection_properties(&mut self, caller: Caller, keys: Vec<String>) -> Result<()> {144 let caller = T::CrossAccountId::from_eth(caller);145 let keys = keys146 .into_iter()147 .map(|key| {148 <Vec<u8>>::from(key)149 .try_into()150 .map_err(|_| Error::Revert("key too large".into()))151 })152 .collect::<Result<Vec<_>>>()?;153154 <Pallet<T>>::delete_collection_properties(self, &caller, keys.into_iter())155 .map_err(dispatch_to_evm::<T>)156 }157158 /// Get collection property.159 ///160 /// @dev Throws error if key not found.161 ///162 /// @param key Property key.163 /// @return bytes The property corresponding to the key.164 fn collection_property(&self, key: String) -> Result<Bytes> {165 let key = <Vec<u8>>::from(key)166 .try_into()167 .map_err(|_| "key too large")?;168169 let props = CollectionProperties::<T>::get(self.id);170 let prop = props.get(&key).ok_or("key not found")?;171172 Ok(Bytes(prop.to_vec()))173 }174175 /// Get collection properties.176 ///177 /// @param keys Properties keys. Empty keys for all propertyes.178 /// @return Vector of properties key/value pairs.179 fn collection_properties(&self, keys: Vec<String>) -> Result<Vec<eth::Property>> {180 let keys = keys181 .into_iter()182 .map(|key| {183 <Vec<u8>>::from(key)184 .try_into()185 .map_err(|_| Error::Revert("key too large".into()))186 })187 .collect::<Result<Vec<_>>>()?;188189 let properties = Pallet::<T>::filter_collection_properties(190 self.id,191 if keys.is_empty() { None } else { Some(keys) },192 )193 .map_err(dispatch_to_evm::<T>)?;194195 let properties = properties196 .into_iter()197 .map(Property::try_into)198 .collect::<Result<Vec<_>>>()?;199 Ok(properties)200 }201202 /// Set the sponsor of the collection.203 ///204 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.205 ///206 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.207 #[solidity(hide)]208 fn set_collection_sponsor(&mut self, caller: Caller, sponsor: Address) -> Result<()> {209 self.consume_store_reads_and_writes(1, 1)?;210211 let caller = T::CrossAccountId::from_eth(caller);212213 let sponsor = T::CrossAccountId::from_eth(sponsor);214 self.set_sponsor(&caller, sponsor.as_sub().clone())215 .map_err(dispatch_to_evm::<T>)216 }217218 /// Set the sponsor of the collection.219 ///220 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.221 ///222 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.223 fn set_collection_sponsor_cross(224 &mut self,225 caller: Caller,226 sponsor: eth::CrossAddress,227 ) -> Result<()> {228 self.consume_store_reads_and_writes(1, 1)?;229230 let caller = T::CrossAccountId::from_eth(caller);231232 let sponsor = sponsor.into_sub_cross_account::<T>()?;233 self.set_sponsor(&caller, sponsor.as_sub().clone())234 .map_err(dispatch_to_evm::<T>)235 }236237 /// Whether there is a pending sponsor.238 fn has_collection_pending_sponsor(&self) -> Result<bool> {239 Ok(matches!(240 self.collection.sponsorship,241 SponsorshipState::Unconfirmed(_)242 ))243 }244245 /// Collection sponsorship confirmation.246 ///247 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.248 fn confirm_collection_sponsorship(&mut self, caller: Caller) -> Result<()> {249 self.consume_store_writes(1)?;250251 let caller = T::CrossAccountId::from_eth(caller);252 self.confirm_sponsorship(caller.as_sub())253 .map_err(dispatch_to_evm::<T>)254 }255256 /// Remove collection sponsor.257 fn remove_collection_sponsor(&mut self, caller: Caller) -> Result<()> {258 self.consume_store_reads_and_writes(1, 1)?;259 let caller = T::CrossAccountId::from_eth(caller);260 self.remove_sponsor(&caller).map_err(dispatch_to_evm::<T>)261 }262263 /// Get current sponsor.264 ///265 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.266 fn collection_sponsor(&self) -> Result<eth::CrossAddress> {267 let sponsor = match self.collection.sponsorship.sponsor() {268 Some(sponsor) => sponsor,269 None => return Ok(Default::default()),270 };271272 Ok(eth::CrossAddress::from_sub::<T>(sponsor))273 }274275 /// Get current collection limits.276 ///277 /// @return Array of collection limits278 fn collection_limits(&self) -> Result<Vec<eth::CollectionLimit>> {279 let limits = &self.collection.limits;280281 Ok(vec![282 eth::CollectionLimit::new(283 eth::CollectionLimitField::AccountTokenOwnership,284 limits.account_token_ownership_limit,285 ),286 eth::CollectionLimit::new(287 eth::CollectionLimitField::SponsoredDataSize,288 limits.sponsored_data_size,289 ),290 limits291 .sponsored_data_rate_limit292 .and_then(|limit| {293 if let SponsoringRateLimit::Blocks(blocks) = limit {294 Some(eth::CollectionLimit::new(295 eth::CollectionLimitField::SponsoredDataRateLimit,296 Some(blocks),297 ))298 } else {299 None300 }301 })302 .unwrap_or_else(|| {303 eth::CollectionLimit::new(304 eth::CollectionLimitField::SponsoredDataRateLimit,305 Default::default(),306 )307 }),308 eth::CollectionLimit::new(eth::CollectionLimitField::TokenLimit, limits.token_limit),309 eth::CollectionLimit::new(310 eth::CollectionLimitField::SponsorTransferTimeout,311 limits.sponsor_transfer_timeout,312 ),313 eth::CollectionLimit::new(314 eth::CollectionLimitField::SponsorApproveTimeout,315 limits.sponsor_approve_timeout,316 ),317 eth::CollectionLimit::new(318 eth::CollectionLimitField::OwnerCanTransfer,319 limits.owner_can_transfer.map(u32::from),320 ),321 eth::CollectionLimit::new(322 eth::CollectionLimitField::OwnerCanDestroy,323 limits.owner_can_destroy.map(u32::from),324 ),325 eth::CollectionLimit::new(326 eth::CollectionLimitField::TransferEnabled,327 limits.transfers_enabled.map(u32::from),328 ),329 ])330 }331332 /// Set limits for the collection.333 /// @dev Throws error if limit not found.334 /// @param limit Some limit.335 #[solidity(rename_selector = "setCollectionLimit")]336 fn set_collection_limit(&mut self, caller: Caller, limit: eth::CollectionLimit) -> Result<()> {337 self.consume_store_reads_and_writes(1, 1)?;338339 if !limit.has_value() {340 return Err(Error::Revert("user can't disable limits".into()));341 }342343 let caller = T::CrossAccountId::from_eth(caller);344 <Pallet<T>>::update_limits(&caller, self, limit.try_into()?).map_err(dispatch_to_evm::<T>)345 }346347 /// Get contract address.348 fn contract_address(&self) -> Result<Address> {349 Ok(crate::eth::collection_id_to_address(self.id))350 }351352 /// Add collection admin.353 /// @param newAdmin Cross account administrator address.354 fn add_collection_admin_cross(355 &mut self,356 caller: Caller,357 new_admin: eth::CrossAddress,358 ) -> Result<()> {359 self.consume_store_reads_and_writes(2, 2)?;360361 let caller = T::CrossAccountId::from_eth(caller);362 let new_admin = new_admin.into_sub_cross_account::<T>()?;363 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;364 Ok(())365 }366367 /// Remove collection admin.368 /// @param admin Cross account administrator address.369 fn remove_collection_admin_cross(370 &mut self,371 caller: Caller,372 admin: eth::CrossAddress,373 ) -> Result<()> {374 self.consume_store_reads_and_writes(2, 2)?;375376 let caller = T::CrossAccountId::from_eth(caller);377 let admin = admin.into_sub_cross_account::<T>()?;378 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;379 Ok(())380 }381382 /// Add collection admin.383 /// @param newAdmin Address of the added administrator.384 #[solidity(hide)]385 fn add_collection_admin(&mut self, caller: Caller, new_admin: Address) -> Result<()> {386 self.consume_store_reads_and_writes(2, 2)?;387388 let caller = T::CrossAccountId::from_eth(caller);389 let new_admin = T::CrossAccountId::from_eth(new_admin);390 <Pallet<T>>::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::<T>)?;391 Ok(())392 }393394 /// Remove collection admin.395 ///396 /// @param admin Address of the removed administrator.397 #[solidity(hide)]398 fn remove_collection_admin(&mut self, caller: Caller, admin: Address) -> Result<()> {399 self.consume_store_reads_and_writes(2, 2)?;400401 let caller = T::CrossAccountId::from_eth(caller);402 let admin = T::CrossAccountId::from_eth(admin);403 <Pallet<T>>::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::<T>)?;404 Ok(())405 }406407 #[solidity(rename_selector = "setCollectionNesting")]408 fn set_nesting(409 &mut self,410 caller: Caller,411 collection_nesting_and_permissions: eth::CollectionNestingAndPermission,412 ) -> Result<()> {413 self.consume_store_reads_and_writes(1, 1)?;414415 let caller = T::CrossAccountId::from_eth(caller);416417 let mut permissions = self.collection.permissions.clone();418 let mut nesting = permissions.nesting().clone();419420 let bv = if !collection_nesting_and_permissions.restricted.is_empty() {421 let mut bv = OwnerRestrictedSet::new();422 for address in collection_nesting_and_permissions.restricted.iter() {423 bv.try_insert(crate::eth::map_eth_to_id(address).ok_or_else(|| {424 Error::Revert("Can't convert address into collection id".into())425 })?)426 .map_err(|_| "too many collections")?;427 }428 Some(bv)429 } else {430 None431 };432433 nesting.token_owner = collection_nesting_and_permissions.token_owner;434 nesting.collection_admin = collection_nesting_and_permissions.collection_admin;435 nesting.restricted = bv;436 permissions.nesting = Some(nesting);437438 <Pallet<T>>::update_permissions(&caller, self, permissions).map_err(dispatch_to_evm::<T>)439 }440441 /// Toggle accessibility of collection nesting.442 ///443 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'444 #[solidity(hide, rename_selector = "setCollectionNesting")]445 fn set_nesting_bool(&mut self, caller: Caller, enable: bool) -> Result<()> {446 self.consume_store_reads_and_writes(1, 1)?;447448 let caller = T::CrossAccountId::from_eth(caller);449450 let mut permissions = self.collection.permissions.clone();451 let mut nesting = permissions.nesting().clone();452 nesting.token_owner = enable;453 nesting.restricted = None;454 permissions.nesting = Some(nesting);455456 <Pallet<T>>::update_permissions(&caller, self, permissions).map_err(dispatch_to_evm::<T>)457 }458459 /// Toggle accessibility of collection nesting.460 ///461 /// @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'462 /// @param collections Addresses of collections that will be available for nesting.463 #[solidity(hide, rename_selector = "setCollectionNesting")]464 fn set_nesting_collection_ids(465 &mut self,466 caller: Caller,467 enable: bool,468 collections: Vec<Address>,469 ) -> Result<()> {470 self.consume_store_reads_and_writes(1, 1)?;471472 if collections.is_empty() {473 return Err("no addresses provided".into());474 }475 let caller = T::CrossAccountId::from_eth(caller);476477 let mut permissions = self.collection.permissions.clone();478 match enable {479 false => {480 let mut nesting = permissions.nesting().clone();481 nesting.token_owner = false;482 nesting.restricted = None;483 permissions.nesting = Some(nesting);484 }485 true => {486 let mut bv = OwnerRestrictedSet::new();487 for i in collections {488 bv.try_insert(crate::eth::map_eth_to_id(&i).ok_or_else(|| {489 Error::Revert("Can't convert address into collection id".into())490 })?)491 .map_err(|_| "too many collections")?;492 }493 let mut nesting = permissions.nesting().clone();494 nesting.token_owner = true;495 nesting.restricted = Some(bv);496 permissions.nesting = Some(nesting);497 }498 };499500 <Pallet<T>>::update_permissions(&caller, self, permissions).map_err(dispatch_to_evm::<T>)501 }502503 #[solidity(rename_selector = "collectionNesting")]504 fn collection_nesting(&self) -> Result<eth::CollectionNestingAndPermission> {505 let nesting = self.collection.permissions.nesting();506507 Ok(eth::CollectionNestingAndPermission::new(508 nesting.token_owner,509 nesting.collection_admin,510 nesting511 .restricted512 .clone()513 .map(|b| {514 b.0.into_inner()515 .iter()516 .map(|id| crate::eth::collection_id_to_address(id.0.into()))517 .collect()518 })519 .unwrap_or_default(),520 ))521 }522523 /// Returns nesting for a collection524 #[solidity(hide, rename_selector = "collectionNestingRestrictedCollectionIds")]525 fn collection_nesting_restricted_ids(&self) -> Result<eth::CollectionNesting> {526 let nesting = self.collection.permissions.nesting();527528 Ok(eth::CollectionNesting::new(529 nesting.token_owner,530 nesting531 .restricted532 .clone()533 .map(|b| b.0.into_inner().iter().map(|id| id.0.into()).collect())534 .unwrap_or_default(),535 ))536 }537538 /// Returns permissions for a collection539 #[solidity(hide)]540 fn collection_nesting_permissions(&self) -> Result<Vec<eth::CollectionNestingPermission>> {541 let nesting = self.collection.permissions.nesting();542 Ok(vec![543 eth::CollectionNestingPermission::new(544 eth::CollectionPermissionField::CollectionAdmin,545 nesting.collection_admin,546 ),547 eth::CollectionNestingPermission::new(548 eth::CollectionPermissionField::TokenOwner,549 nesting.token_owner,550 ),551 ])552 }553 /// Set the collection access method.554 /// @param mode Access mode555 fn set_collection_access(&mut self, caller: Caller, mode: eth::AccessMode) -> Result<()> {556 self.consume_store_reads_and_writes(1, 1)?;557558 let caller = T::CrossAccountId::from_eth(caller);559 let permissions = CollectionPermissions {560 access: Some(mode.into()),561 ..Default::default()562 };563 <Pallet<T>>::update_permissions(&caller, self, permissions).map_err(dispatch_to_evm::<T>)564 }565566 /// Checks that user allowed to operate with collection.567 ///568 /// @param user User address to check.569 fn allowlisted_cross(&self, user: eth::CrossAddress) -> Result<bool> {570 let user = user.into_sub_cross_account::<T>()?;571 Ok(Pallet::<T>::allowed(self.id, user))572 }573574 /// Add the user to the allowed list.575 ///576 /// @param user Address of a trusted user.577 #[solidity(hide)]578 fn add_to_collection_allow_list(&mut self, caller: Caller, user: Address) -> Result<()> {579 self.consume_store_writes(1)?;580581 let caller = T::CrossAccountId::from_eth(caller);582 let user = T::CrossAccountId::from_eth(user);583 <Pallet<T>>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;584 Ok(())585 }586587 /// Add user to allowed list.588 ///589 /// @param user User cross account address.590 fn add_to_collection_allow_list_cross(591 &mut self,592 caller: Caller,593 user: eth::CrossAddress,594 ) -> Result<()> {595 self.consume_store_writes(1)?;596597 let caller = T::CrossAccountId::from_eth(caller);598 let user = user.into_sub_cross_account::<T>()?;599 Pallet::<T>::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::<T>)?;600 Ok(())601 }602603 /// Remove the user from the allowed list.604 ///605 /// @param user Address of a removed user.606 #[solidity(hide)]607 fn remove_from_collection_allow_list(&mut self, caller: Caller, user: Address) -> Result<()> {608 self.consume_store_writes(1)?;609610 let caller = T::CrossAccountId::from_eth(caller);611 let user = T::CrossAccountId::from_eth(user);612 <Pallet<T>>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;613 Ok(())614 }615616 /// Remove user from allowed list.617 ///618 /// @param user User cross account address.619 fn remove_from_collection_allow_list_cross(620 &mut self,621 caller: Caller,622 user: eth::CrossAddress,623 ) -> Result<()> {624 self.consume_store_writes(1)?;625626 let caller = T::CrossAccountId::from_eth(caller);627 let user = user.into_sub_cross_account::<T>()?;628 Pallet::<T>::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::<T>)?;629 Ok(())630 }631632 /// Switch permission for minting.633 ///634 /// @param mode Enable if "true".635 fn set_collection_mint_mode(&mut self, caller: Caller, mode: bool) -> Result<()> {636 self.consume_store_reads_and_writes(1, 1)?;637638 let caller = T::CrossAccountId::from_eth(caller);639 let permissions = CollectionPermissions {640 mint_mode: Some(mode),641 ..Default::default()642 };643 <Pallet<T>>::update_permissions(&caller, self, permissions).map_err(dispatch_to_evm::<T>)644 }645646 /// Check that account is the owner or admin of the collection647 ///648 /// @param user account to verify649 /// @return "true" if account is the owner or admin650 #[solidity(hide, rename_selector = "isOwnerOrAdmin")]651 fn is_owner_or_admin_eth(&self, user: Address) -> Result<bool> {652 let user = T::CrossAccountId::from_eth(user);653 Ok(self.is_owner_or_admin(&user))654 }655656 /// Check that account is the owner or admin of the collection657 ///658 /// @param user User cross account to verify659 /// @return "true" if account is the owner or admin660 fn is_owner_or_admin_cross(&self, user: eth::CrossAddress) -> Result<bool> {661 let user = user.into_sub_cross_account::<T>()?;662 Ok(self.is_owner_or_admin(&user))663 }664665 /// Returns collection type666 ///667 /// @return `Fungible` or `NFT` or `ReFungible`668 fn unique_collection_type(&self) -> Result<String> {669 let mode = match self.collection.mode {670 CollectionMode::Fungible(_) => "Fungible",671 CollectionMode::NFT => "NFT",672 CollectionMode::ReFungible => "ReFungible",673 };674 Ok(mode.into())675 }676677 /// Get collection owner.678 ///679 /// @return Tuble with sponsor address and his substrate mirror.680 /// If address is canonical then substrate mirror is zero and vice versa.681 fn collection_owner(&self) -> Result<eth::CrossAddress> {682 Ok(eth::CrossAddress::from_sub_cross_account::<T>(683 &T::CrossAccountId::from_sub(self.owner.clone()),684 ))685 }686687 /// Changes collection owner to another account688 ///689 /// @dev Owner can be changed only by current owner690 /// @param newOwner new owner account691 #[solidity(hide, rename_selector = "changeCollectionOwner")]692 fn set_owner(&mut self, caller: Caller, new_owner: Address) -> Result<()> {693 self.consume_store_writes(1)?;694695 let caller = T::CrossAccountId::from_eth(caller);696 let new_owner = T::CrossAccountId::from_eth(new_owner);697 self.change_owner(caller, new_owner)698 .map_err(dispatch_to_evm::<T>)699 }700701 /// Get collection administrators702 ///703 /// @return Vector of tuples with admins address and his substrate mirror.704 /// If address is canonical then substrate mirror is zero and vice versa.705 fn collection_admins(&self) -> Result<Vec<eth::CrossAddress>> {706 let result = crate::IsAdmin::<T>::iter_prefix((self.id,))707 .map(|(admin, _)| eth::CrossAddress::from_sub_cross_account::<T>(&admin))708 .collect();709 Ok(result)710 }711712 /// Changes collection owner to another account713 ///714 /// @dev Owner can be changed only by current owner715 /// @param newOwner new owner cross account716 fn change_collection_owner_cross(717 &mut self,718 caller: Caller,719 new_owner: eth::CrossAddress,720 ) -> Result<()> {721 self.consume_store_writes(1)?;722723 let caller = T::CrossAccountId::from_eth(caller);724 let new_owner = new_owner.into_sub_cross_account::<T>()?;725 self.change_owner(caller, new_owner)726 .map_err(dispatch_to_evm::<T>)727 }728}729730/// Contains static property keys and values.731pub mod static_property {732 use alloc::format;733734 use pallet_evm_coder_substrate::execution::{Error, Result};735736 const EXPECT_CONVERT_ERROR: &str = "length < limit";737738 /// Keys.739 pub mod key {740 use super::*;741742 /// Key "baseURI".743 pub fn base_uri() -> up_data_structs::PropertyKey {744 property_key_from_bytes(b"baseURI").expect(EXPECT_CONVERT_ERROR)745 }746747 /// Key "url".748 pub fn url() -> up_data_structs::PropertyKey {749 property_key_from_bytes(b"URI").expect(EXPECT_CONVERT_ERROR)750 }751752 /// Key "suffix".753 pub fn suffix() -> up_data_structs::PropertyKey {754 property_key_from_bytes(b"URISuffix").expect(EXPECT_CONVERT_ERROR)755 }756757 /// Key "parentNft".758 pub fn parent_nft() -> up_data_structs::PropertyKey {759 property_key_from_bytes(b"parentNft").expect(EXPECT_CONVERT_ERROR)760 }761 }762763 /// Convert `byte` to [`PropertyKey`].764 pub fn property_key_from_bytes(bytes: &[u8]) -> Result<up_data_structs::PropertyKey> {765 bytes.to_vec().try_into().map_err(|_| {766 Error::Revert(format!(767 "Property key is too long. Max length is {}.",768 up_data_structs::PropertyKey::bound()769 ))770 })771 }772773 /// Convert `bytes` to [`PropertyValue`].774 pub fn property_value_from_bytes(bytes: &[u8]) -> Result<up_data_structs::PropertyValue> {775 bytes.to_vec().try_into().map_err(|_| {776 Error::Revert(format!(777 "Property key is too long. Max length is {}.",778 up_data_structs::PropertyKey::bound()779 ))780 })781 }782}pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -2626,8 +2626,8 @@
impl<T: Config> BenchmarkPropertyWriter<T> {
/// Creates a [`PropertyWriter`] for benchmarking tokens properties writing.
pub fn new<'a, Handle>(
- collection: &Handle,
- collection_lazy_info: PropertyWriterLazyCollectionInfo,
+ collection: &'a Handle,
+ collection_lazy_info: PropertyWriterLazyCollectionInfo<'a>,
) -> PropertyWriter<'a, Self, T, Handle>
where
Handle: CommonCollectionOperations<T> + Deref<Target = CollectionHandle<T>>,
pallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/benchmarking.rs
+++ b/pallets/nonfungible/src/benchmarking.rs
@@ -18,7 +18,6 @@
use pallet_common::{
bench_init,
benchmarking::{create_collection_raw, property_key, property_value},
- CommonCollectionOperations,
};
use sp_std::prelude::*;
use up_data_structs::{
@@ -131,53 +130,12 @@
#[block]
{
<Pallet<T>>::burn(&collection, &burner, item)?;
- }
-
- Ok(())
- }
-
- #[benchmark]
- fn burn_recursively_self_raw() -> Result<(), BenchmarkError> {
- bench_init! {
- owner: sub; collection: collection(owner);
- sender: cross_from_sub(owner); burner: cross_sub;
- };
- let item = create_max_item(&collection, &sender, burner.clone())?;
-
- #[block]
- {
- <Pallet<T>>::burn_recursively(&collection, &burner, item, &Unlimited, &Unlimited)?;
}
Ok(())
}
#[benchmark]
- fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(
- b: Linear<0, 200>,
- ) -> Result<(), BenchmarkError> {
- bench_init! {
- owner: sub; collection: collection(owner);
- sender: cross_from_sub(owner); burner: cross_sub;
- };
- let item = create_max_item(&collection, &sender, burner.clone())?;
- for _ in 0..b {
- create_max_item(
- &collection,
- &sender,
- T::CrossTokenAddressMapping::token_to_address(collection.id, item),
- )?;
- }
-
- #[block]
- {
- <Pallet<T>>::burn_recursively(&collection, &burner, item, &Unlimited, &Unlimited)?;
- }
-
- Ok(())
- }
-
- #[benchmark]
fn transfer_raw() -> Result<(), BenchmarkError> {
bench_init! {
owner: sub; collection: collection(owner);
@@ -262,116 +220,34 @@
{
<Pallet<T>>::burn_from(&collection, &burner, &sender, item, &Unlimited)?;
}
- }
- // set_token_properties {
- // let b in 0..MAX_PROPERTIES_PER_ITEM;
- // bench_init!{
- // owner: sub; collection: collection(owner);
- // owner: cross_from_sub;
- // };
- // let perms = (0..b).map(|k| PropertyKeyPermission {
- // key: property_key(k as usize),
- // permission: PropertyPermission {
- // mutable: false,
- // collection_admin: true,
- // token_owner: true,
- // },
- // }).collect::<Vec<_>>();
- // <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;
- // let props = (0..b).map(|k| Property {
- // key: property_key(k as usize),
- // value: property_value(),
- // }).collect::<Vec<_>>();
- // let item = create_max_item(&collection, &owner, owner.clone())?;
- // }: {<Pallet<T>>::set_token_properties(&collection, &owner, item, props.into_iter(), &Unlimited)?}
-
- // load_token_properties {
- // bench_init!{
- // owner: sub; collection: collection(owner);
- // owner: cross_from_sub;
- // };
-
- // let item = create_max_item(&collection, &owner, owner.clone())?;
- // }: {
- // pallet_common::BenchmarkPropertyWriter::<T>::load_token_properties(
- // &collection,
- // item,
- // )
- // }
-
- // write_token_properties {
- // let b in 0..MAX_PROPERTIES_PER_ITEM;
- // bench_init!{
- // owner: sub; collection: collection(owner);
- // owner: cross_from_sub;
- // };
+ Ok(())
+ }
- // let perms = (0..b).map(|k| PropertyKeyPermission {
- // key: property_key(k as usize),
- // permission: PropertyPermission {
- // mutable: false,
- // collection_admin: true,
- // token_owner: true,
- // },
- // }).collect::<Vec<_>>();
- // <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;
- // let props = (0..b).map(|k| Property {
- // key: property_key(k as usize),
- // value: property_value(),
- // }).collect::<Vec<_>>();
- // let item = create_max_item(&collection, &owner, owner.clone())?;
-
- // let lazy_collection_info = pallet_common::BenchmarkPropertyWriter::<T>::load_collection_info(
- // &collection,
- // &owner,
- // );
- // }: {
- // let mut property_writer = pallet_common::BenchmarkPropertyWriter::new(&collection, lazy_collection_info);
-
- // property_writer.write_token_properties(
- // item,
- // props.into_iter(),
- // crate::erc::ERC721TokenEvent::TokenChanged {
- // token_id: item.into(),
- // }
- // .to_log(T::ContractAddress::get()),
- // )?
- // }
-
#[benchmark]
- fn set_token_property_permissions(
- b: Linear<0, MAX_PROPERTIES_PER_ITEM>,
- ) -> Result<(), BenchmarkError> {
+ fn load_token_properties() -> Result<(), BenchmarkError> {
bench_init! {
owner: sub; collection: collection(owner);
owner: cross_from_sub;
};
- let perms = (0..b)
- .map(|k| PropertyKeyPermission {
- key: property_key(k as usize),
- permission: PropertyPermission {
- mutable: false,
- collection_admin: false,
- token_owner: false,
- },
- })
- .collect::<Vec<_>>();
+ let item = create_max_item(&collection, &owner, owner.clone())?;
+
#[block]
{
- <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;
+ pallet_common::BenchmarkPropertyWriter::<T>::load_token_properties(&collection, item);
}
Ok(())
}
#[benchmark]
- fn set_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {
+ fn write_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {
bench_init! {
owner: sub; collection: collection(owner);
owner: cross_from_sub;
};
+
let perms = (0..b)
.map(|k| PropertyKeyPermission {
key: property_key(k as usize),
@@ -391,71 +267,29 @@
.collect::<Vec<_>>();
let item = create_max_item(&collection, &owner, owner.clone())?;
+ let lazy_collection_info =
+ pallet_common::BenchmarkPropertyWriter::<T>::load_collection_info(&collection, &owner);
+
#[block]
{
- <Pallet<T>>::set_token_properties(
- &collection,
- &owner,
+ let mut property_writer =
+ pallet_common::BenchmarkPropertyWriter::new(&collection, lazy_collection_info);
+
+ property_writer.write_token_properties(
item,
props.into_iter(),
- &Unlimited,
+ crate::erc::ERC721TokenEvent::TokenChanged {
+ token_id: item.into(),
+ }
+ .to_log(T::ContractAddress::get()),
)?;
}
Ok(())
}
- // TODO:
#[benchmark]
- fn init_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {
- // bench_init! {
- // owner: sub; collection: collection(owner);
- // owner: cross_from_sub;
- // };
-
- // let perms = (0..b)
- // .map(|k| PropertyKeyPermission {
- // key: property_key(k as usize),
- // permission: PropertyPermission {
- // mutable: false,
- // collection_admin: true,
- // token_owner: true,
- // },
- // })
- // .collect::<Vec<_>>();
- // <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;
- #[block]
- {}
- // let props = (0..b)
- // .map(|k| Property {
- // key: property_key(k as usize),
- // value: property_value(),
- // })
- // .collect::<Vec<_>>();
- // let item = create_max_item(&collection, &owner, owner.clone())?;
-
- // let (is_collection_admin, property_permissions) =
- // load_is_admin_and_property_permissions(&collection, &owner);
- // #[block]
- // {
- // let mut property_writer =
- // pallet_common::BenchmarkPropertyWriter::new(&collection, lazy_collection_info);
-
- // property_writer.write_token_properties(
- // item,
- // props.into_iter(),
- // crate::erc::ERC721TokenEvent::TokenChanged {
- // token_id: item.into(),
- // }
- // .to_log(T::ContractAddress::get()),
- // )?;
- // }
-
- Ok(())
- }
-
- #[benchmark]
- fn delete_token_properties(
+ fn set_token_property_permissions(
b: Linear<0, MAX_PROPERTIES_PER_ITEM>,
) -> Result<(), BenchmarkError> {
bench_init! {
@@ -466,54 +300,16 @@
.map(|k| PropertyKeyPermission {
key: property_key(k as usize),
permission: PropertyPermission {
- mutable: true,
- collection_admin: true,
- token_owner: true,
+ mutable: false,
+ collection_admin: false,
+ token_owner: false,
},
- })
- .collect::<Vec<_>>();
- <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;
- let props = (0..b)
- .map(|k| Property {
- key: property_key(k as usize),
- value: property_value(),
})
.collect::<Vec<_>>();
- let item = create_max_item(&collection, &owner, owner.clone())?;
- <Pallet<T>>::set_token_properties(
- &collection,
- &owner,
- item,
- props.into_iter(),
- &Unlimited,
- )?;
- let to_delete = (0..b).map(|k| property_key(k as usize)).collect::<Vec<_>>();
#[block]
{
- <Pallet<T>>::delete_token_properties(
- &collection,
- &owner,
- item,
- to_delete.into_iter(),
- &Unlimited,
- )?;
- }
-
- Ok(())
- }
-
- #[benchmark]
- fn token_owner() -> Result<(), BenchmarkError> {
- bench_init! {
- owner: sub; collection: collection(owner);
- owner: cross_from_sub;
- };
- let item = create_max_item(&collection, &owner, owner.clone())?;
-
- #[block]
- {
- collection.token_owner(item).unwrap();
+ <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;
}
Ok(())
pallets/nonfungible/src/common.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -39,24 +39,21 @@
impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {
fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {
match data {
- CreateItemExData::NFT(t) => <SelfWeightOf<T>>::create_multiple_items_ex(t.len() as u32)
- .saturating_add(write_token_properties_total_weight::<T, _>(
- t.iter().map(|t| t.properties.len() as u32),
- <SelfWeightOf<T>>::write_token_properties,
- )),
+ CreateItemExData::NFT(t) => mint_with_props_weight::<T>(
+ <SelfWeightOf<T>>::create_multiple_items_ex(t.len() as u32),
+ t.iter().map(|t| t.properties.len() as u32),
+ ),
_ => Weight::zero(),
}
}
fn create_multiple_items(data: &[up_data_structs::CreateItemData]) -> Weight {
- <SelfWeightOf<T>>::create_multiple_items(data.len() as u32).saturating_add(
- write_token_properties_total_weight::<T, _>(
- data.iter().map(|t| match t {
- up_data_structs::CreateItemData::NFT(n) => n.properties.len() as u32,
- _ => 0,
- }),
- <SelfWeightOf<T>>::write_token_properties,
- ),
+ mint_with_props_weight::<T>(
+ <SelfWeightOf<T>>::create_multiple_items(data.len() as u32),
+ data.iter().map(|t| match t {
+ up_data_structs::CreateItemData::NFT(n) => n.properties.len() as u32,
+ _ => 0,
+ }),
)
}
@@ -113,6 +110,16 @@
}
}
+pub(crate) fn mint_with_props_weight<T: Config>(
+ create_no_data_weight: Weight,
+ tokens: impl Iterator<Item = u32> + Clone,
+) -> Weight {
+ create_no_data_weight.saturating_add(write_token_properties_total_weight::<T, _>(
+ tokens,
+ <SelfWeightOf<T>>::write_token_properties,
+ ))
+}
+
fn map_create_data<T: Config>(
data: up_data_structs::CreateItemData,
to: &T::CrossAccountId,
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -49,8 +49,10 @@
};
use crate::{
- common::CommonWeights, weights::WeightInfo, AccountBalance, Config, CreateItemData,
- NonfungibleHandle, Pallet, SelfWeightOf, TokenData, TokenProperties, TokensMinted,
+ common::{mint_with_props_weight, CommonWeights},
+ weights::WeightInfo,
+ AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, SelfWeightOf, TokenData,
+ TokenProperties, TokensMinted,
};
/// Nft events.
@@ -620,7 +622,7 @@
/// @param tokenUri Token URI that would be stored in the NFT properties
/// @return uint256 The id of the newly minted token
#[solidity(rename_selector = "mintWithTokenURI")]
- #[weight(<SelfWeightOf<T>>::create_item() + <SelfWeightOf<T>>::set_token_properties(1))]
+ #[weight(mint_with_props_weight::<T>(<SelfWeightOf<T>>::create_item(), [1].into_iter()))]
fn mint_with_token_uri(
&mut self,
caller: Caller,
@@ -642,7 +644,7 @@
/// @param tokenId ID of the minted NFT
/// @param tokenUri Token URI that would be stored in the NFT properties
#[solidity(hide, rename_selector = "mintWithTokenURI")]
- #[weight(<SelfWeightOf<T>>::create_item() + <SelfWeightOf<T>>::set_token_properties(1))]
+ #[weight(mint_with_props_weight::<T>(<SelfWeightOf<T>>::create_item(), [1].into_iter()))]
fn mint_with_token_uri_check_id(
&mut self,
caller: Caller,
@@ -974,7 +976,12 @@
/// @notice Function to mint a token.
/// @param data Array of pairs of token owner and token's properties for minted token
- #[weight(<SelfWeightOf<T>>::create_multiple_items(data.len() as u32) + <SelfWeightOf<T>>::set_token_properties(data.len() as u32))]
+ #[weight(
+ mint_with_props_weight::<T>(
+ <SelfWeightOf<T>>::create_multiple_items_ex(data.len() as u32),
+ data.iter().map(|d| d.properties.len() as u32),
+ )
+ )]
fn mint_bulk_cross(&mut self, caller: Caller, data: Vec<MintTokenData>) -> Result<bool> {
let caller = T::CrossAccountId::from_eth(caller);
@@ -1008,7 +1015,12 @@
/// @param to The new owner
/// @param tokens array of pairs of token ID and token URI for minted tokens
#[solidity(hide, rename_selector = "mintBulkWithTokenURI")]
- #[weight(<SelfWeightOf<T>>::create_multiple_items(tokens.len() as u32) + <SelfWeightOf<T>>::set_token_properties(tokens.len() as u32))]
+ #[weight(
+ mint_with_props_weight::<T>(
+ <SelfWeightOf<T>>::create_multiple_items(tokens.len() as u32),
+ tokens.iter().map(|_| 1),
+ )
+ )]
fn mint_bulk_with_token_uri(
&mut self,
caller: Caller,
@@ -1056,7 +1068,7 @@
/// @param to The new owner crossAccountId
/// @param properties Properties of minted token
/// @return uint256 The id of the newly minted token
- #[weight(<SelfWeightOf<T>>::create_item() + <SelfWeightOf<T>>::set_token_properties(properties.len() as u32))]
+ #[weight(mint_with_props_weight::<T>(<SelfWeightOf<T>>::create_item(), [properties.len() as u32].into_iter()))]
fn mint_cross(
&mut self,
caller: Caller,
pallets/refungible/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/refungible/src/benchmarking.rs
+++ b/pallets/refungible/src/benchmarking.rs
@@ -421,114 +421,30 @@
Ok(())
}
- // set_token_properties {
- // let b in 0..MAX_PROPERTIES_PER_ITEM;
- // bench_init!{
- // owner: sub; collection: collection(owner);
- // owner: cross_from_sub;
- // };
- // let perms = (0..b).map(|k| PropertyKeyPermission {
- // key: property_key(k as usize),
- // permission: PropertyPermission {
- // mutable: false,
- // collection_admin: true,
- // token_owner: true,
- // },
- // }).collect::<Vec<_>>();
- // <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;
- // let props = (0..b).map(|k| Property {
- // key: property_key(k as usize),
- // value: property_value(),
- // }).collect::<Vec<_>>();
- // let item = create_max_item(&collection, &owner, [(owner.clone(), 200)])?;
- // }: {<Pallet<T>>::set_token_properties(&collection, &owner, item, props.into_iter(), &Unlimited)?}
-
- // load_token_properties {
- // bench_init!{
- // owner: sub; collection: collection(owner);
- // owner: cross_from_sub;
- // };
-
- // let item = create_max_item(&collection, &owner, [(owner.clone(), 200)])?;
- // }: {
- // pallet_common::BenchmarkPropertyWriter::<T>::load_token_properties(
- // &collection,
- // item,
- // )
- // }
-
- // write_token_properties {
- // let b in 0..MAX_PROPERTIES_PER_ITEM;
- // bench_init!{
- // owner: sub; collection: collection(owner);
- // owner: cross_from_sub;
- // };
-
- // let perms = (0..b).map(|k| PropertyKeyPermission {
- // key: property_key(k as usize),
- // permission: PropertyPermission {
- // mutable: false,
- // collection_admin: true,
- // token_owner: true,
- // },
- // }).collect::<Vec<_>>();
- // <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;
- // let props = (0..b).map(|k| Property {
- // key: property_key(k as usize),
- // value: property_value(),
- // }).collect::<Vec<_>>();
- // let item = create_max_item(&collection, &owner, [(owner.clone(), 200)])?;
-
- // let lazy_collection_info = pallet_common::BenchmarkPropertyWriter::<T>::load_collection_info(
- // &collection,
- // &owner,
- // );
- // }: {
- // let mut property_writer = pallet_common::BenchmarkPropertyWriter::new(&collection, lazy_collection_info);
-
- // property_writer.write_token_properties(
- // item,
- // props.into_iter(),
- // crate::erc::ERC721TokenEvent::TokenChanged {
- // token_id: item.into(),
- // }
- // .to_log(T::ContractAddress::get()),
- // )?
- // }
-
#[benchmark]
- fn set_token_property_permissions(
- b: Linear<0, MAX_PROPERTIES_PER_ITEM>,
- ) -> Result<(), BenchmarkError> {
+ fn load_token_properties() -> Result<(), BenchmarkError> {
bench_init! {
owner: sub; collection: collection(owner);
owner: cross_from_sub;
};
- let perms = (0..b)
- .map(|k| PropertyKeyPermission {
- key: property_key(k as usize),
- permission: PropertyPermission {
- mutable: false,
- collection_admin: false,
- token_owner: false,
- },
- })
- .collect::<Vec<_>>();
+ let item = create_max_item(&collection, &owner, [(owner.clone(), 200)])?;
+
#[block]
{
- <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;
+ pallet_common::BenchmarkPropertyWriter::<T>::load_token_properties(&collection, item);
}
Ok(())
}
#[benchmark]
- fn set_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {
+ fn write_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {
bench_init! {
owner: sub; collection: collection(owner);
owner: cross_from_sub;
};
+
let perms = (0..b)
.map(|k| PropertyKeyPermission {
key: property_key(k as usize),
@@ -548,73 +464,29 @@
.collect::<Vec<_>>();
let item = create_max_item(&collection, &owner, [(owner.clone(), 200)])?;
+ let lazy_collection_info =
+ pallet_common::BenchmarkPropertyWriter::<T>::load_collection_info(&collection, &owner);
+
#[block]
{
- <Pallet<T>>::set_token_properties(
- &collection,
- &owner,
+ let mut property_writer =
+ pallet_common::BenchmarkPropertyWriter::new(&collection, lazy_collection_info);
+
+ property_writer.write_token_properties(
item,
props.into_iter(),
- &Unlimited,
+ crate::erc::ERC721TokenEvent::TokenChanged {
+ token_id: item.into(),
+ }
+ .to_log(T::ContractAddress::get()),
)?;
}
Ok(())
}
- // TODO:
#[benchmark]
- fn init_token_properties(b: Linear<0, MAX_PROPERTIES_PER_ITEM>) -> Result<(), BenchmarkError> {
- // bench_init! {
- // owner: sub; collection: collection(owner);
- // owner: cross_from_sub;
- // };
-
- // let perms = (0..b)
- // .map(|k| PropertyKeyPermission {
- // key: property_key(k as usize),
- // permission: PropertyPermission {
- // mutable: false,
- // collection_admin: true,
- // token_owner: true,
- // },
- // })
- // .collect::<Vec<_>>();
- // <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;
-
- #[block]
- {}
- // let props = (0..b).map(|k| Property {
- // key: property_key(k as usize),
- // value: property_value(),
- // }).collect::<Vec<_>>();
- // let item = create_max_item(&collection, &owner, [(owner.clone(), 200)])?;
-
- // let (is_collection_admin, property_permissions) = load_is_admin_and_property_permissions(&collection, &owner)
- // let mut property_writer = pallet_common::collection_info_loaded_property_writer(
- // &collection,
- // is_collection_admin,
- // property_permissions,
- // );
-
- // #[block]
- // {
- // property_writer.write_token_properties(
- // true,
- // item,
- // props.into_iter(),
- // crate::erc::ERC721TokenEvent::TokenChanged {
- // token_id: item.into(),
- // }
- // .to_log(T::ContractAddress::get()),
- // )?;
- // }
-
- Ok(())
- }
-
- #[benchmark]
- fn delete_token_properties(
+ fn set_token_property_permissions(
b: Linear<0, MAX_PROPERTIES_PER_ITEM>,
) -> Result<(), BenchmarkError> {
bench_init! {
@@ -625,38 +497,16 @@
.map(|k| PropertyKeyPermission {
key: property_key(k as usize),
permission: PropertyPermission {
- mutable: true,
- collection_admin: true,
- token_owner: true,
+ mutable: false,
+ collection_admin: false,
+ token_owner: false,
},
- })
- .collect::<Vec<_>>();
- <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;
- let props = (0..b)
- .map(|k| Property {
- key: property_key(k as usize),
- value: property_value(),
})
.collect::<Vec<_>>();
- let item = create_max_item(&collection, &owner, [(owner.clone(), 200)])?;
- <Pallet<T>>::set_token_properties(
- &collection,
- &owner,
- item,
- props.into_iter(),
- &Unlimited,
- )?;
- let to_delete = (0..b).map(|k| property_key(k as usize)).collect::<Vec<_>>();
#[block]
{
- <Pallet<T>>::delete_token_properties(
- &collection,
- &owner,
- item,
- to_delete.into_iter(),
- &Unlimited,
- )?;
+ <Pallet<T>>::set_token_property_permissions(&collection, &owner, perms)?;
}
Ok(())
@@ -673,22 +523,6 @@
#[block]
{
<Pallet<T>>::repartition(&collection, &owner, item, 200)?;
- }
-
- Ok(())
- }
-
- #[benchmark]
- fn token_owner() -> Result<(), BenchmarkError> {
- bench_init! {
- owner: sub; collection: collection(owner);
- sender: cross_from_sub(owner); owner: cross_sub;
- };
- let item = create_max_item(&collection, &sender, [(owner, 100)])?;
-
- #[block]
- {
- <Pallet<T>>::token_owner(collection.id, item).unwrap();
}
Ok(())
pallets/refungible/src/common.rsdiffbeforeafterboth--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -47,35 +47,27 @@
pub struct CommonWeights<T: Config>(PhantomData<T>);
impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {
fn create_multiple_items(data: &[up_data_structs::CreateItemData]) -> Weight {
- <SelfWeightOf<T>>::create_multiple_items(data.len() as u32).saturating_add(
- write_token_properties_total_weight::<T, _>(
- data.iter().map(|data| match data {
- up_data_structs::CreateItemData::ReFungible(rft_data) => {
- rft_data.properties.len() as u32
- }
- _ => 0,
- }),
- <SelfWeightOf<T>>::write_token_properties,
- ),
+ mint_with_props_weight::<T>(
+ <SelfWeightOf<T>>::create_multiple_items(data.len() as u32),
+ data.iter().map(|data| match data {
+ up_data_structs::CreateItemData::ReFungible(rft_data) => {
+ rft_data.properties.len() as u32
+ }
+ _ => 0,
+ }),
)
}
fn create_multiple_items_ex(call: &CreateItemExData<T::CrossAccountId>) -> Weight {
match call {
- CreateItemExData::RefungibleMultipleOwners(i) => {
- <SelfWeightOf<T>>::create_multiple_items_ex_multiple_owners(i.users.len() as u32)
- .saturating_add(write_token_properties_total_weight::<T, _>(
- [i.properties.len() as u32].into_iter(),
- <SelfWeightOf<T>>::write_token_properties,
- ))
- }
- CreateItemExData::RefungibleMultipleItems(i) => {
- <SelfWeightOf<T>>::create_multiple_items_ex_multiple_items(i.len() as u32)
- .saturating_add(write_token_properties_total_weight::<T, _>(
- i.iter().map(|d| d.properties.len() as u32),
- <SelfWeightOf<T>>::write_token_properties,
- ))
- }
+ CreateItemExData::RefungibleMultipleOwners(i) => mint_with_props_weight::<T>(
+ <SelfWeightOf<T>>::create_multiple_items_ex_multiple_owners(i.users.len() as u32),
+ [i.properties.len() as u32].into_iter(),
+ ),
+ CreateItemExData::RefungibleMultipleItems(i) => mint_with_props_weight::<T>(
+ <SelfWeightOf<T>>::create_multiple_items_ex_multiple_items(i.len() as u32),
+ i.iter().map(|d| d.properties.len() as u32),
+ ),
_ => Weight::zero(),
}
}
@@ -138,6 +130,16 @@
}
}
+pub(crate) fn mint_with_props_weight<T: Config>(
+ create_no_data_weight: Weight,
+ tokens: impl Iterator<Item = u32> + Clone,
+) -> Weight {
+ create_no_data_weight.saturating_add(write_token_properties_total_weight::<T, _>(
+ tokens,
+ <SelfWeightOf<T>>::write_token_properties,
+ ))
+}
+
fn map_create_data<T: Config>(
data: up_data_structs::CreateItemData,
to: &T::CrossAccountId,
pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -50,8 +50,10 @@
};
use crate::{
- common::CommonWeights, weights::WeightInfo, AccountBalance, Balance, Config, CreateItemData,
- Pallet, RefungibleHandle, SelfWeightOf, TokenProperties, TokensMinted, TotalSupply,
+ common::{mint_with_props_weight, CommonWeights},
+ weights::WeightInfo,
+ AccountBalance, Balance, Config, CreateItemData, Pallet, RefungibleHandle, SelfWeightOf,
+ TokenProperties, TokensMinted, TotalSupply,
};
frontier_contract! {
@@ -661,7 +663,7 @@
/// @param tokenUri Token URI that would be stored in the NFT properties
/// @return uint256 The id of the newly minted token
#[solidity(rename_selector = "mintWithTokenURI")]
- #[weight(<SelfWeightOf<T>>::create_item() + <SelfWeightOf<T>>::set_token_properties(1))]
+ #[weight(mint_with_props_weight::<T>(<SelfWeightOf<T>>::create_item(), [1].into_iter()))]
fn mint_with_token_uri(
&mut self,
caller: Caller,
@@ -683,7 +685,7 @@
/// @param tokenId ID of the minted RFT
/// @param tokenUri Token URI that would be stored in the RFT properties
#[solidity(hide, rename_selector = "mintWithTokenURI")]
- #[weight(<SelfWeightOf<T>>::create_item() + <SelfWeightOf<T>>::set_token_properties(1))]
+ #[weight(mint_with_props_weight::<T>(<SelfWeightOf<T>>::create_item(), [1].into_iter()))]
fn mint_with_token_uri_check_id(
&mut self,
caller: Caller,
@@ -1052,22 +1054,26 @@
}
/// @notice Function to mint a token.
- /// @param tokenProperties Properties of minted token
- #[weight(if token_properties.len() == 1 {
- <SelfWeightOf<T>>::create_multiple_items_ex_multiple_owners(token_properties.iter().next().unwrap().owners.len() as u32)
+ /// @param tokensData Data of minted token(s)
+ #[weight(if tokens_data.len() == 1 {
+ let token_data = tokens_data.first().unwrap();
+
+ mint_with_props_weight::<T>(
+ <SelfWeightOf<T>>::create_multiple_items_ex_multiple_owners(token_data.owners.len() as u32),
+ [token_data.properties.len() as u32].into_iter(),
+ )
} else {
- <SelfWeightOf<T>>::create_multiple_items_ex_multiple_items(token_properties.len() as u32)
- } + <SelfWeightOf<T>>::set_token_properties(token_properties.len() as u32))]
- fn mint_bulk_cross(
- &mut self,
- caller: Caller,
- token_properties: Vec<MintTokenData>,
- ) -> Result<bool> {
+ mint_with_props_weight::<T>(
+ <SelfWeightOf<T>>::create_multiple_items_ex_multiple_items(tokens_data.len() as u32),
+ tokens_data.iter().map(|d| d.properties.len() as u32),
+ )
+ })]
+ fn mint_bulk_cross(&mut self, caller: Caller, tokens_data: Vec<MintTokenData>) -> Result<bool> {
let caller = T::CrossAccountId::from_eth(caller);
- let has_multiple_tokens = token_properties.len() > 1;
+ let has_multiple_tokens = tokens_data.len() > 1;
- let mut create_rft_data = Vec::with_capacity(token_properties.len());
- for MintTokenData { owners, properties } in token_properties {
+ let mut create_rft_data = Vec::with_capacity(tokens_data.len());
+ for MintTokenData { owners, properties } in tokens_data {
let has_multiple_owners = owners.len() > 1;
if has_multiple_tokens & has_multiple_owners {
return Err(
@@ -1108,7 +1114,12 @@
/// @param to The new owner
/// @param tokens array of pairs of token ID and token URI for minted tokens
#[solidity(hide, rename_selector = "mintBulkWithTokenURI")]
- #[weight(<SelfWeightOf<T>>::create_multiple_items(tokens.len() as u32) + <SelfWeightOf<T>>::set_token_properties(tokens.len() as u32))]
+ #[weight(
+ mint_with_props_weight::<T>(
+ <SelfWeightOf<T>>::create_multiple_items(tokens.len() as u32),
+ tokens.iter().map(|_| 1),
+ )
+ )]
fn mint_bulk_with_token_uri(
&mut self,
caller: Caller,
@@ -1162,7 +1173,7 @@
/// @param to The new owner crossAccountId
/// @param properties Properties of minted token
/// @return uint256 The id of the newly minted token
- #[weight(<SelfWeightOf<T>>::create_item() + <SelfWeightOf<T>>::set_token_properties(properties.len() as u32))]
+ #[weight(mint_with_props_weight::<T>(<SelfWeightOf<T>>::create_item(), [properties.len() as u32].into_iter()))]
fn mint_cross(
&mut self,
caller: Caller,