mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-09 03:38:00 +00:00
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:
@@ -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,
|
||||
};
|
||||
@@ -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>>,
|
||||
@@ -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)>,
|
||||
);
|
||||
@@ -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)>,
|
||||
);
|
||||
@@ -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>
|
||||
{}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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()),
|
||||
@@ -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>
|
||||
{}
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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
|
||||
);
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ use frame_benchmarking::v1::{
|
||||
use frame_support::{
|
||||
assert_ok,
|
||||
dispatch::UnfilteredDispatchable,
|
||||
traits::{Bounded, Currency, EnsureOrigin},
|
||||
traits::{Bounded, Currency, EnsureOrigin, EnsureOriginWithArg},
|
||||
};
|
||||
use frame_system::RawOrigin;
|
||||
use sp_runtime::traits::Bounded as ArithBounded;
|
||||
@@ -196,7 +196,7 @@ fn is_not_confirming<T: Config<I>, I: 'static>(index: ReferendumIndex) -> bool {
|
||||
benchmarks_instance_pallet! {
|
||||
submit {
|
||||
let origin =
|
||||
T::SubmitOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
||||
T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into()).map_err(|_| BenchmarkError::Weightless)?;
|
||||
if let Ok(caller) = frame_system::ensure_signed(origin.clone()) {
|
||||
T::Currency::make_free_balance_be(&caller, BalanceOf::<T, I>::max_value());
|
||||
whitelist_account!(caller);
|
||||
@@ -213,7 +213,7 @@ benchmarks_instance_pallet! {
|
||||
|
||||
place_decision_deposit_preparing {
|
||||
let origin =
|
||||
T::SubmitOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
||||
T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into()).map_err(|_| BenchmarkError::Weightless)?;
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
}: place_decision_deposit<T::RuntimeOrigin>(origin, index)
|
||||
verify {
|
||||
@@ -222,7 +222,7 @@ benchmarks_instance_pallet! {
|
||||
|
||||
place_decision_deposit_queued {
|
||||
let origin =
|
||||
T::SubmitOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
||||
T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into()).map_err(|_| BenchmarkError::Weightless)?;
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
fill_queue::<T, I>(origin.clone(), index, 1, 90);
|
||||
}: place_decision_deposit<T::RuntimeOrigin>(origin, index)
|
||||
@@ -234,7 +234,7 @@ benchmarks_instance_pallet! {
|
||||
|
||||
place_decision_deposit_not_queued {
|
||||
let origin =
|
||||
T::SubmitOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
||||
T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into()).map_err(|_| BenchmarkError::Weightless)?;
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
fill_queue::<T, I>(origin.clone(), index, 0, 90);
|
||||
let track = Referenda::<T, I>::ensure_ongoing(index).unwrap().track;
|
||||
@@ -248,7 +248,7 @@ benchmarks_instance_pallet! {
|
||||
|
||||
place_decision_deposit_passing {
|
||||
let origin =
|
||||
T::SubmitOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
||||
T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into()).map_err(|_| BenchmarkError::Weightless)?;
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
skip_prepare_period::<T, I>(index);
|
||||
make_passing::<T, I>(index);
|
||||
@@ -259,7 +259,7 @@ benchmarks_instance_pallet! {
|
||||
|
||||
place_decision_deposit_failing {
|
||||
let origin =
|
||||
T::SubmitOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
||||
T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into()).map_err(|_| BenchmarkError::Weightless)?;
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
skip_prepare_period::<T, I>(index);
|
||||
}: place_decision_deposit<T::RuntimeOrigin>(origin, index)
|
||||
@@ -269,7 +269,7 @@ benchmarks_instance_pallet! {
|
||||
|
||||
refund_decision_deposit {
|
||||
let origin =
|
||||
T::SubmitOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
||||
T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into()).map_err(|_| BenchmarkError::Weightless)?;
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
place_deposit::<T, I>(index);
|
||||
assert_ok!(Referenda::<T, I>::cancel(
|
||||
@@ -284,7 +284,7 @@ benchmarks_instance_pallet! {
|
||||
|
||||
refund_submission_deposit {
|
||||
let origin =
|
||||
T::SubmitOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
||||
T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into()).map_err(|_| BenchmarkError::Weightless)?;
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
let caller = frame_system::ensure_signed(origin.clone()).unwrap();
|
||||
let balance = T::Currency::free_balance(&caller);
|
||||
@@ -303,7 +303,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
cancel {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
place_deposit::<T, I>(index);
|
||||
@@ -315,7 +315,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
kill {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
place_deposit::<T, I>(index);
|
||||
@@ -327,7 +327,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
one_fewer_deciding_queue_empty {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
place_deposit::<T, I>(index);
|
||||
@@ -346,7 +346,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
one_fewer_deciding_failing {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
// No spaces free in the queue.
|
||||
@@ -371,7 +371,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
one_fewer_deciding_passing {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
// No spaces free in the queue.
|
||||
@@ -396,7 +396,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_requeued_insertion {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
// First create our referendum and place the deposit. It will be failing.
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
@@ -419,7 +419,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_requeued_slide {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
// First create our referendum and place the deposit. It will be failing.
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
@@ -447,7 +447,7 @@ benchmarks_instance_pallet! {
|
||||
// free and this failing. It would result in `QUEUE_SIZE - 1` items being shifted for the
|
||||
// insertion at the beginning.
|
||||
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
// First create our referendum and place the deposit. It will be failing.
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
@@ -466,7 +466,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_not_queued {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
// First create our referendum and place the deposit. It will be failing.
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
@@ -485,7 +485,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_no_deposit {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
skip_prepare_period::<T, I>(index);
|
||||
@@ -496,7 +496,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_preparing {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
place_deposit::<T, I>(index);
|
||||
@@ -507,7 +507,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_timed_out {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
skip_timeout_period::<T, I>(index);
|
||||
@@ -518,7 +518,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_begin_deciding_failing {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
place_deposit::<T, I>(index);
|
||||
@@ -529,7 +529,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_begin_deciding_passing {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
place_deposit::<T, I>(index);
|
||||
@@ -541,7 +541,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_begin_confirming {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
place_deposit::<T, I>(index);
|
||||
@@ -555,7 +555,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_end_confirming {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
place_deposit::<T, I>(index);
|
||||
@@ -570,7 +570,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_continue_not_confirming {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
place_deposit::<T, I>(index);
|
||||
@@ -586,7 +586,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_continue_confirming {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
place_deposit::<T, I>(index);
|
||||
@@ -601,7 +601,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_approved {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
place_deposit::<T, I>(index);
|
||||
@@ -616,7 +616,7 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
|
||||
nudge_referendum_rejected {
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin);
|
||||
place_deposit::<T, I>(index);
|
||||
@@ -632,7 +632,7 @@ benchmarks_instance_pallet! {
|
||||
|
||||
set_some_metadata {
|
||||
use sp_std::borrow::Cow;
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
let hash = T::Preimages::note(Cow::from(vec![5, 6])).unwrap();
|
||||
@@ -643,7 +643,7 @@ benchmarks_instance_pallet! {
|
||||
|
||||
clear_metadata {
|
||||
use sp_std::borrow::Cow;
|
||||
let origin = T::SubmitOrigin::try_successful_origin()
|
||||
let origin = T::SubmitOrigin::try_successful_origin(&RawOrigin::Root.into())
|
||||
.expect("SubmitOrigin has no successful origin required for the benchmark");
|
||||
let index = create_referendum::<T, I>(origin.clone());
|
||||
let hash = T::Preimages::note(Cow::from(vec![6, 7, 8])).unwrap();
|
||||
|
||||
@@ -138,7 +138,7 @@ const ASSEMBLY_ID: LockIdentifier = *b"assembly";
|
||||
#[frame_support::pallet]
|
||||
pub mod pallet {
|
||||
use super::*;
|
||||
use frame_support::pallet_prelude::*;
|
||||
use frame_support::{pallet_prelude::*, traits::EnsureOriginWithArg};
|
||||
use frame_system::pallet_prelude::*;
|
||||
|
||||
/// The current storage version.
|
||||
@@ -167,7 +167,11 @@ pub mod pallet {
|
||||
type Currency: ReservableCurrency<Self::AccountId>;
|
||||
// Origins and unbalances.
|
||||
/// Origin from which proposals may be submitted.
|
||||
type SubmitOrigin: EnsureOrigin<Self::RuntimeOrigin, Success = Self::AccountId>;
|
||||
type SubmitOrigin: EnsureOriginWithArg<
|
||||
Self::RuntimeOrigin,
|
||||
PalletsOriginOf<Self>,
|
||||
Success = Self::AccountId,
|
||||
>;
|
||||
/// Origin from which any vote may be cancelled.
|
||||
type CancelOrigin: EnsureOrigin<Self::RuntimeOrigin>;
|
||||
/// Origin from which any vote may be killed.
|
||||
@@ -430,7 +434,8 @@ pub mod pallet {
|
||||
proposal: BoundedCallOf<T, I>,
|
||||
enactment_moment: DispatchTime<T::BlockNumber>,
|
||||
) -> DispatchResult {
|
||||
let who = T::SubmitOrigin::ensure_origin(origin)?;
|
||||
let proposal_origin = *proposal_origin;
|
||||
let who = T::SubmitOrigin::ensure_origin(origin, &proposal_origin)?;
|
||||
|
||||
let track =
|
||||
T::Tracks::track_for(&proposal_origin).map_err(|_| Error::<T, I>::NoTrack)?;
|
||||
@@ -445,7 +450,7 @@ pub mod pallet {
|
||||
T::Preimages::bound(CallOf::<T, I>::from(Call::nudge_referendum { index }))?;
|
||||
let status = ReferendumStatus {
|
||||
track,
|
||||
origin: *proposal_origin,
|
||||
origin: proposal_origin,
|
||||
proposal: proposal.clone(),
|
||||
enactment: enactment_moment,
|
||||
submitted: now,
|
||||
|
||||
@@ -252,10 +252,11 @@ mod mock;
|
||||
mod tests;
|
||||
|
||||
use frame_support::{
|
||||
impl_ensure_origin_with_arg_ignoring_arg,
|
||||
pallet_prelude::*,
|
||||
traits::{
|
||||
BalanceStatus, ChangeMembers, Currency, EnsureOrigin, ExistenceRequirement::AllowDeath,
|
||||
Imbalance, OnUnbalanced, Randomness, ReservableCurrency,
|
||||
BalanceStatus, ChangeMembers, Currency, EnsureOrigin, EnsureOriginWithArg,
|
||||
ExistenceRequirement::AllowDeath, Imbalance, OnUnbalanced, Randomness, ReservableCurrency,
|
||||
},
|
||||
PalletId,
|
||||
};
|
||||
@@ -1181,6 +1182,12 @@ impl<T: Config> EnsureOrigin<T::RuntimeOrigin> for EnsureFounder<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl_ensure_origin_with_arg_ignoring_arg! {
|
||||
impl<{ T: Config, A }>
|
||||
EnsureOriginWithArg<T::RuntimeOrigin, A> for EnsureFounder<T>
|
||||
{}
|
||||
}
|
||||
|
||||
/// Pick an item at pseudo-random from the slice, given the `rng`. `None` iff the slice is empty.
|
||||
fn pick_item<'a, R: RngCore, T>(rng: &mut R, items: &'a [T]) -> Option<&'a T> {
|
||||
if items.is_empty() {
|
||||
|
||||
@@ -418,6 +418,34 @@ fn expand_origin_pallet_conversions(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#attr
|
||||
impl<'a> TryFrom<&'a OriginCaller> for &'a #pallet_origin {
|
||||
type Error = ();
|
||||
fn try_from(
|
||||
x: &'a OriginCaller,
|
||||
) -> #scrate::sp_std::result::Result<&'a #pallet_origin, ()> {
|
||||
if let OriginCaller::#variant_name(l) = x {
|
||||
Ok(&l)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#attr
|
||||
impl<'a> TryFrom<&'a RuntimeOrigin> for &'a #pallet_origin {
|
||||
type Error = ();
|
||||
fn try_from(
|
||||
x: &'a RuntimeOrigin,
|
||||
) -> #scrate::sp_std::result::Result<&'a #pallet_origin, ()> {
|
||||
if let OriginCaller::#variant_name(l) = &x.caller {
|
||||
Ok(&l)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +89,26 @@ impl<AccountId> From<Option<AccountId>> for RawOrigin<AccountId> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<AccountId> RawOrigin<AccountId> {
|
||||
/// Returns `Some` with a reference to the `AccountId` if `self` is `Signed`, `None` otherwise.
|
||||
pub fn as_signed(&self) -> Option<&AccountId> {
|
||||
match &self {
|
||||
Self::Signed(x) => Some(x),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is `Root`, `None` otherwise.
|
||||
pub fn is_root(&self) -> bool {
|
||||
matches!(&self, Self::Root)
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is `None`, `None` otherwise.
|
||||
pub fn is_none(&self) -> bool {
|
||||
matches!(&self, Self::None)
|
||||
}
|
||||
}
|
||||
|
||||
/// A type that can be used as a parameter in a dispatchable function.
|
||||
///
|
||||
/// When using `decl_module` all arguments for call functions must implement this trait.
|
||||
|
||||
@@ -98,7 +98,7 @@ pub use dispatch::EnsureOneOf;
|
||||
pub use dispatch::{
|
||||
AsEnsureOriginWithArg, CallerTrait, EitherOf, EitherOfDiverse, EnsureOrigin,
|
||||
EnsureOriginEqualOrHigherPrivilege, EnsureOriginWithArg, MapSuccess, NeverEnsureOrigin,
|
||||
OriginTrait, TryMapSuccess, UnfilteredDispatchable,
|
||||
OriginTrait, TryMapSuccess, TryWithMorphedArg, UnfilteredDispatchable,
|
||||
};
|
||||
|
||||
mod voting;
|
||||
|
||||
@@ -48,19 +48,6 @@ pub trait EnsureOrigin<OuterOrigin> {
|
||||
fn try_successful_origin() -> Result<OuterOrigin, ()>;
|
||||
}
|
||||
|
||||
/// [`EnsureOrigin`] implementation that always fails.
|
||||
pub struct NeverEnsureOrigin<Success>(sp_std::marker::PhantomData<Success>);
|
||||
impl<OO, Success> EnsureOrigin<OO> for NeverEnsureOrigin<Success> {
|
||||
type Success = Success;
|
||||
fn try_origin(o: OO) -> Result<Success, OO> {
|
||||
Err(o)
|
||||
}
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin() -> Result<OO, ()> {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
/// [`EnsureOrigin`] implementation that checks that an origin has equal or higher privilege
|
||||
/// compared to the expected `Origin`.
|
||||
///
|
||||
@@ -166,6 +153,62 @@ pub trait EnsureOriginWithArg<OuterOrigin, Argument> {
|
||||
fn try_successful_origin(a: &Argument) -> Result<OuterOrigin, ()>;
|
||||
}
|
||||
|
||||
/// Simple macro to explicitly implement [EnsureOriginWithArg] to be used on any type which
|
||||
/// implements [EnsureOrigin]. This is quick and dirty, so you must use the type parameters `O`
|
||||
/// (the origin type), `T` (the argument type) and `AccountId` (if you are using the `O: ..` form).
|
||||
///
|
||||
/// The argument is ignored, much like in [AsEnsureOriginWithArg].
|
||||
#[macro_export]
|
||||
macro_rules! impl_ensure_origin_with_arg_ignoring_arg {
|
||||
( impl < { O: .., I: 'static, $( $bound:tt )* }> EnsureOriginWithArg<O, $t_param:ty> for $name:ty {} ) => {
|
||||
impl_ensure_origin_with_arg_ignoring_arg! {
|
||||
impl <{
|
||||
O: Into<Result<RawOrigin<AccountId, I>, O>> + From<RawOrigin<AccountId, I>>,
|
||||
I: 'static,
|
||||
$( $bound )*
|
||||
}> EnsureOriginWithArg<O, $t_param> for $name {}
|
||||
}
|
||||
};
|
||||
( impl < { O: .. , $( $bound:tt )* }> EnsureOriginWithArg<O, $t_param:ty> for $name:ty {} ) => {
|
||||
impl_ensure_origin_with_arg_ignoring_arg! {
|
||||
impl <{
|
||||
O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
|
||||
$( $bound )*
|
||||
}> EnsureOriginWithArg<O, $t_param> for $name {}
|
||||
}
|
||||
};
|
||||
( impl < { $( $bound:tt )* } > EnsureOriginWithArg<$o_param:ty, $t_param:ty> for $name:ty {} ) => {
|
||||
impl < $( $bound )* > EnsureOriginWithArg<$o_param, $t_param> for $name {
|
||||
type Success = <Self as EnsureOrigin<$o_param>>::Success;
|
||||
fn try_origin(o: $o_param, _: &$t_param) -> Result<Self::Success, $o_param> {
|
||||
<Self as EnsureOrigin<$o_param>>::try_origin(o)
|
||||
}
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin(_: &$t_param) -> Result<$o_param, ()> {
|
||||
<Self as EnsureOrigin<$o_param>>::try_successful_origin()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// [`EnsureOrigin`] implementation that always fails.
|
||||
pub struct NeverEnsureOrigin<Success>(sp_std::marker::PhantomData<Success>);
|
||||
impl<OO, Success> EnsureOrigin<OO> for NeverEnsureOrigin<Success> {
|
||||
type Success = Success;
|
||||
fn try_origin(o: OO) -> Result<Success, OO> {
|
||||
Err(o)
|
||||
}
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin() -> Result<OO, ()> {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
impl_ensure_origin_with_arg_ignoring_arg! {
|
||||
impl<{ OO, Success, A }>
|
||||
EnsureOriginWithArg<OO, A> for NeverEnsureOrigin<Success>
|
||||
{}
|
||||
}
|
||||
|
||||
pub struct AsEnsureOriginWithArg<EO>(sp_std::marker::PhantomData<EO>);
|
||||
impl<OuterOrigin, Argument, EO: EnsureOrigin<OuterOrigin>>
|
||||
EnsureOriginWithArg<OuterOrigin, Argument> for AsEnsureOriginWithArg<EO>
|
||||
@@ -207,6 +250,18 @@ impl<O, Original: EnsureOrigin<O>, Mutator: Morph<Original::Success>> EnsureOrig
|
||||
Original::try_successful_origin()
|
||||
}
|
||||
}
|
||||
impl<O, Original: EnsureOriginWithArg<O, A>, Mutator: Morph<Original::Success>, A>
|
||||
EnsureOriginWithArg<O, A> for MapSuccess<Original, Mutator>
|
||||
{
|
||||
type Success = Mutator::Outcome;
|
||||
fn try_origin(o: O, a: &A) -> Result<Mutator::Outcome, O> {
|
||||
Ok(Mutator::morph(Original::try_origin(o, a)?))
|
||||
}
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin(a: &A) -> Result<O, ()> {
|
||||
Original::try_successful_origin(a)
|
||||
}
|
||||
}
|
||||
|
||||
/// A derivative `EnsureOrigin` implementation. It mutates the `Success` result of an `Original`
|
||||
/// implementation with a given `Mutator`, allowing the possibility of an error to be returned
|
||||
@@ -228,6 +283,43 @@ impl<O: Clone, Original: EnsureOrigin<O>, Mutator: TryMorph<Original::Success>>
|
||||
Original::try_successful_origin()
|
||||
}
|
||||
}
|
||||
impl<O: Clone, Original: EnsureOriginWithArg<O, A>, Mutator: TryMorph<Original::Success>, A>
|
||||
EnsureOriginWithArg<O, A> for TryMapSuccess<Original, Mutator>
|
||||
{
|
||||
type Success = Mutator::Outcome;
|
||||
fn try_origin(o: O, a: &A) -> Result<Mutator::Outcome, O> {
|
||||
let orig = o.clone();
|
||||
Mutator::try_morph(Original::try_origin(o, a)?).map_err(|()| orig)
|
||||
}
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin(a: &A) -> Result<O, ()> {
|
||||
Original::try_successful_origin(a)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TryWithMorphedArg<O, A, Morph, Inner, Success>(
|
||||
PhantomData<(O, A, Morph, Inner, Success)>,
|
||||
);
|
||||
impl<
|
||||
O,
|
||||
A,
|
||||
Morph: for<'a> TryMorph<&'a A>,
|
||||
Inner: for<'a> EnsureOriginWithArg<O, <Morph as TryMorph<&'a A>>::Outcome, Success = Success>,
|
||||
Success,
|
||||
> EnsureOriginWithArg<O, A> for TryWithMorphedArg<O, A, Morph, Inner, Success>
|
||||
{
|
||||
type Success = Success;
|
||||
fn try_origin(o: O, a: &A) -> Result<Success, O> {
|
||||
match Morph::try_morph(a) {
|
||||
Ok(x) => Inner::try_origin(o, &x),
|
||||
_ => return Err(o),
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin(a: &A) -> Result<O, ()> {
|
||||
Inner::try_successful_origin(&Morph::try_morph(a).map_err(|_| ())?)
|
||||
}
|
||||
}
|
||||
|
||||
/// "OR gate" implementation of `EnsureOrigin` allowing for different `Success` types for `L`
|
||||
/// and `R`, with them combined using an `Either` type.
|
||||
@@ -250,6 +342,24 @@ impl<OuterOrigin, L: EnsureOrigin<OuterOrigin>, R: EnsureOrigin<OuterOrigin>>
|
||||
L::try_successful_origin().or_else(|()| R::try_successful_origin())
|
||||
}
|
||||
}
|
||||
impl<
|
||||
OuterOrigin,
|
||||
L: EnsureOriginWithArg<OuterOrigin, Argument>,
|
||||
R: EnsureOriginWithArg<OuterOrigin, Argument>,
|
||||
Argument,
|
||||
> EnsureOriginWithArg<OuterOrigin, Argument> for EitherOfDiverse<L, R>
|
||||
{
|
||||
type Success = Either<L::Success, R::Success>;
|
||||
fn try_origin(o: OuterOrigin, a: &Argument) -> Result<Self::Success, OuterOrigin> {
|
||||
L::try_origin(o, a)
|
||||
.map_or_else(|o| R::try_origin(o, a).map(Either::Right), |o| Ok(Either::Left(o)))
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin(a: &Argument) -> Result<OuterOrigin, ()> {
|
||||
L::try_successful_origin(a).or_else(|()| R::try_successful_origin(a))
|
||||
}
|
||||
}
|
||||
|
||||
/// "OR gate" implementation of `EnsureOrigin` allowing for different `Success` types for `L`
|
||||
/// and `R`, with them combined using an `Either` type.
|
||||
@@ -283,6 +393,23 @@ impl<
|
||||
L::try_successful_origin().or_else(|()| R::try_successful_origin())
|
||||
}
|
||||
}
|
||||
impl<
|
||||
OuterOrigin,
|
||||
L: EnsureOriginWithArg<OuterOrigin, Argument>,
|
||||
R: EnsureOriginWithArg<OuterOrigin, Argument, Success = L::Success>,
|
||||
Argument,
|
||||
> EnsureOriginWithArg<OuterOrigin, Argument> for EitherOf<L, R>
|
||||
{
|
||||
type Success = L::Success;
|
||||
fn try_origin(o: OuterOrigin, a: &Argument) -> Result<Self::Success, OuterOrigin> {
|
||||
L::try_origin(o, a).or_else(|o| R::try_origin(o, a))
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin(a: &Argument) -> Result<OuterOrigin, ()> {
|
||||
L::try_successful_origin(a).or_else(|()| R::try_successful_origin(a))
|
||||
}
|
||||
}
|
||||
|
||||
/// Type that can be dispatched with an origin but without checking the origin filter.
|
||||
///
|
||||
@@ -306,6 +433,21 @@ pub trait CallerTrait<AccountId>: Parameter + Member + From<RawOrigin<AccountId>
|
||||
|
||||
/// Extract a reference to the system-level `RawOrigin` if it is that.
|
||||
fn as_system_ref(&self) -> Option<&RawOrigin<AccountId>>;
|
||||
|
||||
/// Extract the signer from it if a system `Signed` origin, `None` otherwise.
|
||||
fn as_signed(&self) -> Option<&AccountId> {
|
||||
self.as_system_ref().and_then(RawOrigin::as_signed)
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is a system `Root` origin, `None` otherwise.
|
||||
fn is_root(&self) -> bool {
|
||||
self.as_system_ref().map_or(false, RawOrigin::is_root)
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is a system `None` origin, `None` otherwise.
|
||||
fn is_none(&self) -> bool {
|
||||
self.as_system_ref().map_or(false, RawOrigin::is_none)
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods available on `frame_system::Config::RuntimeOrigin`.
|
||||
@@ -356,7 +498,13 @@ pub trait OriginTrait: Sized {
|
||||
fn signed(by: Self::AccountId) -> Self;
|
||||
|
||||
/// Extract the signer from the message if it is a `Signed` origin.
|
||||
#[deprecated = "Use `into_signer` instead"]
|
||||
fn as_signed(self) -> Option<Self::AccountId> {
|
||||
self.into_signer()
|
||||
}
|
||||
|
||||
/// Extract the signer from the message if it is a `Signed` origin.
|
||||
fn into_signer(self) -> Option<Self::AccountId> {
|
||||
self.into_caller().into_system().and_then(|s| {
|
||||
if let RawOrigin::Signed(who) = s {
|
||||
Some(who)
|
||||
|
||||
@@ -89,10 +89,11 @@ use frame_support::{
|
||||
extract_actual_pays_fee, extract_actual_weight, DispatchClass, DispatchInfo,
|
||||
DispatchResult, DispatchResultWithPostInfo, PerDispatchClass,
|
||||
},
|
||||
impl_ensure_origin_with_arg_ignoring_arg,
|
||||
storage::{self, StorageStreamIter},
|
||||
traits::{
|
||||
ConstU32, Contains, EnsureOrigin, Get, HandleLifetime, OnKilledAccount, OnNewAccount,
|
||||
OriginTrait, PalletInfo, SortedMembers, StoredMap, TypedGet,
|
||||
ConstU32, Contains, EnsureOrigin, EnsureOriginWithArg, Get, HandleLifetime,
|
||||
OnKilledAccount, OnNewAccount, OriginTrait, PalletInfo, SortedMembers, StoredMap, TypedGet,
|
||||
},
|
||||
Parameter,
|
||||
};
|
||||
@@ -265,7 +266,7 @@ pub mod pallet {
|
||||
type RuntimeOrigin: Into<Result<RawOrigin<Self::AccountId>, Self::RuntimeOrigin>>
|
||||
+ From<RawOrigin<Self::AccountId>>
|
||||
+ Clone
|
||||
+ OriginTrait<Call = Self::RuntimeCall>;
|
||||
+ OriginTrait<Call = Self::RuntimeCall, AccountId = Self::AccountId>;
|
||||
|
||||
/// The aggregated `RuntimeCall` type.
|
||||
#[pallet::no_default]
|
||||
@@ -823,6 +824,12 @@ impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, Acco
|
||||
}
|
||||
}
|
||||
|
||||
impl_ensure_origin_with_arg_ignoring_arg! {
|
||||
impl< { O: .., AccountId: Decode, T } >
|
||||
EnsureOriginWithArg<O, T> for EnsureRoot<AccountId>
|
||||
{}
|
||||
}
|
||||
|
||||
/// Ensure the origin is Root and return the provided `Success` value.
|
||||
pub struct EnsureRootWithSuccess<AccountId, Success>(
|
||||
sp_std::marker::PhantomData<(AccountId, Success)>,
|
||||
@@ -847,6 +854,12 @@ impl<
|
||||
}
|
||||
}
|
||||
|
||||
impl_ensure_origin_with_arg_ignoring_arg! {
|
||||
impl< { O: .., AccountId: Decode, Success: TypedGet, T } >
|
||||
EnsureOriginWithArg<O, T> for EnsureRootWithSuccess<AccountId, Success>
|
||||
{}
|
||||
}
|
||||
|
||||
/// Ensure the origin is provided `Ensure` origin and return the provided `Success` value.
|
||||
pub struct EnsureWithSuccess<Ensure, AccountId, Success>(
|
||||
sp_std::marker::PhantomData<(Ensure, AccountId, Success)>,
|
||||
@@ -892,6 +905,12 @@ impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, Acco
|
||||
}
|
||||
}
|
||||
|
||||
impl_ensure_origin_with_arg_ignoring_arg! {
|
||||
impl< { O: .., AccountId: Decode, T } >
|
||||
EnsureOriginWithArg<O, T> for EnsureSigned<AccountId>
|
||||
{}
|
||||
}
|
||||
|
||||
/// Ensure the origin is `Signed` origin from the given `AccountId`.
|
||||
pub struct EnsureSignedBy<Who, AccountId>(sp_std::marker::PhantomData<(Who, AccountId)>);
|
||||
impl<
|
||||
@@ -918,6 +937,12 @@ impl<
|
||||
}
|
||||
}
|
||||
|
||||
impl_ensure_origin_with_arg_ignoring_arg! {
|
||||
impl< { O: .., Who: SortedMembers<AccountId>, AccountId: PartialEq + Clone + Ord + Decode, T } >
|
||||
EnsureOriginWithArg<O, T> for EnsureSignedBy<Who, AccountId>
|
||||
{}
|
||||
}
|
||||
|
||||
/// Ensure the origin is `None`. i.e. unsigned transaction.
|
||||
pub struct EnsureNone<AccountId>(sp_std::marker::PhantomData<AccountId>);
|
||||
impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, AccountId>
|
||||
@@ -937,10 +962,16 @@ impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, Acco
|
||||
}
|
||||
}
|
||||
|
||||
impl_ensure_origin_with_arg_ignoring_arg! {
|
||||
impl< { O: .., AccountId, T } >
|
||||
EnsureOriginWithArg<O, T> for EnsureNone<AccountId>
|
||||
{}
|
||||
}
|
||||
|
||||
/// Always fail.
|
||||
pub struct EnsureNever<T>(sp_std::marker::PhantomData<T>);
|
||||
impl<O, T> EnsureOrigin<O> for EnsureNever<T> {
|
||||
type Success = T;
|
||||
pub struct EnsureNever<Success>(sp_std::marker::PhantomData<Success>);
|
||||
impl<O, Success> EnsureOrigin<O> for EnsureNever<Success> {
|
||||
type Success = Success;
|
||||
fn try_origin(o: O) -> Result<Self::Success, O> {
|
||||
Err(o)
|
||||
}
|
||||
@@ -951,6 +982,12 @@ impl<O, T> EnsureOrigin<O> for EnsureNever<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl_ensure_origin_with_arg_ignoring_arg! {
|
||||
impl< { O, Success, T } >
|
||||
EnsureOriginWithArg<O, T> for EnsureNever<Success>
|
||||
{}
|
||||
}
|
||||
|
||||
/// Ensure that the origin `o` represents a signed extrinsic (i.e. transaction).
|
||||
/// Returns `Ok` with the account that signed the extrinsic or an `Err` otherwise.
|
||||
pub fn ensure_signed<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<AccountId, BadOrigin>
|
||||
|
||||
@@ -746,19 +746,20 @@ fn ensure_signed_stuff_works() {
|
||||
}
|
||||
|
||||
let signed_origin = RuntimeOrigin::signed(0u64);
|
||||
assert_ok!(EnsureSigned::try_origin(signed_origin.clone()));
|
||||
assert_ok!(EnsureSignedBy::<Members, _>::try_origin(signed_origin));
|
||||
assert_ok!(<EnsureSigned<_> as EnsureOrigin<_>>::try_origin(signed_origin.clone()));
|
||||
assert_ok!(<EnsureSignedBy<Members, _> as EnsureOrigin<_>>::try_origin(signed_origin));
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
{
|
||||
let successful_origin: RuntimeOrigin = EnsureSigned::try_successful_origin()
|
||||
.expect("EnsureSigned has no successful origin required for the test");
|
||||
assert_ok!(EnsureSigned::try_origin(successful_origin));
|
||||
let successful_origin: RuntimeOrigin =
|
||||
<EnsureSigned<_> as EnsureOrigin<_>>::try_successful_origin()
|
||||
.expect("EnsureSigned has no successful origin required for the test");
|
||||
assert_ok!(<EnsureSigned<_> as EnsureOrigin<_>>::try_origin(successful_origin));
|
||||
|
||||
let successful_origin: RuntimeOrigin =
|
||||
EnsureSignedBy::<Members, _>::try_successful_origin()
|
||||
<EnsureSignedBy<Members, _> as EnsureOrigin<_>>::try_successful_origin()
|
||||
.expect("EnsureSignedBy has no successful origin required for the test");
|
||||
assert_ok!(EnsureSignedBy::<Members, _>::try_origin(successful_origin));
|
||||
assert_ok!(<EnsureSignedBy<Members, _> as EnsureOrigin<_>>::try_origin(successful_origin));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -339,6 +339,33 @@ impl<T, A: TryInto<T>> TryMorph<A> for TryMorphInto<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation of `Morph` to retrieve just the first element of a tuple.
|
||||
pub struct TakeFirst;
|
||||
impl<T1> Morph<(T1,)> for TakeFirst {
|
||||
type Outcome = T1;
|
||||
fn morph(a: (T1,)) -> T1 {
|
||||
a.0
|
||||
}
|
||||
}
|
||||
impl<T1, T2> Morph<(T1, T2)> for TakeFirst {
|
||||
type Outcome = T1;
|
||||
fn morph(a: (T1, T2)) -> T1 {
|
||||
a.0
|
||||
}
|
||||
}
|
||||
impl<T1, T2, T3> Morph<(T1, T2, T3)> for TakeFirst {
|
||||
type Outcome = T1;
|
||||
fn morph(a: (T1, T2, T3)) -> T1 {
|
||||
a.0
|
||||
}
|
||||
}
|
||||
impl<T1, T2, T3, T4> Morph<(T1, T2, T3, T4)> for TakeFirst {
|
||||
type Outcome = T1;
|
||||
fn morph(a: (T1, T2, T3, T4)) -> T1 {
|
||||
a.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a `Morph` and/or `TryMorph` impls with a simple closure-like expression.
|
||||
///
|
||||
/// # Examples
|
||||
|
||||
Reference in New Issue
Block a user