mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 12:17:58 +00:00
Introduce EnsureOrigin::try_successul_origin (#11558)
* Introduce `EnsureOrigin::try_successul_origin` * Formatting * Fixes * Add Morph * Fixes * Formatting
This commit is contained in:
@@ -996,11 +996,11 @@ impl<
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> O {
|
||||
fn try_successful_origin() -> Result<O, ()> {
|
||||
let zero_account_id =
|
||||
AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes())
|
||||
.expect("infinite length input; no invalid inputs for type; qed");
|
||||
O::from(RawOrigin::Member(zero_account_id))
|
||||
Ok(O::from(RawOrigin::Member(zero_account_id)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1021,8 +1021,8 @@ impl<
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> O {
|
||||
O::from(RawOrigin::Members(N, N))
|
||||
fn try_successful_origin() -> Result<O, ()> {
|
||||
Ok(O::from(RawOrigin::Members(N, N)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,8 +1046,8 @@ impl<
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> O {
|
||||
O::from(RawOrigin::Members(1u32, 0u32))
|
||||
fn try_successful_origin() -> Result<O, ()> {
|
||||
Ok(O::from(RawOrigin::Members(1u32, 0u32)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1071,7 +1071,7 @@ impl<
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> O {
|
||||
O::from(RawOrigin::Members(0u32, 0u32))
|
||||
fn try_successful_origin() -> Result<O, ()> {
|
||||
Ok(O::from(RawOrigin::Members(0u32, 0u32)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1272,9 +1272,9 @@ impl<T: Config> EnsureOrigin<T::Origin> for EnsureFounder<T> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> T::Origin {
|
||||
let founder = Founder::<T>::get().expect("society founder should exist");
|
||||
T::Origin::from(frame_system::RawOrigin::Signed(founder))
|
||||
fn try_successful_origin() -> Result<T::Origin, ()> {
|
||||
let founder = Founder::<T>::get().ok_or(())?;
|
||||
Ok(T::Origin::from(frame_system::RawOrigin::Signed(founder)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,10 +18,14 @@
|
||||
//! Traits for dealing with dispatching calls and the origin from which they are dispatched.
|
||||
|
||||
use crate::dispatch::{DispatchResultWithPostInfo, Parameter, RawOrigin};
|
||||
use sp_arithmetic::traits::{CheckedSub, Zero};
|
||||
use sp_runtime::{
|
||||
traits::{BadOrigin, Member},
|
||||
traits::{BadOrigin, Member, Morph, TryMorph},
|
||||
Either,
|
||||
};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
use super::TypedGet;
|
||||
|
||||
/// Some sort of check on the origin is performed by this object.
|
||||
pub trait EnsureOrigin<OuterOrigin> {
|
||||
@@ -38,9 +42,23 @@ pub trait EnsureOrigin<OuterOrigin> {
|
||||
|
||||
/// Returns an outer origin capable of passing `try_origin` check.
|
||||
///
|
||||
/// NOTE: This should generally *NOT* be reimplemented. Instead implement
|
||||
/// `try_successful_origin`.
|
||||
///
|
||||
/// ** Should be used for benchmarking only!!! **
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> OuterOrigin;
|
||||
fn successful_origin() -> OuterOrigin {
|
||||
Self::try_successful_origin().expect("No origin exists which can satisfy the guard")
|
||||
}
|
||||
|
||||
/// Attept to get an outer origin capable of passing `try_origin` check. May return `Err` if it
|
||||
/// is impossible. Default implementation just uses `successful_origin()`.
|
||||
///
|
||||
/// ** Should be used for benchmarking only!!! **
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin() -> Result<OuterOrigin, ()> {
|
||||
Ok(Self::successful_origin())
|
||||
}
|
||||
}
|
||||
|
||||
/// `EnsureOrigin` implementation that always fails.
|
||||
@@ -51,8 +69,8 @@ impl<OO, Success> EnsureOrigin<OO> for NeverEnsureOrigin<Success> {
|
||||
Err(o)
|
||||
}
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> OO {
|
||||
panic!("No `successful_origin` possible for `NeverEnsureOrigin`")
|
||||
fn try_successful_origin() -> Result<OO, ()> {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,9 +89,23 @@ pub trait EnsureOriginWithArg<OuterOrigin, Argument> {
|
||||
|
||||
/// Returns an outer origin capable of passing `try_origin` check.
|
||||
///
|
||||
/// NOTE: This should generally *NOT* be reimplemented. Instead implement
|
||||
/// `try_successful_origin`.
|
||||
///
|
||||
/// ** Should be used for benchmarking only!!! **
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin(a: &Argument) -> OuterOrigin;
|
||||
fn successful_origin(a: &Argument) -> OuterOrigin {
|
||||
Self::try_successful_origin(a).expect("No origin exists which can satisfy the guard")
|
||||
}
|
||||
|
||||
/// Attept to get an outer origin capable of passing `try_origin` check. May return `Err` if it
|
||||
/// is impossible. Default implementation just uses `successful_origin()`.
|
||||
///
|
||||
/// ** Should be used for benchmarking only!!! **
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin(a: &Argument) -> Result<OuterOrigin, ()> {
|
||||
Ok(Self::successful_origin(a))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AsEnsureOriginWithArg<EO>(sp_std::marker::PhantomData<EO>);
|
||||
@@ -97,8 +129,121 @@ impl<OuterOrigin, Argument, EO: EnsureOrigin<OuterOrigin>>
|
||||
///
|
||||
/// ** Should be used for benchmarking only!!! **
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin(_: &Argument) -> OuterOrigin {
|
||||
EO::successful_origin()
|
||||
fn try_successful_origin(_: &Argument) -> Result<OuterOrigin, ()> {
|
||||
EO::try_successful_origin()
|
||||
}
|
||||
}
|
||||
|
||||
/// A derivative `EnsureOrigin` implementation. It mutates the `Success` result of an `Original`
|
||||
/// implementation with a given `Mutator`.
|
||||
pub struct MapSuccess<Original, Mutator>(PhantomData<(Original, Mutator)>);
|
||||
impl<O, Original: EnsureOrigin<O>, Mutator: Morph<Original::Success>> EnsureOrigin<O>
|
||||
for MapSuccess<Original, Mutator>
|
||||
{
|
||||
type Success = Mutator::Outcome;
|
||||
fn try_origin(o: O) -> Result<Mutator::Outcome, O> {
|
||||
Ok(Mutator::morph(Original::try_origin(o)?))
|
||||
}
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin() -> Result<O, ()> {
|
||||
Original::try_successful_origin()
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// from the mutator.
|
||||
///
|
||||
/// NOTE: This is strictly worse performance than `MapSuccess` since it clones the original origin
|
||||
/// value. If possible, use `MapSuccess` instead.
|
||||
pub struct TryMapSuccess<Orig, Mutator>(PhantomData<(Orig, Mutator)>);
|
||||
impl<O: Clone, Original: EnsureOrigin<O>, Mutator: TryMorph<Original::Success>> EnsureOrigin<O>
|
||||
for TryMapSuccess<Original, Mutator>
|
||||
{
|
||||
type Success = Mutator::Outcome;
|
||||
fn try_origin(o: O) -> Result<Mutator::Outcome, O> {
|
||||
let orig = o.clone();
|
||||
Mutator::try_morph(Original::try_origin(o)?).map_err(|()| orig)
|
||||
}
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin() -> Result<O, ()> {
|
||||
Original::try_successful_origin()
|
||||
}
|
||||
}
|
||||
|
||||
/// "OR gate" implementation of `EnsureOrigin` allowing for different `Success` types for `L`
|
||||
/// and `R`, with them combined using an `Either` type.
|
||||
///
|
||||
/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first.
|
||||
///
|
||||
/// Successful origin is derived from the left side.
|
||||
pub struct EitherOfDiverse<L, R>(sp_std::marker::PhantomData<(L, R)>);
|
||||
impl<OuterOrigin, L: EnsureOrigin<OuterOrigin>, R: EnsureOrigin<OuterOrigin>>
|
||||
EnsureOrigin<OuterOrigin> for EitherOfDiverse<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(Either::Right), |o| Ok(Either::Left(o)))
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin() -> Result<OuterOrigin, ()> {
|
||||
L::try_successful_origin().or_else(|()| R::try_successful_origin())
|
||||
}
|
||||
}
|
||||
|
||||
/// "OR gate" implementation of `EnsureOrigin` allowing for different `Success` types for `L`
|
||||
/// and `R`, with them combined using an `Either` type.
|
||||
///
|
||||
/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first.
|
||||
///
|
||||
/// Successful origin is derived from the left side.
|
||||
#[deprecated = "Use `EitherOfDiverse` instead"]
|
||||
pub type EnsureOneOf<L, R> = EitherOfDiverse<L, R>;
|
||||
|
||||
/// "OR gate" implementation of `EnsureOrigin`, `Success` type for both `L` and `R` must
|
||||
/// be equal.
|
||||
///
|
||||
/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first.
|
||||
///
|
||||
/// Successful origin is derived from the left side.
|
||||
pub struct EitherOf<L, R>(sp_std::marker::PhantomData<(L, R)>);
|
||||
impl<
|
||||
OuterOrigin,
|
||||
L: EnsureOrigin<OuterOrigin>,
|
||||
R: EnsureOrigin<OuterOrigin, Success = L::Success>,
|
||||
> EnsureOrigin<OuterOrigin> for EitherOf<L, R>
|
||||
{
|
||||
type Success = L::Success;
|
||||
fn try_origin(o: OuterOrigin) -> Result<Self::Success, OuterOrigin> {
|
||||
L::try_origin(o).or_else(|o| R::try_origin(o))
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin() -> Result<OuterOrigin, ()> {
|
||||
L::try_successful_origin().or_else(|()| R::try_successful_origin())
|
||||
}
|
||||
}
|
||||
|
||||
/// Mutator which reduces a scalar by a particular amount.
|
||||
pub struct ReduceBy<N>(PhantomData<N>);
|
||||
impl<N: TypedGet> TryMorph<N::Type> for ReduceBy<N>
|
||||
where
|
||||
N::Type: CheckedSub,
|
||||
{
|
||||
type Outcome = N::Type;
|
||||
fn try_morph(r: N::Type) -> Result<N::Type, ()> {
|
||||
r.checked_sub(&N::get()).ok_or(())
|
||||
}
|
||||
}
|
||||
impl<N: TypedGet> Morph<N::Type> for ReduceBy<N>
|
||||
where
|
||||
N::Type: CheckedSub + Zero,
|
||||
{
|
||||
type Outcome = N::Type;
|
||||
fn morph(r: N::Type) -> N::Type {
|
||||
r.checked_sub(&N::get()).unwrap_or(Zero::zero())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,63 +321,6 @@ pub trait OriginTrait: Sized {
|
||||
fn signed(by: Self::AccountId) -> Self;
|
||||
}
|
||||
|
||||
/// "OR gate" implementation of `EnsureOrigin` allowing for different `Success` types for `L`
|
||||
/// and `R`, with them combined using an `Either` type.
|
||||
///
|
||||
/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first.
|
||||
///
|
||||
/// Successful origin is derived from the left side.
|
||||
pub struct EitherOfDiverse<L, R>(sp_std::marker::PhantomData<(L, R)>);
|
||||
|
||||
impl<OuterOrigin, L: EnsureOrigin<OuterOrigin>, R: EnsureOrigin<OuterOrigin>>
|
||||
EnsureOrigin<OuterOrigin> for EitherOfDiverse<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(Either::Right), |o| Ok(Either::Left(o)))
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> OuterOrigin {
|
||||
L::successful_origin()
|
||||
}
|
||||
}
|
||||
|
||||
/// "OR gate" implementation of `EnsureOrigin` allowing for different `Success` types for `L`
|
||||
/// and `R`, with them combined using an `Either` type.
|
||||
///
|
||||
/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first.
|
||||
///
|
||||
/// Successful origin is derived from the left side.
|
||||
#[deprecated = "Use `EitherOfDiverse` instead"]
|
||||
pub type EnsureOneOf<L, R> = EitherOfDiverse<L, R>;
|
||||
|
||||
/// "OR gate" implementation of `EnsureOrigin`, `Success` type for both `L` and `R` must
|
||||
/// be equal.
|
||||
///
|
||||
/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first.
|
||||
///
|
||||
/// Successful origin is derived from the left side.
|
||||
pub struct EitherOf<L, R>(sp_std::marker::PhantomData<(L, R)>);
|
||||
|
||||
impl<
|
||||
OuterOrigin,
|
||||
L: EnsureOrigin<OuterOrigin>,
|
||||
R: EnsureOrigin<OuterOrigin, Success = L::Success>,
|
||||
> EnsureOrigin<OuterOrigin> for EitherOf<L, R>
|
||||
{
|
||||
type Success = L::Success;
|
||||
fn try_origin(o: OuterOrigin) -> Result<Self::Success, OuterOrigin> {
|
||||
L::try_origin(o).or_else(|o| R::try_origin(o))
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> OuterOrigin {
|
||||
L::successful_origin()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -248,8 +336,8 @@ mod tests {
|
||||
Ok(V::get())
|
||||
}
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> () {
|
||||
()
|
||||
fn try_successful_origin() -> Result<(), ()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,8 +347,8 @@ mod tests {
|
||||
Err(())
|
||||
}
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> () {
|
||||
()
|
||||
fn try_successful_origin() -> Result<(), ()> {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,8 @@
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use serde::Serialize;
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
use sp_runtime::traits::TrailingZeroInput;
|
||||
use sp_runtime::{
|
||||
generic,
|
||||
traits::{
|
||||
@@ -782,8 +784,8 @@ impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, Acco
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> O {
|
||||
O::from(RawOrigin::Root)
|
||||
fn try_successful_origin() -> Result<O, ()> {
|
||||
Ok(O::from(RawOrigin::Root))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -805,8 +807,8 @@ impl<
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> O {
|
||||
O::from(RawOrigin::Root)
|
||||
fn try_successful_origin() -> Result<O, ()> {
|
||||
Ok(O::from(RawOrigin::Root))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,11 +825,10 @@ impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, Acco
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> O {
|
||||
fn try_successful_origin() -> Result<O, ()> {
|
||||
let zero_account_id =
|
||||
AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes())
|
||||
.expect("infinite length input; no invalid inputs for type; qed");
|
||||
O::from(RawOrigin::Signed(zero_account_id))
|
||||
AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?;
|
||||
Ok(O::from(RawOrigin::Signed(zero_account_id)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -847,16 +848,15 @@ impl<
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> O {
|
||||
fn try_successful_origin() -> Result<O, ()> {
|
||||
let zero_account_id =
|
||||
AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes())
|
||||
.expect("infinite length input; no invalid inputs for type; qed");
|
||||
AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?;
|
||||
let members = Who::sorted_members();
|
||||
let first_member = match members.get(0) {
|
||||
Some(account) => account.clone(),
|
||||
None => zero_account_id,
|
||||
};
|
||||
O::from(RawOrigin::Signed(first_member))
|
||||
Ok(O::from(RawOrigin::Signed(first_member)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -873,8 +873,8 @@ impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, Acco
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> O {
|
||||
O::from(RawOrigin::None)
|
||||
fn try_successful_origin() -> Result<O, ()> {
|
||||
Ok(O::from(RawOrigin::None))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -886,8 +886,8 @@ impl<O, T> EnsureOrigin<O> for EnsureNever<T> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> O {
|
||||
unimplemented!()
|
||||
fn try_successful_origin() -> Result<O, ()> {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -116,8 +116,8 @@ impl frame_support::traits::EnsureOrigin<Origin> for TestSpendOrigin {
|
||||
})
|
||||
}
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn successful_origin() -> Origin {
|
||||
Origin::root()
|
||||
fn try_successful_origin() -> Result<Origin, ()> {
|
||||
Ok(Origin::root())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -274,6 +274,42 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Extensible conversion trait. Generic over only source type, with destination type being
|
||||
/// associated.
|
||||
pub trait Morph<A> {
|
||||
/// The type into which `A` is mutated.
|
||||
type Outcome;
|
||||
|
||||
/// Make conversion.
|
||||
fn morph(a: A) -> Self::Outcome;
|
||||
}
|
||||
|
||||
/// A structure that performs identity conversion.
|
||||
impl<T> Morph<T> for Identity {
|
||||
type Outcome = T;
|
||||
fn morph(a: T) -> T {
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
/// Extensible conversion trait. Generic over only source type, with destination type being
|
||||
/// associated.
|
||||
pub trait TryMorph<A> {
|
||||
/// The type into which `A` is mutated.
|
||||
type Outcome;
|
||||
|
||||
/// Make conversion.
|
||||
fn try_morph(a: A) -> Result<Self::Outcome, ()>;
|
||||
}
|
||||
|
||||
/// A structure that performs identity conversion.
|
||||
impl<T> TryMorph<T> for Identity {
|
||||
type Outcome = T;
|
||||
fn try_morph(a: T) -> Result<T, ()> {
|
||||
Ok(a)
|
||||
}
|
||||
}
|
||||
|
||||
/// Extensible conversion trait. Generic over both source and destination types.
|
||||
pub trait Convert<A, B> {
|
||||
/// Make conversion.
|
||||
|
||||
Reference in New Issue
Block a user