Skip to content

Commit

Permalink
feat: Configure Gas Tank for Memberships (#437)
Browse files Browse the repository at this point in the history
* chore(kreivo-runtime): bump version

* chore: bump patch

* chore: update dependencies

* feat(pallet-communities-manager): add `set_gas_tank` and `maybe_tank_config` for memberships being created

* feat(kreivo-runtime): `NonFungiblesGasBurner` -> `NonFungiblesGasTank` / Add `MakeTank` to `pallet_communities_manager`

* feat(kreivo-runtime): Relax `BlockHashChallenger` to accept challenges for blocks up to `P` back in the past.

* fix(kreivo-runtime): missing `set_gas_tank` on `WeightInfo` for `pallet_communities_manager`

* feat(kreivo-runtime): handle transfeerring of memberships base attributes from items in `MembershipsManagementCollection` to items in communities' collections.

* fix: fmt

* fix(kreivo-runtime): resolve non-conflicting errors

* fix(kreivo-runtime): add selector to filter out tanks for memberships that are not expired

* chore(Cargo): update dependencies

* fix(pallet-communities-manager/pallet-communities): replace memberships manager pallet reference with `NonFungiblesMemberships` support structure.

* fix(Cargo): update dependencies (again)

* chore(kreivo-runtime): improve documentation for `BlockHashChallenger`

* feat(kreivo-runtime): configure hooks on `CommunitiesMemberships` to copy certain fields (such as gas and expirations) when a membership is assigned.

* feat(kreivo-runtime): make clippy happy

* fix(Cargo): update dependencies

* fix(kreivo-runtime): make ci happy

* fix(kreivo-runtime): bump version

* fix(pallet-communities-manager): address review changes suggested by @olanod

* make ci happy
  • Loading branch information
pandres95 authored Jan 7, 2025
1 parent ccb3272 commit 9eee9a3
Show file tree
Hide file tree
Showing 18 changed files with 463 additions and 237 deletions.
405 changes: 210 additions & 195 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion chain-spec-generator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ homepage.workspace = true
license.workspace = true
name = "chain-spec-generator"
repository.workspace = true
version = "0.14.2"
version = "0.15.0"

[dependencies]
clap = { workspace = true, features = ["derive"] }
Expand Down
4 changes: 4 additions & 0 deletions pallets/communities-manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ version = "0.1.0"
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
fc-traits-gas-tank.workspace = true
fc-traits-tracks.workspace = true

frame-benchmarking = { workspace = true, optional = true }
Expand All @@ -31,6 +32,7 @@ sp-runtime.workspace = true
sp-std.workspace = true

[dev-dependencies]
fc-traits-memberships.workspace = true
sp-core.workspace = true
sp-io.workspace = true

Expand All @@ -47,6 +49,8 @@ virto-common = { workspace = true, default-features = false, features = [
[features]
default = ["std"]
std = [
"fc-traits-gas-tank/std",
"fc-traits-memberships/std",
"fc-traits-tracks/std",
"frame-benchmarking?/std",
"frame-support/std",
Expand Down
66 changes: 56 additions & 10 deletions pallets/communities-manager/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ use sp_runtime::SaturatedConversion;

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

// Since `periodicity` is arbitrary, we assume `DAYS` is a nominal day for 6s
// block.
const DAYS: u32 = 14_400;

fn block_weight<T: frame_system::Config>() -> Weight {
<T as frame_system::Config>::BlockWeights::get().max_block
}

fn assert_has_event<T: Config>(generic_event: RuntimeEventFor<T>) {
frame_system::Pallet::<T>::assert_has_event(generic_event.into());
}
Expand All @@ -22,6 +30,21 @@ where
Ok(())
}

fn setup_collection<T: Config>() -> Result<(), BenchmarkError> {
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(),
},
)?;

Ok(())
}

#[benchmarks(
where
RuntimeEventFor<T>: From<pallet_communities::Event<T>>,
Expand Down Expand Up @@ -60,23 +83,19 @@ mod benchmarks {
#[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(),
},
)?;
setup_collection::<T>()?;

#[extrinsic_call]
_(
RawOrigin::Root,
q.saturated_into(),
100u32.into(),
300_000_000_000u64.into(),
TankConfig {
capacity: Some(block_weight::<T>()),
periodicity: Some((7 * DAYS).into()),
},
Some(u32::MAX.into()),
);

// verification code
Expand All @@ -90,6 +109,33 @@ mod benchmarks {
Ok(())
}

#[benchmark]
fn set_gas_tank() -> Result<(), BenchmarkError> {
// Setup code
setup_collection::<T>()?;
Pallet::<T>::create_memberships(
RawOrigin::Root.into(),
1,
1u32.into(),
0u64.into(),
TankConfig::default(),
None,
)?;

#[extrinsic_call]
_(
RawOrigin::Root,
T::MembershipsManagerCollectionId::get(),
1u32.into(),
TankConfig {
capacity: Some(block_weight::<T>()),
periodicity: Some((7 * DAYS).into()),
},
);

Ok(())
}

impl_benchmark_test_suite!(
Pallet,
sp_io::TestExternalities::new(Default::default()),
Expand Down
58 changes: 53 additions & 5 deletions pallets/communities-manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod tests;
pub mod weights;
pub use weights::*;

use fc_traits_gas_tank::MakeTank;
use fc_traits_tracks::MutateTracks;
use frame_support::{
pallet_prelude::*,
Expand All @@ -37,11 +38,16 @@ use sp_runtime::{

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

#[derive(Default, Encode, Decode, Clone, PartialEq, Eq, Debug, TypeInfo)]
pub struct TankConfig<Weight, BlockNumber> {
capacity: Option<Weight>,
periodicity: Option<BlockNumber>,
}

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

use super::*;
use parity_scale_codec::HasCompact;

type CommunityName = BoundedVec<u8, ConstU32<25>>;

Expand All @@ -59,6 +65,12 @@ pub mod pallet {
CollectionId = CommunityIdOf<Self>,
>;

type MakeTank: fc_traits_gas_tank::MakeTank<
Gas = Weight,
TankId = (CommunityIdOf<Self>, <Self as Config>::MembershipId),
BlockNumber = BlockNumberFor<Self>,
>;

type Tracks: TracksInfo<NativeBalanceOf<Self>, BlockNumberFor<Self>>
+ MutateTracks<
NativeBalanceOf<Self>,
Expand Down Expand Up @@ -106,7 +118,7 @@ pub mod pallet {
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// The community with [`CommmunityId`](pallet_communities::CommunityId)
/// The community with [`CommunityId`](pallet_communities::CommunityId)
/// has been created.
CommunityRegistered { id: T::CommunityId },
/// The
Expand Down Expand Up @@ -196,21 +208,35 @@ pub mod pallet {
amount: u16,
starting_at: <T as Config>::MembershipId,
#[pallet::compact] price: NativeBalanceOf<T>,
tank_config: TankConfig<Weight, BlockNumberFor<T>>,
maybe_expiration: Option<BlockNumberFor<T>>,
) -> DispatchResult {
ensure!(amount <= 1024u16, Error::<T>::CreatingTooManyMemberships);
T::CreateMembershipsOrigin::ensure_origin(origin)?;
T::CreateMembershipsOrigin::ensure_origin(origin.clone())?;

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

Self::do_set_gas_tank(&(*collection_id, id.clone()), &tank_config)?;

if let Some(expiration) = maybe_expiration {
T::CreateMemberships::set_typed_attribute(
collection_id,
&id,
&b"membership_expiration",
&expiration,
)?;
}

T::CreateMemberships::set_price(
&T::MembershipsManagerCollectionId::get(),
&id,
Expand All @@ -232,9 +258,31 @@ pub mod pallet {
});
Ok(())
}

#[pallet::call_index(2)]
pub fn set_gas_tank(
origin: OriginFor<T>,
community_id: CommunityIdOf<T>,
membership_id: <T as Config>::MembershipId,
config: TankConfig<Weight, BlockNumberFor<T>>,
) -> DispatchResult {
T::CreateMembershipsOrigin::ensure_origin(origin)?;
Self::do_set_gas_tank(&(community_id, membership_id), &config)
}
}

impl<T: Config> Pallet<T> {
#[inline]
pub(crate) fn do_set_gas_tank(
tank_id: &(CommunityIdOf<T>, <T as Config>::MembershipId),
config: &TankConfig<Weight, BlockNumberFor<T>>,
) -> DispatchResult {
let TankConfig { capacity, periodicity } = config;
T::MakeTank::make_tank(tank_id, *capacity, *periodicity)?;

Ok(())
}

fn default_tack(name: &str) -> TrackInfoOf<T> {
use sp_runtime::Perbill;
TrackInfo {
Expand Down
34 changes: 26 additions & 8 deletions pallets/communities-manager/src/mock/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use super::*;

use fc_traits_gas_tank::NonFungibleGasTank;
use fc_traits_memberships::NonFungiblesMemberships;
use frame_support::{
derive_impl, parameter_types,
assert_ok, derive_impl, parameter_types,
traits::{AsEnsureOriginWithArg, ConstU16, ConstU32, ConstU64, EitherOf, EqualPrivilegeOnly, VariantCountOf},
PalletId,
};
Expand All @@ -26,6 +27,7 @@ mod runtime_benchmarks;
use runtime_benchmarks::*;

type Block = frame_system::mocking::MockBlock<Test>;
pub type BlockNumber = BlockNumberFor<Test>;
type WeightInfo = ();

pub type AccountPublic = <MultiSignature as Verify>::Signer;
Expand Down Expand Up @@ -89,7 +91,8 @@ impl frame_system::Config for Test {
type RuntimeEvent = RuntimeEvent;
}

#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig)]
#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig
)]
impl pallet_balances::Config for Test {
type AccountStore = System;
type FreezeIdentifier = RuntimeFreezeReason;
Expand Down Expand Up @@ -192,7 +195,7 @@ impl pallet_nfts::Config for Test {
type OffchainSignature = MultiSignature;
type RuntimeEvent = RuntimeEvent;
type StringLimit = ();
type ValueLimit = ConstU32<10>;
type ValueLimit = ConstU32<40>;
type WeightInfo = ();
#[cfg(feature = "runtime-benchmarks")]
type Helper = ();
Expand All @@ -206,7 +209,7 @@ impl pallet_communities::Config for Test {
type AssetsFreezer = AssetsFreezer;
type Balances = Balances;
type ItemConfig = pallet_nfts::ItemConfig;
type MemberMgmt = Memberships;
type MemberMgmt = NonFungiblesMemberships<Memberships>;
type Polls = Referenda;
type CreateOrigin = EnsureNever<Deposit>;
type AdminOrigin = EnsureCommunity<Self>;
Expand Down Expand Up @@ -234,11 +237,26 @@ impl Config for Test {
type MembershipsManagerCollectionId = MembershipsManagerCollectionId;
type MembershipsManagerOwner = RootAccount;
type CreateMemberships = Memberships;
type MakeTank = NonFungibleGasTank<Test, Memberships, pallet_nfts::ItemConfig>;

type WeightInfo = WeightInfo;
}

#[allow(dead_code)]
fn new_test_ext() -> TestExternalities {
TestExternalities::new(Default::default())
pub fn new_test_ext() -> TestExternalities {
let mut t = TestExternalities::new(Default::default());

t.execute_with(|| {
assert_ok!(Memberships::create_collection_with_id(
MembershipsManagerCollectionId::get(),
&RootAccount::get(),
&RootAccount::get(),
&pallet_nfts::CollectionConfig {
settings: Default::default(),
max_supply: None,
mint_settings: Default::default(),
},
));
});

t
}
24 changes: 24 additions & 0 deletions pallets/communities-manager/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,32 @@
use crate::mock::new_test_ext;
use crate::{
mock::*,
weights::{SubstrateWeight, WeightInfo},
TankConfig,
};
use frame_support::assert_ok;
use frame_support::weights::Weight;

#[test]
fn create_membership_works() {
new_test_ext().execute_with(|| {
const DAYS: u64 = 14_400;
let config = TankConfig {
capacity: Some(Weight::MAX),
periodicity: Some(7 * DAYS),
};

assert_ok!(CommunitiesManager::create_memberships(
RuntimeOrigin::root(),
1,
1,
1,
config,
Some(BlockNumber::MAX),
));
})
}

#[test]
fn weights() {
let max_total_extrinsics = MAX_BLOCK_WEIGHT * NORMAL_DISPATCH_RATIO;
Expand All @@ -25,6 +48,7 @@ fn weights() {
"create_memberships(1024)",
SubstrateWeight::<Test>::create_memberships(1024),
),
("set_gas_tank", SubstrateWeight::<Test>::set_gas_tank()),
];

for (function, weight) in calls {
Expand Down
Loading

0 comments on commit 9eee9a3

Please sign in to comment.