referrerpolicy=no-referrer-when-downgrade

sp_runtime/traits/transaction_extension/
mod.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! The transaction extension trait.
19
20use crate::{
21	scale_info::{MetaType, StaticTypeInfo},
22	transaction_validity::{
23		TransactionSource, TransactionValidity, TransactionValidityError, ValidTransaction,
24	},
25	DispatchResult,
26};
27use alloc::vec::Vec;
28use codec::{Codec, Decode, DecodeWithMemTracking, Encode};
29use core::fmt::Debug;
30#[doc(hidden)]
31pub use core::marker::PhantomData;
32use impl_trait_for_tuples::impl_for_tuples;
33use sp_weights::Weight;
34use tuplex::{PopFront, PushBack};
35
36use super::{
37	DispatchInfoOf, DispatchOriginOf, Dispatchable, ExtensionPostDispatchWeightHandler,
38	PostDispatchInfoOf, RefundWeight,
39};
40
41mod as_transaction_extension;
42mod dispatch_transaction;
43#[allow(deprecated)]
44pub use as_transaction_extension::AsTransactionExtension;
45pub use dispatch_transaction::DispatchTransaction;
46
47/// Provides `Sealed` trait.
48mod private {
49	/// Special trait that prevents the implementation of some traits outside of this crate.
50	pub trait Sealed {}
51}
52
53/// The base implication in a transaction.
54///
55/// This struct is used to represent the base implication in the transaction, that is
56/// the implication not part of any transaction extensions. It usually comprises of the call and
57/// the transaction extension version.
58///
59/// The concept of implication in the transaction extension pipeline is explained in the trait
60/// documentation: [`TransactionExtension`].
61#[derive(Encode)]
62pub struct TxBaseImplication<T>(pub T);
63
64impl<T: Encode> Implication for TxBaseImplication<T> {
65	fn parts(&self) -> ImplicationParts<&impl Encode, &impl Encode, &impl Encode> {
66		ImplicationParts { base: self, explicit: &(), implicit: &() }
67	}
68}
69
70impl<T> private::Sealed for TxBaseImplication<T> {}
71
72/// The implication in a transaction.
73///
74/// The concept of implication in the transaction extension pipeline is explained in the trait
75/// documentation: [`TransactionExtension`].
76#[derive(Encode)]
77pub struct ImplicationParts<Base, Explicit, Implicit> {
78	/// The base implication, that is implication not part of any transaction extension, usually
79	/// the call and the transaction extension version.
80	pub base: Base,
81	/// The explicit implication in transaction extensions.
82	pub explicit: Explicit,
83	/// The implicit implication in transaction extensions.
84	pub implicit: Implicit,
85}
86
87impl<Base: Encode, Explicit: Encode, Implicit: Encode> Implication
88	for ImplicationParts<Base, Explicit, Implicit>
89{
90	fn parts(&self) -> ImplicationParts<&impl Encode, &impl Encode, &impl Encode> {
91		ImplicationParts { base: &self.base, explicit: &self.explicit, implicit: &self.implicit }
92	}
93}
94
95impl<Base, Explicit, Implicit> private::Sealed for ImplicationParts<Base, Explicit, Implicit> {}
96
97/// Interface of implications in the transaction extension pipeline.
98///
99/// Implications can be encoded, this is useful for checking signature on the implications.
100/// Implications can be split into parts, this allow to destructure and restructure the
101/// implications, this is useful for nested pipeline.
102///
103/// This trait is sealed, consider using [`TxBaseImplication`] and [`ImplicationParts`]
104/// implementations.
105///
106/// The concept of implication in the transaction extension pipeline is explained in the trait
107/// documentation: [`TransactionExtension`].
108pub trait Implication: Encode + private::Sealed {
109	/// Destructure the implication into its parts.
110	fn parts(&self) -> ImplicationParts<&impl Encode, &impl Encode, &impl Encode>;
111}
112
113/// Shortcut for the result value of the `validate` function.
114pub type ValidateResult<Val, Call> =
115	Result<(ValidTransaction, Val, DispatchOriginOf<Call>), TransactionValidityError>;
116
117/// Means by which a transaction may be extended. This type embodies both the data and the logic
118/// that should be additionally associated with the transaction. It should be plain old data.
119///
120/// The simplest transaction extension would be the Unit type (and empty pipeline) `()`. This
121/// executes no additional logic and implies a dispatch of the transaction's call using the
122/// inherited origin (either `None` or `Signed`, depending on whether this is a signed or general
123/// transaction).
124///
125/// Transaction extensions are capable of altering certain associated semantics:
126///
127/// - They may define the origin with which the transaction's call should be dispatched.
128/// - They may define various parameters used by the transaction queue to determine under what
129///   conditions the transaction should be retained and introduced on-chain.
130/// - They may define whether this transaction is acceptable for introduction on-chain at all.
131///
132/// Each of these semantics are defined by the `validate` function.
133///
134/// **NOTE: Transaction extensions cannot under any circumstances alter the call itself.**
135///
136/// Transaction extensions are capable of defining logic which is executed additionally to the
137/// dispatch of the call:
138///
139/// - They may define logic which must be executed prior to the dispatch of the call.
140/// - They may also define logic which must be executed after the dispatch of the call.
141///
142/// Each of these semantics are defined by the `prepare` and `post_dispatch_details` functions
143/// respectively.
144///
145/// Finally, transaction extensions may define additional data to help define the implications of
146/// the logic they introduce. This additional data may be explicitly defined by the transaction
147/// author (in which case it is included as part of the transaction body), or it may be implicitly
148/// defined by the transaction extension based around the on-chain state (which the transaction
149/// author is assumed to know). This data may be utilized by the above logic to alter how a node's
150/// transaction queue treats this transaction.
151///
152/// ## Default implementations
153///
154/// Of the 6 functions in this trait along with `TransactionExtension`, 2 of them must return a
155/// value of an associated type on success, with only `implicit` having a default implementation.
156/// This means that default implementations cannot be provided for `validate` and `prepare`.
157/// However, a macro is provided [impl_tx_ext_default](crate::impl_tx_ext_default) which is capable
158/// of generating default implementations for both of these functions. If you do not wish to
159/// introduce additional logic into the transaction pipeline, then it is recommended that you use
160/// this macro to implement these functions. Additionally, [weight](TransactionExtension::weight)
161/// can return a default value, which would mean the extension is weightless, but it is not
162/// implemented by default. Instead, implementers can explicitly choose to implement this default
163/// behavior through the same [impl_tx_ext_default](crate::impl_tx_ext_default) macro.
164///
165/// If your extension does any post-flight logic, then the functionality must be implemented in
166/// [post_dispatch_details](TransactionExtension::post_dispatch_details). This function can return
167/// the actual weight used by the extension during an entire dispatch cycle by wrapping said weight
168/// value in a `Some`. This is useful in computing fee refunds, similar to how post dispatch
169/// information is used to refund fees for calls. Alternatively, a `None` can be returned, which
170/// means that the worst case scenario weight, namely the value returned by
171/// [weight](TransactionExtension::weight), is the actual weight. This particular piece of logic
172/// is embedded in the default implementation of
173/// [post_dispatch](TransactionExtension::post_dispatch) so that the weight is assumed to be worst
174/// case scenario, but implementers of this trait can correct it with extra effort. Therefore, all
175/// users of an extension should use [post_dispatch](TransactionExtension::post_dispatch), with
176/// [post_dispatch_details](TransactionExtension::post_dispatch_details) considered an internal
177/// function.
178///
179/// ## Pipelines, Inherited Implications, and Authorized Origins
180///
181/// Requiring a single transaction extension to define all of the above semantics would be
182/// cumbersome and would lead to a lot of boilerplate. Instead, transaction extensions are
183/// aggregated into pipelines, which are tuples of transaction extensions. Each extension in the
184/// pipeline is executed in order, and the output of each extension is aggregated and/or relayed as
185/// the input to the next extension in the pipeline.
186///
187/// This ordered composition happens with all data types ([Val](TransactionExtension::Val),
188/// [Pre](TransactionExtension::Pre) and [Implicit](TransactionExtension::Implicit)) as well as
189/// all functions. There are important consequences stemming from how the composition affects the
190/// meaning of the `origin` and `implication` parameters as well as the results. Whereas the
191/// [prepare](TransactionExtension::prepare) and
192/// [post_dispatch](TransactionExtension::post_dispatch) functions are clear in their meaning, the
193/// [validate](TransactionExtension::validate) function is fairly sophisticated and warrants further
194/// explanation.
195///
196/// Firstly, the `origin` parameter. The `origin` passed into the first item in a pipeline is simply
197/// that passed into the tuple itself. It represents an authority who has authorized the implication
198/// of the transaction, as of the extension it has been passed into *and any further extensions it
199/// may pass though, all the way to, and including, the transaction's dispatch call itself. Each
200/// following item in the pipeline is passed the origin which the previous item returned. The origin
201/// returned from the final item in the pipeline is the origin which is returned by the tuple
202/// itself.
203///
204/// This means that if a constituent extension returns a different origin to the one it was called
205/// with, then (assuming no other extension changes it further) *this new origin will be used for
206/// all extensions following it in the pipeline, and will be returned from the pipeline to be used
207/// as the origin for the call's dispatch*. The call itself as well as all these extensions
208/// following may each imply consequence for this origin. We call this the *inherited implication*.
209///
210/// The *inherited implication* is the cumulated on-chain effects born by whatever origin is
211/// returned. It is expressed to the [validate](TransactionExtension::validate) function only as the
212/// `implication` argument which implements the [Encode] trait. A transaction extension may define
213/// its own implications through its own fields and the
214/// [implicit](TransactionExtension::implicit) function. This is only utilized by extensions
215/// which precede it in a pipeline or, if the transaction is an old-school signed transaction, the
216/// underlying transaction verification logic.
217///
218/// **The inherited implication passed as the `implication` parameter to
219/// [validate](TransactionExtension::validate) does not include the extension's inner data itself
220/// nor does it include the result of the extension's `implicit` function.** If you both provide an
221/// implication and rely on the implication, then you need to manually aggregate your extensions
222/// implication with the aggregated implication passed in.
223///
224/// In the post dispatch pipeline, the actual weight of each extension is accrued in the
225/// [PostDispatchInfo](PostDispatchInfoOf<Call>) of that transaction sequentially with each
226/// [post_dispatch](TransactionExtension::post_dispatch) call. This means that an extension handling
227/// transaction payment and refunds should be at the end of the pipeline in order to capture the
228/// correct amount of weight used during the call. This is because one cannot know the actual weight
229/// of an extension after post dispatch without running the post dispatch ahead of time.
230pub trait TransactionExtension<Call: Dispatchable>:
231	Codec + DecodeWithMemTracking + Debug + Sync + Send + Clone + Eq + PartialEq + StaticTypeInfo
232{
233	/// Unique identifier of this signed extension.
234	///
235	/// This will be exposed in the metadata to identify the signed extension used in an extrinsic.
236	const IDENTIFIER: &'static str;
237
238	/// Any additional data which was known at the time of transaction construction and can be
239	/// useful in authenticating the transaction. This is determined dynamically in part from the
240	/// on-chain environment using the `implicit` function and not directly contained in the
241	/// transaction itself and therefore is considered "implicit".
242	type Implicit: Codec + StaticTypeInfo;
243
244	/// Determine any additional data which was known at the time of transaction construction and
245	/// can be useful in authenticating the transaction. The expected usage of this is to include in
246	/// any data which is signed and verified as part of transaction validation. Also perform any
247	/// pre-signature-verification checks and return an error if needed.
248	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
249		use crate::transaction_validity::InvalidTransaction::IndeterminateImplicit;
250		Ok(Self::Implicit::decode(&mut &[][..]).map_err(|_| IndeterminateImplicit)?)
251	}
252
253	/// Returns the metadata for this extension.
254	///
255	/// As a [`TransactionExtension`] can be a tuple of [`TransactionExtension`]s we need to return
256	/// a `Vec` that holds the metadata of each one. Each individual `TransactionExtension` must
257	/// return *exactly* one [`TransactionExtensionMetadata`].
258	///
259	/// This method provides a default implementation that returns a vec containing a single
260	/// [`TransactionExtensionMetadata`].
261	fn metadata() -> Vec<TransactionExtensionMetadata> {
262		alloc::vec![TransactionExtensionMetadata {
263			identifier: Self::IDENTIFIER,
264			ty: scale_info::meta_type::<Self>(),
265			implicit: scale_info::meta_type::<Self::Implicit>()
266		}]
267	}
268
269	/// The type that encodes information that can be passed from `validate` to `prepare`.
270	type Val;
271
272	/// The type that encodes information that can be passed from `prepare` to `post_dispatch`.
273	type Pre;
274
275	/// The weight consumed by executing this extension instance fully during transaction dispatch.
276	fn weight(&self, call: &Call) -> Weight;
277
278	/// Validate a transaction for the transaction queue.
279	///
280	/// This function can be called frequently by the transaction queue to obtain transaction
281	/// validity against current state. It should perform all checks that determine a valid
282	/// transaction, that can pay for its execution and quickly eliminate ones that are stale or
283	/// incorrect.
284	///
285	/// Parameters:
286	/// - `origin`: The origin of the transaction which this extension inherited; coming from an
287	///   "old-school" *signed transaction*, this will be a system `RawOrigin::Signed` value. If the
288	///   transaction is a "new-school" *General Transaction*, then this will be a system
289	///   `RawOrigin::None` value. If this extension is an item in a composite, then it could be
290	///   anything which was previously returned as an `origin` value in the result of a `validate`
291	///   call.
292	/// - `call`: The `Call` wrapped by this extension.
293	/// - `info`: Information concerning, and inherent to, the transaction's call.
294	/// - `len`: The total length of the encoded transaction.
295	/// - `inherited_implication`: The *implication* which this extension inherits. This is a tuple
296	///   of the transaction's call and some additional opaque-but-encodable data. Coming directly
297	///   from a transaction, the latter is [()]. However, if this extension is expressed as part of
298	///   a composite type, then the latter component is equal to any further implications to which
299	///   the returned `origin` could potentially apply. See Pipelines, Inherited Implications, and
300	///   Authorized Origins for more information.
301	///
302	/// Returns a [ValidateResult], which is a [Result] whose success type is a tuple of
303	/// [ValidTransaction] (defining useful metadata for the transaction queue), the [Self::Val]
304	/// token of this transaction, which gets passed into [prepare](TransactionExtension::prepare),
305	/// and the origin of the transaction, which gets passed into
306	/// [prepare](TransactionExtension::prepare) and is ultimately used for dispatch.
307	fn validate(
308		&self,
309		origin: DispatchOriginOf<Call>,
310		call: &Call,
311		info: &DispatchInfoOf<Call>,
312		len: usize,
313		self_implicit: Self::Implicit,
314		inherited_implication: &impl Implication,
315		source: TransactionSource,
316	) -> ValidateResult<Self::Val, Call>;
317
318	/// Do any pre-flight stuff for a transaction after validation.
319	///
320	/// This is for actions which do not happen in the transaction queue but only immediately prior
321	/// to the point of dispatch on-chain. This should not return an error, since errors should
322	/// already have been identified during the [validate](TransactionExtension::validate) call. If
323	/// an error is returned, the transaction will be considered invalid but no state changes will
324	/// happen and therefore work done in [validate](TransactionExtension::validate) will not be
325	/// paid for.
326	///
327	/// Unlike `validate`, this function may consume `self`.
328	///
329	/// Parameters:
330	/// - `val`: `Self::Val` returned by the result of the `validate` call.
331	/// - `origin`: The origin returned by the result of the `validate` call.
332	/// - `call`: The `Call` wrapped by this extension.
333	/// - `info`: Information concerning, and inherent to, the transaction's call.
334	/// - `len`: The total length of the encoded transaction.
335	///
336	/// Returns a [Self::Pre] value on success, which gets passed into
337	/// [post_dispatch](TransactionExtension::post_dispatch) and after the call is dispatched.
338	///
339	/// IMPORTANT: **Checks made in validation need not be repeated here.**
340	fn prepare(
341		self,
342		val: Self::Val,
343		origin: &DispatchOriginOf<Call>,
344		call: &Call,
345		info: &DispatchInfoOf<Call>,
346		len: usize,
347	) -> Result<Self::Pre, TransactionValidityError>;
348
349	/// Do any post-flight stuff for an extrinsic.
350	///
351	/// `_pre` contains the output of `prepare`.
352	///
353	/// This gets given the `DispatchResult` `_result` from the extrinsic and can, if desired,
354	/// introduce a `TransactionValidityError`, causing the block to become invalid for including
355	/// it.
356	///
357	/// On success, the caller must return the amount of unspent weight left over by this extension
358	/// after dispatch. By default, this function returns no unspent weight, which means the entire
359	/// weight computed for the worst case scenario is consumed.
360	///
361	/// WARNING: This function does not automatically keep track of accumulated "actual" weight.
362	/// Unless this weight is handled at the call site, use
363	/// [post_dispatch](TransactionExtension::post_dispatch)
364	/// instead.
365	///
366	/// Parameters:
367	/// - `pre`: `Self::Pre` returned by the result of the `prepare` call prior to dispatch.
368	/// - `info`: Information concerning, and inherent to, the transaction's call.
369	/// - `post_info`: Information concerning the dispatch of the transaction's call.
370	/// - `len`: The total length of the encoded transaction.
371	/// - `result`: The result of the dispatch.
372	///
373	/// WARNING: It is dangerous to return an error here. To do so will fundamentally invalidate the
374	/// transaction and any block that it is included in, causing the block author to not be
375	/// compensated for their work in validating the transaction or producing the block so far. It
376	/// can only be used safely when you *know* that the transaction is one that would only be
377	/// introduced by the current block author.
378	fn post_dispatch_details(
379		_pre: Self::Pre,
380		_info: &DispatchInfoOf<Call>,
381		_post_info: &PostDispatchInfoOf<Call>,
382		_len: usize,
383		_result: &DispatchResult,
384	) -> Result<Weight, TransactionValidityError> {
385		Ok(Weight::zero())
386	}
387
388	/// A wrapper for [`post_dispatch_details`](TransactionExtension::post_dispatch_details) that
389	/// refunds the unspent weight consumed by this extension into the post dispatch information.
390	///
391	/// If `post_dispatch_details` returns a non-zero unspent weight, which, by definition, must be
392	/// less than the worst case weight provided by [weight](TransactionExtension::weight), that
393	/// is the value refunded in `post_info`.
394	///
395	/// If no unspent weight is reported by `post_dispatch_details`, this function assumes the worst
396	/// case weight and does not refund anything.
397	///
398	/// For more information, look into
399	/// [post_dispatch_details](TransactionExtension::post_dispatch_details).
400	fn post_dispatch(
401		pre: Self::Pre,
402		info: &DispatchInfoOf<Call>,
403		post_info: &mut PostDispatchInfoOf<Call>,
404		len: usize,
405		result: &DispatchResult,
406	) -> Result<(), TransactionValidityError> {
407		let unspent_weight = Self::post_dispatch_details(pre, info, &post_info, len, result)?;
408		post_info.refund(unspent_weight);
409
410		Ok(())
411	}
412
413	/// Validation logic for bare extrinsics.
414	///
415	/// NOTE: This function will be migrated to a separate `InherentExtension` interface.
416	fn bare_validate(
417		_call: &Call,
418		_info: &DispatchInfoOf<Call>,
419		_len: usize,
420	) -> TransactionValidity {
421		Ok(ValidTransaction::default())
422	}
423
424	/// All pre-flight logic run before dispatching bare extrinsics.
425	///
426	/// NOTE: This function will be migrated to a separate `InherentExtension` interface.
427	fn bare_validate_and_prepare(
428		_call: &Call,
429		_info: &DispatchInfoOf<Call>,
430		_len: usize,
431	) -> Result<(), TransactionValidityError> {
432		Ok(())
433	}
434
435	/// Post dispatch logic run after dispatching bare extrinsics.
436	///
437	/// NOTE: This function will be migrated to a separate `InherentExtension` interface.
438	fn bare_post_dispatch(
439		_info: &DispatchInfoOf<Call>,
440		_post_info: &mut PostDispatchInfoOf<Call>,
441		_len: usize,
442		_result: &DispatchResult,
443	) -> Result<(), TransactionValidityError> {
444		Ok(())
445	}
446}
447
448/// Helper macro to be used in a `impl TransactionExtension` block to add default implementations of
449/// `weight`, `validate`, `prepare` or any combinations of the them.
450///
451/// The macro is to be used with 2 parameters, separated by ";":
452/// - the `Call` type;
453/// - the functions for which a default implementation should be generated, separated by " ";
454///   available options are `weight`, `validate` and `prepare`.
455///
456/// Example usage:
457/// ```nocompile
458/// impl TransactionExtension<FirstCall> for EmptyExtension {
459/// 	type Val = ();
460/// 	type Pre = ();
461///
462/// 	impl_tx_ext_default!(FirstCall; weight validate prepare);
463/// }
464///
465/// impl TransactionExtension<SecondCall> for SimpleExtension {
466/// 	type Val = u32;
467/// 	type Pre = ();
468///
469/// 	fn weight(&self, _: &SecondCall) -> Weight {
470/// 		Weight::zero()
471/// 	}
472///
473/// 	fn validate(
474/// 			&self,
475/// 			_origin: <T as Config>::RuntimeOrigin,
476/// 			_call: &SecondCall,
477/// 			_info: &DispatchInfoOf<SecondCall>,
478/// 			_len: usize,
479/// 			_self_implicit: Self::Implicit,
480/// 			_inherited_implication: &impl Encode,
481/// 		) -> ValidateResult<Self::Val, SecondCall> {
482/// 		Ok((Default::default(), 42u32, origin))
483/// 	}
484///
485/// 	impl_tx_ext_default!(SecondCall; prepare);
486/// }
487/// ```
488#[macro_export]
489macro_rules! impl_tx_ext_default {
490	($call:ty ; , $( $rest:tt )*) => {
491		$crate::impl_tx_ext_default!{$call ; $( $rest )*}
492	};
493	($call:ty ; validate $( $rest:tt )*) => {
494		fn validate(
495			&self,
496			origin: $crate::traits::DispatchOriginOf<$call>,
497			_call: &$call,
498			_info: &$crate::traits::DispatchInfoOf<$call>,
499			_len: usize,
500			_self_implicit: Self::Implicit,
501			_inherited_implication: &impl $crate::codec::Encode,
502			_source: $crate::transaction_validity::TransactionSource,
503		) -> $crate::traits::ValidateResult<Self::Val, $call> {
504			Ok((Default::default(), Default::default(), origin))
505		}
506		$crate::impl_tx_ext_default!{$call ; $( $rest )*}
507	};
508	($call:ty ; prepare $( $rest:tt )*) => {
509		fn prepare(
510			self,
511			_val: Self::Val,
512			_origin: &$crate::traits::DispatchOriginOf<$call>,
513			_call: &$call,
514			_info: &$crate::traits::DispatchInfoOf<$call>,
515			_len: usize,
516		) -> Result<Self::Pre, $crate::transaction_validity::TransactionValidityError> {
517			Ok(Default::default())
518		}
519		$crate::impl_tx_ext_default!{$call ; $( $rest )*}
520	};
521	($call:ty ; weight $( $rest:tt )*) => {
522		fn weight(&self, _call: &$call) -> $crate::Weight {
523			$crate::Weight::zero()
524		}
525		$crate::impl_tx_ext_default!{$call ; $( $rest )*}
526	};
527	($call:ty ;) => {};
528}
529
530/// Information about a [`TransactionExtension`] for the runtime metadata.
531pub struct TransactionExtensionMetadata {
532	/// The unique identifier of the [`TransactionExtension`].
533	pub identifier: &'static str,
534	/// The type of the [`TransactionExtension`].
535	pub ty: MetaType,
536	/// The type of the [`TransactionExtension`] additional signed data for the payload.
537	pub implicit: MetaType,
538}
539
540#[impl_for_tuples(1, 12)]
541impl<Call: Dispatchable> TransactionExtension<Call> for Tuple {
542	const IDENTIFIER: &'static str = "Use `metadata()`!";
543	for_tuples!( type Implicit = ( #( Tuple::Implicit ),* ); );
544	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
545		Ok(for_tuples!( ( #( Tuple.implicit()? ),* ) ))
546	}
547	fn metadata() -> Vec<TransactionExtensionMetadata> {
548		let mut ids = Vec::new();
549		for_tuples!( #( ids.extend(Tuple::metadata()); )* );
550		ids
551	}
552
553	for_tuples!( type Val = ( #( Tuple::Val ),* ); );
554	for_tuples!( type Pre = ( #( Tuple::Pre ),* ); );
555
556	fn weight(&self, call: &Call) -> Weight {
557		let mut weight = Weight::zero();
558		for_tuples!( #( weight = weight.saturating_add(Tuple.weight(call)); )* );
559		weight
560	}
561
562	fn validate(
563		&self,
564		origin: <Call as Dispatchable>::RuntimeOrigin,
565		call: &Call,
566		info: &DispatchInfoOf<Call>,
567		len: usize,
568		self_implicit: Self::Implicit,
569		inherited_implication: &impl Implication,
570		source: TransactionSource,
571	) -> Result<
572		(ValidTransaction, Self::Val, <Call as Dispatchable>::RuntimeOrigin),
573		TransactionValidityError,
574	> {
575		let valid = ValidTransaction::default();
576		let val = ();
577		let following_explicit_implications = for_tuples!( ( #( &self.Tuple ),* ) );
578		let following_implicit_implications = self_implicit;
579
580		let implication_parts = inherited_implication.parts();
581
582		for_tuples!(#(
583			// Implication of this pipeline element not relevant for later items, so we pop it.
584			let (_item, following_explicit_implications) = following_explicit_implications.pop_front();
585			let (item_implicit, following_implicit_implications) = following_implicit_implications.pop_front();
586			let (item_valid, item_val, origin) = {
587				Tuple.validate(origin, call, info, len, item_implicit,
588					&ImplicationParts {
589						base: implication_parts.base,
590						explicit: (&following_explicit_implications, implication_parts.explicit),
591						implicit: (&following_implicit_implications, implication_parts.implicit),
592					},
593					source)?
594			};
595			let valid = valid.combine_with(item_valid);
596			let val = val.push_back(item_val);
597		)* );
598		Ok((valid, val, origin))
599	}
600
601	fn prepare(
602		self,
603		val: Self::Val,
604		origin: &<Call as Dispatchable>::RuntimeOrigin,
605		call: &Call,
606		info: &DispatchInfoOf<Call>,
607		len: usize,
608	) -> Result<Self::Pre, TransactionValidityError> {
609		Ok(for_tuples!( ( #(
610			Tuple::prepare(self.Tuple, val.Tuple, origin, call, info, len)?
611		),* ) ))
612	}
613
614	fn post_dispatch_details(
615		pre: Self::Pre,
616		info: &DispatchInfoOf<Call>,
617		post_info: &PostDispatchInfoOf<Call>,
618		len: usize,
619		result: &DispatchResult,
620	) -> Result<Weight, TransactionValidityError> {
621		let mut total_unspent_weight = Weight::zero();
622		for_tuples!( #({
623			let unspent_weight = Tuple::post_dispatch_details(pre.Tuple, info, post_info, len, result)?;
624			total_unspent_weight = total_unspent_weight.saturating_add(unspent_weight);
625		})* );
626		Ok(total_unspent_weight)
627	}
628
629	fn post_dispatch(
630		pre: Self::Pre,
631		info: &DispatchInfoOf<Call>,
632		post_info: &mut PostDispatchInfoOf<Call>,
633		len: usize,
634		result: &DispatchResult,
635	) -> Result<(), TransactionValidityError> {
636		for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info, post_info, len, result)?; )* );
637		Ok(())
638	}
639
640	fn bare_validate(call: &Call, info: &DispatchInfoOf<Call>, len: usize) -> TransactionValidity {
641		let valid = ValidTransaction::default();
642		for_tuples!(#(
643			let item_valid = Tuple::bare_validate(call, info, len)?;
644			let valid = valid.combine_with(item_valid);
645		)* );
646		Ok(valid)
647	}
648
649	fn bare_validate_and_prepare(
650		call: &Call,
651		info: &DispatchInfoOf<Call>,
652		len: usize,
653	) -> Result<(), TransactionValidityError> {
654		for_tuples!( #( Tuple::bare_validate_and_prepare(call, info, len)?; )* );
655		Ok(())
656	}
657
658	fn bare_post_dispatch(
659		info: &DispatchInfoOf<Call>,
660		post_info: &mut PostDispatchInfoOf<Call>,
661		len: usize,
662		result: &DispatchResult,
663	) -> Result<(), TransactionValidityError> {
664		for_tuples!( #( Tuple::bare_post_dispatch(info, post_info, len, result)?; )* );
665		Ok(())
666	}
667}
668
669impl<Call: Dispatchable> TransactionExtension<Call> for () {
670	const IDENTIFIER: &'static str = "UnitTransactionExtension";
671	type Implicit = ();
672	fn implicit(&self) -> core::result::Result<Self::Implicit, TransactionValidityError> {
673		Ok(())
674	}
675	type Val = ();
676	type Pre = ();
677	fn weight(&self, _call: &Call) -> Weight {
678		Weight::zero()
679	}
680	fn validate(
681		&self,
682		origin: <Call as Dispatchable>::RuntimeOrigin,
683		_call: &Call,
684		_info: &DispatchInfoOf<Call>,
685		_len: usize,
686		_self_implicit: Self::Implicit,
687		_inherited_implication: &impl Implication,
688		_source: TransactionSource,
689	) -> Result<
690		(ValidTransaction, (), <Call as Dispatchable>::RuntimeOrigin),
691		TransactionValidityError,
692	> {
693		Ok((ValidTransaction::default(), (), origin))
694	}
695	fn prepare(
696		self,
697		_val: (),
698		_origin: &<Call as Dispatchable>::RuntimeOrigin,
699		_call: &Call,
700		_info: &DispatchInfoOf<Call>,
701		_len: usize,
702	) -> Result<(), TransactionValidityError> {
703		Ok(())
704	}
705}
706
707#[cfg(test)]
708mod test {
709	use super::*;
710
711	#[test]
712	fn test_implications_on_nested_structure() {
713		use scale_info::TypeInfo;
714		use std::cell::RefCell;
715
716		#[derive(Clone, Debug, Eq, PartialEq, Encode, Decode, DecodeWithMemTracking, TypeInfo)]
717		struct MockExtension {
718			also_implicit: u8,
719			explicit: u8,
720		}
721
722		const CALL_IMPLICIT: u8 = 23;
723
724		thread_local! {
725			static COUNTER: RefCell<u8> = RefCell::new(1);
726		}
727
728		impl TransactionExtension<()> for MockExtension {
729			const IDENTIFIER: &'static str = "MockExtension";
730			type Implicit = u8;
731			fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
732				Ok(self.also_implicit)
733			}
734			type Val = ();
735			type Pre = ();
736			fn weight(&self, _call: &()) -> Weight {
737				Weight::zero()
738			}
739			fn prepare(
740				self,
741				_val: Self::Val,
742				_origin: &DispatchOriginOf<()>,
743				_call: &(),
744				_info: &DispatchInfoOf<()>,
745				_len: usize,
746			) -> Result<Self::Pre, TransactionValidityError> {
747				Ok(())
748			}
749			fn validate(
750				&self,
751				origin: DispatchOriginOf<()>,
752				_call: &(),
753				_info: &DispatchInfoOf<()>,
754				_len: usize,
755				self_implicit: Self::Implicit,
756				inherited_implication: &impl Implication,
757				_source: TransactionSource,
758			) -> ValidateResult<Self::Val, ()> {
759				COUNTER.with(|c| {
760					let mut counter = c.borrow_mut();
761
762					assert_eq!(self_implicit, *counter);
763					assert_eq!(
764						self,
765						&MockExtension { also_implicit: *counter, explicit: *counter + 1 }
766					);
767
768					// Implications must be call then 1 to 22 then 1 to 22 odd.
769					let mut assert_implications = Vec::new();
770					assert_implications.push(CALL_IMPLICIT);
771					for i in *counter + 2..23 {
772						assert_implications.push(i);
773					}
774					for i in *counter + 2..23 {
775						if i % 2 == 1 {
776							assert_implications.push(i);
777						}
778					}
779					assert_eq!(inherited_implication.encode(), assert_implications);
780
781					*counter += 2;
782				});
783				Ok((ValidTransaction::default(), (), origin))
784			}
785			fn post_dispatch_details(
786				_pre: Self::Pre,
787				_info: &DispatchInfoOf<()>,
788				_post_info: &PostDispatchInfoOf<()>,
789				_len: usize,
790				_result: &DispatchResult,
791			) -> Result<Weight, TransactionValidityError> {
792				Ok(Weight::zero())
793			}
794		}
795
796		// Test for one nested structure
797
798		let ext = (
799			MockExtension { also_implicit: 1, explicit: 2 },
800			MockExtension { also_implicit: 3, explicit: 4 },
801			(
802				MockExtension { also_implicit: 5, explicit: 6 },
803				MockExtension { also_implicit: 7, explicit: 8 },
804				(
805					MockExtension { also_implicit: 9, explicit: 10 },
806					MockExtension { also_implicit: 11, explicit: 12 },
807				),
808				MockExtension { also_implicit: 13, explicit: 14 },
809				MockExtension { also_implicit: 15, explicit: 16 },
810			),
811			MockExtension { also_implicit: 17, explicit: 18 },
812			(MockExtension { also_implicit: 19, explicit: 20 },),
813			MockExtension { also_implicit: 21, explicit: 22 },
814		);
815
816		let implicit = ext.implicit().unwrap();
817
818		let res = ext
819			.validate(
820				(),
821				&(),
822				&DispatchInfoOf::<()>::default(),
823				0,
824				implicit,
825				&TxBaseImplication(CALL_IMPLICIT),
826				TransactionSource::Local,
827			)
828			.expect("valid");
829
830		assert_eq!(res.0, ValidTransaction::default());
831
832		// Test for another nested structure
833
834		COUNTER.with(|c| {
835			*c.borrow_mut() = 1;
836		});
837
838		let ext = (
839			MockExtension { also_implicit: 1, explicit: 2 },
840			MockExtension { also_implicit: 3, explicit: 4 },
841			MockExtension { also_implicit: 5, explicit: 6 },
842			MockExtension { also_implicit: 7, explicit: 8 },
843			MockExtension { also_implicit: 9, explicit: 10 },
844			MockExtension { also_implicit: 11, explicit: 12 },
845			(
846				MockExtension { also_implicit: 13, explicit: 14 },
847				MockExtension { also_implicit: 15, explicit: 16 },
848				MockExtension { also_implicit: 17, explicit: 18 },
849				MockExtension { also_implicit: 19, explicit: 20 },
850				MockExtension { also_implicit: 21, explicit: 22 },
851			),
852		);
853
854		let implicit = ext.implicit().unwrap();
855
856		let res = ext
857			.validate(
858				(),
859				&(),
860				&DispatchInfoOf::<()>::default(),
861				0,
862				implicit,
863				&TxBaseImplication(CALL_IMPLICIT),
864				TransactionSource::Local,
865			)
866			.expect("valid");
867
868		assert_eq!(res.0, ValidTransaction::default());
869	}
870}