frame_support_procedural/construct_runtime/expand/
unsigned.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
18use crate::construct_runtime::Pallet;
19use proc_macro2::TokenStream;
20use quote::quote;
21use std::str::FromStr;
22use syn::Ident;
23
24pub fn expand_outer_validate_unsigned(
25	runtime: &Ident,
26	pallet_decls: &[Pallet],
27	scrate: &TokenStream,
28) -> TokenStream {
29	let mut pallet_names = Vec::new();
30	let mut pallet_attrs = Vec::new();
31	let mut query_validate_unsigned_part_macros = Vec::new();
32
33	for pallet_decl in pallet_decls {
34		if pallet_decl.exists_part("ValidateUnsigned") {
35			let name = &pallet_decl.name;
36			let path = &pallet_decl.path;
37			let attr = pallet_decl.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
38				let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
39					.expect("was successfully parsed before; qed");
40				quote! {
41					#acc
42					#attr
43				}
44			});
45
46			pallet_names.push(name);
47			pallet_attrs.push(attr);
48			query_validate_unsigned_part_macros.push(quote! {
49				#path::__substrate_validate_unsigned_check::is_validate_unsigned_part_defined!(#name);
50			});
51		}
52	}
53
54	quote! {
55		#( #query_validate_unsigned_part_macros )*
56
57		impl #scrate::unsigned::ValidateUnsigned for #runtime {
58			type Call = RuntimeCall;
59
60			fn pre_dispatch(call: &Self::Call) -> Result<(), #scrate::unsigned::TransactionValidityError> {
61				#[allow(unreachable_patterns)]
62				match call {
63					#(
64						#pallet_attrs
65						RuntimeCall::#pallet_names(inner_call) => #pallet_names::pre_dispatch(inner_call),
66					)*
67					// pre-dispatch should not stop inherent extrinsics, validation should prevent
68					// including arbitrary (non-inherent) extrinsics to blocks.
69					_ => Ok(()),
70				}
71			}
72
73			fn validate_unsigned(
74				#[allow(unused_variables)]
75				source: #scrate::unsigned::TransactionSource,
76				call: &Self::Call,
77			) -> #scrate::unsigned::TransactionValidity {
78				#[allow(unreachable_patterns)]
79				match call {
80					#(
81						#pallet_attrs
82						RuntimeCall::#pallet_names(inner_call) => #pallet_names::validate_unsigned(source, inner_call),
83					)*
84					_ => #scrate::unsigned::UnknownTransaction::NoUnsignedValidator.into(),
85				}
86			}
87		}
88	}
89}