mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 02:17:58 +00:00
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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ use sp_std::{prelude::*, result, marker::PhantomData, ops::Div, fmt::Debug};
|
||||
use codec::{FullCodec, Codec, Encode, Decode};
|
||||
use sp_core::u32_trait::Value as U32;
|
||||
use sp_runtime::{
|
||||
RuntimeDebug,
|
||||
ConsensusEngineId, DispatchResult, DispatchError,
|
||||
traits::{MaybeSerializeDeserialize, SimpleArithmetic, Saturating, TrailingZeroInput},
|
||||
};
|
||||
@@ -800,3 +801,24 @@ pub trait ModuleToIndex {
|
||||
impl ModuleToIndex for () {
|
||||
fn module_to_index<M: 'static>() -> Option<usize> { Some(0) }
|
||||
}
|
||||
|
||||
/// The function and pallet name of the Call.
|
||||
#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug)]
|
||||
pub struct CallMetadata {
|
||||
/// Name of the function.
|
||||
pub function_name: &'static str,
|
||||
/// Name of the pallet to which the function belongs.
|
||||
pub pallet_name: &'static str,
|
||||
}
|
||||
|
||||
/// Gets the function name of the Call.
|
||||
pub trait GetCallName {
|
||||
/// Return the function name of the Call.
|
||||
fn get_call_name(&self) -> &'static str;
|
||||
}
|
||||
|
||||
/// Gets the metadata for the Call - function name and pallet name.
|
||||
pub trait GetCallMetadata {
|
||||
/// Return a [`CallMetadata`], containing function and pallet name of the Call.
|
||||
fn get_call_metadata(&self) -> CallMetadata;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user