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.rsdiffbeforeafterboth--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -36,8 +36,8 @@
use sp_runtime::{sp_std::prelude::Vec};
use nft_data_structs::{
MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, CUSTOM_DATA_LIMIT,
- VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, COLLECTION_ADMINS_LIMIT,
- OFFCHAIN_SCHEMA_LIMIT, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+ VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, OFFCHAIN_SCHEMA_LIMIT,
+ FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
NFT_SPONSOR_TRANSFER_TIMEOUT, AccessMode, Collection, CreateItemData, CollectionLimits,
CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,
};
@@ -156,7 +156,6 @@
where
origin: T::Origin
{
- const CollectionAdminsLimit: u64 = COLLECTION_ADMINS_LIMIT;
type Error = Error<T>;
fn on_initialize(_now: T::BlockNumber) -> Weight {
@@ -406,12 +405,9 @@
#[transactional]
pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::CrossAccountId) -> DispatchResult {
let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
-
let collection = <CollectionHandle<T>>::try_get(collection_id)?;
- collection.check_is_owner_or_admin(&sender)?;
- <IsAdmin<T>>::insert((collection_id, new_admin_id.as_sub()), true);
- Ok(())
+ <PalletCommon<T>>::toggle_admin(&collection, &sender, &new_admin_id, true)
}
/// 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.
@@ -430,12 +426,9 @@
#[transactional]
pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::CrossAccountId) -> DispatchResult {
let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
-
let collection = <CollectionHandle<T>>::try_get(collection_id)?;
- collection.check_is_owner_or_admin(&sender)?;
- <IsAdmin<T>>::remove((collection_id, account_id.as_sub()));
- Ok(())
+ <PalletCommon<T>>::toggle_admin(&collection, &sender, &account_id, false)
}
/// # Permissions
primitives/nft/src/lib.rsdiffbeforeafterboth41} else {41} else {42 1042 1043};43};44pub const COLLECTION_ADMINS_LIMIT: u64 = 5;44pub const COLLECTION_ADMINS_LIMIT: u32 = 5;45pub const COLLECTION_TOKEN_LIMIT: u32 = u32::MAX;45pub const COLLECTION_TOKEN_LIMIT: u32 = u32::MAX;46pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {46pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {47 100000047 1000000