Skip to content

Commit

Permalink
Move EnsureOneOf into the dispatch.rs, make an interface more general (
Browse files Browse the repository at this point in the history
…paritytech#10379)

* move EnsureOneOf into the dispatch.rs, make an interface more general

* Update frame/support/src/traits/dispatch.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
  • Loading branch information
3 people authored and ark0f committed Feb 27, 2023
1 parent 493c2e0 commit d06c33b
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 51 deletions.
9 changes: 2 additions & 7 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{
construct_runtime, parameter_types,
traits::{
ConstU32, Currency, EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter,
ConstU32, Currency, EnsureOneOf, EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter,
KeyOwnerProofSystem, LockIdentifier, Nothing, OnUnbalanced, U128CurrencyToVote,
},
weights::{
Expand All @@ -37,7 +37,7 @@ use frame_support::{
};
use frame_system::{
limits::{BlockLength, BlockWeights},
EnsureOneOf, EnsureRoot,
EnsureRoot,
};
pub use node_primitives::{AccountId, Signature};
use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment};
Expand Down Expand Up @@ -535,7 +535,6 @@ impl pallet_staking::Config for Runtime {
type SlashDeferDuration = SlashDeferDuration;
/// A super-majority of the council can cancel the slash.
type SlashCancelOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>,
>;
Expand Down Expand Up @@ -726,7 +725,6 @@ impl pallet_democracy::Config for Runtime {
// To cancel a proposal before it has been passed, the technical committee must be unanimous or
// Root must agree.
type CancelProposalOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, TechnicalCollective>,
>;
Expand Down Expand Up @@ -817,7 +815,6 @@ impl pallet_collective::Config<TechnicalCollective> for Runtime {
}

type EnsureRootOrHalfCouncil = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>,
>;
Expand Down Expand Up @@ -857,12 +854,10 @@ impl pallet_treasury::Config for Runtime {
type PalletId = TreasuryPalletId;
type Currency = Balances;
type ApproveOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<_3, _5, AccountId, CouncilCollective>,
>;
type RejectOrigin = EnsureOneOf<
AccountId,
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>,
>;
Expand Down
10 changes: 6 additions & 4 deletions frame/identity/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ use super::*;
use crate as pallet_identity;

use codec::{Decode, Encode};
use frame_support::{assert_noop, assert_ok, ord_parameter_types, parameter_types, BoundedVec};
use frame_system::{EnsureOneOf, EnsureRoot, EnsureSignedBy};
use frame_support::{
assert_noop, assert_ok, ord_parameter_types, parameter_types, traits::EnsureOneOf, BoundedVec,
};
use frame_system::{EnsureRoot, EnsureSignedBy};
use sp_core::H256;
use sp_runtime::{
testing::Header,
Expand Down Expand Up @@ -100,8 +102,8 @@ ord_parameter_types! {
pub const One: u64 = 1;
pub const Two: u64 = 2;
}
type EnsureOneOrRoot = EnsureOneOf<u64, EnsureRoot<u64>, EnsureSignedBy<One, u64>>;
type EnsureTwoOrRoot = EnsureOneOf<u64, EnsureRoot<u64>, EnsureSignedBy<Two, u64>>;
type EnsureOneOrRoot = EnsureOneOf<EnsureRoot<u64>, EnsureSignedBy<One, u64>>;
type EnsureTwoOrRoot = EnsureOneOf<EnsureRoot<u64>, EnsureSignedBy<Two, u64>>;
impl pallet_identity::Config for Test {
type Event = Event;
type Currency = Balances;
Expand Down
6 changes: 3 additions & 3 deletions frame/scheduler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -805,11 +805,11 @@ mod tests {
use crate as scheduler;
use frame_support::{
assert_err, assert_noop, assert_ok, ord_parameter_types, parameter_types,
traits::{Contains, EqualPrivilegeOnly, OnFinalize, OnInitialize},
traits::{Contains, EnsureOneOf, EqualPrivilegeOnly, OnFinalize, OnInitialize},
weights::constants::RocksDbWeight,
Hashable,
};
use frame_system::{EnsureOneOf, EnsureRoot, EnsureSignedBy};
use frame_system::{EnsureRoot, EnsureSignedBy};
use sp_core::H256;
use sp_runtime::{
testing::Header,
Expand Down Expand Up @@ -950,7 +950,7 @@ mod tests {
type PalletsOrigin = OriginCaller;
type Call = Call;
type MaximumWeight = MaximumSchedulerWeight;
type ScheduleOrigin = EnsureOneOf<u64, EnsureRoot<u64>, EnsureSignedBy<One, u64>>;
type ScheduleOrigin = EnsureOneOf<EnsureRoot<u64>, EnsureSignedBy<One, u64>>;
type MaxScheduledPerBlock = MaxScheduledPerBlock;
type WeightInfo = ();
type OriginPrivilegeCmp = EqualPrivilegeOnly;
Expand Down
2 changes: 1 addition & 1 deletion frame/support/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub use storage::{
};

mod dispatch;
pub use dispatch::{EnsureOrigin, OriginTrait, UnfilteredDispatchable};
pub use dispatch::{EnsureOneOf, EnsureOrigin, OriginTrait, UnfilteredDispatchable};

mod voting;
pub use voting::{CurrencyToVote, SaturatingCurrencyToVote, U128CurrencyToVote};
60 changes: 59 additions & 1 deletion frame/support/src/traits/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//! Traits for dealing with dispatching calls and the origin from which they are dispatched.

use crate::dispatch::DispatchResultWithPostInfo;
use sp_runtime::traits::BadOrigin;
use sp_runtime::{traits::BadOrigin, Either};

/// Some sort of check on the origin is performed by this object.
pub trait EnsureOrigin<OuterOrigin> {
Expand Down Expand Up @@ -94,3 +94,61 @@ pub trait OriginTrait: Sized {
/// Create with system signed origin and `frame_system::Config::BaseCallFilter`.
fn signed(by: Self::AccountId) -> Self;
}

/// The "OR gate" implementation of `EnsureOrigin`.
///
/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first.
pub struct EnsureOneOf<L, R>(sp_std::marker::PhantomData<(L, R)>);

impl<OuterOrigin, L: EnsureOrigin<OuterOrigin>, R: EnsureOrigin<OuterOrigin>>
EnsureOrigin<OuterOrigin> for EnsureOneOf<L, R>
{
type Success = Either<L::Success, R::Success>;
fn try_origin(o: OuterOrigin) -> Result<Self::Success, OuterOrigin> {
L::try_origin(o)
.map_or_else(|o| R::try_origin(o).map(|o| Either::Right(o)), |o| Ok(Either::Left(o)))
}

#[cfg(feature = "runtime-benchmarks")]
fn successful_origin() -> OuterOrigin {
L::successful_origin()
}
}

#[cfg(test)]
mod tests {
use super::*;

struct EnsureSuccess;
struct EnsureFail;

impl EnsureOrigin<()> for EnsureSuccess {
type Success = ();
fn try_origin(_: ()) -> Result<Self::Success, ()> {
Ok(())
}
#[cfg(feature = "runtime-benchmarks")]
fn successful_origin() -> () {
()
}
}

impl EnsureOrigin<()> for EnsureFail {
type Success = ();
fn try_origin(_: ()) -> Result<Self::Success, ()> {
Err(())
}
#[cfg(feature = "runtime-benchmarks")]
fn successful_origin() -> () {
()
}
}

#[test]
fn ensure_one_of_test() {
assert!(<EnsureOneOf<EnsureSuccess, EnsureSuccess>>::try_origin(()).is_ok());
assert!(<EnsureOneOf<EnsureSuccess, EnsureFail>>::try_origin(()).is_ok());
assert!(<EnsureOneOf<EnsureFail, EnsureSuccess>>::try_origin(()).is_ok());
assert!(<EnsureOneOf<EnsureFail, EnsureFail>>::try_origin(()).is_err());
}
}
25 changes: 1 addition & 24 deletions frame/system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ use sp_runtime::{
CheckEqual, Dispatchable, Hash, Lookup, LookupError, MaybeDisplay, MaybeMallocSizeOf,
MaybeSerializeDeserialize, Member, One, Saturating, SimpleBitOps, StaticLookup, Zero,
},
DispatchError, Either, Perbill, RuntimeDebug,
DispatchError, Perbill, RuntimeDebug,
};
#[cfg(any(feature = "std", test))]
use sp_std::map;
Expand Down Expand Up @@ -902,29 +902,6 @@ impl<O, T> EnsureOrigin<O> for EnsureNever<T> {
}
}

/// The "OR gate" implementation of `EnsureOrigin`.
///
/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first.
pub struct EnsureOneOf<AccountId, L, R>(sp_std::marker::PhantomData<(AccountId, L, R)>);
impl<
AccountId,
O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
L: EnsureOrigin<O>,
R: EnsureOrigin<O>,
> EnsureOrigin<O> for EnsureOneOf<AccountId, L, R>
{
type Success = Either<L::Success, R::Success>;
fn try_origin(o: O) -> Result<Self::Success, O> {
L::try_origin(o)
.map_or_else(|o| R::try_origin(o).map(|o| Either::Right(o)), |o| Ok(Either::Left(o)))
}

#[cfg(feature = "runtime-benchmarks")]
fn successful_origin() -> O {
L::successful_origin()
}
}

/// 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>
Expand Down
11 changes: 0 additions & 11 deletions frame/system/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,17 +461,6 @@ fn events_not_emitted_during_genesis() {
});
}

#[test]
fn ensure_one_of_works() {
fn ensure_root_or_signed(o: RawOrigin<u64>) -> Result<Either<(), u64>, Origin> {
EnsureOneOf::<u64, EnsureRoot<u64>, EnsureSigned<u64>>::try_origin(o.into())
}

assert_eq!(ensure_root_or_signed(RawOrigin::Root).unwrap(), Either::Left(()));
assert_eq!(ensure_root_or_signed(RawOrigin::Signed(0)).unwrap(), Either::Right(0));
assert!(ensure_root_or_signed(RawOrigin::None).is_err());
}

#[test]
fn extrinsics_root_is_calculated_correctly() {
new_test_ext().execute_with(|| {
Expand Down

0 comments on commit d06c33b

Please sign in to comment.