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