sp_runtime/generic/
checked_extrinsic.rs1use crate::{
22 traits::{
23 self, DispatchInfoOf, Dispatchable, MaybeDisplay, Member, PostDispatchInfoOf,
24 SignedExtension, ValidateUnsigned,
25 },
26 transaction_validity::{TransactionSource, TransactionValidity},
27};
28
29#[derive(PartialEq, Eq, Clone, sp_core::RuntimeDebug)]
35pub struct CheckedExtrinsic<AccountId, Call, Extra> {
36 pub signed: Option<(AccountId, Extra)>,
39
40 pub function: Call,
42}
43
44impl<AccountId, Call, Extra, RuntimeOrigin> traits::Applyable
45 for CheckedExtrinsic<AccountId, Call, Extra>
46where
47 AccountId: Member + MaybeDisplay,
48 Call: Member + Dispatchable<RuntimeOrigin = RuntimeOrigin>,
49 Extra: SignedExtension<AccountId = AccountId, Call = Call>,
50 RuntimeOrigin: From<Option<AccountId>>,
51{
52 type Call = Call;
53
54 fn validate<U: ValidateUnsigned<Call = Self::Call>>(
55 &self,
56 source: TransactionSource,
59 info: &DispatchInfoOf<Self::Call>,
60 len: usize,
61 ) -> TransactionValidity {
62 if let Some((ref id, ref extra)) = self.signed {
63 Extra::validate(extra, id, &self.function, info, len)
64 } else {
65 let valid = Extra::validate_unsigned(&self.function, info, len)?;
66 let unsigned_validation = U::validate_unsigned(source, &self.function)?;
67 Ok(valid.combine_with(unsigned_validation))
68 }
69 }
70
71 fn apply<U: ValidateUnsigned<Call = Self::Call>>(
72 self,
73 info: &DispatchInfoOf<Self::Call>,
74 len: usize,
75 ) -> crate::ApplyExtrinsicResultWithInfo<PostDispatchInfoOf<Self::Call>> {
76 let (maybe_who, maybe_pre) = if let Some((id, extra)) = self.signed {
77 let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?;
78 (Some(id), Some(pre))
79 } else {
80 Extra::pre_dispatch_unsigned(&self.function, info, len)?;
81 U::pre_dispatch(&self.function)?;
82 (None, None)
83 };
84 let res = self.function.dispatch(RuntimeOrigin::from(maybe_who));
85 let post_info = match res {
86 Ok(info) => info,
87 Err(err) => err.post_info,
88 };
89 Extra::post_dispatch(
90 maybe_pre,
91 info,
92 &post_info,
93 len,
94 &res.map(|_| ()).map_err(|e| e.error),
95 )?;
96 Ok(res)
97 }
98}