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