frame_support_procedural/lib.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//! Proc macro of Support code for the runtime.
19
20#![recursion_limit = "512"]
21#![deny(rustdoc::broken_intra_doc_links)]
22
23mod benchmark;
24mod construct_runtime;
25mod crate_version;
26mod deprecation;
27mod derive_impl;
28mod dummy_part_checker;
29mod dynamic_params;
30mod key_prefix;
31mod match_and_insert;
32mod no_bound;
33mod pallet;
34mod pallet_error;
35mod runtime;
36mod storage_alias;
37mod transactional;
38mod tt_macro;
39
40use frame_support_procedural_tools::generate_access_from_frame_or_crate;
41use macro_magic::{import_tokens_attr, import_tokens_attr_verbatim};
42use proc_macro::TokenStream;
43use quote::{quote, ToTokens};
44use std::{cell::RefCell, str::FromStr};
45use syn::{parse_macro_input, Error, ItemImpl, ItemMod, TraitItemType};
46
47pub(crate) const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance";
48
49thread_local! {
50 /// A global counter, can be used to generate a relatively unique identifier.
51 static COUNTER: RefCell<Counter> = RefCell::new(Counter(0));
52}
53
54/// Counter to generate a relatively unique identifier for macros. This is necessary because
55/// declarative macros gets hoisted to the crate root, which shares the namespace with other pallets
56/// containing the very same macros.
57struct Counter(u64);
58
59impl Counter {
60 fn inc(&mut self) -> u64 {
61 let ret = self.0;
62 self.0 += 1;
63 ret
64 }
65}
66
67/// Get the value from the given environment variable set by cargo.
68///
69/// The value is parsed into the requested destination type.
70fn get_cargo_env_var<T: FromStr>(version_env: &str) -> std::result::Result<T, ()> {
71 let version = std::env::var(version_env)
72 .unwrap_or_else(|_| panic!("`{}` is always set by cargo; qed", version_env));
73
74 T::from_str(&version).map_err(drop)
75}
76
77/// Generate the counter_prefix related to the storage.
78/// counter_prefix is used by counted storage map.
79fn counter_prefix(prefix: &str) -> String {
80 format!("CounterFor{}", prefix)
81}
82
83/// Construct a runtime, with the given name and the given pallets.
84///
85/// NOTE: A new version of this macro is available at `frame_support::runtime`. This macro will
86/// soon be deprecated. Please use the new macro instead.
87///
88/// The parameters here are specific types for `Block`, `NodeBlock`, and `UncheckedExtrinsic`
89/// and the pallets that are used by the runtime.
90/// `Block` is the block type that is used in the runtime and `NodeBlock` is the block type
91/// that is used in the node. For instance they can differ in the extrinsics type.
92///
93/// # Example:
94///
95/// ```ignore
96/// construct_runtime!(
97/// pub enum Runtime where
98/// Block = Block,
99/// NodeBlock = node::Block,
100/// UncheckedExtrinsic = UncheckedExtrinsic
101/// {
102/// System: frame_system::{Pallet, Call, Event<T>, Config<T>} = 0,
103/// Test: path::to::test::{Pallet, Call} = 1,
104///
105/// // Pallets with instances.
106/// Test2_Instance1: test2::<Instance1>::{Pallet, Call, Storage, Event<T, I>, Config<T, I>, Origin<T, I>},
107/// Test2_DefaultInstance: test2::{Pallet, Call, Storage, Event<T>, Config<T>, Origin<T>} = 4,
108///
109/// // Pallets declared with `pallet` attribute macro: no need to define the parts
110/// Test3_Instance1: test3::<Instance1>,
111/// Test3_DefaultInstance: test3,
112///
113/// // with `exclude_parts` keyword some part can be excluded.
114/// Test4_Instance1: test4::<Instance1> exclude_parts { Call, Origin },
115/// Test4_DefaultInstance: test4 exclude_parts { Storage },
116///
117/// // with `use_parts` keyword, a subset of the pallet parts can be specified.
118/// Test4_Instance1: test4::<Instance1> use_parts { Pallet, Call},
119/// Test4_DefaultInstance: test4 use_parts { Pallet },
120/// }
121/// )
122/// ```
123///
124/// Each pallet is declared as such:
125/// * `Identifier`: name given to the pallet that uniquely identifies it.
126///
127/// * `:`: colon separator
128///
129/// * `path::to::pallet`: identifiers separated by colons which declare the path to a pallet
130/// definition.
131///
132/// * `::<InstanceN>` optional: specify the instance of the pallet to use. If not specified it will
133/// use the default instance (or the only instance in case of non-instantiable pallets).
134///
135/// * `::{ Part1, Part2<T>, .. }` optional if pallet declared with `frame_support::pallet`: Comma
136/// separated parts declared with their generic. If a pallet is declared with
137/// `frame_support::pallet` macro then the parts can be automatically derived if not explicitly
138/// provided. We provide support for the following module parts in a pallet:
139///
140/// - `Pallet` - Required for all pallets
141/// - `Call` - If the pallet has callable functions
142/// - `Storage` - If the pallet uses storage
143/// - `Event` or `Event<T>` (if the event is generic) - If the pallet emits events
144/// - `Origin` or `Origin<T>` (if the origin is generic) - If the pallet has instantiable origins
145/// - `Config` or `Config<T>` (if the config is generic) - If the pallet builds the genesis
146/// storage with `GenesisConfig`
147/// - `Inherent` - If the pallet provides/can check inherents.
148/// - `ValidateUnsigned` - If the pallet validates unsigned extrinsics.
149///
150/// It is important to list these parts here to export them correctly in the metadata or to make
151/// the pallet usable in the runtime.
152///
153/// * `exclude_parts { Part1, Part2 }` optional: comma separated parts without generics. I.e. one of
154/// `Pallet`, `Call`, `Storage`, `Event`, `Origin`, `Config`, `Inherent`, `ValidateUnsigned`. It
155/// is incompatible with `use_parts`. This specifies the part to exclude. In order to select
156/// subset of the pallet parts.
157///
158/// For example excluding the part `Call` can be useful if the runtime doesn't want to make the
159/// pallet calls available.
160///
161/// * `use_parts { Part1, Part2 }` optional: comma separated parts without generics. I.e. one of
162/// `Pallet`, `Call`, `Storage`, `Event`, `Origin`, `Config`, `Inherent`, `ValidateUnsigned`. It
163/// is incompatible with `exclude_parts`. This specifies the part to use. In order to select a
164/// subset of the pallet parts.
165///
166/// For example not using the part `Call` can be useful if the runtime doesn't want to make the
167/// pallet calls available.
168///
169/// * `= $n` optional: number to define at which index the pallet variants in `OriginCaller`, `Call`
170/// and `Event` are encoded, and to define the ModuleToIndex value.
171///
172/// if `= $n` is not given, then index is resolved in the same way as fieldless enum in Rust
173/// (i.e. incrementally from previous index):
174/// ```nocompile
175/// pallet1 .. = 2,
176/// pallet2 .., // Here pallet2 is given index 3
177/// pallet3 .. = 0,
178/// pallet4 .., // Here pallet4 is given index 1
179/// ```
180///
181/// # Note
182///
183/// The population of the genesis storage depends on the order of pallets. So, if one of your
184/// pallets depends on another pallet, the pallet that is depended upon needs to come before
185/// the pallet depending on it.
186///
187/// # Type definitions
188///
189/// * The macro generates a type alias for each pallet to their `Pallet`. E.g. `type System =
190/// frame_system::Pallet<Runtime>`
191#[proc_macro]
192pub fn construct_runtime(input: TokenStream) -> TokenStream {
193 construct_runtime::construct_runtime(input)
194}
195
196///
197/// ---
198///
199/// Documentation for this macro can be found at `frame_support::pallet`.
200#[proc_macro_attribute]
201pub fn pallet(attr: TokenStream, item: TokenStream) -> TokenStream {
202 pallet::pallet(attr, item)
203}
204
205/// An attribute macro that can be attached to a (non-empty) module declaration. Doing so will
206/// designate that module as a benchmarking module.
207///
208/// See `frame_benchmarking::v2` for more info.
209#[proc_macro_attribute]
210pub fn benchmarks(attr: TokenStream, tokens: TokenStream) -> TokenStream {
211 match benchmark::benchmarks(attr, tokens, false) {
212 Ok(tokens) => tokens,
213 Err(err) => err.to_compile_error().into(),
214 }
215}
216
217/// An attribute macro that can be attached to a (non-empty) module declaration. Doing so will
218/// designate that module as an instance benchmarking module.
219///
220/// See `frame_benchmarking::v2` for more info.
221#[proc_macro_attribute]
222pub fn instance_benchmarks(attr: TokenStream, tokens: TokenStream) -> TokenStream {
223 match benchmark::benchmarks(attr, tokens, true) {
224 Ok(tokens) => tokens,
225 Err(err) => err.to_compile_error().into(),
226 }
227}
228
229/// An attribute macro used to declare a benchmark within a benchmarking module. Must be
230/// attached to a function definition containing an `#[extrinsic_call]` or `#[block]`
231/// attribute.
232///
233/// See `frame_benchmarking::v2` for more info.
234#[proc_macro_attribute]
235pub fn benchmark(_attrs: TokenStream, _tokens: TokenStream) -> TokenStream {
236 quote!(compile_error!(
237 "`#[benchmark]` must be in a module labeled with #[benchmarks] or #[instance_benchmarks]."
238 ))
239 .into()
240}
241
242/// An attribute macro used to specify the extrinsic call inside a benchmark function, and also
243/// used as a boundary designating where the benchmark setup code ends, and the benchmark
244/// verification code begins.
245///
246/// See `frame_benchmarking::v2` for more info.
247#[proc_macro_attribute]
248pub fn extrinsic_call(_attrs: TokenStream, _tokens: TokenStream) -> TokenStream {
249 quote!(compile_error!(
250 "`#[extrinsic_call]` must be in a benchmark function definition labeled with `#[benchmark]`."
251 );)
252 .into()
253}
254
255/// An attribute macro used to specify that a block should be the measured portion of the
256/// enclosing benchmark function, This attribute is also used as a boundary designating where
257/// the benchmark setup code ends, and the benchmark verification code begins.
258///
259/// See `frame_benchmarking::v2` for more info.
260#[proc_macro_attribute]
261pub fn block(_attrs: TokenStream, _tokens: TokenStream) -> TokenStream {
262 quote!(compile_error!(
263 "`#[block]` must be in a benchmark function definition labeled with `#[benchmark]`."
264 ))
265 .into()
266}
267
268/// Execute the annotated function in a new storage transaction.
269///
270/// The return type of the annotated function must be `Result`. All changes to storage performed
271/// by the annotated function are discarded if it returns `Err`, or committed if `Ok`.
272///
273/// # Example
274///
275/// ```nocompile
276/// #[transactional]
277/// fn value_commits(v: u32) -> result::Result<u32, &'static str> {
278/// Value::set(v);
279/// Ok(v)
280/// }
281///
282/// #[transactional]
283/// fn value_rollbacks(v: u32) -> result::Result<u32, &'static str> {
284/// Value::set(v);
285/// Err("nah")
286/// }
287/// ```
288#[proc_macro_attribute]
289pub fn transactional(attr: TokenStream, input: TokenStream) -> TokenStream {
290 transactional::transactional(attr, input).unwrap_or_else(|e| e.to_compile_error().into())
291}
292
293///
294/// ---
295///
296/// Documentation for this macro can be found at `frame_support::require_transactional`.
297#[proc_macro_attribute]
298pub fn require_transactional(attr: TokenStream, input: TokenStream) -> TokenStream {
299 transactional::require_transactional(attr, input)
300 .unwrap_or_else(|e| e.to_compile_error().into())
301}
302
303/// Derive [`Clone`] but do not bound any generic.
304///
305/// Docs at `frame_support::CloneNoBound`.
306#[proc_macro_derive(CloneNoBound)]
307pub fn derive_clone_no_bound(input: TokenStream) -> TokenStream {
308 no_bound::clone::derive_clone_no_bound(input)
309}
310
311/// Derive [`Debug`] but do not bound any generics.
312///
313/// Docs at `frame_support::DebugNoBound`.
314#[proc_macro_derive(DebugNoBound)]
315pub fn derive_debug_no_bound(input: TokenStream) -> TokenStream {
316 no_bound::debug::derive_debug_no_bound(input)
317}
318
319/// Derive [`Debug`], if `std` is enabled it uses `frame_support::DebugNoBound`, if `std` is not
320/// enabled it just returns `"<wasm:stripped>"`.
321/// This behaviour is useful to prevent bloating the runtime WASM blob from unneeded code.
322#[proc_macro_derive(RuntimeDebugNoBound)]
323pub fn derive_runtime_debug_no_bound(input: TokenStream) -> TokenStream {
324 let try_runtime_or_std_impl: proc_macro2::TokenStream =
325 no_bound::debug::derive_debug_no_bound(input.clone()).into();
326
327 let stripped_impl = {
328 let input = syn::parse_macro_input!(input as syn::DeriveInput);
329
330 let name = &input.ident;
331 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
332
333 quote::quote!(
334 const _: () = {
335 impl #impl_generics ::core::fmt::Debug for #name #ty_generics #where_clause {
336 fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> core::fmt::Result {
337 fmt.write_str("<wasm:stripped>")
338 }
339 }
340 };
341 )
342 };
343
344 let frame_support = match generate_access_from_frame_or_crate("frame-support") {
345 Ok(frame_support) => frame_support,
346 Err(e) => return e.to_compile_error().into(),
347 };
348
349 quote::quote!(
350 #frame_support::try_runtime_or_std_enabled! {
351 #try_runtime_or_std_impl
352 }
353 #frame_support::try_runtime_and_std_not_enabled! {
354 #stripped_impl
355 }
356 )
357 .into()
358}
359
360/// Derive [`PartialEq`] but do not bound any generic.
361///
362/// Docs at `frame_support::PartialEqNoBound`.
363#[proc_macro_derive(PartialEqNoBound)]
364pub fn derive_partial_eq_no_bound(input: TokenStream) -> TokenStream {
365 no_bound::partial_eq::derive_partial_eq_no_bound(input)
366}
367
368/// DeriveEq but do no bound any generic.
369///
370/// Docs at `frame_support::EqNoBound`.
371#[proc_macro_derive(EqNoBound)]
372pub fn derive_eq_no_bound(input: TokenStream) -> TokenStream {
373 let input = syn::parse_macro_input!(input as syn::DeriveInput);
374
375 let name = &input.ident;
376 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
377
378 quote::quote_spanned!(name.span() =>
379 #[allow(deprecated)]
380 const _: () = {
381 impl #impl_generics ::core::cmp::Eq for #name #ty_generics #where_clause {}
382 };
383 )
384 .into()
385}
386
387/// Derive [`PartialOrd`] but do not bound any generic. Docs are at
388/// `frame_support::PartialOrdNoBound`.
389#[proc_macro_derive(PartialOrdNoBound)]
390pub fn derive_partial_ord_no_bound(input: TokenStream) -> TokenStream {
391 no_bound::partial_ord::derive_partial_ord_no_bound(input)
392}
393
394/// Derive [`Ord`] but do no bound any generic. Docs are at `frame_support::OrdNoBound`.
395#[proc_macro_derive(OrdNoBound)]
396pub fn derive_ord_no_bound(input: TokenStream) -> TokenStream {
397 no_bound::ord::derive_ord_no_bound(input)
398}
399
400/// derive `Default` but do no bound any generic. Docs are at `frame_support::DefaultNoBound`.
401#[proc_macro_derive(DefaultNoBound, attributes(default))]
402pub fn derive_default_no_bound(input: TokenStream) -> TokenStream {
403 no_bound::default::derive_default_no_bound(input)
404}
405
406/// Macro used internally in FRAME to generate the crate version for a pallet.
407#[proc_macro]
408pub fn crate_to_crate_version(input: TokenStream) -> TokenStream {
409 crate_version::crate_to_crate_version(input)
410 .unwrap_or_else(|e| e.to_compile_error())
411 .into()
412}
413
414/// The number of module instances supported by the runtime, starting at index 1,
415/// and up to `NUMBER_OF_INSTANCE`.
416pub(crate) const NUMBER_OF_INSTANCE: u8 = 16;
417
418/// This macro is meant to be used by frame-support only.
419/// It implements the trait `HasKeyPrefix` and `HasReversibleKeyPrefix` for tuple of `Key`.
420#[proc_macro]
421pub fn impl_key_prefix_for_tuples(input: TokenStream) -> TokenStream {
422 key_prefix::impl_key_prefix_for_tuples(input)
423 .unwrap_or_else(syn::Error::into_compile_error)
424 .into()
425}
426
427/// Internal macro use by frame_support to generate dummy part checker for old pallet declaration
428#[proc_macro]
429pub fn __generate_dummy_part_checker(input: TokenStream) -> TokenStream {
430 dummy_part_checker::generate_dummy_part_checker(input)
431}
432
433/// Macro that inserts some tokens after the first match of some pattern.
434///
435/// # Example:
436///
437/// ```nocompile
438/// match_and_insert!(
439/// target = [{ Some content with { at some point match pattern } other match pattern are ignored }]
440/// pattern = [{ match pattern }] // the match pattern cannot contain any group: `[]`, `()`, `{}`
441/// // can relax this constraint, but will require modifying the match logic in code
442/// tokens = [{ expansion tokens }] // content inside braces can be anything including groups
443/// );
444/// ```
445///
446/// will generate:
447///
448/// ```nocompile
449/// Some content with { at some point match pattern expansion tokens } other match patterns are
450/// ignored
451/// ```
452#[proc_macro]
453pub fn match_and_insert(input: TokenStream) -> TokenStream {
454 match_and_insert::match_and_insert(input)
455}
456
457#[proc_macro_derive(PalletError, attributes(codec))]
458pub fn derive_pallet_error(input: TokenStream) -> TokenStream {
459 pallet_error::derive_pallet_error(input)
460}
461
462/// Internal macro used by `frame_support` to create tt-call-compliant macros
463#[proc_macro]
464pub fn __create_tt_macro(input: TokenStream) -> TokenStream {
465 tt_macro::create_tt_return_macro(input)
466}
467
468///
469/// ---
470///
471/// Documentation for this macro can be found at `frame_support::pallet_macros::storage_alias`.
472#[proc_macro_attribute]
473pub fn storage_alias(attributes: TokenStream, input: TokenStream) -> TokenStream {
474 storage_alias::storage_alias(attributes.into(), input.into())
475 .unwrap_or_else(|r| r.into_compile_error())
476 .into()
477}
478
479/// This attribute can be used to derive a full implementation of a trait based on a local partial
480/// impl and an external impl containing defaults that can be overridden in the local impl.
481///
482/// For a full end-to-end example, see [below](#use-case-auto-derive-test-pallet-config-traits).
483///
484/// # Usage
485///
486/// The attribute should be attached to an impl block (strictly speaking a `syn::ItemImpl`) for
487/// which we want to inject defaults in the event of missing trait items in the block.
488///
489/// The attribute minimally takes a single `default_impl_path` argument, which should be the module
490/// path to an impl registered via [`#[register_default_impl]`](`macro@register_default_impl`) that
491/// contains the default trait items we want to potentially inject, with the general form:
492///
493/// ```ignore
494/// #[derive_impl(default_impl_path)]
495/// impl SomeTrait for SomeStruct {
496/// ...
497/// }
498/// ```
499///
500/// Optionally, a `disambiguation_path` can be specified as follows by providing `as path::here`
501/// after the `default_impl_path`:
502///
503/// ```ignore
504/// #[derive_impl(default_impl_path as disambiguation_path)]
505/// impl SomeTrait for SomeStruct {
506/// ...
507/// }
508/// ```
509///
510/// The `disambiguation_path`, if specified, should be the path to a trait that will be used to
511/// qualify all default entries that are injected into the local impl. For example if your
512/// `default_impl_path` is `some::path::TestTraitImpl` and your `disambiguation_path` is
513/// `another::path::DefaultTrait`, any items injected into the local impl will be qualified as
514/// `<some::path::TestTraitImpl as another::path::DefaultTrait>::specific_trait_item`.
515///
516/// If you omit the `as disambiguation_path` portion, the `disambiguation_path` will internally
517/// default to `A` from the `impl A for B` part of the default impl. This is useful for scenarios
518/// where all of the relevant types are already in scope via `use` statements.
519///
520/// In case the `default_impl_path` is scoped to a different module such as
521/// `some::path::TestTraitImpl`, the same scope is assumed for the `disambiguation_path`, i.e.
522/// `some::A`. This enables the use of `derive_impl` attribute without having to specify the
523/// `disambiguation_path` in most (if not all) uses within FRAME's context.
524///
525/// Conversely, the `default_impl_path` argument is required and cannot be omitted.
526///
527/// Optionally, `no_aggregated_types` can be specified as follows:
528///
529/// ```ignore
530/// #[derive_impl(default_impl_path as disambiguation_path, no_aggregated_types)]
531/// impl SomeTrait for SomeStruct {
532/// ...
533/// }
534/// ```
535///
536/// If specified, this indicates that the aggregated types (as denoted by impl items
537/// attached with [`#[inject_runtime_type]`]) should not be injected with the respective concrete
538/// types. By default, all such types are injected.
539///
540/// You can also make use of `#[pallet::no_default]` on specific items in your default impl that you
541/// want to ensure will not be copied over but that you nonetheless want to use locally in the
542/// context of the foreign impl and the pallet (or context) in which it is defined.
543///
544/// ## Use-Case Example: Auto-Derive Test Pallet Config Traits
545///
546/// The `#[derive_imp(..)]` attribute can be used to derive a test pallet `Config` based on an
547/// existing pallet `Config` that has been marked with
548/// [`#[pallet::config(with_default)]`](`macro@config`) (which under the hood, generates a
549/// `DefaultConfig` trait in the pallet in which the macro was invoked).
550///
551/// In this case, the `#[derive_impl(..)]` attribute should be attached to an `impl` block that
552/// implements a compatible `Config` such as `frame_system::Config` for a test/mock runtime, and
553/// should receive as its first argument the path to a `DefaultConfig` impl that has been registered
554/// via [`#[register_default_impl]`](`macro@register_default_impl`), and as its second argument, the
555/// path to the auto-generated `DefaultConfig` for the existing pallet `Config` we want to base our
556/// test config off of.
557///
558/// The following is what the `basic` example pallet would look like with a default testing config:
559///
560/// ```ignore
561/// #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::pallet::DefaultConfig)]
562/// impl frame_system::Config for Test {
563/// // These are all defined by system as mandatory.
564/// type BaseCallFilter = frame_support::traits::Everything;
565/// type RuntimeEvent = RuntimeEvent;
566/// type RuntimeCall = RuntimeCall;
567/// type RuntimeOrigin = RuntimeOrigin;
568/// type OnSetCode = ();
569/// type PalletInfo = PalletInfo;
570/// type Block = Block;
571/// // We decide to override this one.
572/// type AccountData = pallet_balances::AccountData<u64>;
573/// }
574/// ```
575///
576/// where `TestDefaultConfig` was defined and registered as follows:
577/// ```ignore
578/// pub struct TestDefaultConfig;
579///
580/// #[register_default_impl(TestDefaultConfig)]
581/// impl DefaultConfig for TestDefaultConfig {
582/// type Version = ();
583/// type BlockWeights = ();
584/// type BlockLength = ();
585/// type DbWeight = ();
586/// type Nonce = u64;
587/// type BlockNumber = u64;
588/// type Hash = sp_core::hash::H256;
589/// type Hashing = sp_runtime::traits::BlakeTwo256;
590/// type AccountId = AccountId;
591/// type Lookup = IdentityLookup<AccountId>;
592/// type BlockHashCount = frame_support::traits::ConstU64<10>;
593/// type AccountData = u32;
594/// type OnNewAccount = ();
595/// type OnKilledAccount = ();
596/// type SystemWeightInfo = ();
597/// type SS58Prefix = ();
598/// type MaxConsumers = frame_support::traits::ConstU32<16>;
599/// }
600/// ```
601///
602/// The above call to `derive_impl` would expand to roughly the following:
603/// ```ignore
604/// impl frame_system::Config for Test {
605/// use frame_system::config_preludes::TestDefaultConfig;
606/// use frame_system::pallet::DefaultConfig;
607///
608/// type BaseCallFilter = frame_support::traits::Everything;
609/// type RuntimeEvent = RuntimeEvent;
610/// type RuntimeCall = RuntimeCall;
611/// type RuntimeOrigin = RuntimeOrigin;
612/// type OnSetCode = ();
613/// type PalletInfo = PalletInfo;
614/// type Block = Block;
615/// type AccountData = pallet_balances::AccountData<u64>;
616/// type Version = <TestDefaultConfig as DefaultConfig>::Version;
617/// type BlockWeights = <TestDefaultConfig as DefaultConfig>::BlockWeights;
618/// type BlockLength = <TestDefaultConfig as DefaultConfig>::BlockLength;
619/// type DbWeight = <TestDefaultConfig as DefaultConfig>::DbWeight;
620/// type Nonce = <TestDefaultConfig as DefaultConfig>::Nonce;
621/// type BlockNumber = <TestDefaultConfig as DefaultConfig>::BlockNumber;
622/// type Hash = <TestDefaultConfig as DefaultConfig>::Hash;
623/// type Hashing = <TestDefaultConfig as DefaultConfig>::Hashing;
624/// type AccountId = <TestDefaultConfig as DefaultConfig>::AccountId;
625/// type Lookup = <TestDefaultConfig as DefaultConfig>::Lookup;
626/// type BlockHashCount = <TestDefaultConfig as DefaultConfig>::BlockHashCount;
627/// type OnNewAccount = <TestDefaultConfig as DefaultConfig>::OnNewAccount;
628/// type OnKilledAccount = <TestDefaultConfig as DefaultConfig>::OnKilledAccount;
629/// type SystemWeightInfo = <TestDefaultConfig as DefaultConfig>::SystemWeightInfo;
630/// type SS58Prefix = <TestDefaultConfig as DefaultConfig>::SS58Prefix;
631/// type MaxConsumers = <TestDefaultConfig as DefaultConfig>::MaxConsumers;
632/// }
633/// ```
634///
635/// You can then use the resulting `Test` config in test scenarios.
636///
637/// Note that items that are _not_ present in our local `DefaultConfig` are automatically copied
638/// from the foreign trait (in this case `TestDefaultConfig`) into the local trait impl (in this
639/// case `Test`), unless the trait item in the local trait impl is marked with
640/// [`#[pallet::no_default]`](`macro@no_default`), in which case it cannot be overridden, and any
641/// attempts to do so will result in a compiler error.
642///
643/// See `frame/examples/default-config/tests.rs` for a runnable end-to-end example pallet that makes
644/// use of `derive_impl` to derive its testing config.
645///
646/// See [here](`macro@config`) for more information and caveats about the auto-generated
647/// `DefaultConfig` trait.
648///
649/// ## Optional Conventions
650///
651/// Note that as an optional convention, we encourage creating a `config_preludes` module inside of
652/// your pallet. This is the convention we follow for `frame_system`'s `TestDefaultConfig` which, as
653/// shown above, is located at `frame_system::config_preludes::TestDefaultConfig`. This is just a
654/// suggested convention -- there is nothing in the code that expects modules with these names to be
655/// in place, so there is no imperative to follow this pattern unless desired.
656///
657/// In `config_preludes`, you can place types named like:
658///
659/// * `TestDefaultConfig`
660/// * `ParachainDefaultConfig`
661/// * `SolochainDefaultConfig`
662///
663/// Signifying in which context they can be used.
664///
665/// # Advanced Usage
666///
667/// ## Expansion
668///
669/// The `#[derive_impl(default_impl_path as disambiguation_path)]` attribute will expand to the
670/// local impl, with any extra items from the foreign impl that aren't present in the local impl
671/// also included. In the case of a colliding trait item, the version of the item that exists in the
672/// local impl will be retained. All imported items are qualified by the `disambiguation_path`, as
673/// discussed above.
674///
675/// ## Handling of Unnamed Trait Items
676///
677/// Items that lack a `syn::Ident` for whatever reason are first checked to see if they exist,
678/// verbatim, in the local/destination trait before they are copied over, so you should not need to
679/// worry about collisions between identical unnamed items.
680#[import_tokens_attr_verbatim {
681 format!(
682 "{}::macro_magic",
683 match generate_access_from_frame_or_crate("frame-support") {
684 Ok(path) => Ok(path),
685 Err(_) => generate_access_from_frame_or_crate("polkadot-sdk-frame"),
686 }
687 .expect("Failed to find either `frame-support` or `polkadot-sdk-frame` in `Cargo.toml` dependencies.")
688 .to_token_stream()
689 .to_string()
690 )
691}]
692#[with_custom_parsing(derive_impl::DeriveImplAttrArgs)]
693#[proc_macro_attribute]
694pub fn derive_impl(attrs: TokenStream, input: TokenStream) -> TokenStream {
695 let custom_attrs = parse_macro_input!(__custom_tokens as derive_impl::DeriveImplAttrArgs);
696 derive_impl::derive_impl(
697 __source_path.into(),
698 attrs.into(),
699 input.into(),
700 custom_attrs.disambiguation_path,
701 custom_attrs.no_aggregated_types,
702 custom_attrs.generics,
703 )
704 .unwrap_or_else(|r| r.into_compile_error())
705 .into()
706}
707
708///
709/// ---
710///
711/// Documentation for this macro can be found at `frame_support::pallet_macros::no_default`.
712#[proc_macro_attribute]
713pub fn no_default(_: TokenStream, _: TokenStream) -> TokenStream {
714 pallet_macro_stub()
715}
716
717///
718/// ---
719///
720/// Documentation for this macro can be found at `frame_support::pallet_macros::no_default_bounds`.
721#[proc_macro_attribute]
722pub fn no_default_bounds(_: TokenStream, _: TokenStream) -> TokenStream {
723 pallet_macro_stub()
724}
725
726/// Attach this attribute to an impl statement that you want to use with
727/// [`#[derive_impl(..)]`](`macro@derive_impl`).
728///
729/// You must also provide an identifier/name as the attribute's argument. This is the name you
730/// must provide to [`#[derive_impl(..)]`](`macro@derive_impl`) when you import this impl via
731/// the `default_impl_path` argument. This name should be unique at the crate-level.
732///
733/// ## Example
734///
735/// ```ignore
736/// pub struct ExampleTestDefaultConfig;
737///
738/// #[register_default_impl(ExampleTestDefaultConfig)]
739/// impl DefaultConfig for ExampleTestDefaultConfig {
740/// type Version = ();
741/// type BlockWeights = ();
742/// type BlockLength = ();
743/// ...
744/// type SS58Prefix = ();
745/// type MaxConsumers = frame_support::traits::ConstU32<16>;
746/// }
747/// ```
748///
749/// ## Advanced Usage
750///
751/// This macro acts as a thin wrapper around macro_magic's `#[export_tokens]`. See the docs
752/// [here](https://docs.rs/macro_magic/latest/macro_magic/attr.export_tokens.html) for more
753/// info.
754///
755/// There are some caveats when applying a `use` statement to bring a
756/// `#[register_default_impl]` item into scope. If you have a `#[register_default_impl]`
757/// defined in `my_crate::submodule::MyItem`, it is currently not sufficient to do something
758/// like:
759///
760/// ```ignore
761/// use my_crate::submodule::MyItem;
762/// #[derive_impl(MyItem as Whatever)]
763/// ```
764///
765/// This will fail with a mysterious message about `__export_tokens_tt_my_item` not being
766/// defined.
767///
768/// You can, however, do any of the following:
769/// ```ignore
770/// // partial path works
771/// use my_crate::submodule;
772/// #[derive_impl(submodule::MyItem as Whatever)]
773/// ```
774/// ```ignore
775/// // full path works
776/// #[derive_impl(my_crate::submodule::MyItem as Whatever)]
777/// ```
778/// ```ignore
779/// // wild-cards work
780/// use my_crate::submodule::*;
781/// #[derive_impl(MyItem as Whatever)]
782/// ```
783#[proc_macro_attribute]
784pub fn register_default_impl(attrs: TokenStream, tokens: TokenStream) -> TokenStream {
785 // ensure this is a impl statement
786 let item_impl = syn::parse_macro_input!(tokens as ItemImpl);
787
788 // internally wrap macro_magic's `#[export_tokens]` macro
789 match macro_magic::mm_core::export_tokens_internal(
790 attrs,
791 item_impl.to_token_stream(),
792 true,
793 false,
794 ) {
795 Ok(tokens) => tokens.into(),
796 Err(err) => err.to_compile_error().into(),
797 }
798}
799
800/// The optional attribute `#[inject_runtime_type]` can be attached to `RuntimeCall`,
801/// `RuntimeEvent`, `RuntimeOrigin` or `PalletInfo` in an impl statement that has
802/// `#[register_default_impl]` attached to indicate that this item is generated by
803/// `construct_runtime`.
804///
805/// Attaching this attribute to such an item ensures that the combined impl generated via
806/// [`#[derive_impl(..)]`](macro@derive_impl) will use the correct type auto-generated by
807/// `construct_runtime!`.
808#[doc = docify::embed!("examples/proc_main/inject_runtime_type.rs", derive_impl_works_with_runtime_type_injection)]
809///
810/// However, if `no_aggregated_types` is specified while using
811/// [`#[derive_impl(..)]`](macro@derive_impl), then these items are attached verbatim to the
812/// combined impl.
813#[doc = docify::embed!("examples/proc_main/inject_runtime_type.rs", derive_impl_works_with_no_aggregated_types)]
814#[proc_macro_attribute]
815pub fn inject_runtime_type(_: TokenStream, tokens: TokenStream) -> TokenStream {
816 let item = tokens.clone();
817 let item = syn::parse_macro_input!(item as TraitItemType);
818 if item.ident != "RuntimeCall" &&
819 item.ident != "RuntimeEvent" &&
820 item.ident != "RuntimeTask" &&
821 item.ident != "RuntimeViewFunction" &&
822 item.ident != "RuntimeOrigin" &&
823 item.ident != "RuntimeHoldReason" &&
824 item.ident != "RuntimeFreezeReason" &&
825 item.ident != "RuntimeParameters" &&
826 item.ident != "PalletInfo"
827 {
828 return syn::Error::new_spanned(
829 item,
830 "`#[inject_runtime_type]` can only be attached to `RuntimeCall`, `RuntimeEvent`, \
831 `RuntimeTask`, `RuntimeViewFunction`, `RuntimeOrigin`, `RuntimeParameters` or `PalletInfo`",
832 )
833 .to_compile_error()
834 .into();
835 }
836 tokens
837}
838
839/// Used internally to decorate pallet attribute macro stubs when they are erroneously used
840/// outside of a pallet module
841fn pallet_macro_stub() -> TokenStream {
842 quote!(compile_error!(
843 "This attribute can only be used from within a pallet module marked with `#[frame_support::pallet]`"
844 ))
845 .into()
846}
847
848///
849/// ---
850///
851/// Documentation for this macro can be found at `frame_support::pallet_macros::config`.
852#[proc_macro_attribute]
853pub fn config(_: TokenStream, _: TokenStream) -> TokenStream {
854 pallet_macro_stub()
855}
856
857///
858/// ---
859///
860/// Documentation for this macro can be found at `frame_support::pallet_macros::constant`.
861#[proc_macro_attribute]
862pub fn constant(_: TokenStream, _: TokenStream) -> TokenStream {
863 pallet_macro_stub()
864}
865
866///
867/// ---
868///
869/// Documentation for this macro can be found at `frame_support::pallet_macros::constant_name`.
870#[proc_macro_attribute]
871pub fn constant_name(_: TokenStream, _: TokenStream) -> TokenStream {
872 pallet_macro_stub()
873}
874
875///
876/// ---
877///
878/// Documentation for this macro can be found at
879/// `frame_support::pallet_macros::disable_frame_system_supertrait_check`.
880#[proc_macro_attribute]
881pub fn disable_frame_system_supertrait_check(_: TokenStream, _: TokenStream) -> TokenStream {
882 pallet_macro_stub()
883}
884
885///
886/// ---
887///
888/// Documentation for this macro can be found at `frame_support::pallet_macros::storage_version`.
889#[proc_macro_attribute]
890pub fn storage_version(_: TokenStream, _: TokenStream) -> TokenStream {
891 pallet_macro_stub()
892}
893
894///
895/// ---
896///
897/// Documentation for this macro can be found at `frame_support::pallet_macros::hooks`.
898#[proc_macro_attribute]
899pub fn hooks(_: TokenStream, _: TokenStream) -> TokenStream {
900 pallet_macro_stub()
901}
902
903///
904/// ---
905///
906/// Documentation for this macro can be found at `frame_support::pallet_macros::weight`.
907#[proc_macro_attribute]
908pub fn weight(_: TokenStream, _: TokenStream) -> TokenStream {
909 pallet_macro_stub()
910}
911
912///
913/// ---
914///
915/// Documentation for this macro can be found at `frame_support::pallet_macros::compact`.
916#[proc_macro_attribute]
917pub fn compact(_: TokenStream, _: TokenStream) -> TokenStream {
918 pallet_macro_stub()
919}
920
921///
922/// ---
923///
924/// Documentation for this macro can be found at `frame_support::pallet_macros::call`.
925#[proc_macro_attribute]
926pub fn call(_: TokenStream, _: TokenStream) -> TokenStream {
927 pallet_macro_stub()
928}
929
930/// Each dispatchable may also be annotated with the `#[pallet::call_index($idx)]` attribute,
931/// which explicitly defines the codec index for the dispatchable function in the `Call` enum.
932///
933/// ---
934///
935/// Documentation for this macro can be found at `frame_support::pallet_macros::call_index`.
936#[proc_macro_attribute]
937pub fn call_index(_: TokenStream, _: TokenStream) -> TokenStream {
938 pallet_macro_stub()
939}
940
941///
942/// ---
943///
944/// Documentation for this macro can be found at `frame_support::pallet_macros::feeless_if`.
945#[proc_macro_attribute]
946pub fn feeless_if(_: TokenStream, _: TokenStream) -> TokenStream {
947 pallet_macro_stub()
948}
949
950///
951/// ---
952///
953/// Documentation for this macro can be found at `frame_support::pallet_macros::extra_constants`.
954#[proc_macro_attribute]
955pub fn extra_constants(_: TokenStream, _: TokenStream) -> TokenStream {
956 pallet_macro_stub()
957}
958
959///
960/// ---
961///
962/// Documentation for this macro can be found at `frame_support::pallet_macros::error`.
963#[proc_macro_attribute]
964pub fn error(_: TokenStream, _: TokenStream) -> TokenStream {
965 pallet_macro_stub()
966}
967
968///
969/// ---
970///
971/// Documentation for this macro can be found at `frame_support::pallet_macros::event`.
972#[proc_macro_attribute]
973pub fn event(_: TokenStream, _: TokenStream) -> TokenStream {
974 pallet_macro_stub()
975}
976
977///
978/// ---
979///
980/// Documentation for this macro can be found at `frame_support::pallet_macros::include_metadata`.
981#[proc_macro_attribute]
982pub fn include_metadata(_: TokenStream, _: TokenStream) -> TokenStream {
983 pallet_macro_stub()
984}
985
986///
987/// ---
988///
989/// Documentation for this macro can be found at `frame_support::pallet_macros::generate_deposit`.
990#[proc_macro_attribute]
991pub fn generate_deposit(_: TokenStream, _: TokenStream) -> TokenStream {
992 pallet_macro_stub()
993}
994
995///
996/// ---
997///
998/// Documentation for this macro can be found at `frame_support::pallet_macros::storage`.
999#[proc_macro_attribute]
1000pub fn storage(_: TokenStream, _: TokenStream) -> TokenStream {
1001 pallet_macro_stub()
1002}
1003
1004///
1005/// ---
1006///
1007/// Documentation for this macro can be found at `frame_support::pallet_macros::getter`.
1008#[proc_macro_attribute]
1009pub fn getter(_: TokenStream, _: TokenStream) -> TokenStream {
1010 pallet_macro_stub()
1011}
1012
1013///
1014/// ---
1015///
1016/// Documentation for this macro can be found at `frame_support::pallet_macros::storage_prefix`.
1017#[proc_macro_attribute]
1018pub fn storage_prefix(_: TokenStream, _: TokenStream) -> TokenStream {
1019 pallet_macro_stub()
1020}
1021
1022///
1023/// ---
1024///
1025/// Documentation for this macro can be found at `frame_support::pallet_macros::unbounded`.
1026#[proc_macro_attribute]
1027pub fn unbounded(_: TokenStream, _: TokenStream) -> TokenStream {
1028 pallet_macro_stub()
1029}
1030
1031///
1032/// ---
1033///
1034/// Documentation for this macro can be found at `frame_support::pallet_macros::whitelist_storage`.
1035#[proc_macro_attribute]
1036pub fn whitelist_storage(_: TokenStream, _: TokenStream) -> TokenStream {
1037 pallet_macro_stub()
1038}
1039
1040///
1041/// ---
1042///
1043/// Documentation for this macro can be found at
1044/// `frame_support::pallet_macros::disable_try_decode_storage`.
1045#[proc_macro_attribute]
1046pub fn disable_try_decode_storage(_: TokenStream, _: TokenStream) -> TokenStream {
1047 pallet_macro_stub()
1048}
1049
1050///
1051/// ---
1052///
1053/// Documentation for this macro can be found at `frame_support::pallet_macros::type_value`.
1054#[proc_macro_attribute]
1055pub fn type_value(_: TokenStream, _: TokenStream) -> TokenStream {
1056 pallet_macro_stub()
1057}
1058
1059///
1060/// ---
1061///
1062/// Documentation for this macro can be found at `frame_support::pallet_macros::genesis_config`.
1063#[proc_macro_attribute]
1064pub fn genesis_config(_: TokenStream, _: TokenStream) -> TokenStream {
1065 pallet_macro_stub()
1066}
1067
1068///
1069/// ---
1070///
1071/// Documentation for this macro can be found at `frame_support::pallet_macros::genesis_build`.
1072#[proc_macro_attribute]
1073pub fn genesis_build(_: TokenStream, _: TokenStream) -> TokenStream {
1074 pallet_macro_stub()
1075}
1076
1077///
1078/// ---
1079///
1080/// Documentation for this macro can be found at `frame_support::pallet_macros::inherent`.
1081#[proc_macro_attribute]
1082pub fn inherent(_: TokenStream, _: TokenStream) -> TokenStream {
1083 pallet_macro_stub()
1084}
1085
1086///
1087/// ---
1088///
1089/// Documentation for this macro can be found at `frame_support::pallet_macros::validate_unsigned`.
1090#[proc_macro_attribute]
1091pub fn validate_unsigned(_: TokenStream, _: TokenStream) -> TokenStream {
1092 pallet_macro_stub()
1093}
1094
1095///
1096/// ---
1097///
1098/// Documentation for this macro can be found at
1099/// `frame_support::pallet_macros::view_functions`.
1100#[proc_macro_attribute]
1101pub fn view_functions(_: TokenStream, _: TokenStream) -> TokenStream {
1102 pallet_macro_stub()
1103}
1104
1105///
1106/// ---
1107///
1108/// Documentation for this macro can be found at `frame_support::pallet_macros::origin`.
1109#[proc_macro_attribute]
1110pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream {
1111 pallet_macro_stub()
1112}
1113
1114///
1115/// ---
1116///
1117/// Documentation for this macro can be found at `frame_support::pallet_macros::composite_enum`.
1118#[proc_macro_attribute]
1119pub fn composite_enum(_: TokenStream, _: TokenStream) -> TokenStream {
1120 pallet_macro_stub()
1121}
1122
1123/// Allows you to define some service work that can be recognized by a script or an
1124/// off-chain worker.
1125///
1126/// Such a script can then create and submit all such work items at any given time.
1127///
1128/// These work items are defined as instances of the `Task` trait (found at
1129/// `frame_support::traits::Task`). [`pallet:tasks_experimental`](macro@tasks_experimental) when
1130/// attached to an `impl` block inside a pallet, will generate an enum `Task<T>` whose variants
1131/// are mapped to functions inside this `impl` block.
1132///
1133/// Each such function must have the following set of attributes:
1134///
1135/// * [`pallet::task_list`](macro@task_list)
1136/// * [`pallet::task_condition`](macro@task_condition)
1137/// * [`pallet::task_weight`](macro@task_weight)
1138/// * [`pallet::task_index`](macro@task_index)
1139///
1140/// All of such Tasks are then aggregated into a `RuntimeTask` by
1141/// [`construct_runtime`](macro@construct_runtime).
1142///
1143/// Finally, the `RuntimeTask` can then used by a script or off-chain worker to create and
1144/// submit such tasks via an extrinsic defined in `frame_system` called `do_task`.
1145///
1146/// When submitted as unsigned transactions (for example via an off-chain workder), note
1147/// that the tasks will be executed in a random order.
1148///
1149/// ## Example
1150#[doc = docify::embed!("examples/proc_main/tasks.rs", tasks_example)]
1151/// Now, this can be executed as follows:
1152#[doc = docify::embed!("examples/proc_main/tasks.rs", tasks_work)]
1153#[proc_macro_attribute]
1154pub fn tasks_experimental(_: TokenStream, _: TokenStream) -> TokenStream {
1155 pallet_macro_stub()
1156}
1157
1158/// Allows defining an iterator over available work items for a task.
1159///
1160/// This attribute is attached to a function inside an `impl` block annotated with
1161/// [`pallet::tasks_experimental`](macro@tasks_experimental).
1162///
1163/// It takes an iterator as input that yields a tuple with same types as the function
1164/// arguments.
1165#[proc_macro_attribute]
1166pub fn task_list(_: TokenStream, _: TokenStream) -> TokenStream {
1167 pallet_macro_stub()
1168}
1169
1170/// Allows defining conditions for a task to run.
1171///
1172/// This attribute is attached to a function inside an `impl` block annotated with
1173/// [`pallet::tasks_experimental`](macro@tasks_experimental) to define the conditions for a
1174/// given work item to be valid.
1175///
1176/// It takes a closure as input, which is then used to define the condition. The closure
1177/// should have the same signature as the function it is attached to, except that it should
1178/// return a `bool` instead.
1179#[proc_macro_attribute]
1180pub fn task_condition(_: TokenStream, _: TokenStream) -> TokenStream {
1181 pallet_macro_stub()
1182}
1183
1184/// Allows defining the weight of a task.
1185///
1186/// This attribute is attached to a function inside an `impl` block annotated with
1187/// [`pallet::tasks_experimental`](macro@tasks_experimental) define the weight of a given work
1188/// item.
1189///
1190/// It takes a closure as input, which should return a `Weight` value.
1191#[proc_macro_attribute]
1192pub fn task_weight(_: TokenStream, _: TokenStream) -> TokenStream {
1193 pallet_macro_stub()
1194}
1195
1196/// Allows defining an index for a task.
1197///
1198/// This attribute is attached to a function inside an `impl` block annotated with
1199/// [`pallet::tasks_experimental`](macro@tasks_experimental) to define the index of a given
1200/// work item.
1201///
1202/// It takes an integer literal as input, which is then used to define the index. This
1203/// index should be unique for each function in the `impl` block.
1204#[proc_macro_attribute]
1205pub fn task_index(_: TokenStream, _: TokenStream) -> TokenStream {
1206 pallet_macro_stub()
1207}
1208
1209///
1210/// ---
1211///
1212/// **Rust-Analyzer users**: See the documentation of the Rust item in
1213/// `frame_support::pallet_macros::pallet_section`.
1214#[proc_macro_attribute]
1215pub fn pallet_section(attr: TokenStream, tokens: TokenStream) -> TokenStream {
1216 let tokens_clone = tokens.clone();
1217 // ensure this can only be attached to a module
1218 let _mod = parse_macro_input!(tokens_clone as ItemMod);
1219
1220 // use macro_magic's export_tokens as the internal implementation otherwise
1221 match macro_magic::mm_core::export_tokens_internal(attr, tokens, false, true) {
1222 Ok(tokens) => tokens.into(),
1223 Err(err) => err.to_compile_error().into(),
1224 }
1225}
1226
1227///
1228/// ---
1229///
1230/// **Rust-Analyzer users**: See the documentation of the Rust item in
1231/// `frame_support::pallet_macros::import_section`.
1232#[import_tokens_attr {
1233 format!(
1234 "{}::macro_magic",
1235 match generate_access_from_frame_or_crate("frame-support") {
1236 Ok(path) => Ok(path),
1237 Err(_) => generate_access_from_frame_or_crate("polkadot-sdk-frame"),
1238 }
1239 .expect("Failed to find either `frame-support` or `polkadot-sdk-frame` in `Cargo.toml` dependencies.")
1240 .to_token_stream()
1241 .to_string()
1242 )
1243}]
1244#[proc_macro_attribute]
1245pub fn import_section(attr: TokenStream, tokens: TokenStream) -> TokenStream {
1246 let foreign_mod = parse_macro_input!(attr as ItemMod);
1247 let mut internal_mod = parse_macro_input!(tokens as ItemMod);
1248
1249 // check that internal_mod is a pallet module
1250 if !internal_mod.attrs.iter().any(|attr| {
1251 if let Some(last_seg) = attr.path().segments.last() {
1252 last_seg.ident == "pallet"
1253 } else {
1254 false
1255 }
1256 }) {
1257 return Error::new(
1258 internal_mod.ident.span(),
1259 "`#[import_section]` can only be applied to a valid pallet module",
1260 )
1261 .to_compile_error()
1262 .into();
1263 }
1264
1265 if let Some(ref mut content) = internal_mod.content {
1266 if let Some(foreign_content) = foreign_mod.content {
1267 content.1.extend(foreign_content.1);
1268 }
1269 }
1270
1271 quote! {
1272 #internal_mod
1273 }
1274 .into()
1275}
1276
1277/// Construct a runtime, with the given name and the given pallets.
1278///
1279/// # Example:
1280#[doc = docify::embed!("examples/proc_main/runtime.rs", runtime_macro)]
1281///
1282/// # Supported Attributes:
1283///
1284/// ## Legacy Ordering
1285///
1286/// An optional attribute can be defined as #[frame_support::runtime(legacy_ordering)] to
1287/// ensure that the order of hooks is same as the order of pallets (and not based on the
1288/// pallet_index). This is to support legacy runtimes and should be avoided for new ones.
1289///
1290/// # Note
1291///
1292/// The population of the genesis storage depends on the order of pallets. So, if one of your
1293/// pallets depends on another pallet, the pallet that is depended upon needs to come before
1294/// the pallet depending on it.
1295///
1296/// # Type definitions
1297///
1298/// * The macro generates a type alias for each pallet to their `Pallet`. E.g. `type System =
1299/// frame_system::Pallet<Runtime>`
1300#[proc_macro_attribute]
1301pub fn runtime(attr: TokenStream, item: TokenStream) -> TokenStream {
1302 runtime::runtime(attr, item)
1303}
1304
1305/// Mark a module that contains dynamic parameters.
1306///
1307/// See the `pallet_parameters` for a full example.
1308///
1309/// # Arguments
1310///
1311/// The macro accepts two positional arguments, of which the second is optional.
1312///
1313/// ## Aggregated Enum Name
1314///
1315/// This sets the name that the aggregated Key-Value enum will be named after. Common names would be
1316/// `RuntimeParameters`, akin to `RuntimeCall`, `RuntimeOrigin` etc. There is no default value for
1317/// this argument.
1318///
1319/// ## Parameter Storage Backend
1320///
1321/// The second argument provides access to the storage of the parameters. It can either be set on
1322/// on this attribute, or on the inner ones. If set on both, the inner one takes precedence.
1323#[proc_macro_attribute]
1324pub fn dynamic_params(attrs: TokenStream, input: TokenStream) -> TokenStream {
1325 dynamic_params::dynamic_params(attrs.into(), input.into())
1326 .unwrap_or_else(|r| r.into_compile_error())
1327 .into()
1328}
1329
1330/// Define a module inside a [`macro@dynamic_params`] module that contains dynamic parameters.
1331///
1332/// See the `pallet_parameters` for a full example.
1333///
1334/// # Argument
1335///
1336/// This attribute takes one optional argument. The argument can either be put here or on the
1337/// surrounding `#[dynamic_params]` attribute. If set on both, the inner one takes precedence.
1338#[proc_macro_attribute]
1339pub fn dynamic_pallet_params(attrs: TokenStream, input: TokenStream) -> TokenStream {
1340 dynamic_params::dynamic_pallet_params(attrs.into(), input.into())
1341 .unwrap_or_else(|r| r.into_compile_error())
1342 .into()
1343}
1344
1345/// Used internally by [`dynamic_params`].
1346#[doc(hidden)]
1347#[proc_macro_attribute]
1348pub fn dynamic_aggregated_params_internal(attrs: TokenStream, input: TokenStream) -> TokenStream {
1349 dynamic_params::dynamic_aggregated_params_internal(attrs.into(), input.into())
1350 .unwrap_or_else(|r| r.into_compile_error())
1351 .into()
1352}
1353
1354/// Allows to authorize some general transactions with specific dispatchable functions
1355/// (dispatchable functions a.k.a. calls).
1356///
1357/// This attribute allows to specify a special validation logic for a specific call.
1358/// A general transaction with this specific call can then be validated by the given function,
1359/// and if valid then dispatched with the origin `frame_system::Origin::Authorized`.
1360///
1361/// To ensure the origin of the call is the authorization process, the call must check the origin
1362/// with `frame_system::ensure_authorized` function.
1363///
1364/// To enable the authorization process on the extrinsic, the runtime must use
1365/// `frame_system::AuthorizeCall` transaction extension in the transaction extension pipeline.
1366///
1367/// To enable the creation of authorized call from offchain worker. The runtime should implement
1368/// `frame_system::CreateAuthorizedTransaction`. This trait allows to specify which transaction
1369/// extension to use when creating a transaction for an authorized call.
1370///
1371/// # Usage in the pallet
1372///
1373/// ## Example/Overview:
1374///
1375/// ```
1376/// # #[allow(unused)]
1377/// #[frame_support::pallet]
1378/// pub mod pallet {
1379/// use frame_support::pallet_prelude::*;
1380/// use frame_system::pallet_prelude::*;
1381///
1382/// #[pallet::pallet]
1383/// pub struct Pallet<T>(_);
1384///
1385/// #[pallet::config]
1386/// pub trait Config: frame_system::Config {}
1387///
1388/// #[pallet::call]
1389/// impl<T: Config> Pallet<T> {
1390/// #[pallet::weight(Weight::zero())]
1391/// #[pallet::authorize(|_source, foo| if *foo == 42 {
1392/// // The amount to refund, here we refund nothing
1393/// let refund = Weight::zero();
1394/// // The validity, here we accept the call and it provides itself.
1395/// // See `ValidTransaction` for more information.
1396/// let validity = ValidTransaction::with_tag_prefix("my-pallet")
1397/// .and_provides("some_call")
1398/// .into();
1399/// Ok((validity, refund))
1400/// } else {
1401/// Err(TransactionValidityError::Invalid(InvalidTransaction::Call))
1402/// })]
1403/// #[pallet::weight_of_authorize(Weight::zero())]
1404/// #[pallet::call_index(0)]
1405/// pub fn some_call(origin: OriginFor<T>, arg: u32) -> DispatchResult {
1406/// ensure_authorized(origin)?;
1407///
1408/// Ok(())
1409/// }
1410///
1411/// #[pallet::weight(Weight::zero())]
1412/// // We can also give the callback as a function
1413/// #[pallet::authorize(Self::authorize_some_other_call)]
1414/// #[pallet::weight_of_authorize(Weight::zero())]
1415/// #[pallet::call_index(1)]
1416/// pub fn some_other_call(origin: OriginFor<T>, arg: u32) -> DispatchResult {
1417/// ensure_authorized(origin)?;
1418///
1419/// Ok(())
1420/// }
1421/// }
1422///
1423/// impl<T: Config> Pallet<T> {
1424/// fn authorize_some_other_call(
1425/// source: TransactionSource,
1426/// foo: &u32
1427/// ) -> TransactionValidityWithRefund {
1428/// if *foo == 42 {
1429/// let refund = Weight::zero();
1430/// let validity = ValidTransaction::default();
1431/// Ok((validity, refund))
1432/// } else {
1433/// Err(TransactionValidityError::Invalid(InvalidTransaction::Call))
1434/// }
1435/// }
1436/// }
1437///
1438/// #[frame_benchmarking::v2::benchmarks]
1439/// mod benchmarks {
1440/// use super::*;
1441/// use frame_benchmarking::v2::BenchmarkError;
1442///
1443/// #[benchmark]
1444/// fn authorize_some_call() -> Result<(), BenchmarkError> {
1445/// let call = Call::<T>::some_call { arg: 42 };
1446///
1447/// #[block]
1448/// {
1449/// use frame_support::pallet_prelude::Authorize;
1450/// call.authorize(TransactionSource::External)
1451/// .ok_or("Call must give some authorization")??;
1452/// }
1453///
1454/// Ok(())
1455/// }
1456/// }
1457/// }
1458/// ```
1459///
1460/// ## Specification:
1461///
1462/// Authorize process comes with 2 attributes macro on top of the authorized call:
1463///
1464/// * `#[pallet::authorize($authorized_function)]` - defines the function that authorizes the call.
1465/// First argument is the transaction source `TransactionSource` then followed by the same as call
1466/// arguments but by reference `&`. Return type is `TransactionValidityWithRefund`.
1467/// * `#[pallet::weight_of_authorize($weight)]` - defines the value of the weight of the authorize
1468/// function. This attribute is similar to `#[pallet::weight]`:
1469/// * it can be ignore in `dev_mode`
1470/// * it can be automatically infered from weight info. For the call `foo` the function
1471/// `authorize_foo` in the weight info will be used. (weight info needs to be provided in the
1472/// call attribute: `#[pallet::call(weight = T::WeightInfo)]`).
1473/// * it can be a fixed value like `Weight::from_all(0)` (not recommended in production).
1474///
1475/// The weight must be small enough so that nodes don't get DDOS by validating transactions.
1476///
1477/// Then in the call it must be ensured that the origin is the authorization process. This can
1478/// be done using `frame_system::ensure_authorized` function.
1479///
1480/// # The macro expansion
1481///
1482/// From the given "authorize" function and weight, the macro will implement the trait
1483/// `Authorize` on the call.
1484///
1485/// # How to benchmark
1486///
1487/// The authorize function is used as the implementation of the trait
1488/// `Authorize` for the call.
1489/// To benchmark a call variant, use the function
1490/// `Authorize::authorize` on a call value.
1491/// See the example in the first section.
1492#[proc_macro_attribute]
1493pub fn authorize(_: TokenStream, _: TokenStream) -> TokenStream {
1494 pallet_macro_stub()
1495}
1496
1497/// Allows to define the weight of the authorize function.
1498///
1499/// See [`authorize`](macro@authorize) for more information on how authorization works.
1500///
1501/// Defines the value of the weight of the authorize function. This attribute is similar to
1502/// `#[pallet::weight]`:
1503/// * it can be ignore in `dev_mode`
1504/// * it can be automatically infered from weight info. For the call `foo` the function
1505/// `authorize_foo` in the weight info will be used.
1506/// * it can be a fixed value like `Weight::from_all(0)` (not recommended in production).
1507#[proc_macro_attribute]
1508pub fn weight_of_authorize(_: TokenStream, _: TokenStream) -> TokenStream {
1509 pallet_macro_stub()
1510}