I have a module method that associates fixed fees to Calls from various pallets. So I'm trying to match a Call passed to my method as a parameter by pallet, Call name, and Call parameters.
Something similar to this:
impl<T: Config> Module<T>
{
fn compute_call_fee_(call: &<T as Config>::Call) -> Result<u64, &'static str> {
let fee = match *call {
Call::PalletA(palletA::Call::name_of_palletA_call(x,y)) => 50u64, // here this is not real syntax, this is what I need to figure out
_ => 100u64
};
Ok(fee)
}
}
for the case above the Config trait would implement the Config traits from the different pallets matched on:
pub trait Config: system::Config + palletA::Config + palletB::Config {
type Call: Parameter + Dispatchable<Origin = Self::Origin> + GetDispatchInfo;
}
How can I match on call
by origin pallet, function name, and function arguments ?
I've tried:
using similar syntax as above, without success
making the Config::Call
implement GetCallMetadata
: this only get me the origin pallet and function name, not the parameters
making the call implement IsSubType
, and following this answer: How to decode and match a call when passed as a parameter in Substrate. This is not related to Calls from other pallets if I get it right.
For using IsSubType
, I've added it as a trait bound to the impl block rather than in the Config
trait:
impl<T: Config> Module<T>
where
<T as Config>::Call: IsSubType<Call<T>>,
{
fn compute_call_fee_(call: &<T as Config>::Call) -> Result<u64, &'static str> {
if let Some(local_call) = call.is_sub_type() {
return match local_call {
palletA::Call::name_of_palletA_call(x,y) => Ok(42u64),
_ => Ok(0u64),
}
}
Ok(21u64)
}
}
Hard to say until you paste your full code (specifically the type Call = xxx
piece), but I can guess that what you miss is: type Call: IsSubType<pallet_balances::Call<Self>>;
. You mentioned another question that recomended the same, but I can guess that you didn't use it correctly.
Note that overall, the outer Call
(the one which you are passing into your pallet here via type Call
) implements two things:
From<pallet_call>
for each individual pallet call. This will allow you to always convert an inner Call
into an outer Call
.IsSubType<pallet_call>
for each individual pallet call. This will allow you to conditionally convert an outer call into an inner call, if it exists.Perhaps the naming could have been a bit better here. I will consider at least renaming the outer Call
to.. OuterCall
.
Lastly, definitely recommend running a cargo expand
on the node template and look for enum Call
.
TLDR; this diff will work if you apply it on top of node-template, should answer your question as well.
diff --git a/bin/node-template/pallets/template/Cargo.toml b/bin/node-template/pallets/template/Cargo.toml
index 12b810de1..6f91e8c9a 100644
--- a/bin/node-template/pallets/template/Cargo.toml
+++ b/bin/node-template/pallets/template/Cargo.toml
@@ -25,6 +25,11 @@ default-features = false
version = "2.0.0"
path = "../../../../frame/system"
+[dependencies.pallet-balances]
+default-features = false
+version = "2.0.0"
+path = "../../../../frame/balances"
+
[dev-dependencies.sp-core]
default-features = false
version = "2.0.0"
@@ -46,5 +51,6 @@ default = ['std']
std = [
'codec/std',
'frame-support/std',
- 'frame-system/std'
+ 'frame-system/std',
+ 'pallet-balances/std'
]
diff --git a/bin/node-template/pallets/template/src/lib.rs b/bin/node-template/pallets/template/src/lib.rs
index 24de4f2f5..562675a0b 100644
--- a/bin/node-template/pallets/template/src/lib.rs
+++ b/bin/node-template/pallets/template/src/lib.rs
@@ -14,9 +14,11 @@ mod mock;
mod tests;
/// Configure the pallet by specifying the parameters and types on which it depends.
-pub trait Config: frame_system::Config {
+use frame_support::traits::IsSubType;
+pub trait Config: frame_system::Config + pallet_balances::Config {
/// Because this pallet emits events, it depends on the runtime's definition of an event.
type Event: From<Event<Self>> + Into<<Self as frame_system::Config>::Event>;
+ type Call: IsSubType<pallet_balances::Call<Self>>;
}
// The pallet's runtime storage items.
diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs
index 51df3dd5a..4ca2ab613 100644
--- a/bin/node-template/runtime/src/lib.rs
+++ b/bin/node-template/runtime/src/lib.rs
@@ -258,6 +258,7 @@ impl pallet_sudo::Config for Runtime {
/// Configure the pallet template in pallets/template.
impl template::Config for Runtime {
type Event = Event;
+ type Call = Call;
}
// Create the runtime by composing the FRAME pallets that were previously configured.