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

Nfts: Fix Auto-Increment #12223

Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions bin/node/runtime/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use frame_support::{
};
use pallet_alliance::{IdentityVerifier, ProposalIndex, ProposalProvider};
use pallet_asset_tx_payment::HandleCredit;
use pallet_nfts::Incrementable;
use sp_std::prelude::*;

pub struct Author;
Expand Down Expand Up @@ -114,6 +115,21 @@ impl ProposalProvider<AccountId, Hash, Call> for AllianceProposalProvider {
}
}

#[derive(Default, Clone, Debug, TypeInfo, Encode, Decode, Copy, MaxEncodedLen, PartialEq, Eq)]
pub struct CollectionId(u32);
impl Incrementable for CollectionId {
fn increment(&self) -> Self {
CollectionId(self.0.saturating_add(1))
}
}

#[cfg(feature = "runtime-benchmarks")]
impl From<u32> for CollectionId {
fn from(id: u32) -> Self {
CollectionId(id)
}
}

#[cfg(test)]
mod multiplier_tests {
use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment};
Expand Down
4 changes: 2 additions & 2 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub use sp_runtime::BuildStorage;
pub mod impls;
#[cfg(not(feature = "runtime-benchmarks"))]
use impls::AllianceIdentityVerifier;
use impls::{AllianceProposalProvider, Author, CreditToBlockAuthor};
use impls::{AllianceProposalProvider, Author, CollectionId, CreditToBlockAuthor};

/// Constant values used within the runtime.
pub mod constants;
Expand Down Expand Up @@ -1478,7 +1478,7 @@ impl pallet_uniques::Config for Runtime {

impl pallet_nfts::Config for Runtime {
type Event = Event;
type CollectionId = u32;
type CollectionId = CollectionId;
type ItemId = u32;
type Currency = Balances;
type ForceOrigin = frame_system::EnsureRoot<AccountId>;
Expand Down
13 changes: 4 additions & 9 deletions frame/nfts/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,8 @@ fn create_collection<T: Config<I>, I: 'static>(
let caller_lookup = T::Lookup::unlookup(caller.clone());
let collection = T::Helper::collection(0);
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
assert!(Nfts::<T, I>::force_create(
SystemOrigin::Root.into(),
collection,
caller_lookup.clone(),
false,
)
.is_ok());
assert!(Nfts::<T, I>::force_create(SystemOrigin::Root.into(), caller_lookup.clone(), false,)
.is_ok());
(collection, caller, caller_lookup)
}

Expand Down Expand Up @@ -142,7 +137,7 @@ benchmarks_instance_pallet! {
whitelist_account!(caller);
let admin = T::Lookup::unlookup(caller.clone());
T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
let call = Call::<T, I>::create { collection, admin };
let call = Call::<T, I>::create { admin };
}: { call.dispatch_bypass_filter(origin)? }
verify {
assert_last_event::<T, I>(Event::Created { collection: T::Helper::collection(0), creator: caller.clone(), owner: caller }.into());
Expand All @@ -151,7 +146,7 @@ benchmarks_instance_pallet! {
force_create {
let caller: T::AccountId = whitelisted_caller();
let caller_lookup = T::Lookup::unlookup(caller.clone());
}: _(SystemOrigin::Root, T::Helper::collection(0), caller_lookup, true)
}: _(SystemOrigin::Root, caller_lookup, true)
verify {
assert_last_event::<T, I>(Event::ForceCreated { collection: T::Helper::collection(0), owner: caller }.into());
}
Expand Down
15 changes: 15 additions & 0 deletions frame/nfts/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,12 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
},
);

let next_id = collection.increment();

CollectionAccount::<T, I>::insert(&owner, &collection, ());
NextCollectionId::<T, I>::set(next_id);

Self::deposit_event(Event::NextCollectionIdIncremented { next_id });
Self::deposit_event(event);
Ok(())
}
Expand Down Expand Up @@ -273,4 +278,14 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {

Ok(())
}

#[cfg(any(test, feature = "runtime-benchmarks"))]
pub fn set_next_id(id: T::CollectionId) {
NextCollectionId::<T, I>::set(id);
}

#[cfg(test)]
pub fn get_next_id() -> T::CollectionId {
NextCollectionId::<T, I>::get()
}
}
37 changes: 25 additions & 12 deletions frame/nfts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ pub use weights::WeightInfo;

type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;

pub trait Incrementable {
fn increment(&self) -> Self;
}

#[frame_support::pallet]
pub mod pallet {
use super::*;
Expand All @@ -73,12 +77,12 @@ pub mod pallet {

#[cfg(feature = "runtime-benchmarks")]
pub trait BenchmarkHelper<CollectionId, ItemId> {
fn collection(i: u16) -> CollectionId;
fn collection(i: u32) -> CollectionId;
fn item(i: u16) -> ItemId;
}
#[cfg(feature = "runtime-benchmarks")]
impl<CollectionId: From<u16>, ItemId: From<u16>> BenchmarkHelper<CollectionId, ItemId> for () {
fn collection(i: u16) -> CollectionId {
impl<CollectionId: From<u32>, ItemId: From<u16>> BenchmarkHelper<CollectionId, ItemId> for () {
fn collection(i: u32) -> CollectionId {
i.into()
}
fn item(i: u16) -> ItemId {
Expand All @@ -93,7 +97,7 @@ pub mod pallet {
type Event: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::Event>;

/// Identifier for the collection of item.
type CollectionId: Member + Parameter + MaxEncodedLen + Copy;
type CollectionId: Member + Parameter + MaxEncodedLen + Copy + Default + Incrementable;
Szegoo marked this conversation as resolved.
Show resolved Hide resolved

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

#[pallet::storage]
/// Stores the `CollectionId` that is going to be used for the next collection.
/// This gets incremented by 1 whenever a new collection is created.
pub(super) type NextCollectionId<T: Config<I>, I: 'static = ()> =
StorageValue<_, T::CollectionId, ValueQuery>;

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config<I>, I: 'static = ()> {
Expand Down Expand Up @@ -358,6 +368,8 @@ pub mod pallet {
OwnershipAcceptanceChanged { who: T::AccountId, maybe_collection: Option<T::CollectionId> },
/// Max supply has been set for a collection.
CollectionMaxSupplySet { collection: T::CollectionId, max_supply: u32 },
/// Event gets emmited when the `NextCollectionId` gets incremented.
NextCollectionIdIncremented { next_id: T::CollectionId },
/// The price was set for the instance.
ItemPriceSet {
collection: T::CollectionId,
Expand Down Expand Up @@ -409,6 +421,10 @@ pub mod pallet {
MaxSupplyAlreadySet,
/// The provided max supply is less to the amount of items a collection already has.
MaxSupplyTooSmall,
/// The `CollectionId` in `NextCollectionId` is not being used.
///
/// This means that you can directly proceed to call `create`.
NextIdNotUsed,
Szegoo marked this conversation as resolved.
Show resolved Hide resolved
/// The given item ID is unknown.
UnknownItem,
/// Item is not for sale.
Expand Down Expand Up @@ -440,19 +456,16 @@ pub mod pallet {
/// `ItemDeposit` funds of sender are reserved.
///
/// Parameters:
/// - `collection`: The identifier of the new collection. This must not be currently in use.
/// - `admin`: The admin of this collection. The admin is the initial address of each
/// member of the collection's admin team.
///
/// Emits `Created` event when successful.
///
/// Weight: `O(1)`
#[pallet::weight(T::WeightInfo::create())]
pub fn create(
origin: OriginFor<T>,
collection: T::CollectionId,
admin: AccountIdLookupOf<T>,
) -> DispatchResult {
pub fn create(origin: OriginFor<T>, admin: AccountIdLookupOf<T>) -> DispatchResult {
let collection = NextCollectionId::<T, I>::get();

let owner = T::CreateOrigin::ensure_origin(origin, &collection)?;
let admin = T::Lookup::lookup(admin)?;

Expand All @@ -474,7 +487,6 @@ pub mod pallet {
///
/// Unlike `create`, no funds are reserved.
///
/// - `collection`: The identifier of the new item. This must not be currently in use.
/// - `owner`: The owner of this collection of items. The owner has full superuser
/// permissions
/// over this item, but may later change and configure the permissions using
Expand All @@ -486,13 +498,14 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::force_create())]
pub fn force_create(
origin: OriginFor<T>,
collection: T::CollectionId,
owner: AccountIdLookupOf<T>,
free_holding: bool,
) -> DispatchResult {
T::ForceOrigin::ensure_origin(origin)?;
let owner = T::Lookup::lookup(owner)?;

let collection = NextCollectionId::<T, I>::get();

Self::do_create_collection(
collection,
owner.clone(),
Expand Down
6 changes: 6 additions & 0 deletions frame/nfts/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ impl pallet_balances::Config for Test {
type ReserveIdentifier = [u8; 8];
}

impl Incrementable for u32 {
fn increment(&self) -> Self {
self.saturating_add(1)
Szegoo marked this conversation as resolved.
Show resolved Hide resolved
}
}

impl Config for Test {
type Event = Event;
type CollectionId = u32;
Expand Down
Loading