I need to be able to identify the source of an unsigned extrinsic for spam prevention purposes. Assume there is a set of known authorities from whom I am willing to accept an unsigned extrinsic. I want to check that the sender of the unsigned extrinsic is a member of this authority set (and that they are who they say they are).
From what I can tell there are a couple of different approaches and I would like to better understand the differences between each and the trade-offs involved.
Add a signature as a call parameter and define ValidateUnsigned
.
This approach is used in the ImOnline
pallet. Roughly speaking:
decl_module!(
// ...
fn my_unsigned_call(_origin,
args: MyArgs<T>,
authority: T::Authority,
signature: T::Signature) {
// Handle the call
todo!()
}
)
impl<T: Trait> frame_support::unsigned::ValidateUnsigned for Module<T> {
// ...
fn validate_unsigned(
_source: TransactionSource,
call: &Self::Call,
) -> TransactionValidity {
if let Call::my_unsigned_call(args, authority, signature) = call {
// Check the sender is in the approved authority set and verify sig
todo!();
}
}
}
Implement SignedExtension
for some metadata associated with the pallet trait. This is touched upon in the docs and seems to be implemented in the TransactionPayment
pallet. Implementation would be something like this:
struct SenderInfo<T> {
authority: T::Authority,
signature: T::Signature,
}
impl<T: Config + Send + Sync> SignedExtension for SenderInfo<T>
where
<T as frame_system::Config>::Call: IsSubType<Call<T>>,
{
// ...
fn validate_unsigned(
call: &Self::Call,
info: &DispatchInfoOf<Self::Call>,
len: usize
) -> TransactionValidity {
// validate self.authority and self.signature
}
}
This SignedExtension
then needs to be aggregated into the SignedExtra
of the runtime. (Right?)
I am tending towards using the second option since it seems cleaner: it doesn't require me to pollute my method signatures with extra information that is not even used in the method call. But would this mean that any transaction submitted to the runtime, signed or unsigned, would need to add this customised SignedExtra
?
Are there any other considerations I should be aware of?
I'm working on a very similar thing.
I was able to do so with your approach 1. Basically I do check two things there:
My working example is available here https://github.com/korzewski/jackblock/blob/master/pallets/jackblock/src/lib.rs#L401
Although, this is not perfect because I need to keep a second list of Authorities and add them manually.
Currently I'm trying to refactor it, so my authorities accounts are the same as my validators (Aura pallet). Still looking for a solution so maybe you know how to solve it? Basically how to reuse Aura pallet in my own pallet