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

Remove impl_outer_ macros #9307

Merged
2 commits merged into from
Jul 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 49 additions & 179 deletions frame/support/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ impl<T> Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {}
/// * `Module`: The struct generated by the macro, with type `Config`.
/// * `Call`: The enum generated for every pallet, which implements
/// [`Callable`](./dispatch/trait.Callable.html).
/// * `origin`: Alias of `T::Origin`, declared by the
/// [`impl_outer_origin!`](./macro.impl_outer_origin.html) macro.
/// * `origin`: Alias of `T::Origin`.
/// * `Result`: The expected return type from pallet functions.
///
/// The first parameter of dispatchable functions must always be `origin`.
Expand Down Expand Up @@ -2164,157 +2163,6 @@ macro_rules! decl_module {
}
}

/// Implement a meta-dispatch module to dispatch to other dispatchers.
#[macro_export]
macro_rules! impl_outer_dispatch {
(
$(#[$attr:meta])*
pub enum $call_type:ident for $runtime:ident where origin: $origin:ty {
$(
$( #[codec(index = $index:tt)] )? $module:ident::$camelcase:ident,
)*
}
) => {
$(#[$attr])*
#[derive(
Clone, PartialEq, Eq,
$crate::codec::Encode,
$crate::codec::Decode,
$crate::RuntimeDebug,
)]
pub enum $call_type {
$(
$( #[codec(index = $index)] )?
$camelcase ( $crate::dispatch::CallableCallFor<$camelcase, $runtime> )
,)*
}
impl $crate::dispatch::GetDispatchInfo for $call_type {
fn get_dispatch_info(&self) -> $crate::dispatch::DispatchInfo {
match self {
$( $call_type::$camelcase(call) => call.get_dispatch_info(), )*
}
}
}
impl $crate::dispatch::GetCallMetadata for $call_type {
fn get_call_metadata(&self) -> $crate::dispatch::CallMetadata {
use $crate::dispatch::GetCallName;
match self {
$( $call_type::$camelcase(call) => {
let function_name = call.get_call_name();
let pallet_name = stringify!($camelcase);
$crate::dispatch::CallMetadata { function_name, pallet_name }
}, )*
}
}

fn get_module_names() -> &'static [&'static str] {
&[$(
stringify!($camelcase),
)*]
}

fn get_call_names(module: &str) -> &'static [&'static str] {
use $crate::dispatch::{Callable, GetCallName};
match module {
$(
stringify!($camelcase) =>
<<$camelcase as Callable<$runtime>>::Call
as GetCallName>::get_call_names(),
)*
_ => unreachable!(),
}
}
}
impl $crate::dispatch::Dispatchable for $call_type {
type Origin = $origin;
type Config = $call_type;
type Info = $crate::weights::DispatchInfo;
type PostInfo = $crate::weights::PostDispatchInfo;
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
self
$call_type
origin
{}
0;
$( $camelcase ),*
}
}
}

$(
impl $crate::traits::IsSubType<$crate::dispatch::CallableCallFor<$camelcase, $runtime>> for $call_type {
#[allow(unreachable_patterns)]
fn is_sub_type(&self) -> Option<&$crate::dispatch::CallableCallFor<$camelcase, $runtime>> {
match *self {
$call_type::$camelcase(ref r) => Some(r),
// May be unreachable
_ => None,
}
}
}

impl From<$crate::dispatch::CallableCallFor<$camelcase, $runtime>> for $call_type {
fn from(call: $crate::dispatch::CallableCallFor<$camelcase, $runtime>) -> Self {
$call_type::$camelcase(call)
}
}
)*
};
(@DISPATCH_MATCH
$self:ident
$call_type:ident
$origin:ident
{ $( $generated:tt )* }
$index:expr;
$name:ident
$( , $rest:ident )*
) => {
$crate::impl_outer_dispatch! {
@DISPATCH_MATCH
$self
$call_type
$origin
{
$( $generated )*
$call_type::$name(call) =>
$crate::traits::UnfilteredDispatchable::dispatch_bypass_filter(call, $origin),
}
$index + 1;
$( $rest ),*
}
};
(@DISPATCH_MATCH
$self:ident
$call_type:ident
$origin:ident
{ $( $generated:tt )* }
$index:expr;
) => {
match $self {
$( $generated )*
}
}
}

/// Implement metadata for dispatch.
#[macro_export]
#[doc(hidden)]
Expand Down Expand Up @@ -2619,7 +2467,7 @@ mod tests {
use super::*;
use crate::weights::{DispatchInfo, DispatchClass, Pays, RuntimeDbWeight};
use crate::traits::{
CallMetadata, GetCallMetadata, GetCallName, OnInitialize, OnFinalize, OnIdle, OnRuntimeUpgrade,
GetCallName, OnInitialize, OnFinalize, OnIdle, OnRuntimeUpgrade,
IntegrityTest, Get, PalletInfo,
};

Expand Down Expand Up @@ -2767,16 +2615,6 @@ mod tests {

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: OuterOrigin {
self::Test,
}
}

impl PalletInfo for TraitImpl {
fn index<P: 'static>() -> Option<usize> {
let type_id = sp_std::any::TypeId::of::<P>();
Expand All @@ -2796,10 +2634,56 @@ mod tests {
}
}

pub struct OuterOrigin;

impl crate::traits::OriginTrait for OuterOrigin {
type Call = <TraitImpl as system::Config>::Call;
type PalletsOrigin = OuterOrigin;
type AccountId = <TraitImpl as system::Config>::AccountId;

fn add_filter(&mut self, _filter: impl Fn(&Self::Call) -> bool + 'static) {
unimplemented!("Not required in tests!")
}

fn reset_filter(&mut self) {
unimplemented!("Not required in tests!")
}

fn set_caller_from(&mut self, _other: impl Into<Self>) {
unimplemented!("Not required in tests!")
}

fn filter_call(&self, _call: &Self::Call) -> bool {
unimplemented!("Not required in tests!")
}

fn caller(&self) -> &Self::PalletsOrigin {
unimplemented!("Not required in tests!")
}

fn try_with_caller<R>(
self,
_f: impl FnOnce(Self::PalletsOrigin) -> Result<R, Self::PalletsOrigin>,
) -> Result<R, Self> {
unimplemented!("Not required in tests!")
}

fn none() -> Self {
unimplemented!("Not required in tests!")
}
fn root() -> Self {
unimplemented!("Not required in tests!")
}
fn signed(_by: <TraitImpl as system::Config>::AccountId) -> Self {
unimplemented!("Not required in tests!")
}
}


impl system::Config for TraitImpl {
type Origin = OuterOrigin;
type AccountId = u32;
type Call = OuterCall;
type Call = ();
type BaseCallFilter = ();
type BlockNumber = u32;
type PalletInfo = Self;
Expand Down Expand Up @@ -2901,26 +2785,12 @@ mod tests {
assert_eq!("aux_3", name);
}

#[test]
fn call_metadata() {
let call = OuterCall::Test(Call::<TraitImpl>::aux_3());
let metadata = call.get_call_metadata();
let expected = CallMetadata { function_name: "aux_3".into(), pallet_name: "Test".into() };
assert_eq!(metadata, expected);
}

#[test]
fn get_call_names() {
let call_names = Call::<TraitImpl>::get_call_names();
assert_eq!(["aux_0", "aux_1", "aux_2", "aux_3", "aux_4", "aux_5", "operational"], call_names);
}

#[test]
fn get_module_names() {
let module_names = OuterCall::get_module_names();
assert_eq!(["Test"], module_names);
}
Copy link
Contributor Author

@gui1117 gui1117 Jul 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those tests are in frame/support/test/tests/construct_runtime.rs


#[test]
#[should_panic(expected = "integrity_test")]
fn integrity_test_should_work() {
Expand Down
Loading