Added GetCallMetadata for extrinsic calls. (#4791)

* Added GetCallMetadata for extrinsic calls.

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

* Improved test for outer call metadata.

* fixed review comments

* removed dead code

* fixed review suggestions

* Update frame/support/src/dispatch.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Gautam Dhameja
2020-02-04 11:25:04 +01:00
committed by GitHub
parent febb6e29b2
commit 78006d0523
2 changed files with 91 additions and 35 deletions
+69 -35
View File
@@ -28,6 +28,7 @@ pub use crate::weights::{
TransactionPriority, Weight, WeighBlock, PaysFee,
};
pub use sp_runtime::{traits::Dispatchable, DispatchError, DispatchResult};
pub use crate::traits::{CallMetadata, GetCallMetadata, GetCallName};
/// A type that cannot be instantiated.
pub enum Never {}
@@ -1302,42 +1303,48 @@ macro_rules! decl_module {
for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn get_dispatch_info(&self) -> $crate::dispatch::DispatchInfo {
$(
if let $call_type::$fn_name($( ref $param_name ),*) = self {
let weight = <dyn $crate::dispatch::WeighData<( $( & $param, )* )>>::weigh_data(
&$weight,
($( $param_name, )*)
);
let class = <dyn $crate::dispatch::ClassifyDispatch<( $( & $param, )* )>>::classify_dispatch(
&$weight,
($( $param_name, )*)
);
let pays_fee = <dyn $crate::dispatch::PaysFee<( $( & $param, )* )>>::pays_fee(
&$weight,
($( $param_name, )*)
);
return $crate::dispatch::DispatchInfo { weight, class, pays_fee };
}
if let $call_type::__PhantomItem(_, _) = self { unreachable!("__PhantomItem should never be used.") }
)*
// Defensive only: this function must have already returned at this point.
// all dispatchable function will have a weight which has the `::default`
// implementation of `SimpleDispatchInfo`. Nonetheless, we create one if it does
// not exist.
let weight = <dyn $crate::dispatch::WeighData<_>>::weigh_data(
&$crate::dispatch::SimpleDispatchInfo::default(),
()
);
let class = <dyn $crate::dispatch::ClassifyDispatch<_>>::classify_dispatch(
&$crate::dispatch::SimpleDispatchInfo::default(),
()
);
let pays_fee = <dyn $crate::dispatch::PaysFee<_>>::pays_fee(
&$crate::dispatch::SimpleDispatchInfo::default(),
()
);
$crate::dispatch::DispatchInfo { weight, class, pays_fee }
match *self {
$(
$call_type::$fn_name( $( ref $param_name ),* ) => {
let weight = <dyn $crate::dispatch::WeighData<( $( & $param, )* )>>::weigh_data(
&$weight,
($( $param_name, )*)
);
let class = <dyn $crate::dispatch::ClassifyDispatch<( $( & $param, )* )>>::classify_dispatch(
&$weight,
($( $param_name, )*)
);
let pays_fee = <dyn $crate::dispatch::PaysFee<( $( & $param, )* )>>::pays_fee(
&$weight,
($( $param_name, )*)
);
$crate::dispatch::DispatchInfo {
weight,
class,
pays_fee,
}
},
)*
$call_type::__PhantomItem(_, _) => unreachable!("__PhantomItem should never be used."),
}
}
}
// Implement GetCallName for the Call.
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::GetCallName
for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn get_call_name(&self) -> &'static str {
match *self {
$(
$call_type::$fn_name( $( ref $param_name ),* ) => {
// Don't generate any warnings for unused variables
let _ = ( $( $param_name ),* );
stringify!($fn_name)
},
)*
$call_type::__PhantomItem(_, _) => unreachable!("__PhantomItem should never be used."),
}
}
}
@@ -1500,6 +1507,18 @@ macro_rules! impl_outer_dispatch {
}
}
}
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 }
}, )*
}
}
}
impl $crate::dispatch::Dispatchable for $call_type {
type Origin = $origin;
type Trait = $call_type;
@@ -1871,6 +1890,7 @@ mod tests {
use super::*;
use crate::sp_runtime::traits::{OnInitialize, OnFinalize};
use crate::weights::{DispatchInfo, DispatchClass};
use crate::traits::{CallMetadata, GetCallMetadata, GetCallName};
pub trait Trait: system::Trait + Sized where Self::AccountId: From<u32> {
type Origin;
@@ -2084,4 +2104,18 @@ mod tests {
assert_eq!(<Test as WeighBlock<u32>>::on_finalize(2), 10);
assert_eq!(<Test as WeighBlock<u32>>::on_finalize(3), 0);
}
#[test]
fn call_name() {
let name = Call::<TraitImpl>::aux_3().get_call_name();
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);
}
}