difftreelog
refactor(interface) remove outdated benchmarks
in: master
3 files changed
pallets/nft/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/nft/src/benchmarking.rs
+++ b/pallets/nft/src/benchmarking.rs
@@ -7,35 +7,10 @@
use nft_data_structs::*;
use core::convert::TryInto;
use sp_runtime::DispatchError;
+use pallet_common::benchmarking::{create_data, create_u16_data};
const SEED: u32 = 1;
-
-fn create_data(size: usize) -> Vec<u8> {
- (0..size).map(|v| (v & 0xff) as u8).collect()
-}
-fn create_u16_data(size: usize) -> Vec<u16> {
- (0..size).map(|v| (v & 0xffff) as u16).collect()
-}
-
-fn default_nft_data() -> CreateItemData {
- CreateItemData::NFT(CreateNftData {
- const_data: create_data(CUSTOM_DATA_LIMIT as usize).try_into().unwrap(),
- variable_data: create_data(CUSTOM_DATA_LIMIT as usize).try_into().unwrap(),
- })
-}
-fn default_fungible_data() -> CreateItemData {
- CreateItemData::Fungible(CreateFungibleData { value: 1000 })
-}
-
-fn default_re_fungible_data() -> CreateItemData {
- CreateItemData::ReFungible(CreateReFungibleData {
- const_data: create_data(CUSTOM_DATA_LIMIT as usize).try_into().unwrap(),
- variable_data: create_data(CUSTOM_DATA_LIMIT as usize).try_into().unwrap(),
- pieces: 1000,
- })
-}
-
fn create_collection_helper<T: Config>(
owner: T::AccountId,
mode: CollectionMode,
@@ -55,20 +30,10 @@
token_prefix,
mode,
)?;
- Ok(CreatedCollectionCount::get())
+ Ok(<pallet_common::CreatedCollectionCount<T>>::get())
}
fn create_nft_collection<T: Config>(owner: T::AccountId) -> Result<CollectionId, DispatchError> {
create_collection_helper::<T>(owner, CollectionMode::NFT)
-}
-fn create_fungible_collection<T: Config>(
- owner: T::AccountId,
-) -> Result<CollectionId, DispatchError> {
- create_collection_helper::<T>(owner, CollectionMode::Fungible(0))
-}
-fn create_refungible_collection<T: Config>(
- owner: T::AccountId,
-) -> Result<CollectionId, DispatchError> {
- create_collection_helper::<T>(owner, CollectionMode::ReFungible)
}
benchmarks! {
@@ -82,7 +47,7 @@
T::Currency::deposit_creating(&caller, T::CollectionCreationPrice::get());
}: _(RawOrigin::Signed(caller.clone()), col_name.clone(), col_desc.clone(), token_prefix.clone(), mode)
verify {
- assert_eq!(<Pallet<T>>::collection_id(2).unwrap().owner, caller);
+ assert_eq!(<pallet_common::CollectionById<T>>::get(CollectionId(1)).unwrap().owner, caller);
}
destroy_collection {
@@ -129,7 +94,7 @@
let caller: T::AccountId = account("caller", 0, SEED);
let collection = create_nft_collection::<T>(caller.clone())?;
let new_admin: T::AccountId = account("admin", 0, SEED);
- <Pallet<T>>::add_collection_admin(RawOrigin::Signed(caller.clone()).into(), 2, T::CrossAccountId::from_sub(new_admin.clone()))?;
+ <Pallet<T>>::add_collection_admin(RawOrigin::Signed(caller.clone()).into(), collection, T::CrossAccountId::from_sub(new_admin.clone()))?;
}: _(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(new_admin))
set_collection_sponsor {
@@ -140,152 +105,21 @@
confirm_sponsorship {
let caller: T::AccountId = account("caller", 0, SEED);
let collection = create_nft_collection::<T>(caller.clone())?;
- <Pallet<T>>::set_collection_sponsor(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone())?;
+ <Pallet<T>>::set_collection_sponsor(RawOrigin::Signed(caller.clone()).into(), collection, caller.clone())?;
}: _(RawOrigin::Signed(caller.clone()), collection)
remove_collection_sponsor {
let caller: T::AccountId = account("caller", 0, SEED);
let collection = create_nft_collection::<T>(caller.clone())?;
- <Pallet<T>>::set_collection_sponsor(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone())?;
- <Pallet<T>>::confirm_sponsorship(RawOrigin::Signed(caller.clone()).into(), 2)?;
+ <Pallet<T>>::set_collection_sponsor(RawOrigin::Signed(caller.clone()).into(), collection, caller.clone())?;
+ <Pallet<T>>::confirm_sponsorship(RawOrigin::Signed(caller.clone()).into(), collection)?;
}: _(RawOrigin::Signed(caller.clone()), collection)
-
- // nft item
- create_item_nft {
- let b in 0..(CUSTOM_DATA_LIMIT * 2);
-
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_nft_collection::<T>(caller.clone())?;
- let data = CreateItemData::NFT(CreateNftData {
- const_data: create_data(b.min(CUSTOM_DATA_LIMIT) as usize).try_into().unwrap(),
- variable_data: create_data(b.saturating_sub(CUSTOM_DATA_LIMIT) as usize).try_into().unwrap(),
- });
- }: create_item(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(caller.clone()), data)
-
- create_multiple_items_nft {
- // TODO: Take item data size into account. As create_item_nft bench shows, this parameter has no effect on execution time,
- // but it may if we increase CUSTOM_DATA_LIMIT
- let b in 1..1000;
-
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_nft_collection::<T>(caller.clone())?;
- let data = (0..b).map(|_| default_nft_data()).collect();
- }: create_multiple_items(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(caller.clone()), data)
- // fungible item
- create_item_fungible {
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_fungible_collection::<T>(caller.clone())?;
- let data = CreateItemData::Fungible(CreateFungibleData {
- value: 1000,
- });
- }: create_item(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(caller.clone()), data)
-
- create_multiple_items_fungible {
- let b in 1..1000;
-
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_fungible_collection::<T>(caller.clone())?;
- let data = (0..b).map(|_| default_fungible_data()).collect();
- }: create_multiple_items(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(caller.clone()), data)
-
- // refungible item
- create_item_refungible {
- let b in 0..(CUSTOM_DATA_LIMIT * 2);
-
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_refungible_collection::<T>(caller.clone())?;
- let data = CreateItemData::ReFungible(CreateReFungibleData {
- const_data: create_data(b.min(CUSTOM_DATA_LIMIT) as usize).try_into().unwrap(),
- variable_data: create_data(b.saturating_sub(CUSTOM_DATA_LIMIT) as usize).try_into().unwrap(),
- pieces: 1000,
- });
- }: create_item(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(caller.clone()), data)
-
- create_multiple_items_refungible {
- // TODO: Take item data size into account. As create_item_nft bench shows, this parameter has no effect on execution time,
- // but it may if we increase CUSTOM_DATA_LIMIT
- let b in 1..1000;
-
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_refungible_collection::<T>(caller.clone())?;
- let data = (0..b).map(|_| default_re_fungible_data()).collect();
- }: create_multiple_items(RawOrigin::Signed(caller.clone()), collection, T::CrossAccountId::from_sub(caller.clone()), data)
-
- burn_item_nft {
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_nft_collection::<T>(caller.clone())?;
- let data = default_nft_data();
- <Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), collection, T::CrossAccountId::from_sub(caller.clone()), data)?;
- }: burn_item(RawOrigin::Signed(caller.clone()), collection, 1, 1)
-
- transfer_nft {
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_nft_collection::<T>(caller.clone())?;
- let recipient: T::AccountId = account("recipient", 0, SEED);
- let data = default_nft_data();
- <Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), collection, T::CrossAccountId::from_sub(caller.clone()), data)?;
- }: transfer(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), collection, 1, 1)
-
- transfer_fungible {
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_fungible_collection::<T>(caller.clone())?;
- let recipient: T::AccountId = account("recipient", 0, SEED);
- let data = default_fungible_data();
- <Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), collection, T::CrossAccountId::from_sub(caller.clone()), data)?;
- }: transfer(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), collection, 1, 1)
-
- transfer_refungible {
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_refungible_collection::<T>(caller.clone())?;
- let recipient: T::AccountId = account("recipient", 0, SEED);
- let data = default_re_fungible_data();
- <Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), collection, T::CrossAccountId::from_sub(caller.clone()), data)?;
- }: transfer(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), collection, 1, 1)
-
set_transfers_enabled_flag {
let caller: T::AccountId = account("caller", 0, SEED);
let collection = create_nft_collection::<T>(caller.clone())?;
}: _(RawOrigin::Signed(caller.clone()), collection, false)
-
- approve_nft {
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_nft_collection::<T>(caller.clone())?;
- let recipient: T::AccountId = account("recipient", 0, SEED);
- let data = default_nft_data();
- <Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, T::CrossAccountId::from_sub(caller.clone()), data)?;
- }: approve(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), collection, 1, 1)
- // Nft
- transfer_from_nft {
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_nft_collection::<T>(caller.clone())?;
- let recipient: T::AccountId = account("recipient", 0, SEED);
- let data = default_nft_data();
- <Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, T::CrossAccountId::from_sub(caller.clone()), data)?;
- <Pallet<T>>::approve(RawOrigin::Signed(caller.clone()).into(), T::CrossAccountId::from_sub(recipient.clone()), 2, 1, 1)?;
- }: transfer_from(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), 2, 1, 1)
-
- // Fungible
- transfer_from_fungible {
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_fungible_collection::<T>(caller.clone())?;
- let recipient: T::AccountId = account("recipient", 0, SEED);
- let data = default_fungible_data();
- <Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, T::CrossAccountId::from_sub(caller.clone()), data)?;
- <Pallet<T>>::approve(RawOrigin::Signed(caller.clone()).into(), T::CrossAccountId::from_sub(recipient.clone()), 2, 1, 1)?;
- }: transfer_from(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), 2, 1, 1)
-
- // ReFungible
- transfer_from_refungible {
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_refungible_collection::<T>(caller.clone())?;
- let recipient: T::AccountId = account("recipient", 0, SEED);
- let data = default_re_fungible_data();
- <Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, T::CrossAccountId::from_sub(caller.clone()), data)?;
- <Pallet<T>>::approve(RawOrigin::Signed(caller.clone()).into(), T::CrossAccountId::from_sub(recipient.clone()), 2, 1, 1)?;
- }: transfer_from(RawOrigin::Signed(caller.clone()), T::CrossAccountId::from_sub(caller.clone()), T::CrossAccountId::from_sub(recipient.clone()), 2, 1, 1)
-
set_offchain_schema {
let b in 0..OFFCHAIN_SCHEMA_LIMIT;
@@ -308,29 +142,19 @@
let caller: T::AccountId = account("caller", 0, SEED);
let collection = create_nft_collection::<T>(caller.clone())?;
let data = create_data(b as usize);
- }: set_variable_on_chain_schema(RawOrigin::Signed(caller.clone()), 2, data)
-
- set_variable_meta_data_nft {
- let b in 0..CUSTOM_DATA_LIMIT;
-
- let caller: T::AccountId = account("caller", 0, SEED);
- let collection = create_nft_collection::<T>(caller.clone())?;
- let data = default_nft_data();
- <Pallet<T>>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, T::CrossAccountId::from_sub(caller.clone()), data)?;
- let data = create_data(b as usize);
- }: set_variable_meta_data(RawOrigin::Signed(caller.clone()), collection, 1, data)
+ }: set_variable_on_chain_schema(RawOrigin::Signed(caller.clone()), collection, data)
set_schema_version {
let caller: T::AccountId = account("caller", 0, SEED);
let collection = create_nft_collection::<T>(caller.clone())?;
- }: set_schema_version(RawOrigin::Signed(caller.clone()), 2, SchemaVersion::Unique)
+ }: set_schema_version(RawOrigin::Signed(caller.clone()), collection, SchemaVersion::Unique)
set_collection_limits{
let caller: T::AccountId = account("caller", 0, SEED);
let collection = create_nft_collection::<T>(caller.clone())?;
let cl = CollectionLimits {
- account_token_ownership_limit: 0,
+ account_token_ownership_limit: Some(0),
sponsored_data_size: 0,
token_limit: 1,
sponsor_transfer_timeout: 0,
@@ -338,5 +162,10 @@
owner_can_transfer: true,
sponsored_data_rate_limit: None,
};
- }: set_collection_limits(RawOrigin::Signed(caller.clone()), 2, cl)
+ }: set_collection_limits(RawOrigin::Signed(caller.clone()), collection, cl)
+
+ set_meta_update_permission_flag {
+ let caller: T::AccountId = account("caller", 0, SEED);
+ let collection = create_nft_collection::<T>(caller.clone())?;
+ }: _(RawOrigin::Signed(caller.clone()), collection, MetaUpdatePermission::Admin)
}
pallets/nft/src/lib.rsdiffbeforeafterboth1//2// This file is subject to the terms and conditions defined in3// file 'LICENSE', which is part of this source code package.4//56#![recursion_limit = "1024"]7#![cfg_attr(not(feature = "std"), no_std)]8#![allow(9 clippy::too_many_arguments,10 clippy::unnecessary_mut_passed,11 clippy::unused_unit12)]1314extern crate alloc;1516pub use serde::{Serialize, Deserialize};1718pub use frame_support::{19 construct_runtime, decl_module, decl_storage, decl_error,20 dispatch::DispatchResult,21 ensure, fail, parameter_types,22 traits::{23 ExistenceRequirement, Get, Imbalance, KeyOwnerProofSystem, OnUnbalanced, Randomness,24 IsSubType, WithdrawReasons,25 },26 weights::{27 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},28 DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,29 WeightToFeePolynomial, DispatchClass,30 },31 StorageValue, transactional,32 pallet_prelude::DispatchResultWithPostInfo,33};34use frame_system::{self as system, ensure_signed};35use sp_runtime::{sp_std::prelude::Vec};36use nft_data_structs::{37 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, CUSTOM_DATA_LIMIT,38 VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, COLLECTION_ADMINS_LIMIT,39 OFFCHAIN_SCHEMA_LIMIT, AccessMode, Collection, CreateItemData, CollectionLimits, CollectionId,40 CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,41};42use pallet_common::{43 account::CrossAccountId, CollectionHandle, IsAdmin, Pallet as PalletCommon,44 Error as CommonError, CommonWeightInfo, Allowlist,45};46use pallet_refungible::{Pallet as PalletRefungible, RefungibleHandle};47use pallet_fungible::{Pallet as PalletFungible, FungibleHandle};48use pallet_nonfungible::{Pallet as PalletNonfungible, NonfungibleHandle};4950#[cfg(test)]51mod mock;5253#[cfg(test)]54mod tests;5556mod eth;57mod sponsorship;58pub use sponsorship::NftSponsorshipHandler;59pub use eth::sponsoring::NftEthSponsorshipHandler;6061pub use eth::NftErcSupport;6263pub mod common;64use common::CommonWeights;65pub mod dispatch;66use dispatch::dispatch_call;6768#[cfg(feature = "runtime-benchmarks")]69mod benchmarking;70pub mod weights;71use weights::WeightInfo;7273decl_error! {74 /// Error for non-fungible-token module.75 pub enum Error for Module<T: Config> {76 /// Decimal_points parameter must be lower than MAX_DECIMAL_POINTS constant, currently it is 30.77 CollectionDecimalPointLimitExceeded,78 /// This address is not set as sponsor, use setCollectionSponsor first.79 ConfirmUnsetSponsorFail,80 /// Length of items properties must be greater than 0.81 EmptyArgument,82 /// Collection limit bounds per collection exceeded83 CollectionLimitBoundsExceeded,84 /// Tried to enable permissions which are only permitted to be disabled85 OwnerPermissionsCantBeReverted,86 }87}88pub trait Config:89 system::Config90 + pallet_evm_coder_substrate::Config91 + pallet_common::Config92 + pallet_nonfungible::Config93 + pallet_refungible::Config94 + pallet_fungible::Config95 + Sized96{97 /// Weight information for extrinsics in this pallet.98 type WeightInfo: WeightInfo;99}100101type SelfWeightOf<T> = <T as Config>::WeightInfo;102103trait WeightInfoHelpers: WeightInfo {104 fn transfer() -> Weight {105 Self::transfer_nft()106 .max(Self::transfer_fungible())107 .max(Self::transfer_refungible())108 }109 fn transfer_from() -> Weight {110 Self::transfer_from_nft()111 .max(Self::transfer_from_fungible())112 .max(Self::transfer_from_refungible())113 }114 fn approve() -> Weight {115 // TODO: refungible, fungible116 Self::approve_nft()117 }118 fn set_variable_meta_data(data: u32) -> Weight {119 // TODO: refungible120 Self::set_variable_meta_data_nft(data)121 }122 fn create_item(data: u32) -> Weight {123 Self::create_item_nft(data)124 .max(Self::create_item_fungible())125 .max(Self::create_item_refungible(data))126 }127 fn create_multiple_items(amount: u32) -> Weight {128 Self::create_multiple_items_nft(amount)129 .max(Self::create_multiple_items_fungible(amount))130 .max(Self::create_multiple_items_refungible(amount))131 }132}133impl<T: WeightInfo> WeightInfoHelpers for T {}134135// # Used definitions136//137// ## User control levels138//139// chain-controlled - key is uncontrolled by user140// i.e autoincrementing index141// can use non-cryptographic hash142// real - key is controlled by user143// but it is hard to generate enough colliding values, i.e owner of signed txs144// can use non-cryptographic hash145// controlled - key is completly controlled by users146// i.e maps with mutable keys147// should use cryptographic hash148//149// ## User control level downgrade reasons150//151// ?1 - chain-controlled -> controlled152// collections/tokens can be destroyed, resulting in massive holes153// ?2 - chain-controlled -> controlled154// same as ?1, but can be only added, resulting in easier exploitation155// ?3 - real -> controlled156// no confirmation required, so addresses can be easily generated157decl_storage! {158 trait Store for Module<T: Config> as Nft {159160 //#region Private members161 /// Used for migrations162 ChainVersion: u64;163 //#endregion164165 //#region Tokens transfer rate limit baskets166 /// (Collection id (controlled?2), who created (real))167 /// TODO: Off chain worker should remove from this map when collection gets removed168 pub CreateItemBasket get(fn create_item_basket): map hasher(blake2_128_concat) (CollectionId, T::AccountId) => T::BlockNumber;169 /// Collection id (controlled?2), token id (controlled?2)170 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => T::BlockNumber;171 /// Collection id (controlled?2), owning user (real)172 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;173 /// Collection id (controlled?2), token id (controlled?2)174 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => T::BlockNumber;175 //#endregion176177 /// Variable metadata sponsoring178 /// Collection id (controlled?2), token id (controlled?2)179 pub VariableMetaDataBasket get(fn variable_meta_data_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber> = None;180 }181}182183decl_module! {184 pub struct Module<T: Config> for enum Call185 where186 origin: T::Origin187 {188 const CollectionAdminsLimit: u64 = COLLECTION_ADMINS_LIMIT;189 type Error = Error<T>;190191 fn on_initialize(_now: T::BlockNumber) -> Weight {192 0193 }194195 /// This method creates a Collection of NFTs. Each Token may have multiple properties encoded as an array of bytes of certain length. The initial owner and admin of the collection are set to the address that signed the transaction. Both addresses can be changed later.196 ///197 /// # Permissions198 ///199 /// * Anyone.200 ///201 /// # Arguments202 ///203 /// * collection_name: UTF-16 string with collection name (limit 64 characters), will be stored as zero-terminated.204 ///205 /// * collection_description: UTF-16 string with collection description (limit 256 characters), will be stored as zero-terminated.206 ///207 /// * token_prefix: UTF-8 string with token prefix.208 ///209 /// * mode: [CollectionMode] collection type and type dependent data.210 // returns collection ID211 #[weight = <SelfWeightOf<T>>::create_collection()]212 #[transactional]213 pub fn create_collection(origin,214 collection_name: Vec<u16>,215 collection_description: Vec<u16>,216 token_prefix: Vec<u8>,217 mode: CollectionMode) -> DispatchResult {218219 // Anyone can create a collection220 let who = ensure_signed(origin)?;221222 let limits = CollectionLimits::<T::BlockNumber> {223 sponsored_data_size: CUSTOM_DATA_LIMIT,224 ..Default::default()225 };226227 // Create new collection228 let new_collection = Collection::<T> {229 owner: who.clone(),230 name: collection_name,231 mode: mode.clone(),232 mint_mode: false,233 access: AccessMode::Normal,234 description: collection_description,235 token_prefix,236 offchain_schema: Vec::new(),237 schema_version: SchemaVersion::ImageURL,238 sponsorship: SponsorshipState::Disabled,239 variable_on_chain_schema: Vec::new(),240 const_on_chain_schema: Vec::new(),241 limits,242 transfers_enabled: true,243 meta_update_permission: Default::default(),244 };245246 let _id = match mode {247 CollectionMode::NFT => {PalletNonfungible::init_collection(new_collection)?},248 CollectionMode::Fungible(decimal_points) => {249 // check params250 ensure!(decimal_points <= MAX_DECIMAL_POINTS, Error::<T>::CollectionDecimalPointLimitExceeded);251 PalletFungible::init_collection(new_collection)?252 }253 CollectionMode::ReFungible => {254 PalletRefungible::init_collection(new_collection)?255 }256 };257258 Ok(())259 }260261 /// **DANGEROUS**: Destroys collection and all NFTs within this collection. Users irrecoverably lose their assets and may lose real money.262 ///263 /// # Permissions264 ///265 /// * Collection Owner.266 ///267 /// # Arguments268 ///269 /// * collection_id: collection to destroy.270 #[weight = <SelfWeightOf<T>>::destroy_collection()]271 #[transactional]272 pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {273 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);274275 let collection = <CollectionHandle<T>>::try_get(collection_id)?;276 collection.check_is_owner(&sender)?;277278 // =========279280 match collection.mode {281 CollectionMode::ReFungible => PalletRefungible::destroy_collection(RefungibleHandle::cast(collection), &sender)?,282 CollectionMode::Fungible(_) => PalletFungible::destroy_collection(FungibleHandle::cast(collection), &sender)?,283 CollectionMode::NFT => PalletNonfungible::destroy_collection(NonfungibleHandle::cast(collection), &sender)?,284 }285286 <NftTransferBasket<T>>::remove_prefix(collection_id, None);287 <FungibleTransferBasket<T>>::remove_prefix(collection_id, None);288 <ReFungibleTransferBasket<T>>::remove_prefix(collection_id, None);289290 <VariableMetaDataBasket<T>>::remove_prefix(collection_id, None);291292 Ok(())293 }294295 /// Add an address to white list.296 ///297 /// # Permissions298 ///299 /// * Collection Owner300 /// * Collection Admin301 ///302 /// # Arguments303 ///304 /// * collection_id.305 ///306 /// * address.307 #[weight = <SelfWeightOf<T>>::add_to_white_list()]308 #[transactional]309 pub fn add_to_white_list(origin, collection_id: CollectionId, address: T::CrossAccountId) -> DispatchResult{310311 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);312 let collection = <CollectionHandle<T>>::try_get(collection_id)?;313314 <PalletCommon<T>>::toggle_allowlist(315 &collection,316 &sender,317 &address,318 true,319 )?;320321 Ok(())322 }323324 /// Remove an address from white list.325 ///326 /// # Permissions327 ///328 /// * Collection Owner329 /// * Collection Admin330 ///331 /// # Arguments332 ///333 /// * collection_id.334 ///335 /// * address.336 #[weight = <SelfWeightOf<T>>::remove_from_white_list()]337 #[transactional]338 pub fn remove_from_white_list(origin, collection_id: CollectionId, address: T::CrossAccountId) -> DispatchResult{339340 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);341 let collection = <CollectionHandle<T>>::try_get(collection_id)?;342343 <PalletCommon<T>>::toggle_allowlist(344 &collection,345 &sender,346 &address,347 false,348 )?;349350 Ok(())351 }352353 /// Toggle between normal and white list access for the methods with access for `Anyone`.354 ///355 /// # Permissions356 ///357 /// * Collection Owner.358 ///359 /// # Arguments360 ///361 /// * collection_id.362 ///363 /// * mode: [AccessMode]364 #[weight = <SelfWeightOf<T>>::set_public_access_mode()]365 #[transactional]366 pub fn set_public_access_mode(origin, collection_id: CollectionId, mode: AccessMode) -> DispatchResult367 {368 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);369370 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;371 target_collection.check_is_owner(&sender)?;372373 target_collection.access = mode;374 target_collection.save()375 }376377 /// Allows Anyone to create tokens if:378 /// * White List is enabled, and379 /// * Address is added to white list, and380 /// * This method was called with True parameter381 ///382 /// # Permissions383 /// * Collection Owner384 ///385 /// # Arguments386 ///387 /// * collection_id.388 ///389 /// * mint_permission: Boolean parameter. If True, allows minting to Anyone with conditions above.390 #[weight = <SelfWeightOf<T>>::set_mint_permission()]391 #[transactional]392 pub fn set_mint_permission(origin, collection_id: CollectionId, mint_permission: bool) -> DispatchResult393 {394 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);395396 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;397 target_collection.check_is_owner(&sender)?;398399 target_collection.mint_mode = mint_permission;400 target_collection.save()401 }402403 /// Change the owner of the collection.404 ///405 /// # Permissions406 ///407 /// * Collection Owner.408 ///409 /// # Arguments410 ///411 /// * collection_id.412 ///413 /// * new_owner.414 #[weight = <SelfWeightOf<T>>::change_collection_owner()]415 #[transactional]416 pub fn change_collection_owner(origin, collection_id: CollectionId, new_owner: T::AccountId) -> DispatchResult {417418 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);419420 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;421 target_collection.check_is_owner(&sender)?;422423 target_collection.owner = new_owner;424 target_collection.save()425 }426427 /// Adds an admin of the Collection.428 /// NFT Collection can be controlled by multiple admin addresses (some which can also be servers, for example). Admins can issue and burn NFTs, as well as add and remove other admins, but cannot change NFT or Collection ownership.429 ///430 /// # Permissions431 ///432 /// * Collection Owner.433 /// * Collection Admin.434 ///435 /// # Arguments436 ///437 /// * collection_id: ID of the Collection to add admin for.438 ///439 /// * new_admin_id: Address of new admin to add.440 #[weight = <SelfWeightOf<T>>::add_collection_admin()]441 #[transactional]442 pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::CrossAccountId) -> DispatchResult {443 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);444445 let collection = <CollectionHandle<T>>::try_get(collection_id)?;446 collection.check_is_owner_or_admin(&sender)?;447448 <IsAdmin<T>>::insert((collection_id, new_admin_id.as_sub()), true);449 Ok(())450 }451452 /// Remove admin address of the Collection. An admin address can remove itself. List of admins may become empty, in which case only Collection Owner will be able to add an Admin.453 ///454 /// # Permissions455 ///456 /// * Collection Owner.457 /// * Collection Admin.458 ///459 /// # Arguments460 ///461 /// * collection_id: ID of the Collection to remove admin for.462 ///463 /// * account_id: Address of admin to remove.464 #[weight = <SelfWeightOf<T>>::remove_collection_admin()]465 #[transactional]466 pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::CrossAccountId) -> DispatchResult {467 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);468469 let collection = <CollectionHandle<T>>::try_get(collection_id)?;470 collection.check_is_owner_or_admin(&sender)?;471472 <IsAdmin<T>>::remove((collection_id, account_id.as_sub()));473 Ok(())474 }475476 /// # Permissions477 ///478 /// * Collection Owner479 ///480 /// # Arguments481 ///482 /// * collection_id.483 ///484 /// * new_sponsor.485 #[weight = <SelfWeightOf<T>>::set_collection_sponsor()]486 #[transactional]487 pub fn set_collection_sponsor(origin, collection_id: CollectionId, new_sponsor: T::AccountId) -> DispatchResult {488 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);489490 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;491 target_collection.check_is_owner_or_admin(&sender)?;492493 target_collection.sponsorship = SponsorshipState::Unconfirmed(new_sponsor);494 target_collection.save()495 }496497 /// # Permissions498 ///499 /// * Sponsor.500 ///501 /// # Arguments502 ///503 /// * collection_id.504 #[weight = <SelfWeightOf<T>>::confirm_sponsorship()]505 #[transactional]506 pub fn confirm_sponsorship(origin, collection_id: CollectionId) -> DispatchResult {507 let sender = ensure_signed(origin)?;508509 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;510 ensure!(511 target_collection.sponsorship.pending_sponsor() == Some(&sender),512 Error::<T>::ConfirmUnsetSponsorFail513 );514515 target_collection.sponsorship = SponsorshipState::Confirmed(sender);516 target_collection.save()517 }518519 /// Switch back to pay-per-own-transaction model.520 ///521 /// # Permissions522 ///523 /// * Collection owner.524 ///525 /// # Arguments526 ///527 /// * collection_id.528 #[weight = <SelfWeightOf<T>>::remove_collection_sponsor()]529 #[transactional]530 pub fn remove_collection_sponsor(origin, collection_id: CollectionId) -> DispatchResult {531 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);532533 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;534 target_collection.check_is_owner(&sender)?;535536 target_collection.sponsorship = SponsorshipState::Disabled;537 target_collection.save()538 }539540 /// This method creates a concrete instance of NFT Collection created with CreateCollection method.541 ///542 /// # Permissions543 ///544 /// * Collection Owner.545 /// * Collection Admin.546 /// * Anyone if547 /// * White List is enabled, and548 /// * Address is added to white list, and549 /// * MintPermission is enabled (see SetMintPermission method)550 ///551 /// # Arguments552 ///553 /// * collection_id: ID of the collection.554 ///555 /// * owner: Address, initial owner of the NFT.556 ///557 /// * data: Token data to store on chain.558 #[weight = <CommonWeights<T>>::create_item()]559 #[transactional]560 pub fn create_item(origin, collection_id: CollectionId, owner: T::CrossAccountId, data: CreateItemData) -> DispatchResultWithPostInfo {561 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);562563 dispatch_call::<T, _>(collection_id, |d| d.create_item(sender, owner, data))564 }565566 /// This method creates multiple items in a collection created with CreateCollection method.567 ///568 /// # Permissions569 ///570 /// * Collection Owner.571 /// * Collection Admin.572 /// * Anyone if573 /// * White List is enabled, and574 /// * Address is added to white list, and575 /// * MintPermission is enabled (see SetMintPermission method)576 ///577 /// # Arguments578 ///579 /// * collection_id: ID of the collection.580 ///581 /// * itemsData: Array items properties. Each property is an array of bytes itself, see [create_item].582 ///583 /// * owner: Address, initial owner of the NFT.584 #[weight = <CommonWeights<T>>::create_multiple_items(items_data.len() as u32)]585 #[transactional]586 pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::CrossAccountId, items_data: Vec<CreateItemData>) -> DispatchResultWithPostInfo {587 ensure!(!items_data.is_empty(), Error::<T>::EmptyArgument);588 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);589590 dispatch_call::<T, _>(collection_id, |d| d.create_multiple_items(sender, owner, items_data))591 }592593 // TODO! transaction weight594595 /// Set transfers_enabled value for particular collection596 ///597 /// # Permissions598 ///599 /// * Collection Owner.600 ///601 /// # Arguments602 ///603 /// * collection_id: ID of the collection.604 ///605 /// * value: New flag value.606 #[weight = <SelfWeightOf<T>>::set_transfers_enabled_flag()]607 #[transactional]608 pub fn set_transfers_enabled_flag(origin, collection_id: CollectionId, value: bool) -> DispatchResult {609 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);610 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;611 target_collection.check_is_owner(&sender)?;612613 // =========614615 target_collection.transfers_enabled = value;616 target_collection.save()617 }618619 /// Destroys a concrete instance of NFT.620 ///621 /// # Permissions622 ///623 /// * Collection Owner.624 /// * Collection Admin.625 /// * Current NFT Owner.626 ///627 /// # Arguments628 ///629 /// * collection_id: ID of the collection.630 ///631 /// * item_id: ID of NFT to burn.632 #[weight = <CommonWeights<T>>::burn_item()]633 #[transactional]634 pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {635 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);636637 dispatch_call::<T, _>(collection_id, |d| d.burn_item(sender, item_id, value))638 }639640 /// Change ownership of the token.641 ///642 /// # Permissions643 ///644 /// * Collection Owner645 /// * Collection Admin646 /// * Current NFT owner647 ///648 /// # Arguments649 ///650 /// * recipient: Address of token recipient.651 ///652 /// * collection_id.653 ///654 /// * item_id: ID of the item655 /// * Non-Fungible Mode: Required.656 /// * Fungible Mode: Ignored.657 /// * Re-Fungible Mode: Required.658 ///659 /// * value: Amount to transfer.660 /// * Non-Fungible Mode: Ignored661 /// * Fungible Mode: Must specify transferred amount662 /// * Re-Fungible Mode: Must specify transferred portion (between 0 and 1)663 #[weight = <CommonWeights<T>>::transfer()]664 #[transactional]665 pub fn transfer(origin, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {666 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);667668 dispatch_call::<T, _>(collection_id, |d| d.transfer(sender, recipient, item_id, value))669 }670671 /// Set, change, or remove approved address to transfer the ownership of the NFT.672 ///673 /// # Permissions674 ///675 /// * Collection Owner676 /// * Collection Admin677 /// * Current NFT owner678 ///679 /// # Arguments680 ///681 /// * approved: Address that is approved to transfer this NFT or zero (if needed to remove approval).682 ///683 /// * collection_id.684 ///685 /// * item_id: ID of the item.686 #[weight = <CommonWeights<T>>::approve()]687 #[transactional]688 pub fn approve(origin, spender: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResultWithPostInfo {689 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);690691 dispatch_call::<T, _>(collection_id, |d| d.approve(sender, spender, item_id, amount))692 }693694 /// Change ownership of a NFT on behalf of the owner. See Approve method for additional information. After this method executes, the approval is removed so that the approved address will not be able to transfer this NFT again from this owner.695 ///696 /// # Permissions697 /// * Collection Owner698 /// * Collection Admin699 /// * Current NFT owner700 /// * Address approved by current NFT owner701 ///702 /// # Arguments703 ///704 /// * from: Address that owns token.705 ///706 /// * recipient: Address of token recipient.707 ///708 /// * collection_id.709 ///710 /// * item_id: ID of the item.711 ///712 /// * value: Amount to transfer.713 #[weight = <CommonWeights<T>>::transfer_from()]714 #[transactional]715 pub fn transfer_from(origin, from: T::CrossAccountId, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResultWithPostInfo {716 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);717718 dispatch_call::<T, _>(collection_id, |d| d.transfer_from(sender, from, recipient, item_id, value))719 }720721 /// Set off-chain data schema.722 ///723 /// # Permissions724 ///725 /// * Collection Owner726 /// * Collection Admin727 ///728 /// # Arguments729 ///730 /// * collection_id.731 ///732 /// * schema: String representing the offchain data schema.733 #[weight = <CommonWeights<T>>::set_variable_metadata(data.len() as u32)]734 #[transactional]735 pub fn set_variable_meta_data (736 origin,737 collection_id: CollectionId,738 item_id: TokenId,739 data: Vec<u8>740 ) -> DispatchResultWithPostInfo {741 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);742743 dispatch_call::<T, _>(collection_id, |d| d.set_variable_metadata(sender, item_id, data))744 }745746 /// Set meta_update_permission value for particular collection747 ///748 /// # Permissions749 ///750 /// * Collection Owner.751 ///752 /// # Arguments753 ///754 /// * collection_id: ID of the collection.755 ///756 /// * value: New flag value.757 #[weight = <SelfWeightOf<T>>::set_variable_meta_data(0)]758 #[transactional]759 pub fn set_meta_update_permission_flag(origin, collection_id: CollectionId, value: MetaUpdatePermission) -> DispatchResult {760 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);761 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;762763 ensure!(764 target_collection.meta_update_permission != MetaUpdatePermission::None,765 <CommonError<T>>::MetadataFlagFrozen,766 );767 target_collection.check_is_owner(&sender)?;768769 target_collection.meta_update_permission = value;770771 target_collection.save()772 }773774 /// Set schema standard775 /// ImageURL776 /// Unique777 ///778 /// # Permissions779 ///780 /// * Collection Owner781 /// * Collection Admin782 ///783 /// # Arguments784 ///785 /// * collection_id.786 ///787 /// * schema: SchemaVersion: enum788 #[weight = <SelfWeightOf<T>>::set_schema_version()]789 #[transactional]790 pub fn set_schema_version(791 origin,792 collection_id: CollectionId,793 version: SchemaVersion794 ) -> DispatchResult {795 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);796 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;797 target_collection.check_is_owner_or_admin(&sender)?;798 target_collection.schema_version = version;799 target_collection.save()800 }801802 /// Set off-chain data schema.803 ///804 /// # Permissions805 ///806 /// * Collection Owner807 /// * Collection Admin808 ///809 /// # Arguments810 ///811 /// * collection_id.812 ///813 /// * schema: String representing the offchain data schema.814 #[weight = <SelfWeightOf<T>>::set_offchain_schema(schema.len() as u32)]815 #[transactional]816 pub fn set_offchain_schema(817 origin,818 collection_id: CollectionId,819 schema: Vec<u8>820 ) -> DispatchResult {821 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);822 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;823 target_collection.check_is_owner_or_admin(&sender)?;824825 // check schema limit826 ensure!(schema.len() as u32 <= OFFCHAIN_SCHEMA_LIMIT, "");827828 target_collection.offchain_schema = schema;829 target_collection.save()830 }831832 /// Set const on-chain data schema.833 ///834 /// # Permissions835 ///836 /// * Collection Owner837 /// * Collection Admin838 ///839 /// # Arguments840 ///841 /// * collection_id.842 ///843 /// * schema: String representing the const on-chain data schema.844 #[weight = <SelfWeightOf<T>>::set_const_on_chain_schema(schema.len() as u32)]845 #[transactional]846 pub fn set_const_on_chain_schema (847 origin,848 collection_id: CollectionId,849 schema: Vec<u8>850 ) -> DispatchResult {851 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);852 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;853 target_collection.check_is_owner_or_admin(&sender)?;854855 // check schema limit856 ensure!(schema.len() as u32 <= CONST_ON_CHAIN_SCHEMA_LIMIT, "");857858 target_collection.const_on_chain_schema = schema;859 target_collection.save()860 }861862 /// Set variable on-chain data schema.863 ///864 /// # Permissions865 ///866 /// * Collection Owner867 /// * Collection Admin868 ///869 /// # Arguments870 ///871 /// * collection_id.872 ///873 /// * schema: String representing the variable on-chain data schema.874 #[weight = <SelfWeightOf<T>>::set_const_on_chain_schema(schema.len() as u32)]875 #[transactional]876 pub fn set_variable_on_chain_schema (877 origin,878 collection_id: CollectionId,879 schema: Vec<u8>880 ) -> DispatchResult {881 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);882 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;883 target_collection.check_is_owner_or_admin(&sender)?;884885 // check schema limit886 ensure!(schema.len() as u32 <= VARIABLE_ON_CHAIN_SCHEMA_LIMIT, "");887888 target_collection.variable_on_chain_schema = schema;889 target_collection.save()890 }891892 #[weight = <SelfWeightOf<T>>::set_collection_limits()]893 #[transactional]894 pub fn set_collection_limits(895 origin,896 collection_id: CollectionId,897 new_limits: CollectionLimits<T::BlockNumber>,898 ) -> DispatchResult {899 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);900 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;901 target_collection.check_is_owner(&sender)?;902 let old_limits = &target_collection.limits;903904 // collection bounds905 ensure!(new_limits.sponsor_transfer_timeout <= MAX_SPONSOR_TIMEOUT &&906 new_limits.account_token_ownership_limit.unwrap_or(0) <= MAX_TOKEN_OWNERSHIP &&907 new_limits.sponsored_data_size <= CUSTOM_DATA_LIMIT,908 Error::<T>::CollectionLimitBoundsExceeded);909910 // token_limit check prev911 ensure!(old_limits.token_limit >= new_limits.token_limit, <CommonError<T>>::CollectionTokenLimitExceeded);912 ensure!(new_limits.token_limit > 0, <CommonError<T>>::CollectionTokenLimitExceeded);913914 ensure!(915 (old_limits.owner_can_transfer || !new_limits.owner_can_transfer) &&916 (old_limits.owner_can_destroy || !new_limits.owner_can_destroy),917 Error::<T>::OwnerPermissionsCantBeReverted,918 );919920 target_collection.limits = new_limits;921922 target_collection.save()923 }924 }925}926927// TODO: limit returned entries?928impl<T: Config> Pallet<T> {929 pub fn adminlist(collection: CollectionId) -> Vec<T::AccountId> {930 <IsAdmin<T>>::iter_prefix((collection,))931 .map(|(a, _)| a)932 .collect()933 }934 pub fn allowlist(collection: CollectionId) -> Vec<T::AccountId> {935 <Allowlist<T>>::iter_prefix((collection,))936 .map(|(a, _)| a)937 .collect()938 }939}1//2// This file is subject to the terms and conditions defined in3// file 'LICENSE', which is part of this source code package.4//56#![recursion_limit = "1024"]7#![cfg_attr(not(feature = "std"), no_std)]8#![allow(9 clippy::too_many_arguments,10 clippy::unnecessary_mut_passed,11 clippy::unused_unit12)]1314extern crate alloc;1516pub use serde::{Serialize, Deserialize};1718pub use frame_support::{19 construct_runtime, decl_module, decl_storage, decl_error,20 dispatch::DispatchResult,21 ensure, fail, parameter_types,22 traits::{23 ExistenceRequirement, Get, Imbalance, KeyOwnerProofSystem, OnUnbalanced, Randomness,24 IsSubType, WithdrawReasons,25 },26 weights::{27 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},28 DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,29 WeightToFeePolynomial, DispatchClass,30 },31 StorageValue, transactional,32 pallet_prelude::DispatchResultWithPostInfo,33};34use frame_system::{self as system, ensure_signed};35use sp_runtime::{sp_std::prelude::Vec};36use nft_data_structs::{37 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, CUSTOM_DATA_LIMIT,38 VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, COLLECTION_ADMINS_LIMIT,39 OFFCHAIN_SCHEMA_LIMIT, AccessMode, Collection, CreateItemData, CollectionLimits, CollectionId,40 CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,41};42use pallet_common::{43 account::CrossAccountId, CollectionHandle, IsAdmin, Pallet as PalletCommon,44 Error as CommonError, CommonWeightInfo, Allowlist,45};46use pallet_refungible::{Pallet as PalletRefungible, RefungibleHandle};47use pallet_fungible::{Pallet as PalletFungible, FungibleHandle};48use pallet_nonfungible::{Pallet as PalletNonfungible, NonfungibleHandle};4950#[cfg(test)]51mod mock;5253#[cfg(test)]54mod tests;5556mod eth;57mod sponsorship;58pub use sponsorship::NftSponsorshipHandler;59pub use eth::sponsoring::NftEthSponsorshipHandler;6061pub use eth::NftErcSupport;6263pub mod common;64use common::CommonWeights;65pub mod dispatch;66use dispatch::dispatch_call;6768#[cfg(feature = "runtime-benchmarks")]69mod benchmarking;70pub mod weights;71use weights::WeightInfo;7273decl_error! {74 /// Error for non-fungible-token module.75 pub enum Error for Module<T: Config> {76 /// Decimal_points parameter must be lower than MAX_DECIMAL_POINTS constant, currently it is 30.77 CollectionDecimalPointLimitExceeded,78 /// This address is not set as sponsor, use setCollectionSponsor first.79 ConfirmUnsetSponsorFail,80 /// Length of items properties must be greater than 0.81 EmptyArgument,82 /// Collection limit bounds per collection exceeded83 CollectionLimitBoundsExceeded,84 /// Tried to enable permissions which are only permitted to be disabled85 OwnerPermissionsCantBeReverted,86 }87}88pub trait Config:89 system::Config90 + pallet_evm_coder_substrate::Config91 + pallet_common::Config92 + pallet_nonfungible::Config93 + pallet_refungible::Config94 + pallet_fungible::Config95 + Sized96{97 /// Weight information for extrinsics in this pallet.98 type WeightInfo: WeightInfo;99}100101type SelfWeightOf<T> = <T as Config>::WeightInfo;102103// # Used definitions104//105// ## User control levels106//107// chain-controlled - key is uncontrolled by user108// i.e autoincrementing index109// can use non-cryptographic hash110// real - key is controlled by user111// but it is hard to generate enough colliding values, i.e owner of signed txs112// can use non-cryptographic hash113// controlled - key is completly controlled by users114// i.e maps with mutable keys115// should use cryptographic hash116//117// ## User control level downgrade reasons118//119// ?1 - chain-controlled -> controlled120// collections/tokens can be destroyed, resulting in massive holes121// ?2 - chain-controlled -> controlled122// same as ?1, but can be only added, resulting in easier exploitation123// ?3 - real -> controlled124// no confirmation required, so addresses can be easily generated125decl_storage! {126 trait Store for Module<T: Config> as Nft {127128 //#region Private members129 /// Used for migrations130 ChainVersion: u64;131 //#endregion132133 //#region Tokens transfer rate limit baskets134 /// (Collection id (controlled?2), who created (real))135 /// TODO: Off chain worker should remove from this map when collection gets removed136 pub CreateItemBasket get(fn create_item_basket): map hasher(blake2_128_concat) (CollectionId, T::AccountId) => T::BlockNumber;137 /// Collection id (controlled?2), token id (controlled?2)138 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => T::BlockNumber;139 /// Collection id (controlled?2), owning user (real)140 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;141 /// Collection id (controlled?2), token id (controlled?2)142 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => T::BlockNumber;143 //#endregion144145 /// Variable metadata sponsoring146 /// Collection id (controlled?2), token id (controlled?2)147 pub VariableMetaDataBasket get(fn variable_meta_data_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber> = None;148 }149}150151decl_module! {152 pub struct Module<T: Config> for enum Call153 where154 origin: T::Origin155 {156 const CollectionAdminsLimit: u64 = COLLECTION_ADMINS_LIMIT;157 type Error = Error<T>;158159 fn on_initialize(_now: T::BlockNumber) -> Weight {160 0161 }162163 /// This method creates a Collection of NFTs. Each Token may have multiple properties encoded as an array of bytes of certain length. The initial owner and admin of the collection are set to the address that signed the transaction. Both addresses can be changed later.164 ///165 /// # Permissions166 ///167 /// * Anyone.168 ///169 /// # Arguments170 ///171 /// * collection_name: UTF-16 string with collection name (limit 64 characters), will be stored as zero-terminated.172 ///173 /// * collection_description: UTF-16 string with collection description (limit 256 characters), will be stored as zero-terminated.174 ///175 /// * token_prefix: UTF-8 string with token prefix.176 ///177 /// * mode: [CollectionMode] collection type and type dependent data.178 // returns collection ID179 #[weight = <SelfWeightOf<T>>::create_collection()]180 #[transactional]181 pub fn create_collection(origin,182 collection_name: Vec<u16>,183 collection_description: Vec<u16>,184 token_prefix: Vec<u8>,185 mode: CollectionMode) -> DispatchResult {186187 // Anyone can create a collection188 let who = ensure_signed(origin)?;189190 let limits = CollectionLimits::<T::BlockNumber> {191 sponsored_data_size: CUSTOM_DATA_LIMIT,192 ..Default::default()193 };194195 // Create new collection196 let new_collection = Collection::<T> {197 owner: who.clone(),198 name: collection_name,199 mode: mode.clone(),200 mint_mode: false,201 access: AccessMode::Normal,202 description: collection_description,203 token_prefix,204 offchain_schema: Vec::new(),205 schema_version: SchemaVersion::ImageURL,206 sponsorship: SponsorshipState::Disabled,207 variable_on_chain_schema: Vec::new(),208 const_on_chain_schema: Vec::new(),209 limits,210 transfers_enabled: true,211 meta_update_permission: Default::default(),212 };213214 let _id = match mode {215 CollectionMode::NFT => {PalletNonfungible::init_collection(new_collection)?},216 CollectionMode::Fungible(decimal_points) => {217 // check params218 ensure!(decimal_points <= MAX_DECIMAL_POINTS, Error::<T>::CollectionDecimalPointLimitExceeded);219 PalletFungible::init_collection(new_collection)?220 }221 CollectionMode::ReFungible => {222 PalletRefungible::init_collection(new_collection)?223 }224 };225226 Ok(())227 }228229 /// **DANGEROUS**: Destroys collection and all NFTs within this collection. Users irrecoverably lose their assets and may lose real money.230 ///231 /// # Permissions232 ///233 /// * Collection Owner.234 ///235 /// # Arguments236 ///237 /// * collection_id: collection to destroy.238 #[weight = <SelfWeightOf<T>>::destroy_collection()]239 #[transactional]240 pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {241 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);242243 let collection = <CollectionHandle<T>>::try_get(collection_id)?;244 collection.check_is_owner(&sender)?;245246 // =========247248 match collection.mode {249 CollectionMode::ReFungible => PalletRefungible::destroy_collection(RefungibleHandle::cast(collection), &sender)?,250 CollectionMode::Fungible(_) => PalletFungible::destroy_collection(FungibleHandle::cast(collection), &sender)?,251 CollectionMode::NFT => PalletNonfungible::destroy_collection(NonfungibleHandle::cast(collection), &sender)?,252 }253254 <NftTransferBasket<T>>::remove_prefix(collection_id, None);255 <FungibleTransferBasket<T>>::remove_prefix(collection_id, None);256 <ReFungibleTransferBasket<T>>::remove_prefix(collection_id, None);257258 <VariableMetaDataBasket<T>>::remove_prefix(collection_id, None);259260 Ok(())261 }262263 /// Add an address to white list.264 ///265 /// # Permissions266 ///267 /// * Collection Owner268 /// * Collection Admin269 ///270 /// # Arguments271 ///272 /// * collection_id.273 ///274 /// * address.275 #[weight = <SelfWeightOf<T>>::add_to_white_list()]276 #[transactional]277 pub fn add_to_white_list(origin, collection_id: CollectionId, address: T::CrossAccountId) -> DispatchResult{278279 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);280 let collection = <CollectionHandle<T>>::try_get(collection_id)?;281282 <PalletCommon<T>>::toggle_allowlist(283 &collection,284 &sender,285 &address,286 true,287 )?;288289 Ok(())290 }291292 /// Remove an address from white list.293 ///294 /// # Permissions295 ///296 /// * Collection Owner297 /// * Collection Admin298 ///299 /// # Arguments300 ///301 /// * collection_id.302 ///303 /// * address.304 #[weight = <SelfWeightOf<T>>::remove_from_white_list()]305 #[transactional]306 pub fn remove_from_white_list(origin, collection_id: CollectionId, address: T::CrossAccountId) -> DispatchResult{307308 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);309 let collection = <CollectionHandle<T>>::try_get(collection_id)?;310311 <PalletCommon<T>>::toggle_allowlist(312 &collection,313 &sender,314 &address,315 false,316 )?;317318 Ok(())319 }320321 /// Toggle between normal and white list access for the methods with access for `Anyone`.322 ///323 /// # Permissions324 ///325 /// * Collection Owner.326 ///327 /// # Arguments328 ///329 /// * collection_id.330 ///331 /// * mode: [AccessMode]332 #[weight = <SelfWeightOf<T>>::set_public_access_mode()]333 #[transactional]334 pub fn set_public_access_mode(origin, collection_id: CollectionId, mode: AccessMode) -> DispatchResult335 {336 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);337338 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;339 target_collection.check_is_owner(&sender)?;340341 target_collection.access = mode;342 target_collection.save()343 }344345 /// Allows Anyone to create tokens if:346 /// * White List is enabled, and347 /// * Address is added to white list, and348 /// * This method was called with True parameter349 ///350 /// # Permissions351 /// * Collection Owner352 ///353 /// # Arguments354 ///355 /// * collection_id.356 ///357 /// * mint_permission: Boolean parameter. If True, allows minting to Anyone with conditions above.358 #[weight = <SelfWeightOf<T>>::set_mint_permission()]359 #[transactional]360 pub fn set_mint_permission(origin, collection_id: CollectionId, mint_permission: bool) -> DispatchResult361 {362 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);363364 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;365 target_collection.check_is_owner(&sender)?;366367 target_collection.mint_mode = mint_permission;368 target_collection.save()369 }370371 /// Change the owner of the collection.372 ///373 /// # Permissions374 ///375 /// * Collection Owner.376 ///377 /// # Arguments378 ///379 /// * collection_id.380 ///381 /// * new_owner.382 #[weight = <SelfWeightOf<T>>::change_collection_owner()]383 #[transactional]384 pub fn change_collection_owner(origin, collection_id: CollectionId, new_owner: T::AccountId) -> DispatchResult {385386 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);387388 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;389 target_collection.check_is_owner(&sender)?;390391 target_collection.owner = new_owner;392 target_collection.save()393 }394395 /// Adds an admin of the Collection.396 /// NFT Collection can be controlled by multiple admin addresses (some which can also be servers, for example). Admins can issue and burn NFTs, as well as add and remove other admins, but cannot change NFT or Collection ownership.397 ///398 /// # Permissions399 ///400 /// * Collection Owner.401 /// * Collection Admin.402 ///403 /// # Arguments404 ///405 /// * collection_id: ID of the Collection to add admin for.406 ///407 /// * new_admin_id: Address of new admin to add.408 #[weight = <SelfWeightOf<T>>::add_collection_admin()]409 #[transactional]410 pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::CrossAccountId) -> DispatchResult {411 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);412413 let collection = <CollectionHandle<T>>::try_get(collection_id)?;414 collection.check_is_owner_or_admin(&sender)?;415416 <IsAdmin<T>>::insert((collection_id, new_admin_id.as_sub()), true);417 Ok(())418 }419420 /// Remove admin address of the Collection. An admin address can remove itself. List of admins may become empty, in which case only Collection Owner will be able to add an Admin.421 ///422 /// # Permissions423 ///424 /// * Collection Owner.425 /// * Collection Admin.426 ///427 /// # Arguments428 ///429 /// * collection_id: ID of the Collection to remove admin for.430 ///431 /// * account_id: Address of admin to remove.432 #[weight = <SelfWeightOf<T>>::remove_collection_admin()]433 #[transactional]434 pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::CrossAccountId) -> DispatchResult {435 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);436437 let collection = <CollectionHandle<T>>::try_get(collection_id)?;438 collection.check_is_owner_or_admin(&sender)?;439440 <IsAdmin<T>>::remove((collection_id, account_id.as_sub()));441 Ok(())442 }443444 /// # Permissions445 ///446 /// * Collection Owner447 ///448 /// # Arguments449 ///450 /// * collection_id.451 ///452 /// * new_sponsor.453 #[weight = <SelfWeightOf<T>>::set_collection_sponsor()]454 #[transactional]455 pub fn set_collection_sponsor(origin, collection_id: CollectionId, new_sponsor: T::AccountId) -> DispatchResult {456 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);457458 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;459 target_collection.check_is_owner_or_admin(&sender)?;460461 target_collection.sponsorship = SponsorshipState::Unconfirmed(new_sponsor);462 target_collection.save()463 }464465 /// # Permissions466 ///467 /// * Sponsor.468 ///469 /// # Arguments470 ///471 /// * collection_id.472 #[weight = <SelfWeightOf<T>>::confirm_sponsorship()]473 #[transactional]474 pub fn confirm_sponsorship(origin, collection_id: CollectionId) -> DispatchResult {475 let sender = ensure_signed(origin)?;476477 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;478 ensure!(479 target_collection.sponsorship.pending_sponsor() == Some(&sender),480 Error::<T>::ConfirmUnsetSponsorFail481 );482483 target_collection.sponsorship = SponsorshipState::Confirmed(sender);484 target_collection.save()485 }486487 /// Switch back to pay-per-own-transaction model.488 ///489 /// # Permissions490 ///491 /// * Collection owner.492 ///493 /// # Arguments494 ///495 /// * collection_id.496 #[weight = <SelfWeightOf<T>>::remove_collection_sponsor()]497 #[transactional]498 pub fn remove_collection_sponsor(origin, collection_id: CollectionId) -> DispatchResult {499 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);500501 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;502 target_collection.check_is_owner(&sender)?;503504 target_collection.sponsorship = SponsorshipState::Disabled;505 target_collection.save()506 }507508 /// This method creates a concrete instance of NFT Collection created with CreateCollection method.509 ///510 /// # Permissions511 ///512 /// * Collection Owner.513 /// * Collection Admin.514 /// * Anyone if515 /// * White List is enabled, and516 /// * Address is added to white list, and517 /// * MintPermission is enabled (see SetMintPermission method)518 ///519 /// # Arguments520 ///521 /// * collection_id: ID of the collection.522 ///523 /// * owner: Address, initial owner of the NFT.524 ///525 /// * data: Token data to store on chain.526 #[weight = <CommonWeights<T>>::create_item()]527 #[transactional]528 pub fn create_item(origin, collection_id: CollectionId, owner: T::CrossAccountId, data: CreateItemData) -> DispatchResultWithPostInfo {529 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);530531 dispatch_call::<T, _>(collection_id, |d| d.create_item(sender, owner, data))532 }533534 /// This method creates multiple items in a collection created with CreateCollection method.535 ///536 /// # Permissions537 ///538 /// * Collection Owner.539 /// * Collection Admin.540 /// * Anyone if541 /// * White List is enabled, and542 /// * Address is added to white list, and543 /// * MintPermission is enabled (see SetMintPermission method)544 ///545 /// # Arguments546 ///547 /// * collection_id: ID of the collection.548 ///549 /// * itemsData: Array items properties. Each property is an array of bytes itself, see [create_item].550 ///551 /// * owner: Address, initial owner of the NFT.552 #[weight = <CommonWeights<T>>::create_multiple_items(items_data.len() as u32)]553 #[transactional]554 pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::CrossAccountId, items_data: Vec<CreateItemData>) -> DispatchResultWithPostInfo {555 ensure!(!items_data.is_empty(), Error::<T>::EmptyArgument);556 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);557558 dispatch_call::<T, _>(collection_id, |d| d.create_multiple_items(sender, owner, items_data))559 }560561 // TODO! transaction weight562563 /// Set transfers_enabled value for particular collection564 ///565 /// # Permissions566 ///567 /// * Collection Owner.568 ///569 /// # Arguments570 ///571 /// * collection_id: ID of the collection.572 ///573 /// * value: New flag value.574 #[weight = <SelfWeightOf<T>>::set_transfers_enabled_flag()]575 #[transactional]576 pub fn set_transfers_enabled_flag(origin, collection_id: CollectionId, value: bool) -> DispatchResult {577 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);578 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;579 target_collection.check_is_owner(&sender)?;580581 // =========582583 target_collection.transfers_enabled = value;584 target_collection.save()585 }586587 /// Destroys a concrete instance of NFT.588 ///589 /// # Permissions590 ///591 /// * Collection Owner.592 /// * Collection Admin.593 /// * Current NFT Owner.594 ///595 /// # Arguments596 ///597 /// * collection_id: ID of the collection.598 ///599 /// * item_id: ID of NFT to burn.600 #[weight = <CommonWeights<T>>::burn_item()]601 #[transactional]602 pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {603 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);604605 dispatch_call::<T, _>(collection_id, |d| d.burn_item(sender, item_id, value))606 }607608 /// Change ownership of the token.609 ///610 /// # Permissions611 ///612 /// * Collection Owner613 /// * Collection Admin614 /// * Current NFT owner615 ///616 /// # Arguments617 ///618 /// * recipient: Address of token recipient.619 ///620 /// * collection_id.621 ///622 /// * item_id: ID of the item623 /// * Non-Fungible Mode: Required.624 /// * Fungible Mode: Ignored.625 /// * Re-Fungible Mode: Required.626 ///627 /// * value: Amount to transfer.628 /// * Non-Fungible Mode: Ignored629 /// * Fungible Mode: Must specify transferred amount630 /// * Re-Fungible Mode: Must specify transferred portion (between 0 and 1)631 #[weight = <CommonWeights<T>>::transfer()]632 #[transactional]633 pub fn transfer(origin, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {634 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);635636 dispatch_call::<T, _>(collection_id, |d| d.transfer(sender, recipient, item_id, value))637 }638639 /// Set, change, or remove approved address to transfer the ownership of the NFT.640 ///641 /// # Permissions642 ///643 /// * Collection Owner644 /// * Collection Admin645 /// * Current NFT owner646 ///647 /// # Arguments648 ///649 /// * approved: Address that is approved to transfer this NFT or zero (if needed to remove approval).650 ///651 /// * collection_id.652 ///653 /// * item_id: ID of the item.654 #[weight = <CommonWeights<T>>::approve()]655 #[transactional]656 pub fn approve(origin, spender: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResultWithPostInfo {657 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);658659 dispatch_call::<T, _>(collection_id, |d| d.approve(sender, spender, item_id, amount))660 }661662 /// Change ownership of a NFT on behalf of the owner. See Approve method for additional information. After this method executes, the approval is removed so that the approved address will not be able to transfer this NFT again from this owner.663 ///664 /// # Permissions665 /// * Collection Owner666 /// * Collection Admin667 /// * Current NFT owner668 /// * Address approved by current NFT owner669 ///670 /// # Arguments671 ///672 /// * from: Address that owns token.673 ///674 /// * recipient: Address of token recipient.675 ///676 /// * collection_id.677 ///678 /// * item_id: ID of the item.679 ///680 /// * value: Amount to transfer.681 #[weight = <CommonWeights<T>>::transfer_from()]682 #[transactional]683 pub fn transfer_from(origin, from: T::CrossAccountId, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResultWithPostInfo {684 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);685686 dispatch_call::<T, _>(collection_id, |d| d.transfer_from(sender, from, recipient, item_id, value))687 }688689 /// Set off-chain data schema.690 ///691 /// # Permissions692 ///693 /// * Collection Owner694 /// * Collection Admin695 ///696 /// # Arguments697 ///698 /// * collection_id.699 ///700 /// * schema: String representing the offchain data schema.701 #[weight = <CommonWeights<T>>::set_variable_metadata(data.len() as u32)]702 #[transactional]703 pub fn set_variable_meta_data (704 origin,705 collection_id: CollectionId,706 item_id: TokenId,707 data: Vec<u8>708 ) -> DispatchResultWithPostInfo {709 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);710711 dispatch_call::<T, _>(collection_id, |d| d.set_variable_metadata(sender, item_id, data))712 }713714 /// Set meta_update_permission value for particular collection715 ///716 /// # Permissions717 ///718 /// * Collection Owner.719 ///720 /// # Arguments721 ///722 /// * collection_id: ID of the collection.723 ///724 /// * value: New flag value.725 #[weight = <SelfWeightOf<T>>::set_meta_update_permission_flag()]726 #[transactional]727 pub fn set_meta_update_permission_flag(origin, collection_id: CollectionId, value: MetaUpdatePermission) -> DispatchResult {728 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);729 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;730731 ensure!(732 target_collection.meta_update_permission != MetaUpdatePermission::None,733 <CommonError<T>>::MetadataFlagFrozen,734 );735 target_collection.check_is_owner(&sender)?;736737 target_collection.meta_update_permission = value;738739 target_collection.save()740 }741742 /// Set schema standard743 /// ImageURL744 /// Unique745 ///746 /// # Permissions747 ///748 /// * Collection Owner749 /// * Collection Admin750 ///751 /// # Arguments752 ///753 /// * collection_id.754 ///755 /// * schema: SchemaVersion: enum756 #[weight = <SelfWeightOf<T>>::set_schema_version()]757 #[transactional]758 pub fn set_schema_version(759 origin,760 collection_id: CollectionId,761 version: SchemaVersion762 ) -> DispatchResult {763 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);764 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;765 target_collection.check_is_owner_or_admin(&sender)?;766 target_collection.schema_version = version;767 target_collection.save()768 }769770 /// Set off-chain data schema.771 ///772 /// # Permissions773 ///774 /// * Collection Owner775 /// * Collection Admin776 ///777 /// # Arguments778 ///779 /// * collection_id.780 ///781 /// * schema: String representing the offchain data schema.782 #[weight = <SelfWeightOf<T>>::set_offchain_schema(schema.len() as u32)]783 #[transactional]784 pub fn set_offchain_schema(785 origin,786 collection_id: CollectionId,787 schema: Vec<u8>788 ) -> DispatchResult {789 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);790 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;791 target_collection.check_is_owner_or_admin(&sender)?;792793 // check schema limit794 ensure!(schema.len() as u32 <= OFFCHAIN_SCHEMA_LIMIT, "");795796 target_collection.offchain_schema = schema;797 target_collection.save()798 }799800 /// Set const on-chain data schema.801 ///802 /// # Permissions803 ///804 /// * Collection Owner805 /// * Collection Admin806 ///807 /// # Arguments808 ///809 /// * collection_id.810 ///811 /// * schema: String representing the const on-chain data schema.812 #[weight = <SelfWeightOf<T>>::set_const_on_chain_schema(schema.len() as u32)]813 #[transactional]814 pub fn set_const_on_chain_schema (815 origin,816 collection_id: CollectionId,817 schema: Vec<u8>818 ) -> DispatchResult {819 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);820 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;821 target_collection.check_is_owner_or_admin(&sender)?;822823 // check schema limit824 ensure!(schema.len() as u32 <= CONST_ON_CHAIN_SCHEMA_LIMIT, "");825826 target_collection.const_on_chain_schema = schema;827 target_collection.save()828 }829830 /// Set variable on-chain data schema.831 ///832 /// # Permissions833 ///834 /// * Collection Owner835 /// * Collection Admin836 ///837 /// # Arguments838 ///839 /// * collection_id.840 ///841 /// * schema: String representing the variable on-chain data schema.842 #[weight = <SelfWeightOf<T>>::set_const_on_chain_schema(schema.len() as u32)]843 #[transactional]844 pub fn set_variable_on_chain_schema (845 origin,846 collection_id: CollectionId,847 schema: Vec<u8>848 ) -> DispatchResult {849 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);850 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;851 target_collection.check_is_owner_or_admin(&sender)?;852853 // check schema limit854 ensure!(schema.len() as u32 <= VARIABLE_ON_CHAIN_SCHEMA_LIMIT, "");855856 target_collection.variable_on_chain_schema = schema;857 target_collection.save()858 }859860 #[weight = <SelfWeightOf<T>>::set_collection_limits()]861 #[transactional]862 pub fn set_collection_limits(863 origin,864 collection_id: CollectionId,865 new_limits: CollectionLimits<T::BlockNumber>,866 ) -> DispatchResult {867 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);868 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;869 target_collection.check_is_owner(&sender)?;870 let old_limits = &target_collection.limits;871872 // collection bounds873 ensure!(new_limits.sponsor_transfer_timeout <= MAX_SPONSOR_TIMEOUT &&874 new_limits.account_token_ownership_limit.unwrap_or(0) <= MAX_TOKEN_OWNERSHIP &&875 new_limits.sponsored_data_size <= CUSTOM_DATA_LIMIT,876 Error::<T>::CollectionLimitBoundsExceeded);877878 // token_limit check prev879 ensure!(old_limits.token_limit >= new_limits.token_limit, <CommonError<T>>::CollectionTokenLimitExceeded);880 ensure!(new_limits.token_limit > 0, <CommonError<T>>::CollectionTokenLimitExceeded);881882 ensure!(883 (old_limits.owner_can_transfer || !new_limits.owner_can_transfer) &&884 (old_limits.owner_can_destroy || !new_limits.owner_can_destroy),885 Error::<T>::OwnerPermissionsCantBeReverted,886 );887888 target_collection.limits = new_limits;889890 target_collection.save()891 }892 }893}894895// TODO: limit returned entries?896impl<T: Config> Pallet<T> {897 pub fn adminlist(collection: CollectionId) -> Vec<T::AccountId> {898 <IsAdmin<T>>::iter_prefix((collection,))899 .map(|(a, _)| a)900 .collect()901 }902 pub fn allowlist(collection: CollectionId) -> Vec<T::AccountId> {903 <Allowlist<T>>::iter_prefix((collection,))904 .map(|(a, _)| a)905 .collect()906 }907}pallets/nft/src/weights.rsdiffbeforeafterboth--- a/pallets/nft/src/weights.rs
+++ b/pallets/nft/src/weights.rs
@@ -2,8 +2,8 @@
//! Autogenerated weights for pallet_nft
//!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
-//! DATE: 2021-08-31, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2021-10-21, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 128
// Executed Command:
@@ -43,202 +43,141 @@
fn set_collection_sponsor() -> Weight;
fn confirm_sponsorship() -> Weight;
fn remove_collection_sponsor() -> Weight;
- fn create_item_nft(b: u32, ) -> Weight;
- fn create_multiple_items_nft(b: u32, ) -> Weight;
- fn create_item_fungible() -> Weight;
- fn create_multiple_items_fungible(b: u32, ) -> Weight;
- fn create_item_refungible(b: u32, ) -> Weight;
- fn create_multiple_items_refungible(b: u32, ) -> Weight;
- fn burn_item_nft() -> Weight;
- fn transfer_nft() -> Weight;
- fn transfer_fungible() -> Weight;
- fn transfer_refungible() -> Weight;
fn set_transfers_enabled_flag() -> Weight;
- fn approve_nft() -> Weight;
- fn transfer_from_nft() -> Weight;
- fn transfer_from_fungible() -> Weight;
- fn transfer_from_refungible() -> Weight;
fn set_offchain_schema(b: u32, ) -> Weight;
fn set_const_on_chain_schema(b: u32, ) -> Weight;
fn set_variable_on_chain_schema(b: u32, ) -> Weight;
- fn set_variable_meta_data_nft(b: u32, ) -> Weight;
fn set_schema_version() -> Weight;
fn set_collection_limits() -> Weight;
+ fn set_meta_update_permission_flag() -> Weight;
}
/// Weights for pallet_nft using the Substrate node and recommended hardware.
pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
+ // Storage: Common CreatedCollectionCount (r:1 w:1)
+ // Storage: Common DestroyedCollectionCount (r:1 w:0)
+ // Storage: System Account (r:2 w:2)
+ // Storage: Common CollectionById (r:0 w:1)
fn create_collection() -> Weight {
- (25_851_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(8 as Weight))
- .saturating_add(T::DbWeight::get().writes(6 as Weight))
+ (23_803_000 as Weight)
+ .saturating_add(T::DbWeight::get().reads(4 as Weight))
+ .saturating_add(T::DbWeight::get().writes(4 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
+ // Storage: Common DestroyedCollectionCount (r:1 w:1)
+ // Storage: Nonfungible TokensMinted (r:0 w:1)
+ // Storage: Nonfungible TokensBurnt (r:0 w:1)
fn destroy_collection() -> Weight {
- (28_737_000 as Weight)
+ (27_831_000 as Weight)
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:0)
+ // Storage: Common Allowlist (r:0 w:1)
fn add_to_white_list() -> Weight {
- (6_237_000 as Weight)
+ (6_629_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:0)
+ // Storage: Common Allowlist (r:0 w:1)
fn remove_from_white_list() -> Weight {
- (6_252_000 as Weight)
+ (6_596_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn set_public_access_mode() -> Weight {
- (6_691_000 as Weight)
+ (6_338_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn set_mint_permission() -> Weight {
- (6_630_000 as Weight)
+ (6_383_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn change_collection_owner() -> Weight {
- (6_521_000 as Weight)
+ (6_493_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:0)
+ // Storage: Common IsAdmin (r:0 w:1)
fn add_collection_admin() -> Weight {
- (8_057_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(2 as Weight))
+ (6_850_000 as Weight)
+ .saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:0)
+ // Storage: Common IsAdmin (r:0 w:1)
fn remove_collection_admin() -> Weight {
- (8_307_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(2 as Weight))
+ (6_615_000 as Weight)
+ .saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn set_collection_sponsor() -> Weight {
- (6_484_000 as Weight)
+ (6_430_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn confirm_sponsorship() -> Weight {
- (6_530_000 as Weight)
+ (6_125_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn remove_collection_sponsor() -> Weight {
- (6_733_000 as Weight)
+ (6_236_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
- fn create_item_nft(_b: u32, ) -> Weight {
- (167_909_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(11 as Weight))
- .saturating_add(T::DbWeight::get().writes(8 as Weight))
- }
- fn create_multiple_items_nft(b: u32, ) -> Weight {
- (336_830_000 as Weight)
- // Standard Error: 42_000
- .saturating_add((11_627_000 as Weight).saturating_mul(b as Weight))
- .saturating_add(T::DbWeight::get().reads(11 as Weight))
- .saturating_add(T::DbWeight::get().writes(7 as Weight))
- .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
- }
- fn create_item_fungible() -> Weight {
- (24_123_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(9 as Weight))
- .saturating_add(T::DbWeight::get().writes(4 as Weight))
- }
- fn create_multiple_items_fungible(b: u32, ) -> Weight {
- (48_227_000 as Weight)
- // Standard Error: 13_000
- .saturating_add((2_918_000 as Weight).saturating_mul(b as Weight))
- .saturating_add(T::DbWeight::get().reads(9 as Weight))
- .saturating_add(T::DbWeight::get().writes(4 as Weight))
- }
- fn create_item_refungible(_b: u32, ) -> Weight {
- (26_293_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(9 as Weight))
- .saturating_add(T::DbWeight::get().writes(7 as Weight))
- }
- fn create_multiple_items_refungible(b: u32, ) -> Weight {
- (0 as Weight)
- // Standard Error: 16_000
- .saturating_add((8_374_000 as Weight).saturating_mul(b as Weight))
- .saturating_add(T::DbWeight::get().reads(9 as Weight))
- .saturating_add(T::DbWeight::get().writes(6 as Weight))
- .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
- }
- fn burn_item_nft() -> Weight {
- (32_237_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(9 as Weight))
- .saturating_add(T::DbWeight::get().writes(7 as Weight))
- }
- fn transfer_nft() -> Weight {
- (192_578_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(14 as Weight))
- .saturating_add(T::DbWeight::get().writes(10 as Weight))
- }
- fn transfer_fungible() -> Weight {
- (170_749_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(11 as Weight))
- .saturating_add(T::DbWeight::get().writes(7 as Weight))
- }
- fn transfer_refungible() -> Weight {
- (35_949_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(10 as Weight))
- .saturating_add(T::DbWeight::get().writes(7 as Weight))
- }
+ // Storage: Common CollectionById (r:1 w:1)
fn set_transfers_enabled_flag() -> Weight {
- (6_376_000 as Weight)
+ (6_500_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
- fn approve_nft() -> Weight {
- (169_825_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(9 as Weight))
- .saturating_add(T::DbWeight::get().writes(4 as Weight))
- }
- fn transfer_from_nft() -> Weight {
- (197_912_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(15 as Weight))
- .saturating_add(T::DbWeight::get().writes(11 as Weight))
- }
- fn transfer_from_fungible() -> Weight {
- (183_789_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(12 as Weight))
- .saturating_add(T::DbWeight::get().writes(8 as Weight))
- }
- fn transfer_from_refungible() -> Weight {
- (37_149_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(11 as Weight))
- .saturating_add(T::DbWeight::get().writes(8 as Weight))
- }
+ // Storage: Common CollectionById (r:1 w:1)
fn set_offchain_schema(_b: u32, ) -> Weight {
- (6_435_000 as Weight)
+ (6_538_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn set_const_on_chain_schema(_b: u32, ) -> Weight {
- (6_646_000 as Weight)
+ (6_542_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
- fn set_variable_on_chain_schema(_b: u32, ) -> Weight {
- (6_542_000 as Weight)
+ // Storage: Common CollectionById (r:1 w:1)
+ fn set_variable_on_chain_schema(b: u32, ) -> Weight {
+ (6_092_000 as Weight)
+ // Standard Error: 0
+ .saturating_add((2_000 as Weight).saturating_mul(b as Weight))
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
- fn set_variable_meta_data_nft(_b: u32, ) -> Weight {
- (14_697_000 as Weight)
- .saturating_add(T::DbWeight::get().reads(2 as Weight))
+ // Storage: Common CollectionById (r:1 w:1)
+ fn set_schema_version() -> Weight {
+ (6_470_000 as Weight)
+ .saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
- fn set_schema_version() -> Weight {
- (6_566_000 as Weight)
+ // Storage: Common CollectionById (r:1 w:1)
+ fn set_collection_limits() -> Weight {
+ (6_841_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
- fn set_collection_limits() -> Weight {
- (6_349_000 as Weight)
+ // Storage: Common CollectionById (r:1 w:1)
+ fn set_meta_update_permission_flag() -> Weight {
+ (6_278_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
@@ -246,178 +185,129 @@
// For backwards compatibility and tests
impl WeightInfo for () {
+ // Storage: Common CreatedCollectionCount (r:1 w:1)
+ // Storage: Common DestroyedCollectionCount (r:1 w:0)
+ // Storage: System Account (r:2 w:2)
+ // Storage: Common CollectionById (r:0 w:1)
fn create_collection() -> Weight {
- (25_851_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(8 as Weight))
- .saturating_add(RocksDbWeight::get().writes(6 as Weight))
+ (23_803_000 as Weight)
+ .saturating_add(RocksDbWeight::get().reads(4 as Weight))
+ .saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
+ // Storage: Common DestroyedCollectionCount (r:1 w:1)
+ // Storage: Nonfungible TokensMinted (r:0 w:1)
+ // Storage: Nonfungible TokensBurnt (r:0 w:1)
fn destroy_collection() -> Weight {
- (28_737_000 as Weight)
+ (27_831_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:0)
+ // Storage: Common Allowlist (r:0 w:1)
fn add_to_white_list() -> Weight {
- (6_237_000 as Weight)
+ (6_629_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:0)
+ // Storage: Common Allowlist (r:0 w:1)
fn remove_from_white_list() -> Weight {
- (6_252_000 as Weight)
+ (6_596_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn set_public_access_mode() -> Weight {
- (6_691_000 as Weight)
+ (6_338_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn set_mint_permission() -> Weight {
- (6_630_000 as Weight)
+ (6_383_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn change_collection_owner() -> Weight {
- (6_521_000 as Weight)
+ (6_493_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:0)
+ // Storage: Common IsAdmin (r:0 w:1)
fn add_collection_admin() -> Weight {
- (8_057_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(2 as Weight))
+ (6_850_000 as Weight)
+ .saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:0)
+ // Storage: Common IsAdmin (r:0 w:1)
fn remove_collection_admin() -> Weight {
- (8_307_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(2 as Weight))
+ (6_615_000 as Weight)
+ .saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn set_collection_sponsor() -> Weight {
- (6_484_000 as Weight)
+ (6_430_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn confirm_sponsorship() -> Weight {
- (6_530_000 as Weight)
+ (6_125_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn remove_collection_sponsor() -> Weight {
- (6_733_000 as Weight)
+ (6_236_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
- fn create_item_nft(b: u32, ) -> Weight {
- (167_180_000 as Weight)
- // Standard Error: 1_000
- .saturating_add((10_000 as Weight).saturating_mul(b as Weight))
- .saturating_add(RocksDbWeight::get().reads(11 as Weight))
- .saturating_add(RocksDbWeight::get().writes(8 as Weight))
- }
- fn create_multiple_items_nft(b: u32, ) -> Weight {
- (336_830_000 as Weight)
- // Standard Error: 42_000
- .saturating_add((11_627_000 as Weight).saturating_mul(b as Weight))
- .saturating_add(RocksDbWeight::get().reads(11 as Weight))
- .saturating_add(RocksDbWeight::get().writes(7 as Weight))
- .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
- }
- fn create_item_fungible() -> Weight {
- (24_123_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(9 as Weight))
- .saturating_add(RocksDbWeight::get().writes(4 as Weight))
- }
- fn create_multiple_items_fungible(b: u32, ) -> Weight {
- (13_217_000 as Weight)
- // Standard Error: 4_000
- .saturating_add((2_971_000 as Weight).saturating_mul(b as Weight))
- .saturating_add(RocksDbWeight::get().reads(9 as Weight))
- .saturating_add(RocksDbWeight::get().writes(4 as Weight))
- }
- fn create_item_refungible(_b: u32, ) -> Weight {
- (26_293_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(9 as Weight))
- .saturating_add(RocksDbWeight::get().writes(7 as Weight))
- }
- fn create_multiple_items_refungible(b: u32, ) -> Weight {
- (0 as Weight)
- // Standard Error: 16_000
- .saturating_add((8_374_000 as Weight).saturating_mul(b as Weight))
- .saturating_add(RocksDbWeight::get().reads(9 as Weight))
- .saturating_add(RocksDbWeight::get().writes(6 as Weight))
- .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
- }
- fn burn_item_nft() -> Weight {
- (32_237_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(9 as Weight))
- .saturating_add(RocksDbWeight::get().writes(7 as Weight))
- }
- fn transfer_nft() -> Weight {
- (192_578_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(14 as Weight))
- .saturating_add(RocksDbWeight::get().writes(10 as Weight))
- }
- fn transfer_fungible() -> Weight {
- (170_749_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(11 as Weight))
- .saturating_add(RocksDbWeight::get().writes(7 as Weight))
- }
- fn transfer_refungible() -> Weight {
- (35_949_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(10 as Weight))
- .saturating_add(RocksDbWeight::get().writes(7 as Weight))
- }
+ // Storage: Common CollectionById (r:1 w:1)
fn set_transfers_enabled_flag() -> Weight {
- (6_376_000 as Weight)
+ (6_500_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
- fn approve_nft() -> Weight {
- (169_825_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(9 as Weight))
- .saturating_add(RocksDbWeight::get().writes(4 as Weight))
- }
- fn transfer_from_nft() -> Weight {
- (197_912_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(15 as Weight))
- .saturating_add(RocksDbWeight::get().writes(11 as Weight))
- }
- fn transfer_from_fungible() -> Weight {
- (183_789_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(12 as Weight))
- .saturating_add(RocksDbWeight::get().writes(8 as Weight))
- }
- fn transfer_from_refungible() -> Weight {
- (37_149_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(11 as Weight))
- .saturating_add(RocksDbWeight::get().writes(8 as Weight))
- }
+ // Storage: Common CollectionById (r:1 w:1)
fn set_offchain_schema(_b: u32, ) -> Weight {
- (6_435_000 as Weight)
+ (6_538_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
+ // Storage: Common CollectionById (r:1 w:1)
fn set_const_on_chain_schema(_b: u32, ) -> Weight {
- (6_646_000 as Weight)
+ (6_542_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
- fn set_variable_on_chain_schema(_b: u32, ) -> Weight {
- (6_542_000 as Weight)
+ // Storage: Common CollectionById (r:1 w:1)
+ fn set_variable_on_chain_schema(b: u32, ) -> Weight {
+ (6_092_000 as Weight)
+ // Standard Error: 0
+ .saturating_add((2_000 as Weight).saturating_mul(b as Weight))
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
- fn set_variable_meta_data_nft(_b: u32, ) -> Weight {
- (14_697_000 as Weight)
- .saturating_add(RocksDbWeight::get().reads(2 as Weight))
+ // Storage: Common CollectionById (r:1 w:1)
+ fn set_schema_version() -> Weight {
+ (6_470_000 as Weight)
+ .saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
- fn set_schema_version() -> Weight {
- (6_566_000 as Weight)
+ // Storage: Common CollectionById (r:1 w:1)
+ fn set_collection_limits() -> Weight {
+ (6_841_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
- fn set_collection_limits() -> Weight {
- (6_349_000 as Weight)
+ // Storage: Common CollectionById (r:1 w:1)
+ fn set_meta_update_permission_flag() -> Weight {
+ (6_278_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}