Trait sp_runtime::traits::ValidateUnsigned
source · pub trait ValidateUnsigned {
type Call;
fn validate_unsigned(
source: TransactionSource,
call: &Self::Call
) -> TransactionValidity;
fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { ... }
}
Expand description
Provide validation for unsigned extrinsics.
This trait provides two functions pre_dispatch
and
validate_unsigned
. The pre_dispatch
function is called right before dispatching the call wrapped by an unsigned extrinsic. The
validate_unsigned
function is mainly being used in the context of
the transaction pool to check the validity of the call wrapped by an unsigned extrinsic.
Required Associated Types§
Required Methods§
sourcefn validate_unsigned(
source: TransactionSource,
call: &Self::Call
) -> TransactionValidity
fn validate_unsigned(
source: TransactionSource,
call: &Self::Call
) -> TransactionValidity
Return the validity of the call
This method has no side-effects. It merely checks whether the call would be rejected by the runtime in an unsigned extrinsic.
The validity checks should be as lightweight as possible because every node will execute this code before the unsigned extrinsic enters the transaction pool and also periodically afterwards to ensure the validity. To prevent dos-ing a network with unsigned extrinsics, these validity checks should include some checks around uniqueness, for example, like checking that the unsigned extrinsic was send by an authority in the active set.
Changes made to storage should be discarded by caller.
Provided Methods§
sourcefn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError>
fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError>
Validate the call right before dispatch.
This method should be used to prevent transactions already in the pool
(i.e. passing validate_unsigned
) from being included in blocks
in case they became invalid since being added to the pool.
By default it’s a good idea to call validate_unsigned
from
within this function again to make sure we never include an invalid transaction. Otherwise
the implementation of the call or this method will need to provide proper validation to
ensure that the transaction is valid.
Changes made to storage WILL be persisted if the call returns Ok
.
Examples found in repository?
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
fn apply<U: ValidateUnsigned<Call = Self::Call>>(
self,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> ApplyExtrinsicResultWithInfo<PostDispatchInfoOf<Self::Call>> {
let maybe_who = if let Some((who, extra)) = self.signature {
Extra::pre_dispatch(extra, &who, &self.call, info, len)?;
Some(who)
} else {
Extra::pre_dispatch_unsigned(&self.call, info, len)?;
U::pre_dispatch(&self.call)?;
None
};
Ok(self.call.dispatch(maybe_who.into()))
}
More examples
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
fn apply<U: ValidateUnsigned<Call = Self::Call>>(
self,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> crate::ApplyExtrinsicResultWithInfo<PostDispatchInfoOf<Self::Call>> {
let (maybe_who, maybe_pre) = if let Some((id, extra)) = self.signed {
let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?;
(Some(id), Some(pre))
} else {
Extra::pre_dispatch_unsigned(&self.function, info, len)?;
U::pre_dispatch(&self.function)?;
(None, None)
};
let res = self.function.dispatch(RuntimeOrigin::from(maybe_who));
let post_info = match res {
Ok(info) => info,
Err(err) => err.post_info,
};
Extra::post_dispatch(
maybe_pre,
info,
&post_info,
len,
&res.map(|_| ()).map_err(|e| e.error),
)?;
Ok(res)
}