Frame: Give Referendum SubmitOrigin argument (#14326)

* Referedum's SubmitOrigin should have an arg

* Fixes

* Nits and two extra utils

* Fixes

* Fixes
This commit is contained in:
Gavin Wood
2023-06-12 09:10:19 +01:00
committed by GitHub
parent 62f37e105c
commit 9716c8a1cb
14 changed files with 462 additions and 88 deletions
+57 -7
View File
@@ -53,8 +53,8 @@ use sp_std::{marker::PhantomData, prelude::*};
use frame_support::{
codec::{Decode, Encode, MaxEncodedLen},
dispatch::{DispatchError, DispatchResultWithPostInfo, PostDispatchInfo},
ensure,
traits::{EnsureOrigin, PollStatus, Polling, RankedMembers, VoteTally},
ensure, impl_ensure_origin_with_arg_ignoring_arg,
traits::{EnsureOrigin, EnsureOriginWithArg, PollStatus, Polling, RankedMembers, VoteTally},
CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound,
};
@@ -263,7 +263,7 @@ impl<T: Config<I>, I: 'static, const MIN_RANK: u16> EnsureOrigin<T::RuntimeOrigi
type Success = Rank;
fn try_origin(o: T::RuntimeOrigin) -> Result<Self::Success, T::RuntimeOrigin> {
let who = frame_system::EnsureSigned::try_origin(o)?;
let who = <frame_system::EnsureSigned<_> as EnsureOrigin<_>>::try_origin(o)?;
match Members::<T, I>::get(&who) {
Some(MemberRecord { rank, .. }) if rank >= MIN_RANK => Ok(rank),
_ => Err(frame_system::RawOrigin::Signed(who).into()),
@@ -272,7 +272,36 @@ impl<T: Config<I>, I: 'static, const MIN_RANK: u16> EnsureOrigin<T::RuntimeOrigi
#[cfg(feature = "runtime-benchmarks")]
fn try_successful_origin() -> Result<T::RuntimeOrigin, ()> {
EnsureRankedMember::<T, I, MIN_RANK>::try_successful_origin()
<EnsureRankedMember<T, I, MIN_RANK> as EnsureOrigin<_>>::try_successful_origin()
}
}
impl_ensure_origin_with_arg_ignoring_arg! {
impl<{ T: Config<I>, I: 'static, const MIN_RANK: u16, A }>
EnsureOriginWithArg<T::RuntimeOrigin, A> for EnsureRanked<T, I, MIN_RANK>
{}
}
/// Guard to ensure that the given origin is a member of the collective. The rank of the member is
/// the `Success` value.
pub struct EnsureOfRank<T, I>(PhantomData<(T, I)>);
impl<T: Config<I>, I: 'static> EnsureOriginWithArg<T::RuntimeOrigin, Rank> for EnsureOfRank<T, I> {
type Success = (T::AccountId, Rank);
fn try_origin(o: T::RuntimeOrigin, min_rank: &Rank) -> Result<Self::Success, T::RuntimeOrigin> {
let who = <frame_system::EnsureSigned<_> as EnsureOrigin<_>>::try_origin(o)?;
match Members::<T, I>::get(&who) {
Some(MemberRecord { rank, .. }) if rank >= *min_rank => Ok((who, rank)),
_ => Err(frame_system::RawOrigin::Signed(who).into()),
}
}
#[cfg(feature = "runtime-benchmarks")]
fn try_successful_origin(min_rank: &Rank) -> Result<T::RuntimeOrigin, ()> {
let who = frame_benchmarking::account::<T::AccountId>("successful_origin", 0, 0);
crate::Pallet::<T, I>::do_add_member_to_rank(who.clone(), *min_rank)
.expect("Could not add members for benchmarks");
Ok(frame_system::RawOrigin::Signed(who).into())
}
}
@@ -285,7 +314,7 @@ impl<T: Config<I>, I: 'static, const MIN_RANK: u16> EnsureOrigin<T::RuntimeOrigi
type Success = T::AccountId;
fn try_origin(o: T::RuntimeOrigin) -> Result<Self::Success, T::RuntimeOrigin> {
let who = frame_system::EnsureSigned::try_origin(o)?;
let who = <frame_system::EnsureSigned<_> as EnsureOrigin<_>>::try_origin(o)?;
match Members::<T, I>::get(&who) {
Some(MemberRecord { rank, .. }) if rank >= MIN_RANK => Ok(who),
_ => Err(frame_system::RawOrigin::Signed(who).into()),
@@ -294,10 +323,16 @@ impl<T: Config<I>, I: 'static, const MIN_RANK: u16> EnsureOrigin<T::RuntimeOrigi
#[cfg(feature = "runtime-benchmarks")]
fn try_successful_origin() -> Result<T::RuntimeOrigin, ()> {
EnsureRankedMember::<T, I, MIN_RANK>::try_successful_origin()
<EnsureRankedMember<T, I, MIN_RANK> as EnsureOrigin<_>>::try_successful_origin()
}
}
impl_ensure_origin_with_arg_ignoring_arg! {
impl<{ T: Config<I>, I: 'static, const MIN_RANK: u16, A }>
EnsureOriginWithArg<T::RuntimeOrigin, A> for EnsureMember<T, I, MIN_RANK>
{}
}
/// Guard to ensure that the given origin is a member of the collective. The pair of both the
/// account ID and the rank of the member is the `Success` value.
pub struct EnsureRankedMember<T, I, const MIN_RANK: u16>(PhantomData<(T, I)>);
@@ -307,7 +342,7 @@ impl<T: Config<I>, I: 'static, const MIN_RANK: u16> EnsureOrigin<T::RuntimeOrigi
type Success = (T::AccountId, Rank);
fn try_origin(o: T::RuntimeOrigin) -> Result<Self::Success, T::RuntimeOrigin> {
let who = frame_system::EnsureSigned::try_origin(o)?;
let who = <frame_system::EnsureSigned<_> as EnsureOrigin<_>>::try_origin(o)?;
match Members::<T, I>::get(&who) {
Some(MemberRecord { rank, .. }) if rank >= MIN_RANK => Ok((who, rank)),
_ => Err(frame_system::RawOrigin::Signed(who).into()),
@@ -323,6 +358,12 @@ impl<T: Config<I>, I: 'static, const MIN_RANK: u16> EnsureOrigin<T::RuntimeOrigi
}
}
impl_ensure_origin_with_arg_ignoring_arg! {
impl<{ T: Config<I>, I: 'static, const MIN_RANK: u16, A }>
EnsureOriginWithArg<T::RuntimeOrigin, A> for EnsureRankedMember<T, I, MIN_RANK>
{}
}
#[frame_support::pallet]
pub mod pallet {
use super::*;
@@ -708,6 +749,15 @@ pub mod pallet {
}
Ok(())
}
/// Determine the rank of the account behind the `Signed` origin `o`, `None` if the account
/// is unknown to this collective or `o` is not `Signed`.
pub fn as_rank(
o: &<T::RuntimeOrigin as frame_support::traits::OriginTrait>::PalletsOrigin,
) -> Option<u16> {
use frame_support::traits::CallerTrait;
o.as_signed().and_then(Self::rank_of)
}
}
impl<T: Config<I>, I: 'static> RankedMembers for Pallet<T, I> {
+30 -12
View File
@@ -464,34 +464,52 @@ fn ensure_ranked_works() {
type Rank2 = EnsureRanked<Test, (), 2>;
type Rank3 = EnsureRanked<Test, (), 3>;
type Rank4 = EnsureRanked<Test, (), 4>;
assert_eq!(Rank1::try_origin(RuntimeOrigin::signed(1)).unwrap(), 1);
assert_eq!(Rank1::try_origin(RuntimeOrigin::signed(2)).unwrap(), 2);
assert_eq!(Rank1::try_origin(RuntimeOrigin::signed(3)).unwrap(), 3);
assert_eq!(<Rank1 as EnsureOrigin<_>>::try_origin(RuntimeOrigin::signed(1)).unwrap(), 1);
assert_eq!(<Rank1 as EnsureOrigin<_>>::try_origin(RuntimeOrigin::signed(2)).unwrap(), 2);
assert_eq!(<Rank1 as EnsureOrigin<_>>::try_origin(RuntimeOrigin::signed(3)).unwrap(), 3);
assert_eq!(
Rank2::try_origin(RuntimeOrigin::signed(1)).unwrap_err().as_signed().unwrap(),
<Rank2 as EnsureOrigin<_>>::try_origin(RuntimeOrigin::signed(1))
.unwrap_err()
.into_signer()
.unwrap(),
1
);
assert_eq!(Rank2::try_origin(RuntimeOrigin::signed(2)).unwrap(), 2);
assert_eq!(Rank2::try_origin(RuntimeOrigin::signed(3)).unwrap(), 3);
assert_eq!(<Rank2 as EnsureOrigin<_>>::try_origin(RuntimeOrigin::signed(2)).unwrap(), 2);
assert_eq!(<Rank2 as EnsureOrigin<_>>::try_origin(RuntimeOrigin::signed(3)).unwrap(), 3);
assert_eq!(
Rank3::try_origin(RuntimeOrigin::signed(1)).unwrap_err().as_signed().unwrap(),
<Rank3 as EnsureOrigin<_>>::try_origin(RuntimeOrigin::signed(1))
.unwrap_err()
.into_signer()
.unwrap(),
1
);
assert_eq!(
Rank3::try_origin(RuntimeOrigin::signed(2)).unwrap_err().as_signed().unwrap(),
<Rank3 as EnsureOrigin<_>>::try_origin(RuntimeOrigin::signed(2))
.unwrap_err()
.into_signer()
.unwrap(),
2
);
assert_eq!(Rank3::try_origin(RuntimeOrigin::signed(3)).unwrap(), 3);
assert_eq!(<Rank3 as EnsureOrigin<_>>::try_origin(RuntimeOrigin::signed(3)).unwrap(), 3);
assert_eq!(
Rank4::try_origin(RuntimeOrigin::signed(1)).unwrap_err().as_signed().unwrap(),
<Rank4 as EnsureOrigin<_>>::try_origin(RuntimeOrigin::signed(1))
.unwrap_err()
.into_signer()
.unwrap(),
1
);
assert_eq!(
Rank4::try_origin(RuntimeOrigin::signed(2)).unwrap_err().as_signed().unwrap(),
<Rank4 as EnsureOrigin<_>>::try_origin(RuntimeOrigin::signed(2))
.unwrap_err()
.into_signer()
.unwrap(),
2
);
assert_eq!(
Rank4::try_origin(RuntimeOrigin::signed(3)).unwrap_err().as_signed().unwrap(),
<Rank4 as EnsureOrigin<_>>::try_origin(RuntimeOrigin::signed(3))
.unwrap_err()
.into_signer()
.unwrap(),
3
);
});