mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 22:41:02 +00:00
9e403629d5
The Ambassador Program on Polkadot Collectives Parachain The Polkadot Ambassador Program has existed for a while; more information can be found [here](https://wiki.polkadot.network/docs/ambassadors). In this PR, the program is being brought on chain. ### On Chain Structure The on-chain program consists of nine ranks, divided into four categories ([full list](https://github.com/paritytech/cumulus/blob/c238fb26b75569a11abb57437fd14acd26e05f18/parachains/runtimes/collectives/collectives-polkadot/src/ambassador/mod.rs#L52)): - Ambassadors (1-2 tiers) - Senior Ambassadors (3-4 tiers) - Head Ambassadors (5-7 tiers) - Master Ambassadors (8-9 tiers) Each rank has a corresponding `Origin` (e.g., `HeadAmbassadorsTier5` - [full list](https://github.com/paritytech/cumulus/blob/c238fb26b75569a11abb57437fd14acd26e05f18/parachains/runtimes/collectives/collectives-polkadot/src/ambassador/origins.rs#L35)), which represents the collective voice of members of that rank and above. ### Referendum The `AmbassadorReferenda` instance of [referenda pallet](https://docs.rs/pallet-referenda/latest/pallet_referenda/) consists of [nine tracks](https://github.com/paritytech/cumulus/blob/c238fb26b75569a11abb57437fd14acd26e05f18/parachains/runtimes/collectives/collectives-polkadot/src/ambassador/tracks.rs#L51), each corresponding to an `Origin`. A referendum taken on `senior ambassador tier 4` track invites all members from rank 4 or above to vote and commands `SeniorAmbassadors` `Origin`. Every member gets one vote plus an additional vote for every excess rank. The referendum proposal can be submitted by any member of a senior rank or above. ### Membership Management Initial members will be brought on chain via migration, with subsequent member management handled through the `AmbassadorCollective` instance of [ranked collective pallet](https://docs.rs/pallet-ranked-collective/latest/pallet_ranked_collective/). Both `Root` and `FellowshipAdmin` `Origins`, commanded via public Polkadot referendum, can promote or demote members to and from any rank. Members themselves also have the power to promote or demote via its referendum, with a senior member vote by the rank two above the new / current rank - [full configuration](https://github.com/paritytech/cumulus/blob/9ab6aa47063d7e8b67ddc10d9c136037f99c03a3/parachains/runtimes/collectives/collectives-polkadot/src/ambassador/mod.rs#L67). ### Content Management The program's on-chain content is managed via the collectives content pallet, allowing for setting its charter and making announcements. The voice of head ambassadors have the authority to set the charter, while announcements can be made by any senior rank member or through a referendum among all members. ### Additional Functionality The `AmbassadorCore` instance of [core fellowship pallet](https://docs.rs/pallet-core-fellowship/latest/pallet_core_fellowship/) decorates the ranked collectives pallet with features like salary determination, activity/passivity registration, and the handling of promotion and demotion periods. While the usage of this pallet is optional in the first version, future updates will make it the exclusive method for induction/promotion. Periodic salaries in USDt, payable on Asset Hub, are introduced through the [salary pallet](https://docs.rs/pallet-salary/latest/pallet_salary/). This requires induction into the ambassador core pallet. Please for more information on the pallets' functionality refer to their documentations. ### Next Steps: - Migrate to seed the program members - Mint ambassador NFT badges on Asset Hub when promoting - Treasury pallet instance for the Ambassador Program --------- Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
89 lines
2.8 KiB
Rust
89 lines
2.8 KiB
Rust
// Copyright (C) 2023 Parity Technologies (UK) Ltd.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
//! The pallet benchmarks.
|
|
|
|
use super::{Pallet as CollectiveContent, *};
|
|
use frame_benchmarking::{impl_benchmark_test_suite, v2::*};
|
|
use frame_support::traits::EnsureOrigin;
|
|
|
|
fn assert_last_event<T: Config<I>, I: 'static>(generic_event: <T as Config<I>>::RuntimeEvent) {
|
|
frame_system::Pallet::<T>::assert_last_event(generic_event.into());
|
|
}
|
|
|
|
/// returns CID hash of 68 bytes of given `i`.
|
|
fn create_cid(i: u8) -> OpaqueCid {
|
|
let cid: OpaqueCid = [i; 68].to_vec().try_into().unwrap();
|
|
cid
|
|
}
|
|
|
|
#[instance_benchmarks]
|
|
mod benchmarks {
|
|
use super::*;
|
|
|
|
#[benchmark]
|
|
fn set_charter() -> Result<(), BenchmarkError> {
|
|
let cid: OpaqueCid = create_cid(1);
|
|
let origin =
|
|
T::CharterOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
|
|
|
#[extrinsic_call]
|
|
_(origin as T::RuntimeOrigin, cid.clone());
|
|
|
|
assert_eq!(Charter::<T, I>::get(), Some(cid.clone()));
|
|
assert_last_event::<T, I>(Event::NewCharterSet { cid }.into());
|
|
Ok(())
|
|
}
|
|
|
|
#[benchmark]
|
|
fn announce() -> Result<(), BenchmarkError> {
|
|
let expire_at = DispatchTime::<_>::At(10u32.into());
|
|
let now = frame_system::Pallet::<T>::block_number();
|
|
let cid: OpaqueCid = create_cid(1);
|
|
let origin = T::AnnouncementOrigin::try_successful_origin()
|
|
.map_err(|_| BenchmarkError::Weightless)?;
|
|
|
|
#[extrinsic_call]
|
|
_(origin as T::RuntimeOrigin, cid.clone(), Some(expire_at.clone()));
|
|
|
|
assert_eq!(<Announcements<T, I>>::count(), 1);
|
|
assert_last_event::<T, I>(
|
|
Event::AnnouncementAnnounced { cid, expire_at: expire_at.evaluate(now) }.into(),
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[benchmark]
|
|
fn remove_announcement() -> Result<(), BenchmarkError> {
|
|
let cid: OpaqueCid = create_cid(1);
|
|
let origin = T::AnnouncementOrigin::try_successful_origin()
|
|
.map_err(|_| BenchmarkError::Weightless)?;
|
|
CollectiveContent::<T, I>::announce(origin.clone(), cid.clone(), None)
|
|
.expect("could not publish an announcement");
|
|
assert_eq!(<Announcements<T, I>>::count(), 1);
|
|
|
|
#[extrinsic_call]
|
|
_(origin as T::RuntimeOrigin, cid.clone());
|
|
|
|
assert_eq!(<Announcements<T, I>>::count(), 0);
|
|
assert_last_event::<T, I>(Event::AnnouncementRemoved { cid }.into());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
impl_benchmark_test_suite!(CollectiveContent, super::mock::new_bench_ext(), super::mock::Test);
|
|
}
|