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