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] Permissionless Registering and Management of Communities #364

Merged
merged 26 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b16bf2a
feat(pallet-communities-manager): Initial commit
pandres95 Apr 15, 2024
5afedd3
change(pallet-communities-manager): define generic mechanism for `reg…
pandres95 Apr 16, 2024
4569f58
change(pallet-communities): remove metadata
pandres95 Apr 16, 2024
1c1b17a
change(pallet-communities): permissionless creation and administratio…
pandres95 Apr 17, 2024
9f7ca8f
change(pallet-communities): simplify benchmarking
pandres95 Apr 18, 2024
22b6319
fix(pallet-communities): export TryConvert only when xcm feature is e…
pandres95 Apr 18, 2024
f55c1db
change(pallet-communities): emit CommunityCreated event on do_registe…
pandres95 Apr 18, 2024
7e9c2ab
change(pallet-communities-manager): implement pallet and benchmarkings
pandres95 Apr 18, 2024
1f61266
fix(pallet-communities): lint
pandres95 Apr 18, 2024
62a4e01
fix(pallet-communities-manager): lint
pandres95 Apr 18, 2024
cc4cc0e
change(kreivo-runtime): missing configuration changes
pandres95 Apr 18, 2024
0b9273f
change(pallet-communities): add origin for ensuring permissionless cr…
pandres95 Apr 19, 2024
1676b3a
change(kreivo-runtime): charge 1KSM for permisionlessly creating a co…
pandres95 Apr 19, 2024
316c6fa
fix(pallet-communities): ensure voting is stored on a membership-basi…
pandres95 Apr 20, 2024
ef79944
Simplify Ensure types and make more descriptive
olanod Apr 20, 2024
7e46db5
Check first community exists + Provide default gov track
olanod Apr 20, 2024
9cf16a0
fix(pallet-communities): only iter over a single acconut's locks / do…
pandres95 Apr 21, 2024
6c216df
Merge branch 'featuire/pallet-communities-manager' of github.com:virt…
pandres95 Apr 21, 2024
049eccd
fix(pallet-communities): lint
pandres95 Apr 21, 2024
bce6215
change(kreivo-runtime): adjust deposits
pandres95 Apr 22, 2024
20aadc1
fix(pallet-communities): ensure holds on an asset are removed when no…
pandres95 Apr 22, 2024
48043b6
feat(kreivo-runtime): configure pallet-communities-manager
pandres95 Apr 22, 2024
255bd31
change(kreivo-runtime): bump minor
pandres95 Apr 22, 2024
0107bad
fix(kreivo-runtime): remove deposit mints in benchmarkings
pandres95 Apr 22, 2024
640e379
fix(pallet-communities): on tests, must unlock on casted votes
pandres95 Apr 22, 2024
97cb520
[ci] calculate weights (#370)
github-actions[bot] Apr 22, 2024
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
238 changes: 150 additions & 88 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,16 @@ pallet-asset-registry = { default-features = false, path = "pallets/asset-regist
pallet-burner = { default-features = false, path = "pallets/burner" }
pallet-payments = { default-features = false, path = "pallets/payments" }
pallet-communities = { default-features = false, path = "pallets/communities" }
pallet-communities-manager = { default-features = false, path = "pallets/communities-manager" }

virto-common = { default-features = false, path = "common" }
runtime-common = { default-features = false, path = "runtime/common" }
kusama-runtime-constants = { default-features = false, path = "runtime/kusama-runtime-constants" }

# Frame Contrib
fc-traits-memberships = { git = "https://github.com/virto-network/frame-contrib", branch = "main", default-features = false }
pallet-referenda-tracks = { git = "https://github.com/virto-network/frame-contrib", branch = "main", package="fc-pallet-referenda-tracks", default-features = false }
fc-traits-tracks = { git = "https://github.com/virto-network/frame-contrib", branch = "feature/trait-tracks", default-features = false }
pallet-referenda-tracks = { git = "https://github.com/virto-network/frame-contrib", branch = "feature/trait-tracks", package="fc-pallet-referenda-tracks", default-features = false }

# Substrate std
try-runtime-cli = { git = "https://github.com/virto-network/polkadot-sdk", branch = "release-virto-v1.5.0" }
Expand Down
94 changes: 94 additions & 0 deletions pallets/communities-manager/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
[package]
name = "pallet-communities-manager"
version = "0.1.0"
authors = ["Virto Team<[email protected]>"]
description = "This pallet helps with all the necesary steps to correctly setup a community."
license = "MIT-0"
homepage = 'https://github.com/virto-network/virto-node'
repository = 'https://github.com/virto-network/virto-node'
edition = "2021"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
fc-traits-tracks = { workspace = true }

frame-benchmarking = { workspace = true, optional = true }
frame-support = { workspace = true }
frame-system = { workspace = true }

pallet-communities = { workspace = true }
pallet-nfts = { workspace = true }
pallet-referenda = { workspace = true }

log = { workspace = true }

parity-scale-codec = { workspace = true, features = ["derive"] }
scale-info = { workspace = true, features = ["derive"] }

sp-runtime = { workspace = true }
sp-std = { workspace = true }

[dev-dependencies]
sp-core = { workspace = true }
sp-io = { workspace = true }

pallet-assets = { workspace = true }
pallet-balances = { workspace = true }
pallet-ranked-collective = { workspace = true }
pallet-referenda-tracks = { workspace = true }
pallet-scheduler = { workspace = true }
virto-common = { workspace = true, default-features = false, features = ["runtime"] }

[features]
default = ["std", "testnet"]
testnet = []
std = [
"fc-traits-tracks/std",
"frame-benchmarking?/std",
"frame-support/std",
"frame-system/std",
"log/std",
"pallet-assets/std",
"pallet-balances/std",
"pallet-communities/std",
"pallet-nfts/std",
"pallet-ranked-collective/std",
"pallet-referenda-tracks/std",
"pallet-referenda/std",
"pallet-scheduler/std",
"parity-scale-codec/std",
"scale-info/std",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
"virto-common/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-communities/runtime-benchmarks",
"pallet-nfts/runtime-benchmarks",
"pallet-ranked-collective/runtime-benchmarks",
"pallet-referenda-tracks/runtime-benchmarks",
"pallet-referenda/runtime-benchmarks",
"pallet-scheduler/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"pallet-assets/try-runtime",
"pallet-balances/try-runtime",
"pallet-nfts/try-runtime",
"pallet-ranked-collective/try-runtime",
"pallet-referenda-tracks/try-runtime",
"pallet-referenda/try-runtime",
"pallet-scheduler/try-runtime",
"sp-runtime/try-runtime",
]
52 changes: 52 additions & 0 deletions pallets/communities-manager/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! Benchmarking setup for pallet-communities
use super::*;

use frame_benchmarking::v2::*;
use Pallet as CommunitiesManager;

use frame_system::RawOrigin;
use sp_runtime::traits::StaticLookup;

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

fn assert_has_event<T: Config>(generic_event: RuntimeEventFor<T>) {
frame_system::Pallet::<T>::assert_has_event(generic_event.into());
}

#[benchmarks(
where
RuntimeEventFor<T>: From<pallet_communities::Event<T>>,
BlockNumberFor<T>: From<u32>,
CommunityIdOf<T>: From<u16>,
)]
mod benchmarks {
use super::*;

#[benchmark]
fn register() {
// setup code
let community_id: CommunityIdOf<T> = 1.into();
let first_member: AccountIdOf<T> = frame_benchmarking::account("founder", 0, 0);
let admin_origin: RuntimeOriginFor<T> = frame_system::Origin::<T>::Signed(first_member.clone()).into();
let admin_origin_caller: PalletsOriginOf<T> = admin_origin.into_caller();

#[extrinsic_call]
_(
RawOrigin::Root,
community_id,
BoundedVec::truncate_from(b"Test Community".into()),
Some(admin_origin_caller.clone()),
None,
Some(T::Lookup::unlookup(first_member)),
);

// verification code
assert_has_event::<T>(Event::<T>::CommunityRegistered { id: community_id }.into());
}

impl_benchmark_test_suite!(
CommunitiesManager,
sp_io::TestExternalities::new(Default::default()),
crate::mock::Test
);
}
178 changes: 178 additions & 0 deletions pallets/communities-manager/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;

#[cfg(test)]
pub(crate) mod mock;
#[cfg(test)]
mod tests;

pub mod weights;
pub use weights::*;

use fc_traits_tracks::MutateTracks;
use frame_support::{
pallet_prelude::*,
traits::{nonfungibles_v2::Create, OriginTrait, RankedMembers},
};
use frame_system::pallet_prelude::{BlockNumberFor, OriginFor};
use pallet_communities::{
types::{
AccountIdLookupOf, AccountIdOf, CommunityIdOf, DecisionMethodFor, NativeBalanceOf, PalletsOriginOf,
RuntimeOriginFor,
},
Origin as CommunityOrigin,
};
use pallet_nfts::CollectionConfig;
use pallet_referenda::{TrackInfo, TracksInfo};

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

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

use super::*;

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

/// Configure the pallet by specifying the parameters and types on which it
/// depends.
#[pallet::config]
pub trait Config: frame_system::Config + pallet_communities::Config {
/// Because this pallet emits events, it depends on the runtime's
/// definition of an event.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

type CreateCollection: Create<
AccountIdOf<Self>,
CollectionConfig<NativeBalanceOf<Self>, BlockNumberFor<Self>, CommunityIdOf<Self>>,
CollectionId = CommunityIdOf<Self>,
>;

type Tracks: TracksInfo<NativeBalanceOf<Self>, BlockNumberFor<Self>>
+ MutateTracks<
NativeBalanceOf<Self>,
BlockNumberFor<Self>,
Id = CommunityIdOf<Self>,
RuntimeOrigin = PalletsOriginOf<Self>,
>;

type RankedCollective: RankedMembers<AccountId = AccountIdOf<Self>>;

/// Type representing the weight of this pallet
type WeightInfo: WeightInfo;

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

#[pallet::pallet]
pub struct Pallet<T>(_);

// Pallets use events to inform users when important changes are made.
// https://docs.substrate.io/main-docs/build/events-errors/
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// The community with [`CommmunityId`](pallet_communities::CommunityId)
/// has been created.
CommunityRegistered { id: T::CommunityId },
}

// Errors inform users that something worked or went wrong.
#[pallet::error]
pub enum Error<T> {
/// Community name didn't contain valid utf8 characters
InvalidCommunityName,
/// It was not possible to register the community
CannotRegister,
}

// Dispatchable functions allows users to interact with the pallet and invoke
// state changes. These functions materialize as "extrinsics", which are often
// compared to transactions. Dispatchable functions must be annotated with a
// weight and must return a DispatchResult.
#[pallet::call(weight(<T as Config>::WeightInfo))]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
pub fn register(
origin: OriginFor<T>,
community_id: CommunityIdOf<T>,
name: CommunityName,
maybe_admin_origin: Option<PalletsOriginOf<T>>,
maybe_decision_method: Option<DecisionMethodFor<T>>,
_maybe_first_member: Option<AccountIdLookupOf<T>>,
) -> DispatchResult {
let maybe_deposit = T::CreateOrigin::ensure_origin(origin)?;

let community_name = core::str::from_utf8(&name).map_err(|_| Error::<T>::InvalidCommunityName)?;
let community_origin: RuntimeOriginFor<T> = CommunityOrigin::<T>::new(community_id).into();
let admin_origin = maybe_admin_origin.unwrap_or(community_origin.clone().into_caller());
// Register first to check if community exists
pallet_communities::Pallet::<T>::register(&admin_origin, &community_id, maybe_deposit)?;

if let Some(decision_method) = maybe_decision_method {
pallet_communities::Pallet::<T>::set_decision_method(
admin_origin.clone().into(),
community_id,
decision_method,
)?;
}

let community_account = pallet_communities::Pallet::<T>::community_account(&community_id);

// Create memberships collection for community
T::CreateCollection::create_collection_with_id(
community_id,
&community_account,
&community_account,
&CollectionConfig {
settings: Default::default(),
max_supply: None,
mint_settings: Default::default(),
},
)?;

// Create governance track for community
T::Tracks::insert(
community_id,
Self::default_tack(community_name),
community_origin.into_caller(),
)?;
// Induct community at Kreivo Governance with rank 1
T::RankedCollective::induct(&community_account)?;

Self::deposit_event(Event::<T>::CommunityRegistered { id: community_id });
Ok(())
}
}

impl<T: Config> Pallet<T> {
fn default_tack(name: &str) -> TrackInfoOf<T> {
use sp_runtime::Perbill;
TrackInfo {
name: str_array(name),
max_deciding: 1,
decision_deposit: 0u8.into(),
prepare_period: 1u8.into(),
decision_period: u8::MAX.into(),
confirm_period: 1u8.into(),
min_enactment_period: 1u8.into(),
min_approval: pallet_referenda::Curve::LinearDecreasing {
length: Perbill::from_percent(100),
floor: Perbill::from_percent(50),
ceil: Perbill::from_percent(100),
},
min_support: pallet_referenda::Curve::LinearDecreasing {
length: Perbill::from_percent(100),
floor: Perbill::from_percent(0),
ceil: Perbill::from_percent(50),
},
}
}
}
}
Loading
Loading