Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 7d8e5a1

Browse files
SzegooSergej Sakačggwpez
authored
Auto-incremental CollectionId (#11796)
* autoincrementing CollectionId * fix * benchmarking fix * fmt * fix * update before checking * fmt * fix * fmt * commit * tests & fix * fix * commit * docs * safe math * unexpose function * benchmark * fmt * better naming * fix? * merge fixes * fmt * ".git/.scripts/bench-bot.sh" pallet dev pallet_uniques * wrong weight * Update frame/uniques/src/lib.rs Co-authored-by: Oliver Tale-Yazdi <[email protected]> * Update frame/uniques/src/lib.rs Co-authored-by: Oliver Tale-Yazdi <[email protected]> * using substrate trait instead of num-traits * remove unnecessary trait * emit NextCollectionIdIncremented in do_create_collection * fix in benchmarks * check for event & group import * docs Co-authored-by: Sergej Sakač <[email protected]> Co-authored-by: command-bot <> Co-authored-by: Oliver Tale-Yazdi <[email protected]>
1 parent 986fab5 commit 7d8e5a1

File tree

6 files changed

+233
-117
lines changed

6 files changed

+233
-117
lines changed

Cargo.lock

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frame/uniques/src/benchmarking.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,10 @@ fn create_collection<T: Config<I>, I: 'static>(
4242
let caller_lookup = T::Lookup::unlookup(caller.clone());
4343
let collection = T::Helper::collection(0);
4444
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
45-
assert!(Uniques::<T, I>::force_create(
46-
SystemOrigin::Root.into(),
47-
collection,
48-
caller_lookup.clone(),
49-
false,
50-
)
51-
.is_ok());
45+
assert!(
46+
Uniques::<T, I>::force_create(SystemOrigin::Root.into(), caller_lookup.clone(), false,)
47+
.is_ok()
48+
);
5249
(collection, caller, caller_lookup)
5350
}
5451

@@ -143,7 +140,7 @@ benchmarks_instance_pallet! {
143140
whitelist_account!(caller);
144141
let admin = T::Lookup::unlookup(caller.clone());
145142
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
146-
let call = Call::<T, I>::create { collection, admin };
143+
let call = Call::<T, I>::create { admin };
147144
}: { call.dispatch_bypass_filter(origin)? }
148145
verify {
149146
assert_last_event::<T, I>(Event::Created { collection: T::Helper::collection(0), creator: caller.clone(), owner: caller }.into());
@@ -152,7 +149,7 @@ benchmarks_instance_pallet! {
152149
force_create {
153150
let caller: T::AccountId = whitelisted_caller();
154151
let caller_lookup = T::Lookup::unlookup(caller.clone());
155-
}: _(SystemOrigin::Root, T::Helper::collection(0), caller_lookup, true)
152+
}: _(SystemOrigin::Root, caller_lookup, true)
156153
verify {
157154
assert_last_event::<T, I>(Event::ForceCreated { collection: T::Helper::collection(0), owner: caller }.into());
158155
}
@@ -408,6 +405,16 @@ benchmarks_instance_pallet! {
408405
}.into());
409406
}
410407

408+
try_increment_id {
409+
let (_, caller, _) = create_collection::<T, I>();
410+
Uniques::<T, I>::set_next_id(0);
411+
}: _(SystemOrigin::Signed(caller.clone()))
412+
verify {
413+
assert_last_event::<T, I>(Event::NextCollectionIdIncremented {
414+
next_id: 1u32.into()
415+
}.into());
416+
}
417+
411418
set_price {
412419
let (collection, caller, _) = create_collection::<T, I>();
413420
let (item, ..) = mint_item::<T, I>(0);

frame/uniques/src/functions.rs

+15
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,12 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
8888
},
8989
);
9090

91+
let next_id = collection.saturating_add(1u32.into());
92+
9193
CollectionAccount::<T, I>::insert(&owner, &collection, ());
94+
NextCollectionId::<T, I>::set(next_id);
95+
96+
Self::deposit_event(Event::NextCollectionIdIncremented { next_id });
9297
Self::deposit_event(event);
9398
Ok(())
9499
}
@@ -208,6 +213,16 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
208213
Ok(())
209214
}
210215

216+
#[cfg(any(test, feature = "runtime-benchmarks"))]
217+
pub fn set_next_id(count: u32) {
218+
NextCollectionId::<T, I>::set(count.into());
219+
}
220+
221+
#[cfg(test)]
222+
pub fn get_next_id() -> T::CollectionId {
223+
NextCollectionId::<T, I>::get()
224+
}
225+
211226
pub fn do_set_price(
212227
collection: T::CollectionId,
213228
item: T::ItemId,

frame/uniques/src/lib.rs

+48-6
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use frame_support::{
5151
};
5252
use frame_system::Config as SystemConfig;
5353
use sp_runtime::{
54-
traits::{Saturating, StaticLookup, Zero},
54+
traits::{AtLeast32BitUnsigned, Saturating, StaticLookup, Zero},
5555
ArithmeticError, RuntimeDebug,
5656
};
5757
use sp_std::prelude::*;
@@ -92,7 +92,12 @@ pub mod pallet {
9292
type Event: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::Event>;
9393

9494
/// Identifier for the collection of item.
95-
type CollectionId: Member + Parameter + MaxEncodedLen + Copy;
95+
type CollectionId: Member
96+
+ Parameter
97+
+ MaxEncodedLen
98+
+ Copy
99+
+ Default
100+
+ AtLeast32BitUnsigned;
96101

97102
/// The type used to identify a unique item within a collection.
98103
type ItemId: Member + Parameter + MaxEncodedLen + Copy;
@@ -266,6 +271,12 @@ pub mod pallet {
266271
pub(super) type CollectionMaxSupply<T: Config<I>, I: 'static = ()> =
267272
StorageMap<_, Blake2_128Concat, T::CollectionId, u32, OptionQuery>;
268273

274+
#[pallet::storage]
275+
/// Stores the `CollectionId` that is going to be used for the next collection.
276+
/// This gets incremented by 1 whenever a new collection is created.
277+
pub(super) type NextCollectionId<T: Config<I>, I: 'static = ()> =
278+
StorageValue<_, T::CollectionId, ValueQuery>;
279+
269280
#[pallet::event]
270281
#[pallet::generate_deposit(pub(super) fn deposit_event)]
271282
pub enum Event<T: Config<I>, I: 'static = ()> {
@@ -357,6 +368,8 @@ pub mod pallet {
357368
OwnershipAcceptanceChanged { who: T::AccountId, maybe_collection: Option<T::CollectionId> },
358369
/// Max supply has been set for a collection.
359370
CollectionMaxSupplySet { collection: T::CollectionId, max_supply: u32 },
371+
/// Event gets emmited when the `NextCollectionId` gets incremented.
372+
NextCollectionIdIncremented { next_id: T::CollectionId },
360373
/// The price was set for the instance.
361374
ItemPriceSet {
362375
collection: T::CollectionId,
@@ -408,6 +421,10 @@ pub mod pallet {
408421
MaxSupplyAlreadySet,
409422
/// The provided max supply is less to the amount of items a collection already has.
410423
MaxSupplyTooSmall,
424+
/// The `CollectionId` in `NextCollectionId` is not being used.
425+
///
426+
/// This means that you can directly proceed to call `create`.
427+
NextIdNotUsed,
411428
/// The given item ID is unknown.
412429
UnknownItem,
413430
/// Item is not for sale.
@@ -439,7 +456,6 @@ pub mod pallet {
439456
/// `ItemDeposit` funds of sender are reserved.
440457
///
441458
/// Parameters:
442-
/// - `collection`: The identifier of the new collection. This must not be currently in use.
443459
/// - `admin`: The admin of this collection. The admin is the initial address of each
444460
/// member of the collection's admin team.
445461
///
@@ -449,9 +465,10 @@ pub mod pallet {
449465
#[pallet::weight(T::WeightInfo::create())]
450466
pub fn create(
451467
origin: OriginFor<T>,
452-
collection: T::CollectionId,
453468
admin: <T::Lookup as StaticLookup>::Source,
454469
) -> DispatchResult {
470+
let collection = NextCollectionId::<T, I>::get();
471+
455472
let owner = T::CreateOrigin::ensure_origin(origin, &collection)?;
456473
let admin = T::Lookup::lookup(admin)?;
457474

@@ -473,7 +490,6 @@ pub mod pallet {
473490
///
474491
/// Unlike `create`, no funds are reserved.
475492
///
476-
/// - `collection`: The identifier of the new item. This must not be currently in use.
477493
/// - `owner`: The owner of this collection of items. The owner has full superuser
478494
/// permissions
479495
/// over this item, but may later change and configure the permissions using
@@ -485,13 +501,14 @@ pub mod pallet {
485501
#[pallet::weight(T::WeightInfo::force_create())]
486502
pub fn force_create(
487503
origin: OriginFor<T>,
488-
collection: T::CollectionId,
489504
owner: <T::Lookup as StaticLookup>::Source,
490505
free_holding: bool,
491506
) -> DispatchResult {
492507
T::ForceOrigin::ensure_origin(origin)?;
493508
let owner = T::Lookup::lookup(owner)?;
494509

510+
let collection = NextCollectionId::<T, I>::get();
511+
495512
Self::do_create_collection(
496513
collection,
497514
owner.clone(),
@@ -502,6 +519,31 @@ pub mod pallet {
502519
)
503520
}
504521

522+
/// Increments the `CollectionId` stored in `NextCollectionId`.
523+
///
524+
/// This is only callable when the next `CollectionId` is already being
525+
/// used for some other collection.
526+
///
527+
/// The origin must be Signed and the sender must have sufficient funds
528+
/// free.
529+
///
530+
/// Emits `NextCollectionIdIncremented` event when successful.
531+
///
532+
/// Weight: `O(1)`
533+
#[pallet::weight(T::WeightInfo::try_increment_id())]
534+
pub fn try_increment_id(origin: OriginFor<T>) -> DispatchResult {
535+
ensure_signed(origin)?;
536+
ensure!(
537+
Collection::<T, I>::contains_key(NextCollectionId::<T, I>::get()),
538+
Error::<T, I>::NextIdNotUsed
539+
);
540+
541+
let next_id = NextCollectionId::<T, I>::get().saturating_add(1u32.into());
542+
NextCollectionId::<T, I>::set(next_id);
543+
Self::deposit_event(Event::NextCollectionIdIncremented { next_id });
544+
Ok(())
545+
}
546+
505547
/// Destroy a collection of fungible items.
506548
///
507549
/// The origin must conform to `ForceOrigin` or must be `Signed` and the sender must be the

0 commit comments

Comments
 (0)