mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 05:37:58 +00:00
Introduce in-origin filtering (#6318)
* impl filter in origin * remove IsCallable usage. Breaking: utility::batch(root, calls) no longer bypass BasicCallFilter * rename BasicCallFilter -> BaseCallFilter * refactor code * Apply suggestions from code review Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * remove forgotten temporar comment * better add suggestion in another PR * refactor: use Clone instead of mem::replace * fix tests * fix tests * fix tests * fix benchmarks * Make root bypass filter in utility::batch * fix unused imports Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
97cac4ce8b
commit
c2ad27271b
@@ -29,7 +29,7 @@ pub use crate::weights::{
|
||||
PaysFee, PostDispatchInfo, WithPostDispatchInfo,
|
||||
};
|
||||
pub use sp_runtime::{traits::Dispatchable, DispatchError};
|
||||
pub use crate::traits::{CallMetadata, GetCallMetadata, GetCallName};
|
||||
pub use crate::traits::{CallMetadata, GetCallMetadata, GetCallName, UnfilteredDispatchable};
|
||||
|
||||
/// The return typ of a `Dispatchable` in frame. When returned explicitly from
|
||||
/// a dispatchable function it allows overriding the default `PostDispatchInfo`
|
||||
@@ -47,10 +47,9 @@ pub type DispatchResult = Result<(), sp_runtime::DispatchError>;
|
||||
pub type DispatchErrorWithPostInfo =
|
||||
sp_runtime::DispatchErrorWithPostInfo<crate::weights::PostDispatchInfo>;
|
||||
|
||||
/// Serializable version of Dispatchable.
|
||||
/// This value can be used as a "function" in an extrinsic.
|
||||
/// Serializable version of pallet dispatchable.
|
||||
pub trait Callable<T> {
|
||||
type Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo> + Codec + Clone + PartialEq + Eq;
|
||||
type Call: UnfilteredDispatchable + Codec + Clone + PartialEq + Eq;
|
||||
}
|
||||
|
||||
// dirty hack to work around serde_derive issue
|
||||
@@ -1005,6 +1004,7 @@ macro_rules! decl_module {
|
||||
impl<$trait_instance: $trait_name$(<I>, $instance: $instantiable)?> $module<$trait_instance $(, $instance)?>
|
||||
where $( $other_where_bounds )*
|
||||
{
|
||||
/// Deposits an event using `frame_system::Module::deposit_event`.
|
||||
$vis fn deposit_event(
|
||||
event: impl Into<< $trait_instance as $trait_name $(<$instance>)? >::Event>
|
||||
) {
|
||||
@@ -1402,6 +1402,8 @@ macro_rules! decl_module {
|
||||
$error_type;
|
||||
$from;
|
||||
$(#[doc = $doc_attr])*
|
||||
///
|
||||
/// NOTE: Calling this function will bypass origin filters.
|
||||
$fn_vis fn $fn_name (
|
||||
$from $(, $param_name : $param )*
|
||||
) $( -> $result )* { $( $impl )* }
|
||||
@@ -1546,14 +1548,11 @@ macro_rules! decl_module {
|
||||
}
|
||||
}
|
||||
|
||||
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::Dispatchable
|
||||
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::traits::UnfilteredDispatchable
|
||||
for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
|
||||
{
|
||||
type Trait = $trait_instance;
|
||||
type Origin = $origin_type;
|
||||
type Info = $crate::weights::DispatchInfo;
|
||||
type PostInfo = $crate::weights::PostDispatchInfo;
|
||||
fn dispatch(self, _origin: Self::Origin) -> $crate::dispatch::DispatchResultWithPostInfo {
|
||||
fn dispatch_bypass_filter(self, _origin: Self::Origin) -> $crate::dispatch::DispatchResultWithPostInfo {
|
||||
match self {
|
||||
$(
|
||||
$call_type::$fn_name( $( $param_name ),* ) => {
|
||||
@@ -1574,17 +1573,6 @@ macro_rules! decl_module {
|
||||
type Call = $call_type<$trait_instance $(, $instance)?>;
|
||||
}
|
||||
|
||||
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $mod_type<$trait_instance $(, $instance)?>
|
||||
where $( $other_where_bounds )*
|
||||
{
|
||||
#[doc(hidden)]
|
||||
pub fn dispatch<D: $crate::dispatch::Dispatchable<Trait = $trait_instance, PostInfo = $crate::weights::PostDispatchInfo>>(
|
||||
d: D,
|
||||
origin: D::Origin
|
||||
) -> $crate::dispatch::DispatchResultWithPostInfo {
|
||||
d.dispatch(origin)
|
||||
}
|
||||
}
|
||||
$crate::__dispatch_impl_metadata! {
|
||||
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>
|
||||
{ $( $other_where_bounds )* }
|
||||
@@ -1684,6 +1672,20 @@ macro_rules! impl_outer_dispatch {
|
||||
fn dispatch(
|
||||
self,
|
||||
origin: $origin,
|
||||
) -> $crate::dispatch::DispatchResultWithPostInfo {
|
||||
if !<Self::Origin as $crate::traits::OriginTrait>::filter_call(&origin, &self) {
|
||||
return $crate::sp_std::result::Result::Err($crate::dispatch::DispatchError::BadOrigin.into())
|
||||
}
|
||||
|
||||
$crate::traits::UnfilteredDispatchable::dispatch_bypass_filter(self, origin)
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::traits::UnfilteredDispatchable for $call_type {
|
||||
type Origin = $origin;
|
||||
fn dispatch_bypass_filter(
|
||||
self,
|
||||
origin: $origin,
|
||||
) -> $crate::dispatch::DispatchResultWithPostInfo {
|
||||
$crate::impl_outer_dispatch! {
|
||||
@DISPATCH_MATCH
|
||||
@@ -1696,6 +1698,7 @@ macro_rules! impl_outer_dispatch {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(
|
||||
impl $crate::dispatch::IsSubType<$camelcase, $runtime> for $call_type {
|
||||
#[allow(unreachable_patterns)]
|
||||
@@ -1731,7 +1734,8 @@ macro_rules! impl_outer_dispatch {
|
||||
$origin
|
||||
{
|
||||
$( $generated )*
|
||||
$call_type::$name(call) => call.dispatch($origin),
|
||||
$call_type::$name(call) =>
|
||||
$crate::traits::UnfilteredDispatchable::dispatch_bypass_filter(call, $origin),
|
||||
}
|
||||
$index + 1;
|
||||
$( $rest ),*
|
||||
@@ -2050,21 +2054,34 @@ mod tests {
|
||||
};
|
||||
|
||||
pub trait Trait: system::Trait + Sized where Self::AccountId: From<u32> {
|
||||
type Origin;
|
||||
type BlockNumber: Into<u32>;
|
||||
type Call: From<Call<Self>>;
|
||||
}
|
||||
|
||||
pub mod system {
|
||||
use super::*;
|
||||
|
||||
pub trait Trait {
|
||||
type AccountId;
|
||||
type Call;
|
||||
type BaseCallFilter;
|
||||
type Origin: crate::traits::OriginTrait<Call = Self::Call>;
|
||||
}
|
||||
|
||||
pub fn ensure_root<R>(_: R) -> DispatchResult {
|
||||
Ok(())
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum RawOrigin<AccountId> {
|
||||
Root,
|
||||
Signed(AccountId),
|
||||
None,
|
||||
}
|
||||
|
||||
impl<AccountId> From<Option<AccountId>> for RawOrigin<AccountId> {
|
||||
fn from(s: Option<AccountId>) -> RawOrigin<AccountId> {
|
||||
match s {
|
||||
Some(who) => RawOrigin::Signed(who),
|
||||
None => RawOrigin::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Origin<T> = RawOrigin<<T as Trait>::AccountId>;
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
@@ -2169,21 +2186,26 @@ mod tests {
|
||||
pub struct TraitImpl {}
|
||||
|
||||
impl Trait for TraitImpl {
|
||||
type Origin = u32;
|
||||
type BlockNumber = u32;
|
||||
type Call = OuterCall;
|
||||
}
|
||||
|
||||
type Test = Module<TraitImpl>;
|
||||
|
||||
impl_outer_origin!{
|
||||
pub enum OuterOrigin for TraitImpl where system = system {}
|
||||
}
|
||||
|
||||
impl_outer_dispatch! {
|
||||
pub enum OuterCall for TraitImpl where origin: u32 {
|
||||
pub enum OuterCall for TraitImpl where origin: OuterOrigin {
|
||||
self::Test,
|
||||
}
|
||||
}
|
||||
|
||||
impl system::Trait for TraitImpl {
|
||||
type Origin = OuterOrigin;
|
||||
type AccountId = u32;
|
||||
type Call = OuterCall;
|
||||
type BaseCallFilter = ();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -51,14 +51,14 @@ pub use sp_runtime::RuntimeDebug;
|
||||
#[macro_use]
|
||||
pub mod debug;
|
||||
#[macro_use]
|
||||
mod origin;
|
||||
#[macro_use]
|
||||
pub mod dispatch;
|
||||
pub mod storage;
|
||||
mod hash;
|
||||
#[macro_use]
|
||||
pub mod event;
|
||||
#[macro_use]
|
||||
mod origin;
|
||||
#[macro_use]
|
||||
pub mod metadata;
|
||||
#[macro_use]
|
||||
pub mod inherent;
|
||||
|
||||
@@ -290,6 +290,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
pub trait Trait: 'static {
|
||||
type BaseCallFilter;
|
||||
const ASSOCIATED_CONST: u64 = 500;
|
||||
type Origin: Into<Result<RawOrigin<Self::AccountId>, Self::Origin>>
|
||||
+ From<RawOrigin<Self::AccountId>>;
|
||||
@@ -297,6 +298,7 @@ mod tests {
|
||||
type BlockNumber: From<u32> + Encode;
|
||||
type SomeValue: Get<u32>;
|
||||
type ModuleToIndex: crate::traits::ModuleToIndex;
|
||||
type Call;
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
@@ -436,11 +438,13 @@ mod tests {
|
||||
}
|
||||
|
||||
impl system::Trait for TestRuntime {
|
||||
type BaseCallFilter = ();
|
||||
type Origin = Origin;
|
||||
type AccountId = u32;
|
||||
type BlockNumber = u32;
|
||||
type SomeValue = SystemValue;
|
||||
type ModuleToIndex = ();
|
||||
type Call = Call;
|
||||
}
|
||||
|
||||
impl_runtime_metadata!(
|
||||
|
||||
@@ -45,19 +45,23 @@ macro_rules! impl_outer_origin {
|
||||
$( $rest_with_system:tt )*
|
||||
}
|
||||
) => {
|
||||
$crate::impl_outer_origin!(
|
||||
$( #[$attr] )*;
|
||||
$name;
|
||||
$runtime;
|
||||
$system;
|
||||
Modules { $( $rest_with_system )* };
|
||||
);
|
||||
$crate::paste::item! {
|
||||
$crate::impl_outer_origin!(
|
||||
$( #[$attr] )*;
|
||||
$name;
|
||||
[< $name Caller >];
|
||||
$runtime;
|
||||
$system;
|
||||
Modules { $( $rest_with_system )* };
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Generic + Instance
|
||||
(
|
||||
$(#[$attr:meta])*;
|
||||
$name:ident;
|
||||
$caller_name:ident;
|
||||
$runtime:ident;
|
||||
$system:ident;
|
||||
Modules {
|
||||
@@ -69,6 +73,7 @@ macro_rules! impl_outer_origin {
|
||||
$crate::impl_outer_origin!(
|
||||
$( #[$attr] )*;
|
||||
$name;
|
||||
$caller_name;
|
||||
$runtime;
|
||||
$system;
|
||||
Modules { $( $( $rest_module )* )? };
|
||||
@@ -80,6 +85,7 @@ macro_rules! impl_outer_origin {
|
||||
(
|
||||
$(#[$attr:meta])*;
|
||||
$name:ident;
|
||||
$caller_name:ident;
|
||||
$runtime:ident;
|
||||
$system:ident;
|
||||
Modules {
|
||||
@@ -91,6 +97,7 @@ macro_rules! impl_outer_origin {
|
||||
$crate::impl_outer_origin!(
|
||||
$( #[$attr] )*;
|
||||
$name;
|
||||
$caller_name;
|
||||
$runtime;
|
||||
$system;
|
||||
Modules { $( $rest_module )* };
|
||||
@@ -102,6 +109,7 @@ macro_rules! impl_outer_origin {
|
||||
(
|
||||
$(#[$attr:meta])*;
|
||||
$name:ident;
|
||||
$caller_name:ident;
|
||||
$runtime:ident;
|
||||
$system:ident;
|
||||
Modules {
|
||||
@@ -113,6 +121,7 @@ macro_rules! impl_outer_origin {
|
||||
$crate::impl_outer_origin!(
|
||||
$( #[$attr] )*;
|
||||
$name;
|
||||
$caller_name;
|
||||
$runtime;
|
||||
$system;
|
||||
Modules { $( $( $rest_module )* )? };
|
||||
@@ -124,6 +133,7 @@ macro_rules! impl_outer_origin {
|
||||
(
|
||||
$(#[$attr:meta])*;
|
||||
$name:ident;
|
||||
$caller_name:ident;
|
||||
$runtime:ident;
|
||||
$system:ident;
|
||||
Modules {
|
||||
@@ -135,6 +145,7 @@ macro_rules! impl_outer_origin {
|
||||
$crate::impl_outer_origin!(
|
||||
$( #[$attr] )*;
|
||||
$name;
|
||||
$caller_name;
|
||||
$runtime;
|
||||
$system;
|
||||
Modules { $( $( $rest_module )* )? };
|
||||
@@ -146,16 +157,78 @@ macro_rules! impl_outer_origin {
|
||||
(
|
||||
$(#[$attr:meta])*;
|
||||
$name:ident;
|
||||
$caller_name:ident;
|
||||
$runtime:ident;
|
||||
$system:ident;
|
||||
Modules { };
|
||||
$( $module:ident $( < $generic:ident > )? $( { $generic_instance:ident } )? ,)*
|
||||
) => {
|
||||
// WARNING: All instance must hold the filter `frame_system::Trait::BaseCallFilter`.
|
||||
// One can use `OriginTrait::reset_filter` to do so.
|
||||
#[derive(Clone)]
|
||||
pub struct $name {
|
||||
caller: $caller_name,
|
||||
filter: $crate::sp_std::rc::Rc<Box<dyn Fn(&<$runtime as $system::Trait>::Call) -> bool>>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
impl $crate::sp_std::fmt::Debug for $name {
|
||||
fn fmt(
|
||||
&self,
|
||||
fmt: &mut $crate::sp_std::fmt::Formatter
|
||||
) -> $crate::sp_std::result::Result<(), $crate::sp_std::fmt::Error> {
|
||||
fmt.write_str("<wasm:stripped>")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl $crate::sp_std::fmt::Debug for $name {
|
||||
fn fmt(
|
||||
&self,
|
||||
fmt: &mut $crate::sp_std::fmt::Formatter
|
||||
) -> $crate::sp_std::result::Result<(), $crate::sp_std::fmt::Error> {
|
||||
fmt.debug_struct(stringify!($name))
|
||||
.field("caller", &self.caller)
|
||||
.field("filter", &"[function ptr]")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::traits::OriginTrait for $name {
|
||||
type Call = <$runtime as $system::Trait>::Call;
|
||||
type PalletsOrigin = $caller_name;
|
||||
|
||||
fn add_filter(&mut self, filter: impl Fn(&Self::Call) -> bool + 'static) {
|
||||
let f = self.filter.clone();
|
||||
|
||||
self.filter = $crate::sp_std::rc::Rc::new(Box::new(move |call| {
|
||||
f(call) && filter(call)
|
||||
}));
|
||||
}
|
||||
|
||||
fn reset_filter(&mut self) {
|
||||
let filter = <
|
||||
<$runtime as $system::Trait>::BaseCallFilter
|
||||
as $crate::traits::Filter<<$runtime as $system::Trait>::Call>
|
||||
>::filter;
|
||||
|
||||
self.filter = $crate::sp_std::rc::Rc::new(Box::new(filter));
|
||||
}
|
||||
|
||||
fn set_caller_from(&mut self, other: impl Into<Self>) {
|
||||
self.caller = other.into().caller
|
||||
}
|
||||
|
||||
fn filter_call(&self, call: &Self::Call) -> bool {
|
||||
(self.filter)(call)
|
||||
}
|
||||
}
|
||||
|
||||
$crate::paste::item! {
|
||||
#[derive(Clone, PartialEq, Eq, $crate::RuntimeDebug)]
|
||||
$(#[$attr])*
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum $name {
|
||||
pub enum $caller_name {
|
||||
system($system::Origin<$runtime>),
|
||||
$(
|
||||
[< $module $( _ $generic_instance )? >]
|
||||
@@ -168,20 +241,30 @@ macro_rules! impl_outer_origin {
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl $name {
|
||||
pub const NONE: Self = $name::system($system::RawOrigin::None);
|
||||
pub const ROOT: Self = $name::system($system::RawOrigin::Root);
|
||||
pub fn none() -> Self {
|
||||
$system::RawOrigin::None.into()
|
||||
}
|
||||
pub fn root() -> Self {
|
||||
$system::RawOrigin::Root.into()
|
||||
}
|
||||
pub fn signed(by: <$runtime as $system::Trait>::AccountId) -> Self {
|
||||
$name::system($system::RawOrigin::Signed(by))
|
||||
$system::RawOrigin::Signed(by).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$system::Origin<$runtime>> for $name {
|
||||
fn from(x: $system::Origin<$runtime>) -> Self {
|
||||
$name::system(x)
|
||||
let mut o = $name {
|
||||
caller: $caller_name::system(x),
|
||||
filter: $crate::sp_std::rc::Rc::new(Box::new(|_| true)),
|
||||
};
|
||||
$crate::traits::OriginTrait::reset_filter(&mut o);
|
||||
o
|
||||
}
|
||||
}
|
||||
impl Into<$crate::sp_std::result::Result<$system::Origin<$runtime>, $name>> for $name {
|
||||
fn into(self) -> $crate::sp_std::result::Result<$system::Origin<$runtime>, Self> {
|
||||
if let $name::system(l) = self {
|
||||
if let $caller_name::system(l) = self.caller {
|
||||
Ok(l)
|
||||
} else {
|
||||
Err(self)
|
||||
@@ -197,7 +280,12 @@ macro_rules! impl_outer_origin {
|
||||
$crate::paste::item! {
|
||||
impl From<$module::Origin < $( $generic )? $(, $module::$generic_instance )? > > for $name {
|
||||
fn from(x: $module::Origin < $( $generic )? $(, $module::$generic_instance )? >) -> Self {
|
||||
$name::[< $module $( _ $generic_instance )? >](x)
|
||||
let mut o = $name {
|
||||
caller: $caller_name::[< $module $( _ $generic_instance )? >](x),
|
||||
filter: $crate::sp_std::rc::Rc::new(Box::new(|_| true)),
|
||||
};
|
||||
$crate::traits::OriginTrait::reset_filter(&mut o);
|
||||
o
|
||||
}
|
||||
}
|
||||
impl Into<
|
||||
@@ -210,7 +298,7 @@ macro_rules! impl_outer_origin {
|
||||
$module::Origin < $( $generic )? $(, $module::$generic_instance )? >,
|
||||
Self,
|
||||
> {
|
||||
if let $name::[< $module $( _ $generic_instance )? >](l) = self {
|
||||
if let $caller_name::[< $module $( _ $generic_instance )? >](l) = self.caller {
|
||||
Ok(l)
|
||||
} else {
|
||||
Err(self)
|
||||
@@ -224,9 +312,12 @@ macro_rules! impl_outer_origin {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::traits::{Filter, OriginTrait};
|
||||
mod system {
|
||||
pub trait Trait {
|
||||
type AccountId;
|
||||
type Call;
|
||||
type BaseCallFilter;
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
@@ -263,8 +354,17 @@ mod tests {
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct TestRuntime;
|
||||
|
||||
pub struct BaseCallFilter;
|
||||
impl Filter<u32> for BaseCallFilter {
|
||||
fn filter(c: &u32) -> bool {
|
||||
*c % 2 == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl system::Trait for TestRuntime {
|
||||
type AccountId = u32;
|
||||
type Call = u32;
|
||||
type BaseCallFilter = BaseCallFilter;
|
||||
}
|
||||
|
||||
impl_outer_origin!(
|
||||
@@ -298,4 +398,35 @@ mod tests {
|
||||
impl_outer_origin!(
|
||||
pub enum OriginEmpty for TestRuntime where system = system {}
|
||||
);
|
||||
|
||||
#[test]
|
||||
fn test_default_filter() {
|
||||
assert_eq!(OriginWithSystem::root().filter_call(&0), true);
|
||||
assert_eq!(OriginWithSystem::root().filter_call(&1), false);
|
||||
assert_eq!(OriginWithSystem::none().filter_call(&0), true);
|
||||
assert_eq!(OriginWithSystem::none().filter_call(&1), false);
|
||||
assert_eq!(OriginWithSystem::signed(0).filter_call(&0), true);
|
||||
assert_eq!(OriginWithSystem::signed(0).filter_call(&1), false);
|
||||
assert_eq!(OriginWithSystem::from(Some(0)).filter_call(&0), true);
|
||||
assert_eq!(OriginWithSystem::from(Some(0)).filter_call(&1), false);
|
||||
assert_eq!(OriginWithSystem::from(None).filter_call(&0), true);
|
||||
assert_eq!(OriginWithSystem::from(None).filter_call(&1), false);
|
||||
assert_eq!(OriginWithSystem::from(origin_without_generic::Origin).filter_call(&0), true);
|
||||
assert_eq!(OriginWithSystem::from(origin_without_generic::Origin).filter_call(&1), false);
|
||||
|
||||
let mut origin = OriginWithSystem::from(Some(0));
|
||||
|
||||
origin.add_filter(|c| *c % 2 == 1);
|
||||
assert_eq!(origin.filter_call(&0), false);
|
||||
assert_eq!(origin.filter_call(&1), false);
|
||||
|
||||
origin.set_caller_from(OriginWithSystem::root());
|
||||
assert!(matches!(origin.caller, OriginWithSystemCaller::system(system::RawOrigin::Root)));
|
||||
assert_eq!(origin.filter_call(&0), false);
|
||||
assert_eq!(origin.filter_call(&1), false);
|
||||
|
||||
origin.reset_filter();
|
||||
assert_eq!(origin.filter_call(&0), true);
|
||||
assert_eq!(origin.filter_call(&1), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1550,6 +1550,63 @@ pub trait EnsureOrigin<OuterOrigin> {
|
||||
fn successful_origin() -> OuterOrigin;
|
||||
}
|
||||
|
||||
/// Type that can be dispatched with an origin but without checking the origin filter.
|
||||
///
|
||||
/// Implemented for pallet dispatchable type by `decl_module` and for runtime dispatchable by
|
||||
/// `construct_runtime` and `impl_outer_dispatch`.
|
||||
pub trait UnfilteredDispatchable {
|
||||
/// The origin type of the runtime, (i.e. `frame_system::Trait::Origin`).
|
||||
type Origin;
|
||||
|
||||
/// Dispatch this call but do not check the filter in origin.
|
||||
fn dispatch_bypass_filter(self, origin: Self::Origin) -> crate::dispatch::DispatchResultWithPostInfo;
|
||||
}
|
||||
|
||||
/// Methods available on `frame_system::Trait::Origin`.
|
||||
pub trait OriginTrait: Sized {
|
||||
/// Runtime call type, as in `frame_system::Trait::Call`
|
||||
type Call;
|
||||
|
||||
/// The caller origin, overarching type of all pallets origins.
|
||||
type PalletsOrigin;
|
||||
|
||||
/// Add a filter to the origin.
|
||||
fn add_filter(&mut self, filter: impl Fn(&Self::Call) -> bool + 'static);
|
||||
|
||||
/// Reset origin filters to default one, i.e `frame_system::Trait::BaseCallFilter`.
|
||||
fn reset_filter(&mut self);
|
||||
|
||||
/// Replace the caller with caller from the other origin
|
||||
fn set_caller_from(&mut self, other: impl Into<Self>);
|
||||
|
||||
/// Filter the call, if false then call is filtered out.
|
||||
fn filter_call(&self, call: &Self::Call) -> bool;
|
||||
}
|
||||
|
||||
/// Trait to be used when types are exactly same.
|
||||
///
|
||||
/// This allow to convert back and forth from type, a reference and a mutable reference.
|
||||
pub trait IsType<T>: Into<T> + From<T> {
|
||||
/// Cast reference.
|
||||
fn from_ref(t: &T) -> &Self;
|
||||
|
||||
/// Cast reference.
|
||||
fn into_ref(&self) -> &T;
|
||||
|
||||
/// Cast mutable reference.
|
||||
fn from_mut(t: &mut T) -> &mut Self;
|
||||
|
||||
/// Cast mutable reference.
|
||||
fn into_mut(&mut self) -> &mut T;
|
||||
}
|
||||
|
||||
impl<T> IsType<T> for T {
|
||||
fn from_ref(t: &T) -> &Self { t }
|
||||
fn into_ref(&self) -> &T { self }
|
||||
fn from_mut(t: &mut T) -> &mut Self { t }
|
||||
fn into_mut(&mut self) -> &mut T { self }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user