--- a/Cargo.lock +++ b/Cargo.lock @@ -6262,7 +6262,7 @@ [[package]] name = "pallet-common" -version = "0.1.13" +version = "0.1.14" dependencies = [ "ethereum", "evm-coder", @@ -6814,7 +6814,7 @@ [[package]] name = "pallet-nonfungible" -version = "0.1.13" +version = "0.1.14" dependencies = [ "evm-coder", "frame-benchmarking", --- a/pallets/app-promotion/src/lib.rs +++ b/pallets/app-promotion/src/lib.rs @@ -845,7 +845,6 @@ /// - `staker`: staker account. pub fn total_staked_by_id(staker: impl EncodeLike) -> Option> { let staked = Staked::::iter_prefix((staker,)) - .into_iter() .fold(>::default(), |acc, (_, (amount, _))| { acc + amount }); @@ -864,7 +863,6 @@ staker: impl EncodeLike, ) -> Option)>> { let mut staked = Staked::::iter_prefix((staker,)) - .into_iter() .map(|(block, (amount, _))| (block, amount)) .collect::>(); staked.sort_by_key(|(block, _)| *block); @@ -883,12 +881,6 @@ Self::total_staked_by_id(s.as_sub()) }) } - - // pub fn cross_id_locked_balance(staker: T::CrossAccountId) -> BalanceOf { - // Self::get_locked_balance(staker.as_sub()) - // .map(|l| l.amount) - // .unwrap_or_default() - // } /// Returns all relay block numbers when stake was made, /// the amount of the stake. --- a/pallets/common/CHANGELOG.md +++ b/pallets/common/CHANGELOG.md @@ -4,6 +4,12 @@ +## [0.1.14] - 2023-03-28 + +### Added + +- Added benchmark to check if user is contained in AllowList (`check_accesslist()`). + ## [0.1.13] - 2023-01-20 ### Changed --- a/pallets/common/Cargo.toml +++ b/pallets/common/Cargo.toml @@ -2,7 +2,7 @@ edition = "2021" license = "GPLv3" name = "pallet-common" -version = "0.1.13" +version = "0.1.14" [dependencies] # Note: `package = "parity-scale-codec"` must be supplied since the `Encode` macro searches for it. --- a/pallets/common/src/benchmarking.rs +++ b/pallets/common/src/benchmarking.rs @@ -22,8 +22,9 @@ use frame_benchmarking::{benchmarks, account}; use up_data_structs::{ CollectionMode, CollectionFlags, CreateCollectionData, CollectionId, Property, PropertyKey, - PropertyValue, CollectionPermissions, NestingPermissions, MAX_COLLECTION_NAME_LENGTH, - MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH, MAX_PROPERTIES_PER_ITEM, + PropertyValue, CollectionPermissions, NestingPermissions, AccessMode, + MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH, + MAX_PROPERTIES_PER_ITEM, }; use frame_support::{ traits::{Currency, Get}, @@ -193,4 +194,38 @@ >::set_collection_properties(&collection, &owner, props.into_iter())?; let to_delete = (0..b).map(|p| property_key(p as usize)).collect::>(); }: {>::delete_collection_properties(&collection, &owner, to_delete.into_iter())?} + + check_accesslist{ + bench_init!{ + owner: sub; collection: collection(owner); + sender: cross_from_sub(owner); receiver: cross_sub; + }; + + let mut collection_handle = >::try_get(collection.id)?; + >::update_permissions( + &sender, + &mut collection_handle, + CollectionPermissions { access: Some(AccessMode::AllowList), ..Default::default() } + )?; + + >::toggle_allowlist( + &collection, + &sender, + &sender, + true, + )?; + + >::toggle_allowlist( + &collection, + &sender, + &receiver, + true, + )?; + + assert_eq!(collection_handle.permissions.access(), AccessMode::AllowList); + + collection_handle.check_allowlist(&sender)?; + collection_handle.check_allowlist(&receiver)?; + + }: {collection_handle.check_allowlist(&sender)?;} } --- a/pallets/common/src/weights.rs +++ b/pallets/common/src/weights.rs @@ -36,6 +36,7 @@ pub trait WeightInfo { fn set_collection_properties(b: u32, ) -> Weight; fn delete_collection_properties(b: u32, ) -> Weight; + fn check_accesslist() -> Weight; } /// Weights for pallet_common using the Substrate node and recommended hardware. @@ -66,11 +67,8 @@ Weight::from_parts(6_684_000, 43467) // Standard Error: 67_984 .saturating_add(Weight::from_parts(21_502_829, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } -} - // For backwards compatibility and tests impl WeightInfo for () { /// Storage: Common CollectionProperties (r:1 w:1) @@ -98,8 +96,5 @@ Weight::from_parts(6_684_000, 43467) // Standard Error: 67_984 .saturating_add(Weight::from_parts(21_502_829, 0).saturating_mul(b.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } -} - --- a/pallets/nonfungible/CHANGELOG.md +++ b/pallets/nonfungible/CHANGELOG.md @@ -4,6 +4,12 @@ +## [0.1.14] - 2023-03-28 + +### Fixed + +- The weight of `transfer` and `transfer_from`. + ## [0.1.13] - 2023-01-20 ### Fixed --- a/pallets/nonfungible/Cargo.toml +++ b/pallets/nonfungible/Cargo.toml @@ -2,7 +2,7 @@ edition = "2021" license = "GPLv3" name = "pallet-nonfungible" -version = "0.1.13" +version = "0.1.14" [dependencies] # Note: `package = "parity-scale-codec"` must be supplied since the `Encode` macro searches for it. --- a/pallets/nonfungible/src/benchmarking.rs +++ b/pallets/nonfungible/src/benchmarking.rs @@ -146,14 +146,14 @@ let item = create_max_item(&collection, &owner, owner_eth.clone())?; }: {>::set_allowance_from(&collection, &sender, &owner_eth, item, Some(&spender))?} - transfer_from { + checks_for_transfer_from { bench_init!{ owner: sub; collection: collection(owner); owner: cross_from_sub; sender: cross_sub; spender: cross_sub; receiver: cross_sub; }; let item = create_max_item(&collection, &owner, sender.clone())?; >::set_allowance(&collection, &sender, item, Some(&spender))?; - }: {>::transfer_from(&collection, &spender, &sender, &receiver, item, &Unlimited)?} + }: {>::check_allowed(&collection, &spender, &sender, item, &Unlimited)?} burn_from { bench_init!{ --- a/pallets/nonfungible/src/common.rs +++ b/pallets/nonfungible/src/common.rs @@ -23,7 +23,7 @@ }; use pallet_common::{ CommonCollectionOperations, CommonWeightInfo, RefungibleExtensions, with_weight, - weights::WeightInfo as _, + weights::WeightInfo as _, SelfWeightOf as PalletCommonWeightOf, }; use sp_runtime::DispatchError; use sp_std::{vec::Vec, vec}; @@ -91,7 +91,7 @@ } fn transfer() -> Weight { - >::transfer() + >::transfer() + >::check_accesslist() * 2 } fn approve() -> Weight { @@ -103,7 +103,7 @@ } fn transfer_from() -> Weight { - >::transfer_from() + Self::transfer() + >::checks_for_transfer_from() } fn burn_from() -> Weight { @@ -325,10 +325,7 @@ ) -> DispatchResultWithPostInfo { ensure!(amount <= 1, >::NonfungibleItemsHaveNoAmount); if amount == 1 { - with_weight( - >::transfer(self, &from, &to, token, nesting_budget), - >::transfer(), - ) + >::transfer(self, &from, &to, token, nesting_budget) } else { >::check_token_immediate_ownership(self, token, &from)?; Ok(().into()) @@ -386,10 +383,7 @@ ensure!(amount <= 1, >::NonfungibleItemsHaveNoAmount); if amount == 1 { - with_weight( - >::transfer_from(self, &sender, &from, &to, token, nesting_budget), - >::transfer_from(), - ) + >::transfer_from(self, &sender, &from, &to, token, nesting_budget) } else { >::check_allowed(self, &sender, &from, token, nesting_budget)?; --- a/pallets/nonfungible/src/erc.rs +++ b/pallets/nonfungible/src/erc.rs @@ -39,6 +39,7 @@ CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations, erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key}, eth::{self, TokenUri}, + CommonWeightInfo, }; use pallet_evm::{account::CrossAccountId, PrecompileHandle}; use pallet_evm_coder_substrate::call; @@ -47,7 +48,7 @@ use crate::{ AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData, TokensMinted, - TokenProperties, SelfWeightOf, weights::WeightInfo, + TokenProperties, SelfWeightOf, weights::WeightInfo, common::CommonWeights, }; /// Nft events. @@ -458,7 +459,7 @@ /// @param from The current owner of the NFT /// @param to The new owner /// @param tokenId The NFT to transfer - #[weight(>::transfer_from())] + #[weight(>::transfer_from())] fn transfer_from( &mut self, caller: Caller, @@ -475,7 +476,7 @@ .weight_calls_budget(>::find_parent()); >::transfer_from(self, &caller, &from, &to, token, &budget) - .map_err(dispatch_to_evm::)?; + .map_err(|e| dispatch_to_evm::(e.error))?; Ok(()) } @@ -824,7 +825,7 @@ /// is the zero address. Throws if `tokenId` is not a valid NFT. /// @param to The new owner /// @param tokenId The NFT to transfer - #[weight(>::transfer())] + #[weight(>::transfer())] fn transfer(&mut self, caller: Caller, to: Address, token_id: U256) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); @@ -833,7 +834,8 @@ .recorder .weight_calls_budget(>::find_parent()); - >::transfer(self, &caller, &to, token, &budget).map_err(dispatch_to_evm::)?; + >::transfer(self, &caller, &to, token, &budget) + .map_err(|e| dispatch_to_evm::(e.error))?; Ok(()) } @@ -842,7 +844,7 @@ /// is the zero address. Throws if `tokenId` is not a valid NFT. /// @param to The new owner /// @param tokenId The NFT to transfer - #[weight(>::transfer())] + #[weight(>::transfer())] fn transfer_cross( &mut self, caller: Caller, @@ -856,7 +858,8 @@ .recorder .weight_calls_budget(>::find_parent()); - >::transfer(self, &caller, &to, token, &budget).map_err(dispatch_to_evm::)?; + >::transfer(self, &caller, &to, token, &budget) + .map_err(|e| dispatch_to_evm::(e.error))?; Ok(()) } @@ -866,7 +869,7 @@ /// @param from Cross acccount address of current owner /// @param to Cross acccount address of new owner /// @param tokenId The NFT to transfer - #[weight(>::transfer())] + #[weight(>::transfer_from())] fn transfer_from_cross( &mut self, caller: Caller, @@ -882,7 +885,7 @@ .recorder .weight_calls_budget(>::find_parent()); Pallet::::transfer_from(self, &caller, &from, &to, token_id, &budget) - .map_err(dispatch_to_evm::)?; + .map_err(|e| dispatch_to_evm::(e.error))?; Ok(()) } --- a/pallets/nonfungible/src/lib.rs +++ b/pallets/nonfungible/src/lib.rs @@ -108,7 +108,8 @@ use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm}; use pallet_common::{ Error as CommonError, Pallet as PalletCommon, Event as CommonEvent, CollectionHandle, - eth::collection_id_to_address, + eth::collection_id_to_address, SelfWeightOf as PalletCommonWeightOf, + weights::WeightInfo as CommonWeightInfo, }; use pallet_structure::{Pallet as PalletStructure, Error as StructureError}; use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder}; @@ -802,7 +803,7 @@ to: &T::CrossAccountId, token: TokenId, nesting_budget: &dyn Budget, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { ensure!( collection.limits.transfers_enabled(), >::TransferNotAllowed @@ -812,7 +813,8 @@ >::get((collection.id, token)).ok_or(>::TokenNotFound)?; ensure!(&token_data.owner == from, >::NoPermission); - if collection.permissions.access() == AccessMode::AllowList { + let is_allow_list_mode = collection.permissions.access() == AccessMode::AllowList; + if is_allow_list_mode { collection.check_allowlist(from)?; collection.check_allowlist(to)?; } @@ -884,7 +886,18 @@ to.clone(), 1, )); - Ok(()) + + let actual_weight = match is_allow_list_mode { + true => Some( + >::transfer() + >::check_accesslist() * 2, + ), + false => Some(>::transfer()), + }; + + Ok(PostDispatchInfo { + actual_weight, + pays_fee: Pays::Yes, + }) } /// Batch operation to mint multiple NFT tokens. @@ -1228,13 +1241,18 @@ to: &T::CrossAccountId, token: TokenId, nesting_budget: &dyn Budget, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { Self::check_allowed(collection, spender, from, token, nesting_budget)?; // ========= // Allowance is reset in [`transfer`] - Self::transfer(collection, from, to, token, nesting_budget) + Self::transfer(collection, from, to, token, nesting_budget).map(|mut p| { + p.actual_weight = Some( + p.actual_weight.unwrap_or_default() + >::checks_for_transfer_from(), + ); + p + }) } /// Burn NFT token for `from` account. --- a/pallets/nonfungible/src/weights.rs +++ b/pallets/nonfungible/src/weights.rs @@ -43,7 +43,7 @@ fn transfer() -> Weight; fn approve() -> Weight; fn approve_from() -> Weight; - fn transfer_from() -> Weight; + fn checks_for_transfer_from() -> Weight; fn burn_from() -> Weight; fn set_token_property_permissions(b: u32, ) -> Weight; fn set_token_properties(b: u32, ) -> Weight;