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

Commit e2a6c3e

Browse files
authored
"OR gate" for EnsureOrigin (#6237)
* 'OR gate' for EnsureOrigin. * Formatting. * More formatting. * Add docstring; Update 'Success' type. * Bump runtime impl_version. * Fix successful_origin. * Add either into std feature list. * Update docs.
1 parent 571cfc1 commit e2a6c3e

File tree

11 files changed

+91
-63
lines changed

11 files changed

+91
-63
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bin/node/runtime/src/lib.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use frame_support::{
3232
},
3333
traits::{Currency, Imbalance, KeyOwnerProofSystem, OnUnbalanced, Randomness, LockIdentifier},
3434
};
35+
use frame_system::{EnsureRoot, EnsureOneOf};
3536
use frame_support::traits::{Filter, InstanceFilter};
3637
use codec::{Encode, Decode};
3738
use sp_core::{
@@ -96,7 +97,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
9697
// implementation changes and behavior does not, then leave spec_version as
9798
// is and increment impl_version.
9899
spec_version: 252,
99-
impl_version: 0,
100+
impl_version: 1,
100101
apis: RUNTIME_API_VERSIONS,
101102
transaction_version: 1,
102103
};
@@ -410,7 +411,11 @@ impl pallet_staking::Trait for Runtime {
410411
type BondingDuration = BondingDuration;
411412
type SlashDeferDuration = SlashDeferDuration;
412413
/// A super-majority of the council can cancel the slash.
413-
type SlashCancelOrigin = pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>;
414+
type SlashCancelOrigin = EnsureOneOf<
415+
AccountId,
416+
EnsureRoot<AccountId>,
417+
pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>
418+
>;
414419
type SessionInterface = Self;
415420
type RewardCurve = RewardCurve;
416421
type NextNewSession = Session;
@@ -528,13 +533,18 @@ impl pallet_collective::Trait<TechnicalCollective> for Runtime {
528533
type MaxProposals = TechnicalMaxProposals;
529534
}
530535

536+
type EnsureRootOrHalfCouncil = EnsureOneOf<
537+
AccountId,
538+
EnsureRoot<AccountId>,
539+
pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>
540+
>;
531541
impl pallet_membership::Trait<pallet_membership::Instance1> for Runtime {
532542
type Event = Event;
533-
type AddOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
534-
type RemoveOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
535-
type SwapOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
536-
type ResetOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
537-
type PrimeOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
543+
type AddOrigin = EnsureRootOrHalfCouncil;
544+
type RemoveOrigin = EnsureRootOrHalfCouncil;
545+
type SwapOrigin = EnsureRootOrHalfCouncil;
546+
type ResetOrigin = EnsureRootOrHalfCouncil;
547+
type PrimeOrigin = EnsureRootOrHalfCouncil;
538548
type MembershipInitialized = TechnicalCommittee;
539549
type MembershipChanged = TechnicalCommittee;
540550
}
@@ -554,8 +564,16 @@ parameter_types! {
554564
impl pallet_treasury::Trait for Runtime {
555565
type ModuleId = TreasuryModuleId;
556566
type Currency = Balances;
557-
type ApproveOrigin = pallet_collective::EnsureMembers<_4, AccountId, CouncilCollective>;
558-
type RejectOrigin = pallet_collective::EnsureMembers<_2, AccountId, CouncilCollective>;
567+
type ApproveOrigin = EnsureOneOf<
568+
AccountId,
569+
EnsureRoot<AccountId>,
570+
pallet_collective::EnsureMembers<_4, AccountId, CouncilCollective>
571+
>;
572+
type RejectOrigin = EnsureOneOf<
573+
AccountId,
574+
EnsureRoot<AccountId>,
575+
pallet_collective::EnsureMembers<_2, AccountId, CouncilCollective>
576+
>;
559577
type Tippers = Elections;
560578
type TipCountdown = TipCountdown;
561579
type TipFindersFee = TipFindersFee;
@@ -734,8 +752,8 @@ impl pallet_identity::Trait for Runtime {
734752
type MaxAdditionalFields = MaxAdditionalFields;
735753
type MaxRegistrars = MaxRegistrars;
736754
type Slashed = Treasury;
737-
type ForceOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
738-
type RegistrarOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
755+
type ForceOrigin = EnsureRootOrHalfCouncil;
756+
type RegistrarOrigin = EnsureRootOrHalfCouncil;
739757
}
740758

741759
parameter_types! {

frame/identity/src/lib.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ use frame_support::{
7878
traits::{Currency, ReservableCurrency, OnUnbalanced, Get, BalanceStatus, EnsureOrigin},
7979
weights::Weight,
8080
};
81-
use frame_system::{self as system, ensure_signed, ensure_root};
81+
use frame_system::{self as system, ensure_signed};
8282

8383
mod benchmarking;
8484

@@ -635,9 +635,7 @@ decl_module! {
635635
/// # </weight>
636636
#[weight = weight_for::add_registrar::<T>(T::MaxRegistrars::get().into()) ]
637637
fn add_registrar(origin, account: T::AccountId) -> DispatchResultWithPostInfo {
638-
T::RegistrarOrigin::try_origin(origin)
639-
.map(|_| ())
640-
.or_else(ensure_root)?;
638+
T::RegistrarOrigin::ensure_origin(origin)?;
641639

642640
let (i, registrar_count) = <Registrars<T>>::try_mutate(
643641
|registrars| -> Result<(RegistrarIndex, usize), DispatchError> {
@@ -1108,9 +1106,7 @@ decl_module! {
11081106
T::MaxAdditionalFields::get().into(), // X
11091107
)]
11101108
fn kill_identity(origin, target: <T::Lookup as StaticLookup>::Source) -> DispatchResultWithPostInfo {
1111-
T::ForceOrigin::try_origin(origin)
1112-
.map(|_| ())
1113-
.or_else(ensure_root)?;
1109+
T::ForceOrigin::ensure_origin(origin)?;
11141110

11151111
// Figure out who we're meant to be clearing.
11161112
let target = T::Lookup::lookup(target)?;
@@ -1435,7 +1431,7 @@ mod tests {
14351431
new_test_ext().execute_with(|| {
14361432
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
14371433
assert_ok!(Identity::set_subs(Origin::signed(10), vec![(20, Data::Raw(vec![40; 1]))]));
1438-
assert_ok!(Identity::kill_identity(Origin::ROOT, 10));
1434+
assert_ok!(Identity::kill_identity(Origin::signed(2), 10));
14391435
assert_eq!(Balances::free_balance(10), 80);
14401436
assert!(Identity::super_of(20).is_none());
14411437
});

frame/membership/src/lib.rs

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use frame_support::{
2828
decl_module, decl_storage, decl_event, decl_error,
2929
traits::{ChangeMembers, InitializeMembers, EnsureOrigin},
3030
};
31-
use frame_system::{self as system, ensure_root, ensure_signed};
31+
use frame_system::{self as system, ensure_signed};
3232

3333
pub trait Trait<I=DefaultInstance>: frame_system::Trait {
3434
/// The overarching event type.
@@ -120,9 +120,7 @@ decl_module! {
120120
/// May only be called from `AddOrigin` or root.
121121
#[weight = 50_000_000]
122122
pub fn add_member(origin, who: T::AccountId) {
123-
T::AddOrigin::try_origin(origin)
124-
.map(|_| ())
125-
.or_else(ensure_root)?;
123+
T::AddOrigin::ensure_origin(origin)?;
126124

127125
let mut members = <Members<T, I>>::get();
128126
let location = members.binary_search(&who).err().ok_or(Error::<T, I>::AlreadyMember)?;
@@ -139,9 +137,7 @@ decl_module! {
139137
/// May only be called from `RemoveOrigin` or root.
140138
#[weight = 50_000_000]
141139
pub fn remove_member(origin, who: T::AccountId) {
142-
T::RemoveOrigin::try_origin(origin)
143-
.map(|_| ())
144-
.or_else(ensure_root)?;
140+
T::RemoveOrigin::ensure_origin(origin)?;
145141

146142
let mut members = <Members<T, I>>::get();
147143
let location = members.binary_search(&who).ok().ok_or(Error::<T, I>::NotMember)?;
@@ -161,9 +157,7 @@ decl_module! {
161157
/// Prime membership is *not* passed from `remove` to `add`, if extant.
162158
#[weight = 50_000_000]
163159
pub fn swap_member(origin, remove: T::AccountId, add: T::AccountId) {
164-
T::SwapOrigin::try_origin(origin)
165-
.map(|_| ())
166-
.or_else(ensure_root)?;
160+
T::SwapOrigin::ensure_origin(origin)?;
167161

168162
if remove == add { return Ok(()) }
169163

@@ -190,9 +184,7 @@ decl_module! {
190184
/// May only be called from `ResetOrigin` or root.
191185
#[weight = 50_000_000]
192186
pub fn reset_members(origin, members: Vec<T::AccountId>) {
193-
T::ResetOrigin::try_origin(origin)
194-
.map(|_| ())
195-
.or_else(ensure_root)?;
187+
T::ResetOrigin::ensure_origin(origin)?;
196188

197189
let mut members = members;
198190
members.sort();
@@ -241,9 +233,7 @@ decl_module! {
241233
/// Set the prime member. Must be a current member.
242234
#[weight = 50_000_000]
243235
pub fn set_prime(origin, who: T::AccountId) {
244-
T::PrimeOrigin::try_origin(origin)
245-
.map(|_| ())
246-
.or_else(ensure_root)?;
236+
T::PrimeOrigin::ensure_origin(origin)?;
247237
Self::members().binary_search(&who).ok().ok_or(Error::<T, I>::NotMember)?;
248238
Prime::<T, I>::put(&who);
249239
T::MembershipChanged::set_prime(Some(who));
@@ -252,9 +242,7 @@ decl_module! {
252242
/// Remove the prime member if it exists.
253243
#[weight = 50_000_000]
254244
pub fn clear_prime(origin) {
255-
T::PrimeOrigin::try_origin(origin)
256-
.map(|_| ())
257-
.or_else(ensure_root)?;
245+
T::PrimeOrigin::ensure_origin(origin)?;
258246
Prime::<T, I>::kill();
259247
T::MembershipChanged::set_prime(None);
260248
}

frame/nicks/src/lib.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use frame_support::{
4747
decl_module, decl_event, decl_storage, ensure, decl_error,
4848
traits::{Currency, EnsureOrigin, ReservableCurrency, OnUnbalanced, Get},
4949
};
50-
use frame_system::{self as system, ensure_signed, ensure_root};
50+
use frame_system::{self as system, ensure_signed};
5151

5252
type BalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
5353
type NegativeImbalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::NegativeImbalance;
@@ -197,9 +197,7 @@ decl_module! {
197197
/// # </weight>
198198
#[weight = 70_000_000]
199199
fn kill_name(origin, target: <T::Lookup as StaticLookup>::Source) {
200-
T::ForceOrigin::try_origin(origin)
201-
.map(|_| ())
202-
.or_else(ensure_root)?;
200+
T::ForceOrigin::ensure_origin(origin)?;
203201

204202
// Figure out who we're meant to be clearing.
205203
let target = T::Lookup::lookup(target)?;
@@ -225,9 +223,7 @@ decl_module! {
225223
/// # </weight>
226224
#[weight = 70_000_000]
227225
fn force_name(origin, target: <T::Lookup as StaticLookup>::Source, name: Vec<u8>) {
228-
T::ForceOrigin::try_origin(origin)
229-
.map(|_| ())
230-
.or_else(ensure_root)?;
226+
T::ForceOrigin::ensure_origin(origin)?;
231227

232228
let target = T::Lookup::lookup(target)?;
233229
let deposit = <NameOf<T>>::get(&target).map(|x| x.1).unwrap_or_else(Zero::zero);

frame/scored-pool/src/lib.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,7 @@ decl_module! {
318318
dest: <T::Lookup as StaticLookup>::Source,
319319
index: u32
320320
) {
321-
T::KickOrigin::try_origin(origin)
322-
.map(|_| ())
323-
.or_else(ensure_root)?;
321+
T::KickOrigin::ensure_origin(origin)?;
324322

325323
let who = T::Lookup::lookup(dest)?;
326324

@@ -344,9 +342,7 @@ decl_module! {
344342
index: u32,
345343
score: T::Score
346344
) {
347-
T::ScoreOrigin::try_origin(origin)
348-
.map(|_| ())
349-
.or_else(ensure_root)?;
345+
T::ScoreOrigin::ensure_origin(origin)?;
350346

351347
let who = T::Lookup::lookup(dest)?;
352348

frame/staking/src/lib.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1906,9 +1906,7 @@ decl_module! {
19061906
.saturating_add((35 * WEIGHT_PER_MICROS).saturating_mul(slash_indices.len() as Weight))
19071907
]
19081908
fn cancel_deferred_slash(origin, era: EraIndex, slash_indices: Vec<u32>) {
1909-
T::SlashCancelOrigin::try_origin(origin)
1910-
.map(|_| ())
1911-
.or_else(ensure_root)?;
1909+
T::SlashCancelOrigin::ensure_origin(origin)?;
19121910

19131911
ensure!(!slash_indices.is_empty(), Error::<T>::EmptyTargets);
19141912
ensure!(is_sorted_and_unique(&slash_indices), Error::<T>::NotSortedAndUnique);

frame/system/src/lib.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ use sp_std::marker::PhantomData;
102102
use sp_std::fmt::Debug;
103103
use sp_version::RuntimeVersion;
104104
use sp_runtime::{
105-
RuntimeDebug, Perbill, DispatchError, DispatchResult,
105+
RuntimeDebug, Perbill, DispatchError, DispatchResult, Either,
106106
generic::{self, Era},
107107
transaction_validity::{
108108
ValidTransaction, TransactionPriority, TransactionLongevity, TransactionValidityError,
@@ -847,6 +847,30 @@ impl<O, T> EnsureOrigin<O> for EnsureNever<T> {
847847
}
848848
}
849849

850+
/// The "OR gate" implementation of `EnsureOrigin`.
851+
///
852+
/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first.
853+
pub struct EnsureOneOf<AccountId, L, R>(sp_std::marker::PhantomData<(AccountId, L, R)>);
854+
impl<
855+
AccountId,
856+
O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
857+
L: EnsureOrigin<O>,
858+
R: EnsureOrigin<O>,
859+
> EnsureOrigin<O> for EnsureOneOf<AccountId, L, R> {
860+
type Success = Either<L::Success, R::Success>;
861+
fn try_origin(o: O) -> Result<Self::Success, O> {
862+
L::try_origin(o).map_or_else(
863+
|o| R::try_origin(o).map(|o| Either::Right(o)),
864+
|o| Ok(Either::Left(o)),
865+
)
866+
}
867+
868+
#[cfg(feature = "runtime-benchmarks")]
869+
fn successful_origin() -> O {
870+
L::successful_origin()
871+
}
872+
}
873+
850874
/// Ensure that the origin `o` represents a signed extrinsic (i.e. transaction).
851875
/// Returns `Ok` with the account that signed the extrinsic or an `Err` otherwise.
852876
pub fn ensure_signed<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<AccountId, BadOrigin>
@@ -1879,7 +1903,7 @@ pub(crate) mod tests {
18791903
use sp_core::H256;
18801904
use sp_runtime::{traits::{BlakeTwo256, IdentityLookup, SignedExtension}, testing::Header, DispatchError};
18811905
use frame_support::{
1882-
impl_outer_origin, parameter_types, assert_ok, assert_noop,
1906+
impl_outer_origin, parameter_types, assert_ok, assert_noop, assert_err,
18831907
weights::WithPostDispatchInfo,
18841908
};
18851909

@@ -2701,4 +2725,15 @@ pub(crate) mod tests {
27012725
assert!(System::events().len() == 1);
27022726
});
27032727
}
2728+
2729+
#[test]
2730+
fn ensure_one_of_works() {
2731+
fn ensure_root_or_signed(o: RawOrigin<u64>) -> Result<Either<(), u64>, Origin> {
2732+
EnsureOneOf::<u64, EnsureRoot<u64>, EnsureSigned<u64>>::try_origin(o.into())
2733+
}
2734+
2735+
assert_ok!(ensure_root_or_signed(RawOrigin::Root), Either::Left(()));
2736+
assert_ok!(ensure_root_or_signed(RawOrigin::Signed(0)), Either::Right(0));
2737+
assert_err!(ensure_root_or_signed(RawOrigin::None), Origin::from(RawOrigin::None));
2738+
}
27042739
}

frame/treasury/src/lib.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ use sp_runtime::{Permill, ModuleId, Percent, RuntimeDebug, traits::{
102102
use frame_support::weights::{Weight, DispatchClass};
103103
use frame_support::traits::{Contains, ContainsLengthBound, EnsureOrigin};
104104
use codec::{Encode, Decode};
105-
use frame_system::{self as system, ensure_signed, ensure_root};
105+
use frame_system::{self as system, ensure_signed};
106106

107107
mod tests;
108108
mod benchmarking;
@@ -362,9 +362,7 @@ decl_module! {
362362
/// # </weight>
363363
#[weight = (130_000_000 + T::DbWeight::get().reads_writes(2, 2), DispatchClass::Operational)]
364364
fn reject_proposal(origin, #[compact] proposal_id: ProposalIndex) {
365-
T::RejectOrigin::try_origin(origin)
366-
.map(|_| ())
367-
.or_else(ensure_root)?;
365+
T::RejectOrigin::ensure_origin(origin)?;
368366

369367
let proposal = <Proposals<T>>::take(&proposal_id).ok_or(Error::<T>::InvalidProposalIndex)?;
370368
let value = proposal.bond;
@@ -384,9 +382,7 @@ decl_module! {
384382
/// # </weight>
385383
#[weight = (34_000_000 + T::DbWeight::get().reads_writes(2, 1), DispatchClass::Operational)]
386384
fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) {
387-
T::ApproveOrigin::try_origin(origin)
388-
.map(|_| ())
389-
.or_else(ensure_root)?;
385+
T::ApproveOrigin::ensure_origin(origin)?;
390386

391387
ensure!(<Proposals<T>>::contains_key(proposal_id), Error::<T>::InvalidProposalIndex);
392388
Approvals::mutate(|v| v.push(proposal_id));

primitives/runtime/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ impl-trait-for-tuples = "0.1.3"
2828
sp-inherents = { version = "2.0.0-rc3", default-features = false, path = "../inherents" }
2929
parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] }
3030
hash256-std-hasher = { version = "0.15.2", default-features = false }
31+
either = { version = "1.5", default-features = false }
3132

3233
[dev-dependencies]
3334
serde_json = "1.0.41"
@@ -51,4 +52,5 @@ std = [
5152
"sp-inherents/std",
5253
"parity-util-mem/std",
5354
"hash256-std-hasher/std",
55+
"either/use_std",
5456
]

0 commit comments

Comments
 (0)