referrerpolicy=no-referrer-when-downgrade

collectives_westend_runtime/
impls.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// SPDX-License-Identifier: Apache-2.0
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// 	http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use crate::OriginCaller;
17use alloc::boxed::Box;
18use core::{cmp::Ordering, marker::PhantomData};
19use frame_support::{
20	dispatch::DispatchResultWithPostInfo,
21	traits::{Currency, PrivilegeCmp},
22	weights::Weight,
23};
24use pallet_alliance::{ProposalIndex, ProposalProvider};
25use sp_runtime::DispatchError;
26
27type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
28
29type ProposalOf<T, I> = <T as pallet_collective::Config<I>>::Proposal;
30
31type HashOf<T> = <T as frame_system::Config>::Hash;
32
33/// Type alias to conveniently refer to the `Currency::Balance` associated type.
34pub type BalanceOf<T> =
35	<pallet_balances::Pallet<T> as Currency<<T as frame_system::Config>::AccountId>>::Balance;
36
37/// Proposal provider for alliance pallet.
38/// Adapter from collective pallet to alliance proposal provider trait.
39pub struct AllianceProposalProvider<T, I = ()>(PhantomData<(T, I)>);
40
41impl<T, I> ProposalProvider<AccountIdOf<T>, HashOf<T>, ProposalOf<T, I>>
42	for AllianceProposalProvider<T, I>
43where
44	T: pallet_collective::Config<I> + frame_system::Config,
45	I: 'static,
46{
47	fn propose_proposal(
48		who: AccountIdOf<T>,
49		threshold: u32,
50		proposal: Box<ProposalOf<T, I>>,
51		length_bound: u32,
52	) -> Result<(u32, u32), DispatchError> {
53		pallet_collective::Pallet::<T, I>::do_propose_proposed(
54			who,
55			threshold,
56			proposal,
57			length_bound,
58		)
59	}
60
61	fn vote_proposal(
62		who: AccountIdOf<T>,
63		proposal: HashOf<T>,
64		index: ProposalIndex,
65		approve: bool,
66	) -> Result<bool, DispatchError> {
67		pallet_collective::Pallet::<T, I>::do_vote(who, proposal, index, approve)
68	}
69
70	fn close_proposal(
71		proposal_hash: HashOf<T>,
72		proposal_index: ProposalIndex,
73		proposal_weight_bound: Weight,
74		length_bound: u32,
75	) -> DispatchResultWithPostInfo {
76		pallet_collective::Pallet::<T, I>::do_close(
77			proposal_hash,
78			proposal_index,
79			proposal_weight_bound,
80			length_bound,
81		)
82	}
83
84	fn proposal_of(proposal_hash: HashOf<T>) -> Option<ProposalOf<T, I>> {
85		pallet_collective::ProposalOf::<T, I>::get(proposal_hash)
86	}
87}
88
89/// Used to compare the privilege of an origin inside the scheduler.
90pub struct EqualOrGreatestRootCmp;
91
92impl PrivilegeCmp<OriginCaller> for EqualOrGreatestRootCmp {
93	fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option<Ordering> {
94		if left == right {
95			return Some(Ordering::Equal)
96		}
97		match (left, right) {
98			// Root is greater than anything.
99			(OriginCaller::system(frame_system::RawOrigin::Root), _) => Some(Ordering::Greater),
100			_ => None,
101		}
102	}
103}
104
105#[cfg(feature = "runtime-benchmarks")]
106pub mod benchmarks {
107	use super::*;
108	use crate::ParachainSystem;
109	use cumulus_primitives_core::{ChannelStatus, GetChannelInfo};
110	use frame_support::traits::{
111		fungible,
112		tokens::{Pay, PaymentStatus},
113		Get,
114	};
115	use pallet_ranked_collective::Rank;
116	use parachains_common::{AccountId, Balance};
117	use sp_runtime::traits::Convert;
118
119	/// Rank to salary conversion helper type.
120	pub struct RankToSalary<Fungible>(PhantomData<Fungible>);
121	impl<Fungible> Convert<Rank, Balance> for RankToSalary<Fungible>
122	where
123		Fungible: fungible::Inspect<AccountId, Balance = Balance>,
124	{
125		fn convert(r: Rank) -> Balance {
126			Balance::from(r).saturating_mul(Fungible::minimum_balance())
127		}
128	}
129
130	/// Trait for setting up any prerequisites for successful execution of benchmarks.
131	pub trait EnsureSuccessful {
132		fn ensure_successful();
133	}
134
135	/// Implementation of the [`EnsureSuccessful`] trait which opens an HRMP channel between
136	/// the Collectives and a parachain with a given ID.
137	pub struct OpenHrmpChannel<I>(PhantomData<I>);
138	impl<I: Get<u32>> EnsureSuccessful for OpenHrmpChannel<I> {
139		fn ensure_successful() {
140			if let ChannelStatus::Closed = ParachainSystem::get_channel_status(I::get().into()) {
141				ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(I::get().into())
142			}
143		}
144	}
145
146	/// Type that wraps a type implementing the [`Pay`] trait to decorate its
147	/// [`Pay::ensure_successful`] function with a provided implementation of the
148	/// [`EnsureSuccessful`] trait.
149	pub struct PayWithEnsure<O, E>(PhantomData<(O, E)>);
150	impl<O, E> Pay for PayWithEnsure<O, E>
151	where
152		O: Pay,
153		E: EnsureSuccessful,
154	{
155		type AssetKind = O::AssetKind;
156		type Balance = O::Balance;
157		type Beneficiary = O::Beneficiary;
158		type Error = O::Error;
159		type Id = O::Id;
160
161		fn pay(
162			who: &Self::Beneficiary,
163			asset_kind: Self::AssetKind,
164			amount: Self::Balance,
165		) -> Result<Self::Id, Self::Error> {
166			O::pay(who, asset_kind, amount)
167		}
168		fn check_payment(id: Self::Id) -> PaymentStatus {
169			O::check_payment(id)
170		}
171		fn ensure_successful(
172			who: &Self::Beneficiary,
173			asset_kind: Self::AssetKind,
174			amount: Self::Balance,
175		) {
176			E::ensure_successful();
177			O::ensure_successful(who, asset_kind, amount)
178		}
179		fn ensure_concluded(id: Self::Id) {
180			O::ensure_concluded(id)
181		}
182	}
183}