Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Communities Manager] Call to Create Memberships #389

Merged
merged 9 commits into from
May 8, 2024
35 changes: 35 additions & 0 deletions pallets/communities-manager/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use frame_benchmarking::v2::*;

use frame_support::traits::fungible::Mutate;
use frame_system::RawOrigin;
use sp_runtime::SaturatedConversion;

type RuntimeEventFor<T> = <T as Config>::RuntimeEvent;

Expand All @@ -27,6 +28,7 @@ where
NativeBalanceOf<T>: From<u128>,
BlockNumberFor<T>: From<u32>,
CommunityIdOf<T>: From<u16>,
<T as Config>::MembershipId: From<u32>,
)]
mod benchmarks {
use super::*;
Expand Down Expand Up @@ -56,6 +58,39 @@ mod benchmarks {
Ok(())
}

#[benchmark]
fn create_memberships(q: Linear<1, 1024>) -> Result<(), BenchmarkError> {
// setup code
T::CreateCollection::create_collection_with_id(
T::MembershipsManagerCollectionId::get(),
&T::MembershipsManagerOwner::get(),
&T::MembershipsManagerOwner::get(),
&pallet_nfts::CollectionConfig {
settings: Default::default(),
max_supply: None,
mint_settings: Default::default(),
},
)?;

#[extrinsic_call]
_(
RawOrigin::Root,
q.saturated_into(),
100u32.into(),
300_000_000_000u128.into(),
);

// verification code
assert_has_event::<T>(
Event::<T>::MembershipsCreated {
starting_at: 100u32.into(),
amount: q.saturated_into(),
}
.into(),
);
Ok(())
}

impl_benchmark_test_suite!(
Pallet,
sp_io::TestExternalities::new(Default::default()),
Expand Down
86 changes: 80 additions & 6 deletions pallets/communities-manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,27 @@ pub use weights::*;
use fc_traits_tracks::MutateTracks;
use frame_support::{
pallet_prelude::*,
traits::{nonfungibles_v2::Create, OriginTrait, RankedMembers},
traits::{
nonfungibles_v2::Mutate as ItemMutate,
nonfungibles_v2::{Create as CollectionCreate, Trading},
Incrementable, OriginTrait, RankedMembers,
},
};
use frame_system::pallet_prelude::{BlockNumberFor, OriginFor};
use pallet_communities::{
types::{AccountIdOf, CommunityIdOf, DecisionMethodFor, NativeBalanceOf, PalletsOriginOf, RuntimeOriginFor},
Origin as CommunityOrigin,
};
use pallet_nfts::CollectionConfig;
use pallet_nfts::{CollectionConfig, ItemConfig};
use pallet_referenda::{TrackInfo, TracksInfo};
use parity_scale_codec::Decode;
use sp_runtime::{str_array, traits::Get};

type TrackInfoOf<T> = TrackInfo<NativeBalanceOf<T>, BlockNumberFor<T>>;

#[frame_support::pallet]
pub mod pallet {
use sp_runtime::str_array;
use parity_scale_codec::HasCompact;

use super::*;

Expand All @@ -44,7 +50,7 @@ pub mod pallet {
/// definition of an event.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

type CreateCollection: Create<
type CreateCollection: CollectionCreate<
AccountIdOf<Self>,
CollectionConfig<NativeBalanceOf<Self>, BlockNumberFor<Self>, CommunityIdOf<Self>>,
CollectionId = CommunityIdOf<Self>,
Expand All @@ -63,8 +69,25 @@ pub mod pallet {
/// Type representing the weight of this pallet
type WeightInfo: WeightInfo;

// #[cfg(feature = "runtime-benchmarks")]
// type BenchmarkHelper: BenchmarkHelper<Self>;
type CreateMembershipsOrigin: EnsureOrigin<OriginFor<Self>>;

type MembershipId: Parameter + Decode + Incrementable + HasCompact;

type MembershipsManagerCollectionId: Get<CommunityIdOf<Self>>;

type MembershipsManagerOwner: Get<AccountIdOf<Self>>;

type CreateMemberships: ItemMutate<
AccountIdOf<Self>,
ItemConfig = ItemConfig,
CollectionId = CommunityIdOf<Self>,
ItemId = <Self as Config>::MembershipId,
> + Trading<
AccountIdOf<Self>,
NativeBalanceOf<Self>,
CollectionId = CommunityIdOf<Self>,
ItemId = <Self as Config>::MembershipId,
>;
}

#[pallet::pallet]
Expand All @@ -78,6 +101,11 @@ pub mod pallet {
/// The community with [`CommmunityId`](pallet_communities::CommunityId)
/// has been created.
CommunityRegistered { id: T::CommunityId },
/// The
MembershipsCreated {
starting_at: <T as Config>::MembershipId,
amount: u32,
},
}

// Errors inform users that something worked or went wrong.
Expand All @@ -87,6 +115,8 @@ pub mod pallet {
InvalidCommunityName,
/// It was not possible to register the community
CannotRegister,
/// The amount of memberships to create exceeds the limit of 1024
CreatingTooManyMemberships,
}

// Dispatchable functions allows users to interact with the pallet and invoke
Expand Down Expand Up @@ -147,6 +177,50 @@ pub mod pallet {
Self::deposit_event(Event::<T>::CommunityRegistered { id: community_id });
Ok(())
}

#[pallet::weight(<T as Config>::WeightInfo::create_memberships(*amount))]
#[pallet::call_index(1)]
pub fn create_memberships(
origin: OriginFor<T>,
amount: u16,
starting_at: <T as Config>::MembershipId,
#[pallet::compact] price: NativeBalanceOf<T>,
) -> DispatchResult {
ensure!(amount <= 1024u16, Error::<T>::CreatingTooManyMemberships);
T::CreateMembershipsOrigin::ensure_origin(origin)?;

let mut id = starting_at.clone();
let mut minted = 0u32;
for _ in 0..amount {
T::CreateMemberships::mint_into(
&T::MembershipsManagerCollectionId::get(),
&id,
&T::MembershipsManagerOwner::get(),
&Default::default(),
true,
)?;

T::CreateMemberships::set_price(
&T::MembershipsManagerCollectionId::get(),
&id,
&T::MembershipsManagerOwner::get(),
Some(price),
None,
)?;
if let Some(next_id) = id.increment() {
id = next_id;
minted += 1;
} else {
break;
}
}

Self::deposit_event(Event::<T>::MembershipsCreated {
starting_at,
amount: minted,
});
Ok(())
}
}

impl<T: Config> Pallet<T> {
Expand Down
9 changes: 9 additions & 0 deletions pallets/communities-manager/src/mock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,18 @@ impl pallet_communities::Config for Test {

impl Config for Test {
type RuntimeEvent = RuntimeEvent;
// Types to support community creation
type CreateCollection = Memberships;
type Tracks = Tracks;
type RankedCollective = Collective;
// Types to support memberships creation
type CreateMembershipsOrigin = EnsureRoot<AccountId>;
type MembershipId = MembershipId;

type MembershipsManagerCollectionId = MembershipsManagerCollectionId;
type MembershipsManagerOwner = RootAccount;
type CreateMemberships = Memberships;

type WeightInfo = WeightInfo;
}

Expand Down
23 changes: 23 additions & 0 deletions pallets/communities-manager/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use core::marker::PhantomData;
/// Weight functions needed for pallet_communities.
pub trait WeightInfo {
fn register() -> Weight;
fn create_memberships(q: u16, ) -> Weight;
}

/// Weights for pallet_communities using the Substrate node and recommended hardware.
Expand Down Expand Up @@ -51,6 +52,17 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
.saturating_add(T::DbWeight::get().reads(7))
.saturating_add(T::DbWeight::get().writes(14))
}

fn create_memberships(_: u16, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `278`
// Estimated: `132561`
// Minimum execution time: 117_045_000 picoseconds.
Weight::from_parts(166_053_000, 0)
.saturating_add(Weight::from_parts(0, 132561))
.saturating_add(T::DbWeight::get().reads(7))
.saturating_add(T::DbWeight::get().writes(14))
}
}

impl WeightInfo for () {
Expand Down Expand Up @@ -92,4 +104,15 @@ impl WeightInfo for () {
.saturating_add(RocksDbWeight::get().reads(7))
.saturating_add(RocksDbWeight::get().writes(14))
}

fn create_memberships(_: u16, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `278`
// Estimated: `132561`
// Minimum execution time: 117_045_000 picoseconds.
Weight::from_parts(166_053_000, 0)
.saturating_add(Weight::from_parts(0, 132561))
.saturating_add(RocksDbWeight::get().reads(7))
.saturating_add(RocksDbWeight::get().writes(14))
}
}
12 changes: 10 additions & 2 deletions runtime/kreivo/src/communities/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use self::{
#[cfg(feature = "runtime-benchmarks")]
use {
frame_benchmarking::BenchmarkError,
frame_support::traits::{schedule::DispatchTime, tokens::nonfungible_v2::ItemOf, tokens::nonfungible_v2::Mutate},
frame_support::traits::{schedule::DispatchTime, tokens::nonfungible_v2::Mutate},
frame_system::pallet_prelude::{OriginFor, RuntimeCallFor},
pallet_communities::{
types::{CommunityIdOf, MembershipIdOf, PalletsOriginOf, PollIndexOf},
Expand Down Expand Up @@ -79,11 +79,19 @@ impl pallet_communities_manager::Config for Runtime {
type CreateCollection = CommunityMemberships;
type Tracks = CommunityTracks;
type RankedCollective = KreivoCollective;

type CreateMembershipsOrigin = EnsureRoot<AccountId>;
type MembershipId = MembershipId;
type MembershipsManagerOwner = TreasuryAccount;
type MembershipsManagerCollectionId = MembershipsCollectionId;
type CreateMemberships = CommunityMemberships;

type WeightInfo = crate::weights::pallet_communities_manager::WeightInfo<Self>;
}

#[cfg(feature = "runtime-benchmarks")]
type MembershipCollection = ItemOf<CommunityMemberships, MembershipsCollectionId, AccountId>;
type MembershipCollection =
frame_support::traits::nonfungible_v2::ItemOf<CommunityMemberships, MembershipsCollectionId, AccountId>;

#[cfg(feature = "runtime-benchmarks")]
pub struct CommunityBenchmarkHelper;
Expand Down
11 changes: 11 additions & 0 deletions runtime/kreivo/src/weights/pallet_communities_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,15 @@ impl<T: frame_system::Config> pallet_communities_manager::WeightInfo for WeightI
.saturating_add(T::DbWeight::get().reads(7))
.saturating_add(T::DbWeight::get().writes(14))
}

fn create_memberships(_: u16, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `278`
// Estimated: `132561`
// Minimum execution time: 172_690_000 picoseconds.
Weight::from_parts(178_773_000, 0)
.saturating_add(Weight::from_parts(0, 132561))
.saturating_add(T::DbWeight::get().reads(7))
.saturating_add(T::DbWeight::get().writes(14))
}
}