difftreelog
feat track and limit admin amount
in: master
3 files changed
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -11,7 +11,8 @@
use nft_data_structs::{
COLLECTION_NUMBER_LIMIT, Collection, CollectionId, CreateItemData, ExistenceRequirement,
MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_COLLECTION_NAME_LENGTH, MAX_TOKEN_PREFIX_LENGTH,
- MetaUpdatePermission, Pays, PostDispatchInfo, TokenId, Weight, WithdrawReasons,
+ COLLECTION_ADMINS_LIMIT, MetaUpdatePermission, Pays, PostDispatchInfo, TokenId, Weight,
+ WithdrawReasons,
};
pub use pallet::*;
use sp_core::H160;
@@ -165,6 +166,13 @@
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
+ #[pallet::extra_constants]
+ impl<T: Config> Pallet<T> {
+ pub fn collection_admins_limit() -> u32 {
+ COLLECTION_ADMINS_LIMIT
+ }
+ }
+
#[pallet::event]
#[pallet::generate_deposit(pub fn deposit_event)]
pub enum Event<T: Config> {
@@ -265,6 +273,8 @@
TotalCollectionsLimitExceeded,
/// variable_data exceeded data limit.
TokenVariableDataLimitExceeded,
+ /// Exceeded max admin amount
+ CollectionAdminAmountExceeded,
/// Collection settings not allowing items transferring
TransferNotAllowed,
@@ -305,6 +315,14 @@
QueryKind = OptionQuery,
>;
+ #[pallet::storage]
+ pub type AdminAmount<T> = StorageMap<
+ Hasher = Blake2_128Concat,
+ Key = CollectionId,
+ Value = u32,
+ QueryKind = ValueQuery,
+ >;
+
/// List of collection admins
#[pallet::storage]
pub type IsAdmin<T: Config> = StorageNMap<
@@ -419,6 +437,7 @@
<DestroyedCollectionCount<T>>::put(destroyed_collections);
<CollectionById<T>>::remove(collection.id);
+ <AdminAmount<T>>::remove(collection.id);
<IsAdmin<T>>::remove_prefix((collection.id,), None);
<Allowlist<T>>::remove_prefix((collection.id,), None);
Ok(())
@@ -435,9 +454,44 @@
// =========
if allowed {
- <Allowlist<T>>::insert((collection.id, user.as_sub()), true);
+ <Allowlist<T>>::insert((collection.id, user), true);
+ } else {
+ <Allowlist<T>>::remove((collection.id, user));
+ }
+
+ Ok(())
+ }
+
+ pub fn toggle_admin(
+ collection: &CollectionHandle<T>,
+ sender: &T::CrossAccountId,
+ user: &T::CrossAccountId,
+ admin: bool,
+ ) -> DispatchResult {
+ collection.check_is_owner_or_admin(&sender)?;
+
+ let was_admin = <IsAdmin<T>>::get((collection.id, user));
+ if was_admin == admin {
+ return Ok(());
+ }
+ let amount = <AdminAmount<T>>::get(collection.id);
+
+ if admin {
+ let amount = amount
+ .checked_add(1)
+ .ok_or(<Error<T>>::CollectionAdminAmountExceeded)?;
+ ensure!(
+ amount <= Self::collection_admins_limit(),
+ <Error<T>>::CollectionAdminAmountExceeded,
+ );
+
+ // =========
+
+ <AdminAmount<T>>::insert(collection.id, amount);
+ <IsAdmin<T>>::insert((collection.id, user), true);
} else {
- <Allowlist<T>>::remove((collection.id, user.as_sub()));
+ <AdminAmount<T>>::insert(collection.id, amount.saturating_sub(1));
+ <IsAdmin<T>>::remove((collection.id, user));
}
Ok(())
pallets/nft/src/lib.rsdiffbeforeafterboth36use sp_runtime::{sp_std::prelude::Vec};36use sp_runtime::{sp_std::prelude::Vec};37use nft_data_structs::{37use nft_data_structs::{38 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, CUSTOM_DATA_LIMIT,38 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, CUSTOM_DATA_LIMIT,39 VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, COLLECTION_ADMINS_LIMIT,39 VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, OFFCHAIN_SCHEMA_LIMIT,40 OFFCHAIN_SCHEMA_LIMIT, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,40 FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,41 NFT_SPONSOR_TRANSFER_TIMEOUT, AccessMode, Collection, CreateItemData, CollectionLimits,41 NFT_SPONSOR_TRANSFER_TIMEOUT, AccessMode, Collection, CreateItemData, CollectionLimits,42 CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,42 CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,156 where156 where157 origin: T::Origin157 origin: T::Origin158 {158 {159 const CollectionAdminsLimit: u64 = COLLECTION_ADMINS_LIMIT;160 type Error = Error<T>;159 type Error = Error<T>;161160162 fn on_initialize(_now: T::BlockNumber) -> Weight {161 fn on_initialize(_now: T::BlockNumber) -> Weight {408 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);407 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);409410 let collection = <CollectionHandle<T>>::try_get(collection_id)?;408 let collection = <CollectionHandle<T>>::try_get(collection_id)?;411 collection.check_is_owner_or_admin(&sender)?;412409413 <IsAdmin<T>>::insert((collection_id, new_admin_id.as_sub()), true);410 <PalletCommon<T>>::toggle_admin(&collection, &sender, &new_admin_id, true)414 Ok(())415 }411 }416412417 /// 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.413 /// 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.432 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);428 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);433434 let collection = <CollectionHandle<T>>::try_get(collection_id)?;429 let collection = <CollectionHandle<T>>::try_get(collection_id)?;435 collection.check_is_owner_or_admin(&sender)?;436430437 <IsAdmin<T>>::remove((collection_id, account_id.as_sub()));431 <PalletCommon<T>>::toggle_admin(&collection, &sender, &account_id, false)438 Ok(())439 }432 }440433441 /// # Permissions434 /// # Permissionsprimitives/nft/src/lib.rsdiffbeforeafterboth--- a/primitives/nft/src/lib.rs
+++ b/primitives/nft/src/lib.rs
@@ -41,7 +41,7 @@
} else {
10
};
-pub const COLLECTION_ADMINS_LIMIT: u64 = 5;
+pub const COLLECTION_ADMINS_LIMIT: u32 = 5;
pub const COLLECTION_TOKEN_LIMIT: u32 = u32::MAX;
pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {
1000000