I have a method that accepts a call (similar to the sudo or recovery pallets) and i want to run some validation on the call before i dispatch it. The validation is mainly around restricting which methods we can call via this method.
Here is an example code i have:
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
type Error = Error<T>;
fn deposit_event() = default;
pub fn foo(origin, call: Box<<T as Trait>::Call>) -> DispatchResult {
ensure_signed(origin)?;
let sender = match *call {
Call::test(x) => Ok(()),
_ => Err(())
};
Ok(())
}
pub fn test(origin, x: u32) -> DispatchResult {
Ok(())
}
}
}
In this example i only want this to succeed if the call
is calling my test()
function.
Unfortunately I get an error about type mismatch and any help would be greatly appreciated, thanks.
the error i get is:
Call::test(x) => Ok(()),
| ^^^^^^^^^^^^^ expected associated type, found enum Call
|
= note: expected associated type <T as Trait>::Call
found enum Call<_>
= note: consider constraining the associated type <T as Trait>::Call to Call<_> or calling a method that returns <T as Trait>::Call
If anyone else has the same problem, IsSubType
is your friend. You can constrain your Call type with IsSubType
type Call: Parameter + Dispatchable<Origin=<Self as frame_system::Trait>::Origin> + IsSubType<Module<Self>, Self>;
And for the matching you can get the subtype of the call and match on that:
let call = match call.is_sub_type() {
Some(call) => call,
None => return Err(),
};
match *call {
Call::test(x) => return Ok(),
_ => return Err()
}