Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Frame: Give Referendum SubmitOrigin argument (#14326)
Browse files Browse the repository at this point in the history
* Referedum's SubmitOrigin should have an arg

* Fixes

* Nits and two extra utils

* Fixes

* Fixes
  • Loading branch information
gavofyork authored Jun 12, 2023
1 parent e5763b8 commit b72c475
Show file tree
Hide file tree
Showing 14 changed files with 462 additions and 88 deletions.
29 changes: 27 additions & 2 deletions frame/collective/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ use frame_support::{
DispatchError, DispatchResult, DispatchResultWithPostInfo, Dispatchable, GetDispatchInfo,
Pays, PostDispatchInfo,
},
ensure,
ensure, impl_ensure_origin_with_arg_ignoring_arg,
traits::{
Backing, ChangeMembers, EnsureOrigin, Get, GetBacking, InitializeMembers, StorageVersion,
Backing, ChangeMembers, EnsureOrigin, EnsureOriginWithArg, Get, GetBacking,
InitializeMembers, StorageVersion,
},
weights::Weight,
};
Expand Down Expand Up @@ -1154,6 +1155,12 @@ impl<
}
}

impl_ensure_origin_with_arg_ignoring_arg! {
impl< { O: .., I: 'static, AccountId: Decode, T } >
EnsureOriginWithArg<O, T> for EnsureMember<AccountId, I>
{}
}

pub struct EnsureMembers<AccountId, I: 'static, const N: u32>(PhantomData<(AccountId, I)>);
impl<
O: Into<Result<RawOrigin<AccountId, I>, O>> + From<RawOrigin<AccountId, I>>,
Expand All @@ -1176,6 +1183,12 @@ impl<
}
}

impl_ensure_origin_with_arg_ignoring_arg! {
impl< { O: .., I: 'static, const N: u32, AccountId, T } >
EnsureOriginWithArg<O, T> for EnsureMembers<AccountId, I, N>
{}
}

pub struct EnsureProportionMoreThan<AccountId, I: 'static, const N: u32, const D: u32>(
PhantomData<(AccountId, I)>,
);
Expand All @@ -1201,6 +1214,12 @@ impl<
}
}

impl_ensure_origin_with_arg_ignoring_arg! {
impl< { O: .., I: 'static, const N: u32, const D: u32, AccountId, T } >
EnsureOriginWithArg<O, T> for EnsureProportionMoreThan<AccountId, I, N, D>
{}
}

pub struct EnsureProportionAtLeast<AccountId, I: 'static, const N: u32, const D: u32>(
PhantomData<(AccountId, I)>,
);
Expand All @@ -1225,3 +1244,9 @@ impl<
Ok(O::from(RawOrigin::Members(0u32, 0u32)))
}
}

impl_ensure_origin_with_arg_ignoring_arg! {
impl< { O: .., I: 'static, const N: u32, const D: u32, AccountId, T } >
EnsureOriginWithArg<O, T> for EnsureProportionAtLeast<AccountId, I, N, D>
{}
}
14 changes: 11 additions & 3 deletions frame/core-fellowship/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ use sp_std::{marker::PhantomData, prelude::*};

use frame_support::{
dispatch::DispatchResultWithPostInfo,
ensure,
traits::{tokens::Balance as BalanceTrait, EnsureOrigin, Get, RankedMembers},
ensure, impl_ensure_origin_with_arg_ignoring_arg,
traits::{
tokens::Balance as BalanceTrait, EnsureOrigin, EnsureOriginWithArg, Get, RankedMembers,
},
BoundedVec, RuntimeDebug,
};

Expand Down Expand Up @@ -570,7 +572,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 T::Members::rank_of(&who) {
Some(rank) if rank >= MIN_RANK && Member::<T, I>::contains_key(&who) => Ok(who),
_ => Err(frame_system::RawOrigin::Signed(who).into()),
Expand All @@ -591,3 +593,9 @@ impl<T: Config<I>, I: 'static, const MIN_RANK: u16> EnsureOrigin<T::RuntimeOrigi
Ok(frame_system::RawOrigin::Signed(who).into())
}
}

impl_ensure_origin_with_arg_ignoring_arg! {
impl< { T: Config<I>, I: 'static, const MIN_RANK: u16, A } >
EnsureOriginWithArg<T::RuntimeOrigin, A> for EnsureInducted<T, I, MIN_RANK>
{}
}
64 changes: 57 additions & 7 deletions frame/ranked-collective/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand Down Expand Up @@ -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()),
Expand All @@ -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())
}
}

Expand All @@ -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()),
Expand All @@ -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)>);
Expand All @@ -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()),
Expand All @@ -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::*;
Expand Down Expand Up @@ -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> {
Expand Down
42 changes: 30 additions & 12 deletions frame/ranked-collective/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
});
Expand Down
Loading

0 comments on commit b72c475

Please sign in to comment.