sp_runtime/traits/transaction_extension/
dispatch_transaction.rs1use crate::{
21 generic::ExtensionVersion,
22 traits::AsTransactionAuthorizedOrigin,
23 transaction_validity::{InvalidTransaction, TransactionSource},
24};
25
26use super::*;
27
28pub trait DispatchTransaction<Call: Dispatchable> {
32 type Origin;
34 type Info;
36 type Result;
38 type Val;
40 type Pre;
42 fn validate_only(
47 &self,
48 origin: Self::Origin,
49 call: &Call,
50 info: &Self::Info,
51 len: usize,
52 source: TransactionSource,
53 extension_version: ExtensionVersion,
54 ) -> Result<(ValidTransaction, Self::Val, Self::Origin), TransactionValidityError>;
55 fn validate_and_prepare(
57 self,
58 origin: Self::Origin,
59 call: &Call,
60 info: &Self::Info,
61 len: usize,
62 extension_version: ExtensionVersion,
63 ) -> Result<(Self::Pre, Self::Origin), TransactionValidityError>;
64 fn dispatch_transaction(
66 self,
67 origin: Self::Origin,
68 call: Call,
69 info: &Self::Info,
70 len: usize,
71 extension_version: ExtensionVersion,
72 ) -> Self::Result;
73 fn test_run(
77 self,
78 origin: Self::Origin,
79 call: &Call,
80 info: &Self::Info,
81 len: usize,
82 extension_version: ExtensionVersion,
83 substitute: impl FnOnce(
84 Self::Origin,
85 ) -> crate::DispatchResultWithInfo<<Call as Dispatchable>::PostInfo>,
86 ) -> Self::Result;
87}
88
89impl<T: TransactionExtension<Call>, Call: Dispatchable + Encode> DispatchTransaction<Call> for T
90where
91 <Call as Dispatchable>::RuntimeOrigin: AsTransactionAuthorizedOrigin,
92{
93 type Origin = <Call as Dispatchable>::RuntimeOrigin;
94 type Info = DispatchInfoOf<Call>;
95 type Result = crate::ApplyExtrinsicResultWithInfo<PostDispatchInfoOf<Call>>;
96 type Val = T::Val;
97 type Pre = T::Pre;
98
99 fn validate_only(
100 &self,
101 origin: Self::Origin,
102 call: &Call,
103 info: &DispatchInfoOf<Call>,
104 len: usize,
105 source: TransactionSource,
106 extension_version: ExtensionVersion,
107 ) -> Result<(ValidTransaction, T::Val, Self::Origin), TransactionValidityError> {
108 match self.validate(
109 origin,
110 call,
111 info,
112 len,
113 self.implicit()?,
114 &TxBaseImplication((extension_version, call)),
115 source,
116 ) {
117 Ok((_, _, origin)) if !origin.is_transaction_authorized() => {
119 Err(InvalidTransaction::UnknownOrigin.into())
120 },
121 res => res,
122 }
123 }
124 fn validate_and_prepare(
125 self,
126 origin: Self::Origin,
127 call: &Call,
128 info: &DispatchInfoOf<Call>,
129 len: usize,
130 extension_version: ExtensionVersion,
131 ) -> Result<(T::Pre, Self::Origin), TransactionValidityError> {
132 let (_, val, origin) = self.validate_only(
133 origin,
134 call,
135 info,
136 len,
137 TransactionSource::InBlock,
138 extension_version,
139 )?;
140 let pre = self.prepare(val, &origin, &call, info, len)?;
141 Ok((pre, origin))
142 }
143 fn dispatch_transaction(
144 self,
145 origin: <Call as Dispatchable>::RuntimeOrigin,
146 call: Call,
147 info: &DispatchInfoOf<Call>,
148 len: usize,
149 extension_version: ExtensionVersion,
150 ) -> Self::Result {
151 let (pre, origin) =
152 self.validate_and_prepare(origin, &call, info, len, extension_version)?;
153 let mut res = call.dispatch(origin);
154 let pd_res = res.map(|_| ()).map_err(|e| e.error);
155 let post_info = match &mut res {
156 Ok(info) => info,
157 Err(err) => &mut err.post_info,
158 };
159 post_info.set_extension_weight(info);
160 T::post_dispatch(pre, info, post_info, len, &pd_res)?;
161 Ok(res)
162 }
163 fn test_run(
164 self,
165 origin: Self::Origin,
166 call: &Call,
167 info: &Self::Info,
168 len: usize,
169 extension_version: ExtensionVersion,
170 substitute: impl FnOnce(
171 Self::Origin,
172 ) -> crate::DispatchResultWithInfo<<Call as Dispatchable>::PostInfo>,
173 ) -> Self::Result {
174 let (pre, origin) =
175 self.validate_and_prepare(origin, &call, info, len, extension_version)?;
176 let mut res = substitute(origin);
177 let pd_res = res.map(|_| ()).map_err(|e| e.error);
178 let post_info = match &mut res {
179 Ok(info) => info,
180 Err(err) => &mut err.post_info,
181 };
182 post_info.set_extension_weight(info);
183 T::post_dispatch(pre, info, post_info, len, &pd_res)?;
184 Ok(res)
185 }
186}