git.delta.rocks / unique-network / refs/commits / ae0e886a6664

difftreelog

feat track and limit admin amount

Yaroslav Bolyukin2021-11-04parent: #98884c8.patch.diff
in: master

3 files changed

modifiedpallets/common/src/lib.rsdiffbeforeafterboth
11use nft_data_structs::{11use nft_data_structs::{
12 COLLECTION_NUMBER_LIMIT, Collection, CollectionId, CreateItemData, ExistenceRequirement,12 COLLECTION_NUMBER_LIMIT, Collection, CollectionId, CreateItemData, ExistenceRequirement,
13 MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_COLLECTION_NAME_LENGTH, MAX_TOKEN_PREFIX_LENGTH,13 MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_COLLECTION_NAME_LENGTH, MAX_TOKEN_PREFIX_LENGTH,
14 MetaUpdatePermission, Pays, PostDispatchInfo, TokenId, Weight, WithdrawReasons,14 COLLECTION_ADMINS_LIMIT, MetaUpdatePermission, Pays, PostDispatchInfo, TokenId, Weight,
15 WithdrawReasons,
15};16};
16pub use pallet::*;17pub use pallet::*;
165 #[pallet::generate_store(pub(super) trait Store)]166 #[pallet::generate_store(pub(super) trait Store)]
166 pub struct Pallet<T>(_);167 pub struct Pallet<T>(_);
168
169 #[pallet::extra_constants]
170 impl<T: Config> Pallet<T> {
171 pub fn collection_admins_limit() -> u32 {
172 COLLECTION_ADMINS_LIMIT
173 }
174 }
167175
168 #[pallet::event]176 #[pallet::event]
169 #[pallet::generate_deposit(pub fn deposit_event)]177 #[pallet::generate_deposit(pub fn deposit_event)]
265 TotalCollectionsLimitExceeded,273 TotalCollectionsLimitExceeded,
266 /// variable_data exceeded data limit.274 /// variable_data exceeded data limit.
267 TokenVariableDataLimitExceeded,275 TokenVariableDataLimitExceeded,
276 /// Exceeded max admin amount
277 CollectionAdminAmountExceeded,
268278
269 /// Collection settings not allowing items transferring279 /// Collection settings not allowing items transferring
270 TransferNotAllowed,280 TransferNotAllowed,
305 QueryKind = OptionQuery,315 QueryKind = OptionQuery,
306 >;316 >;
317
318 #[pallet::storage]
319 pub type AdminAmount<T> = StorageMap<
320 Hasher = Blake2_128Concat,
321 Key = CollectionId,
322 Value = u32,
323 QueryKind = ValueQuery,
324 >;
307325
308 /// List of collection admins326 /// List of collection admins
309 #[pallet::storage]327 #[pallet::storage]
419437
420 <DestroyedCollectionCount<T>>::put(destroyed_collections);438 <DestroyedCollectionCount<T>>::put(destroyed_collections);
421 <CollectionById<T>>::remove(collection.id);439 <CollectionById<T>>::remove(collection.id);
440 <AdminAmount<T>>::remove(collection.id);
422 <IsAdmin<T>>::remove_prefix((collection.id,), None);441 <IsAdmin<T>>::remove_prefix((collection.id,), None);
423 <Allowlist<T>>::remove_prefix((collection.id,), None);442 <Allowlist<T>>::remove_prefix((collection.id,), None);
424 Ok(())443 Ok(())
435 // =========454 // =========
436455
437 if allowed {456 if allowed {
438 <Allowlist<T>>::insert((collection.id, user.as_sub()), true);457 <Allowlist<T>>::insert((collection.id, user), true);
439 } else {458 } else {
440 <Allowlist<T>>::remove((collection.id, user.as_sub()));459 <Allowlist<T>>::remove((collection.id, user));
441 }460 }
442461
443 Ok(())462 Ok(())
444 }463 }
464
465 pub fn toggle_admin(
466 collection: &CollectionHandle<T>,
467 sender: &T::CrossAccountId,
468 user: &T::CrossAccountId,
469 admin: bool,
470 ) -> DispatchResult {
471 collection.check_is_owner_or_admin(&sender)?;
472
473 let was_admin = <IsAdmin<T>>::get((collection.id, user));
474 if was_admin == admin {
475 return Ok(());
476 }
477 let amount = <AdminAmount<T>>::get(collection.id);
478
479 if admin {
480 let amount = amount
481 .checked_add(1)
482 .ok_or(<Error<T>>::CollectionAdminAmountExceeded)?;
483 ensure!(
484 amount <= Self::collection_admins_limit(),
485 <Error<T>>::CollectionAdminAmountExceeded,
486 );
487
488 // =========
489
490 <AdminAmount<T>>::insert(collection.id, amount);
491 <IsAdmin<T>>::insert((collection.id, user), true);
492 } else {
493 <AdminAmount<T>>::insert(collection.id, amount.saturating_sub(1));
494 <IsAdmin<T>>::remove((collection.id, user));
495 }
496
497 Ok(())
498 }
445}499}
446500
447#[macro_export]501#[macro_export]
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
36use 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 where
157 origin: T::Origin157 origin: T::Origin
158 {158 {
159 const CollectionAdminsLimit: u64 = COLLECTION_ADMINS_LIMIT;
160 type Error = Error<T>;159 type Error = Error<T>;
161160
162 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)?);
409
410 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)?;
412409
413 <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 }
416412
417 /// 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)?);
433
434 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)?;
436430
437 <IsAdmin<T>>::remove((collection_id, account_id.as_sub()));431 <PalletCommon<T>>::toggle_admin(&collection, &sender, &account_id, false)
438 Ok(())
439 }432 }
440433
441 /// # Permissions434 /// # Permissions
modifiedprimitives/nft/src/lib.rsdiffbeforeafterboth
41} else {41} else {
42 1042 10
43};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