topsoil_core/lib.rs
1// This file is part of Soil.
2
3// Copyright (C) Soil contributors.
4// Copyright (C) Parity Technologies (UK) Ltd.
5// SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later WITH Classpath-exception-2.0
6
7//! Support code for the runtime.
8//!
9//! ## Note on Tuple Traits
10//!
11//! Many of the traits defined in [`traits`] have auto-implementations on tuples as well. Usually,
12//! the tuple is a function of number of pallets in the runtime. By default, the traits are
13//! implemented for tuples of up to 64 items.
14// If you have more pallets in your runtime, or for any other reason need more, enabled `tuples-96`
15// or the `tuples-128` complication flag. Note that these features *will increase* the compilation
16// of this crate.
17
18#![cfg_attr(not(feature = "std"), no_std)]
19
20/// Export ourself as `topsoil_core` to make tests happy.
21#[doc(hidden)]
22extern crate self as topsoil_core;
23
24#[doc(hidden)]
25extern crate alloc;
26
27/// System pallet (formerly the `topsoil-system` crate).
28pub mod system;
29
30/// Maximum nesting level for extrinsics.
31pub const MAX_EXTRINSIC_DEPTH: u32 = 256;
32
33/// Re-export subsoil for proc-macro generated code.
34#[doc(hidden)]
35pub use subsoil;
36
37/// Private exports that are being used by macros.
38///
39/// The exports are not stable and should not be relied on.
40#[doc(hidden)]
41pub mod __private {
42 pub use alloc::{
43 boxed::Box,
44 fmt::Debug,
45 rc::Rc,
46 string::String,
47 vec,
48 vec::{IntoIter, Vec},
49 };
50 pub use codec;
51 pub use frame_metadata as metadata;
52 pub use impl_trait_for_tuples;
53 pub use log;
54 pub use paste;
55 pub use scale_info;
56 pub use serde;
57 pub use serde_json;
58 pub use subsoil;
59 pub use subsoil::core::{Get, OpaqueMetadata, Void};
60 pub use subsoil::inherents;
61 #[cfg(feature = "std")]
62 pub use subsoil::io::TestExternalities;
63 pub use subsoil::io::{self, hashing, storage::root as storage_root};
64 pub use subsoil::metadata_ir;
65 #[cfg(feature = "std")]
66 pub use subsoil::runtime::{bounded_btree_map, bounded_vec};
67 pub use subsoil::runtime::{
68 traits::{AsSystemOriginSigner, AsTransactionAuthorizedOrigin, Dispatchable},
69 DispatchError, StateVersion, TransactionOutcome,
70 };
71 #[cfg(feature = "std")]
72 pub use subsoil::state_machine::BasicExternalities;
73 pub use subsoil::std;
74 pub use subsoil::tracing;
75 pub use subsoil_macros;
76 pub use tt_call::*;
77}
78
79#[macro_use]
80pub mod dispatch;
81pub mod crypto;
82pub mod dispatch_context;
83mod hash;
84pub mod inherent;
85pub mod instances;
86mod macros;
87pub mod migrations;
88pub mod storage;
89#[cfg(test)]
90mod tests;
91pub mod traits;
92pub mod view_functions;
93pub mod weights;
94#[doc(hidden)]
95pub mod unsigned {
96 #[doc(hidden)]
97 pub use subsoil::runtime::traits::ValidateUnsigned;
98 #[doc(hidden)]
99 pub use subsoil::runtime::transaction_validity::{
100 TransactionSource, TransactionValidity, TransactionValidityError, UnknownTransaction,
101 };
102}
103
104#[cfg(any(feature = "std", feature = "runtime-benchmarks", feature = "try-runtime", test))]
105pub use self::storage::storage_noop_guard::StorageNoopGuard;
106pub use self::{
107 dispatch::{Callable, Parameter},
108 hash::{
109 Blake2_128, Blake2_128Concat, Blake2_256, Hashable, Identity, ReversibleStorageHasher,
110 StorageHasher, Twox128, Twox256, Twox64Concat,
111 },
112 storage::{
113 bounded_btree_map::BoundedBTreeMap,
114 bounded_btree_set::BoundedBTreeSet,
115 bounded_vec::{BoundedSlice, BoundedVec},
116 migration,
117 weak_bounded_vec::WeakBoundedVec,
118 IterableStorageDoubleMap, IterableStorageMap, IterableStorageNMap, StorageDoubleMap,
119 StorageMap, StorageNMap, StoragePrefixedMap, StorageValue,
120 },
121};
122pub use subsoil::runtime::{
123 self, print, traits::Printable, ConsensusEngineId, MAX_MODULE_ERROR_ENCODED_SIZE,
124};
125
126use codec::{Decode, Encode};
127use scale_info::TypeInfo;
128use subsoil::runtime::TypeId;
129
130/// A unified log target for support operations.
131pub const LOG_TARGET: &str = "runtime::topsoil-support";
132
133/// A type that cannot be instantiated.
134#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
135pub enum Never {}
136
137/// A pallet identifier. These are per pallet and should be stored in a registry somewhere.
138#[derive(Clone, Copy, Eq, PartialEq, Encode, Decode, TypeInfo)]
139pub struct PalletId(pub [u8; 8]);
140
141impl TypeId for PalletId {
142 const TYPE_ID: [u8; 4] = *b"modl";
143}
144
145/// Generate a [`#[pallet::storage]`](pallet_macros::storage) alias outside of a pallet.
146///
147/// This storage alias works similarly to the [`#[pallet::storage]`](pallet_macros::storage)
148/// attribute macro. It supports [`StorageValue`](storage::types::StorageValue),
149/// [`StorageMap`](storage::types::StorageMap),
150/// [`StorageDoubleMap`](storage::types::StorageDoubleMap) and
151/// [`StorageNMap`](storage::types::StorageNMap). The main difference to the normal
152/// [`#[pallet::storage]`](pallet_macros::storage) is the flexibility around declaring the
153/// storage prefix to use. The storage prefix determines where to find the value in the
154/// storage. [`#[pallet::storage]`](pallet_macros::storage) uses the name of the pallet as
155/// declared in [`construct_runtime!`].
156///
157/// The flexibility around declaring the storage prefix makes this macro very useful for
158/// writing migrations etc.
159///
160/// # Examples
161///
162/// There are different ways to declare the `prefix` to use. The `prefix` type can either be
163/// declared explicitly by passing it to the macro as an attribute or by letting the macro
164/// guess on what the `prefix` type is. The `prefix` is always passed as the first generic
165/// argument to the type declaration. When using [`#[pallet::storage]`](pallet_macros::storage)
166/// this first generic argument is always `_`. Besides declaring the `prefix`, the rest of the
167/// type declaration works as with [`#[pallet::storage]`](pallet_macros::storage).
168///
169/// 1. Use the `verbatim` prefix type. This prefix type uses the given identifier as the
170/// `prefix`:
171#[doc = docify::embed!("src/tests/storage_alias.rs", verbatim_attribute)]
172/// 2. Use the `pallet_name` prefix type. This prefix type uses the name of the pallet as
173/// configured in [`construct_runtime!`] as the `prefix`:
174#[doc = docify::embed!("src/tests/storage_alias.rs", pallet_name_attribute)]
175/// It requires that the given prefix type implements
176/// [`PalletInfoAccess`](traits::PalletInfoAccess) (which is always the case for FRAME pallet
177/// structs). In the example above, `Pallet<T>` is the prefix type.
178///
179/// 3. Use the `dynamic` prefix type. This prefix type calls [`Get::get()`](traits::Get::get)
180/// to get the `prefix`:
181#[doc = docify::embed!("src/tests/storage_alias.rs", dynamic_attribute)]
182/// It requires that the given prefix type implements [`Get<'static str>`](traits::Get).
183///
184/// 4. Let the macro "guess" what kind of prefix type to use. This only supports verbatim or
185/// pallet name. The macro uses the presence of generic arguments to the prefix type as an
186/// indication that it should use the pallet name as the `prefix`:
187#[doc = docify::embed!("src/tests/storage_alias.rs", storage_alias_guess)]
188pub use topsoil_core_procedural::storage_alias;
189
190pub use topsoil_core_procedural::derive_impl;
191
192/// Experimental macros for defining dynamic params that can be used in pallet configs.
193#[cfg(feature = "experimental")]
194pub mod dynamic_params {
195 pub use topsoil_core_procedural::{
196 dynamic_aggregated_params_internal, dynamic_pallet_params, dynamic_params,
197 };
198}
199
200#[doc(inline)]
201pub use topsoil_core_procedural::{
202 construct_runtime, match_and_insert, transactional, PalletError,
203};
204
205pub use topsoil_core_procedural::runtime;
206
207#[doc(hidden)]
208pub use topsoil_core_procedural::{__create_tt_macro, __generate_dummy_part_checker};
209
210/// Derive [`Clone`] but do not bound any generic.
211///
212/// This is useful for type generic over runtime:
213/// ```
214/// # use topsoil_core::CloneNoBound;
215/// trait Config {
216/// type C: Clone;
217/// }
218///
219/// // Foo implements [`Clone`] because `C` bounds [`Clone`].
220/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Clone`].
221/// #[derive(CloneNoBound)]
222/// struct Foo<T: Config> {
223/// c: T::C,
224/// }
225/// ```
226pub use topsoil_core_procedural::CloneNoBound;
227
228/// Derive [`Eq`] but do not bound any generic.
229///
230/// This is useful for type generic over runtime:
231/// ```
232/// # use topsoil_core::{EqNoBound, PartialEqNoBound};
233/// trait Config {
234/// type C: Eq;
235/// }
236///
237/// // Foo implements [`Eq`] because `C` bounds [`Eq`].
238/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Eq`].
239/// #[derive(PartialEqNoBound, EqNoBound)]
240/// struct Foo<T: Config> {
241/// c: T::C,
242/// }
243/// ```
244pub use topsoil_core_procedural::EqNoBound;
245
246/// Derive [`PartialEq`] but do not bound any generic.
247///
248/// This is useful for type generic over runtime:
249/// ```
250/// # use topsoil_core::PartialEqNoBound;
251/// trait Config {
252/// type C: PartialEq;
253/// }
254///
255/// // Foo implements [`PartialEq`] because `C` bounds [`PartialEq`].
256/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`PartialEq`].
257/// #[derive(PartialEqNoBound)]
258/// struct Foo<T: Config> {
259/// c: T::C,
260/// }
261/// ```
262pub use topsoil_core_procedural::PartialEqNoBound;
263
264/// Derive [`Ord`] but do not bound any generic.
265///
266/// This is useful for type generic over runtime:
267/// ```
268/// # use topsoil_core::{OrdNoBound, PartialOrdNoBound, EqNoBound, PartialEqNoBound};
269/// trait Config {
270/// type C: Ord;
271/// }
272///
273/// // Foo implements [`Ord`] because `C` bounds [`Ord`].
274/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Ord`].
275/// #[derive(EqNoBound, OrdNoBound, PartialEqNoBound, PartialOrdNoBound)]
276/// struct Foo<T: Config> {
277/// c: T::C,
278/// }
279/// ```
280pub use topsoil_core_procedural::OrdNoBound;
281
282/// Derive [`PartialOrd`] but do not bound any generic.
283///
284/// This is useful for type generic over runtime:
285/// ```
286/// # use topsoil_core::{OrdNoBound, PartialOrdNoBound, EqNoBound, PartialEqNoBound};
287/// trait Config {
288/// type C: PartialOrd;
289/// }
290///
291/// // Foo implements [`PartialOrd`] because `C` bounds [`PartialOrd`].
292/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`PartialOrd`].
293/// #[derive(PartialOrdNoBound, PartialEqNoBound, EqNoBound)]
294/// struct Foo<T: Config> {
295/// c: T::C,
296/// }
297/// ```
298pub use topsoil_core_procedural::PartialOrdNoBound;
299
300/// Derive [`Debug`] but do not bound any generic.
301///
302/// This is useful for type generic over runtime:
303/// ```
304/// # use topsoil_core::DebugNoBound;
305/// # use core::fmt::Debug;
306/// trait Config {
307/// type C: Debug;
308/// }
309///
310/// // Foo implements [`Debug`] because `C` bounds [`Debug`].
311/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Debug`].
312/// #[derive(DebugNoBound)]
313/// struct Foo<T: Config> {
314/// c: T::C,
315/// }
316/// ```
317pub use topsoil_core_procedural::DebugNoBound;
318
319/// Derive [`Default`] but do not bound any generic.
320///
321/// This is useful for type generic over runtime:
322/// ```
323/// # use topsoil_core::DefaultNoBound;
324/// # use core::default::Default;
325/// trait Config {
326/// type C: Default;
327/// }
328///
329/// // Foo implements [`Default`] because `C` bounds [`Default`].
330/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Default`].
331/// #[derive(DefaultNoBound)]
332/// struct Foo<T: Config> {
333/// c: T::C,
334/// }
335///
336/// // Also works with enums, by specifying the default with #[default]:
337/// #[derive(DefaultNoBound)]
338/// enum Bar<T: Config> {
339/// // Bar will implement Default as long as all of the types within Baz also implement default.
340/// #[default]
341/// Baz(T::C),
342/// Quxx,
343/// }
344/// ```
345pub use topsoil_core_procedural::DefaultNoBound;
346
347/// Assert the annotated function is executed within a storage transaction.
348///
349/// The assertion is enabled for native execution and when `debug_assertions` are enabled.
350///
351/// # Example
352///
353/// ```
354/// # use topsoil_core::{
355/// # require_transactional, transactional, dispatch::DispatchResult
356/// # };
357///
358/// #[require_transactional]
359/// fn update_all(value: u32) -> DispatchResult {
360/// // Update multiple storages.
361/// // Return `Err` to indicate should revert.
362/// Ok(())
363/// }
364///
365/// #[transactional]
366/// fn safe_update(value: u32) -> DispatchResult {
367/// // This is safe
368/// update_all(value)
369/// }
370///
371/// fn unsafe_update(value: u32) -> DispatchResult {
372/// // this may panic if unsafe_update is not called within a storage transaction
373/// update_all(value)
374/// }
375/// ```
376pub use topsoil_core_procedural::require_transactional;
377
378/// Convert the current crate version into a [`CrateVersion`](crate::traits::CrateVersion).
379///
380/// It uses the `CARGO_PKG_VERSION_MAJOR`, `CARGO_PKG_VERSION_MINOR` and
381/// `CARGO_PKG_VERSION_PATCH` environment variables to fetch the crate version.
382/// This means that the [`CrateVersion`](crate::traits::CrateVersion)
383/// object will correspond to the version of the crate the macro is called in!
384///
385/// # Example
386///
387/// ```
388/// # use topsoil_core::{traits::CrateVersion, crate_to_crate_version};
389/// const Version: CrateVersion = crate_to_crate_version!();
390/// ```
391pub use topsoil_core_procedural::crate_to_crate_version;
392
393#[doc(hidden)]
394pub use serde::{Deserialize, Serialize};
395
396#[doc(hidden)]
397pub use macro_magic;
398
399/// Prelude to be used for pallet testing, for ease of use.
400#[cfg(feature = "std")]
401pub mod testing_prelude {
402 pub use super::traits::Get;
403 pub use crate::{
404 assert_err, assert_err_ignore_postinfo, assert_err_with_weight, assert_noop, assert_ok,
405 assert_storage_noop, parameter_types,
406 };
407 pub use subsoil::assert_eq_error_rate;
408 pub use subsoil::runtime::{bounded_btree_map, bounded_vec};
409}
410
411/// Prelude to be used alongside pallet macro, for ease of use.
412pub mod pallet_prelude {
413 pub use crate::{
414 defensive, defensive_assert,
415 dispatch::{DispatchClass, DispatchResult, DispatchResultWithPostInfo, Parameter, Pays},
416 ensure,
417 inherent::{InherentData, InherentIdentifier, ProvideInherent},
418 storage,
419 storage::{
420 bounded_btree_map::BoundedBTreeMap,
421 bounded_btree_set::BoundedBTreeSet,
422 bounded_vec::BoundedVec,
423 types::{
424 CountedStorageMap, CountedStorageNMap, Key as NMapKey, OptionQuery, ResultQuery,
425 StorageDoubleMap, StorageMap, StorageNMap, StorageValue, ValueQuery,
426 },
427 weak_bounded_vec::WeakBoundedVec,
428 StorageList,
429 },
430 traits::{
431 Authorize, BuildGenesisConfig, ConstU32, ConstUint, EnsureOrigin, Get, GetDefault,
432 GetStorageVersion, Hooks, IsType, OriginTrait, PalletInfoAccess, StorageInfoTrait,
433 StorageVersion, Task, TypedGet,
434 },
435 Blake2_128, Blake2_128Concat, Blake2_256, CloneNoBound, DebugNoBound, EqNoBound, Identity,
436 PartialEqNoBound, Twox128, Twox256, Twox64Concat,
437 };
438 pub use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
439 pub use core::marker::PhantomData;
440 pub use scale_info::TypeInfo;
441 pub use subsoil::inherents::MakeFatalError;
442 pub use subsoil::runtime::{
443 traits::{
444 CheckedAdd, CheckedConversion, CheckedDiv, CheckedMul, CheckedShl, CheckedShr,
445 CheckedSub, MaybeSerializeDeserialize, Member, One, ValidateResult, ValidateUnsigned,
446 Zero,
447 },
448 transaction_validity::{
449 InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource,
450 TransactionTag, TransactionValidity, TransactionValidityError,
451 TransactionValidityWithRefund, UnknownTransaction, ValidTransaction,
452 },
453 Debug, DispatchError, MAX_MODULE_ERROR_ENCODED_SIZE,
454 };
455 pub use subsoil::weights::Weight;
456 pub use topsoil_core::pallet_macros::*;
457 pub use topsoil_core_procedural::{inject_runtime_type, register_default_impl};
458}
459
460/// The pallet macro has 2 purposes:
461///
462/// * [For declaring a pallet as a rust module](#1---pallet-module-declaration)
463/// * [For declaring the `struct` placeholder of a
464/// pallet](#2---pallet-struct-placeholder-declaration)
465///
466/// # 1 - Pallet module declaration
467///
468/// The module to declare a pallet is organized as follows:
469/// ```
470/// #[topsoil_core::pallet] // <- the macro
471/// mod pallet {
472/// #[pallet::pallet]
473/// pub struct Pallet<T>(_);
474///
475/// #[pallet::config]
476/// pub trait Config: topsoil_core::system::Config {}
477///
478/// #[pallet::call]
479/// impl<T: Config> Pallet<T> {
480/// }
481///
482/// /* ... */
483/// }
484/// ```
485///
486/// The documentation for each individual part can be found at [topsoil_core::pallet_macros]
487///
488/// ## Dev Mode (`#[pallet(dev_mode)]`)
489///
490/// Syntax:
491///
492/// ```
493/// #[topsoil_core::pallet(dev_mode)]
494/// mod pallet {
495/// # #[pallet::pallet]
496/// # pub struct Pallet<T>(_);
497/// # #[pallet::config]
498/// # pub trait Config: topsoil_core::system::Config {}
499/// /* ... */
500/// }
501/// ```
502///
503/// Specifying the argument `dev_mode` will allow you to enable dev mode for a pallet. The
504/// aim of dev mode is to loosen some of the restrictions and requirements placed on
505/// production pallets for easy tinkering and development. Dev mode pallets should not be
506/// used in production. Enabling dev mode has the following effects:
507///
508/// * Weights no longer need to be specified on every `#[pallet::call]` declaration. By
509/// default, dev mode pallets will assume a weight of zero (`0`) if a weight is not
510/// specified. This is equivalent to specifying `#[weight(0)]` on all calls that do not
511/// specify a weight.
512/// * Call indices no longer need to be specified on every `#[pallet::call]` declaration. By
513/// default, dev mode pallets will assume a call index based on the order of the call.
514/// * All storages are marked as unbounded, meaning you do not need to implement
515/// [`MaxEncodedLen`](topsoil_core::pallet_prelude::MaxEncodedLen) on storage types. This is
516/// equivalent to specifying `#[pallet::unbounded]` on all storage type definitions.
517/// * Storage hashers no longer need to be specified and can be replaced by `_`. In dev mode,
518/// these will be replaced by `Blake2_128Concat`. In case of explicit key-binding, `Hasher`
519/// can simply be ignored when in `dev_mode`.
520///
521/// Note that the `dev_mode` argument can only be supplied to the `#[pallet]` or
522/// `#[topsoil_core::pallet]` attribute macro that encloses your pallet module. This
523/// argument cannot be specified anywhere else, including but not limited to the
524/// `#[pallet::pallet]` attribute macro.
525///
526/// <div class="example-wrap" style="display:inline-block"><pre class="compile_fail"
527/// style="white-space:normal;font:inherit;">
528/// <strong>WARNING</strong>:
529/// You should never deploy or use dev mode pallets in production. Doing so can break your
530/// chain. Once you are done tinkering, you should
531/// remove the 'dev_mode' argument from your #[pallet] declaration and fix any compile
532/// errors before attempting to use your pallet in a production scenario.
533/// </pre></div>
534///
535/// # 2 - Pallet struct placeholder declaration
536///
537/// The pallet struct placeholder `#[pallet::pallet]` is mandatory and allows you to
538/// specify pallet information.
539///
540/// The struct must be defined as follows:
541/// ```
542/// #[topsoil_core::pallet]
543/// mod pallet {
544/// #[pallet::pallet] // <- the macro
545/// pub struct Pallet<T>(_); // <- the struct definition
546///
547/// #[pallet::config]
548/// pub trait Config: topsoil_core::system::Config {}
549/// }
550/// ```
551//
552/// I.e. a regular struct definition named `Pallet`, with generic T and no where clause.
553///
554/// ## Macro expansion:
555///
556/// The macro adds this attribute to the Pallet struct definition:
557/// ```ignore
558/// #[derive(
559/// topsoil_core::CloneNoBound,
560/// topsoil_core::EqNoBound,
561/// topsoil_core::PartialEqNoBound,
562/// topsoil_core::DebugNoBound,
563/// )]
564/// ```
565/// and replaces the type `_` with `PhantomData<T>`.
566///
567/// It also implements on the pallet:
568///
569/// * [`GetStorageVersion`](topsoil_core::traits::GetStorageVersion)
570/// * [`OnGenesis`](topsoil_core::traits::OnGenesis): contains some logic to write the pallet
571/// version into storage.
572/// * [`PalletInfoAccess`](topsoil_core::traits::PalletInfoAccess) to ease access to pallet
573/// information given by [`topsoil_core::traits::PalletInfo`]. (The implementation uses the
574/// associated type [`topsoil_core::traits::PalletInfo`]).
575/// * [`StorageInfoTrait`](topsoil_core::traits::StorageInfoTrait) to give information about
576/// storages.
577///
578/// If the attribute `set_storage_max_encoded_len` is set then the macro calls
579/// [`StorageInfoTrait`](topsoil_core::traits::StorageInfoTrait) for each storage in the
580/// implementation of [`StorageInfoTrait`](topsoil_core::traits::StorageInfoTrait) for the
581/// pallet. Otherwise, it implements
582/// [`StorageInfoTrait`](topsoil_core::traits::StorageInfoTrait) for the pallet using the
583/// [`PartialStorageInfoTrait`](topsoil_core::traits::PartialStorageInfoTrait)
584/// implementation of storages.
585///
586/// ## Note on deprecation.
587///
588/// - Usage of `deprecated` attribute will propagate deprecation information to the pallet
589/// metadata.
590/// - For general usage examples of `deprecated` attribute please refer to <https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-deprecated-attribute>
591/// - Usage of `allow(deprecated)` on the item will propagate this attribute to the generated
592/// code.
593/// - If the item is annotated with `deprecated` attribute then the generated code will be
594/// automatically annotated with `allow(deprecated)`
595pub use topsoil_core_procedural::pallet;
596
597/// Contains macro stubs for all of the `pallet::` macros
598pub mod pallet_macros {
599 /// Declare the storage as whitelisted from benchmarking.
600 ///
601 /// Doing so will exclude reads of that value's storage key from counting towards weight
602 /// calculations during benchmarking.
603 ///
604 /// This attribute should only be attached to storages that are known to be
605 /// read/used in every block. This will result in a more accurate benchmarking weight.
606 ///
607 /// ### Example
608 /// ```
609 /// #[topsoil_core::pallet]
610 /// mod pallet {
611 /// # use topsoil_core::pallet_prelude::*;
612 /// #
613 /// #[pallet::pallet]
614 /// pub struct Pallet<T>(_);
615 ///
616 /// #[pallet::storage]
617 /// #[pallet::whitelist_storage]
618 /// pub type MyStorage<T> = StorageValue<_, u32>;
619 /// #
620 /// # #[pallet::config]
621 /// # pub trait Config: topsoil_core::system::Config {}
622 /// }
623 /// ```
624 pub use topsoil_core_procedural::whitelist_storage;
625
626 /// Allows specifying the weight of a call.
627 ///
628 /// Each dispatchable needs to define a weight.
629 /// This attribute allows to define a weight using the expression:
630 /// `#[pallet::weight($expr)]` Note that argument of the call are available inside the
631 /// expression.
632 ///
633 /// If not defined explicitly, the weight can be implicitly inferred from the weight info
634 /// defined in the attribute `pallet::call`: `#[pallet::call(weight = $WeightInfo)]`.
635 /// Or it can be simply ignored when the pallet is in `dev_mode`.
636 ///
637 /// ## Example
638 ///
639 /// ```
640 /// #[topsoil_core::pallet]
641 /// mod pallet {
642 /// use topsoil_core::pallet_prelude::*;
643 /// use topsoil_core::system::pallet_prelude::*;
644 ///
645 /// #[pallet::pallet]
646 /// pub struct Pallet<T>(_);
647 ///
648 /// #[pallet::config]
649 /// pub trait Config: topsoil_core::system::Config {
650 /// /// Type for specifying dispatchable weights.
651 /// type WeightInfo: WeightInfo;
652 /// }
653 ///
654 /// #[pallet::call(weight = <T as Config>::WeightInfo)]
655 /// impl<T: Config> Pallet<T> {
656 /// // Explicit weight definition
657 /// #[pallet::weight(<T as Config>::WeightInfo::do_something())]
658 /// #[pallet::call_index(0)]
659 /// pub fn do_something(
660 /// origin: OriginFor<T>,
661 /// foo: u32,
662 /// ) -> DispatchResult {
663 /// Ok(())
664 /// }
665 ///
666 /// // Implicit weight definition, the macro looks up to the weight info defined in
667 /// // `#[pallet::call(weight = $WeightInfo)]` attribute. Then use
668 /// // `$WeightInfo::do_something_else` as the weight function.
669 /// #[pallet::call_index(1)]
670 /// pub fn do_something_else(
671 /// origin: OriginFor<T>,
672 /// bar: u64,
673 /// ) -> DispatchResult {
674 /// Ok(())
675 /// }
676 /// }
677 ///
678 /// /// The `WeightInfo` trait defines weight functions for dispatchable calls.
679 /// pub trait WeightInfo {
680 /// fn do_something() -> Weight;
681 /// fn do_something_else() -> Weight;
682 /// }
683 /// }
684 /// ```
685 pub use topsoil_core_procedural::weight;
686
687 /// Allows whitelisting a storage item from decoding during try-runtime checks.
688 ///
689 /// The optional attribute `#[pallet::disable_try_decode_storage]` will declare the
690 /// storage as whitelisted from decoding during try-runtime checks. This should only be
691 /// attached to transient storage which cannot be migrated during runtime upgrades.
692 ///
693 /// ### Example
694 /// ```
695 /// #[topsoil_core::pallet]
696 /// mod pallet {
697 /// # use topsoil_core::pallet_prelude::*;
698 /// #
699 /// #[pallet::pallet]
700 /// pub struct Pallet<T>(_);
701 ///
702 /// #[pallet::storage]
703 /// #[pallet::disable_try_decode_storage]
704 /// pub type MyStorage<T> = StorageValue<_, u32>;
705 /// #
706 /// # #[pallet::config]
707 /// # pub trait Config: topsoil_core::system::Config {}
708 /// }
709 /// ```
710 pub use topsoil_core_procedural::disable_try_decode_storage;
711
712 /// Declares a storage as unbounded in potential size.
713 ///
714 /// When implementing the storage info (when `#[pallet::generate_storage_info]` is
715 /// specified on the pallet struct placeholder), the size of the storage will be declared
716 /// as unbounded. This can be useful for storage which can never go into PoV (Proof of
717 /// Validity).
718 ///
719 /// ## Example
720 ///
721 /// ```
722 /// #[topsoil_core::pallet]
723 /// mod pallet {
724 /// # use topsoil_core::pallet_prelude::*;
725 /// #
726 /// #[pallet::pallet]
727 /// pub struct Pallet<T>(_);
728 ///
729 /// #[pallet::storage]
730 /// #[pallet::unbounded]
731 /// pub type MyStorage<T> = StorageValue<_, u32>;
732 /// #
733 /// # #[pallet::config]
734 /// # pub trait Config: topsoil_core::system::Config {}
735 /// }
736 /// ```
737 pub use topsoil_core_procedural::unbounded;
738
739 /// Defines what storage prefix to use for a storage item when building the trie.
740 ///
741 /// This is helpful if you wish to rename the storage field but don't want to perform a
742 /// migration.
743 ///
744 /// ## Example
745 ///
746 /// ```
747 /// #[topsoil_core::pallet]
748 /// mod pallet {
749 /// # use topsoil_core::pallet_prelude::*;
750 /// #
751 /// #[pallet::pallet]
752 /// pub struct Pallet<T>(_);
753 ///
754 /// #[pallet::storage]
755 /// #[pallet::storage_prefix = "foo"]
756 /// pub type MyStorage<T> = StorageValue<_, u32>;
757 /// #
758 /// # #[pallet::config]
759 /// # pub trait Config: topsoil_core::system::Config {}
760 /// }
761 /// ```
762 pub use topsoil_core_procedural::storage_prefix;
763
764 /// Ensures the generated `DefaultConfig` will not have any bounds for
765 /// that trait item.
766 ///
767 /// Attaching this attribute to a trait item ensures that the generated trait
768 /// `DefaultConfig` will not have any bounds for this trait item.
769 ///
770 /// As an example, if you have a trait item `type AccountId: SomeTrait;` in your `Config`
771 /// trait, the generated `DefaultConfig` will only have `type AccountId;` with no trait
772 /// bound.
773 pub use topsoil_core_procedural::no_default_bounds;
774
775 /// Ensures the trait item will not be used as a default with the
776 /// `#[derive_impl(..)]` attribute macro.
777 ///
778 /// The optional attribute `#[pallet::no_default]` can be attached to trait items within a
779 /// `Config` trait impl that has [`#[pallet::config(with_default)]`](`config`)
780 /// attached.
781 pub use topsoil_core_procedural::no_default;
782
783 /// Declares a module as importable into a pallet via
784 /// [`#[import_section]`](`import_section`).
785 ///
786 /// Note that sections are imported by their module name/ident, and should be referred to
787 /// by their _full path_ from the perspective of the target pallet. Do not attempt to make
788 /// use of `use` statements to bring pallet sections into scope, as this will not work
789 /// (unless you do so as part of a wildcard import, in which case it will work).
790 ///
791 /// ## Naming Logistics
792 ///
793 /// Also note that because of how `#[pallet_section]` works, pallet section names must be
794 /// globally unique _within the crate in which they are defined_. For more information on
795 /// why this must be the case, see macro_magic's
796 /// [`#[export_tokens]`](https://docs.rs/macro_magic/latest/macro_magic/attr.export_tokens.html) macro.
797 ///
798 /// Optionally, you may provide an argument to `#[pallet_section]` such as
799 /// `#[pallet_section(some_ident)]`, in the event that there is another pallet section in
800 /// same crate with the same ident/name. The ident you specify can then be used instead of
801 /// the module's ident name when you go to import it via
802 /// [`#[import_section]`](`import_section`).
803 pub use topsoil_core_procedural::pallet_section;
804
805 /// The `#[pallet::inherent]` attribute allows the pallet to provide
806 /// [inherents](https://docs.substrate.io/fundamentals/transaction-types/#inherent-transactions).
807 ///
808 /// An inherent is some piece of data that is inserted by a block authoring node at block
809 /// creation time and can either be accepted or rejected by validators based on whether the
810 /// data falls within an acceptable range.
811 ///
812 /// The most common inherent is the `timestamp` that is inserted into every block. Since
813 /// there is no way to validate timestamps, validators simply check that the timestamp
814 /// reported by the block authoring node falls within an acceptable range.
815 ///
816 /// Example usage:
817 ///
818 /// ```
819 /// #[topsoil_core::pallet]
820 /// mod pallet {
821 /// # use topsoil_core::pallet_prelude::*;
822 /// # use topsoil_core::inherent::IsFatalError;
823 /// # use subsoil::timestamp::InherentError;
824 /// # use core::result;
825 /// #
826 /// // Example inherent identifier
827 /// pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"timstap0";
828 ///
829 /// #[pallet::pallet]
830 /// pub struct Pallet<T>(_);
831 ///
832 /// #[pallet::inherent]
833 /// impl<T: Config> ProvideInherent for Pallet<T> {
834 /// type Call = Call<T>;
835 /// type Error = InherentError;
836 /// const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
837 ///
838 /// fn create_inherent(data: &InherentData) -> Option<Self::Call> {
839 /// unimplemented!()
840 /// }
841 ///
842 /// fn check_inherent(
843 /// call: &Self::Call,
844 /// data: &InherentData,
845 /// ) -> result::Result<(), Self::Error> {
846 /// unimplemented!()
847 /// }
848 ///
849 /// fn is_inherent(call: &Self::Call) -> bool {
850 /// unimplemented!()
851 /// }
852 /// }
853 /// #
854 /// # #[pallet::config]
855 /// # pub trait Config: topsoil_core::system::Config {}
856 /// }
857 /// ```
858 ///
859 /// I.e. a trait implementation with bound `T: Config`, of trait `ProvideInherent` for type
860 /// `Pallet<T>`, and some optional where clause.
861 ///
862 /// ## Macro expansion
863 ///
864 /// The macro currently makes no use of this information, but it might use this information
865 /// in the future to give information directly to `construct_runtime`.
866 pub use topsoil_core_procedural::inherent;
867
868 /// Splits a pallet declaration into multiple parts.
869 ///
870 /// An attribute macro that can be attached to a module declaration. Doing so will
871 /// import the contents of the specified external pallet section that is defined
872 /// elsewhere using [`#[pallet_section]`](`pallet_section`).
873 ///
874 /// ## Example
875 /// ```
876 /// # use topsoil_core::pallet_macros::pallet_section;
877 /// # use topsoil_core::pallet_macros::import_section;
878 /// #
879 /// /// A [`pallet_section`] that defines the events for a pallet.
880 /// /// This can later be imported into the pallet using [`import_section`].
881 /// #[pallet_section]
882 /// mod events {
883 /// #[pallet::event]
884 /// #[pallet::generate_deposit(pub(super) fn deposit_event)]
885 /// pub enum Event<T: Config> {
886 /// /// Event documentation should end with an array that provides descriptive names for event
887 /// /// parameters. [something, who]
888 /// SomethingStored { something: u32, who: T::AccountId },
889 /// }
890 /// }
891 ///
892 /// #[import_section(events)]
893 /// #[topsoil_core::pallet]
894 /// mod pallet {
895 /// # use topsoil_core::pallet_prelude::*;
896 /// #
897 /// #[pallet::pallet]
898 /// pub struct Pallet<T>(_);
899 /// #
900 /// # #[pallet::config]
901 /// # pub trait Config: topsoil_core::system::Config<RuntimeEvent: From<Event<Self>>> {
902 /// # }
903 /// }
904 /// ```
905 ///
906 /// This will result in the contents of `some_section` being _verbatim_ imported into
907 /// the pallet above. Note that since the tokens for `some_section` are essentially
908 /// copy-pasted into the target pallet, you cannot refer to imports that don't also
909 /// exist in the target pallet, but this is easily resolved by including all relevant
910 /// `use` statements within your pallet section, so they are imported as well, or by
911 /// otherwise ensuring that you have the same imports on the target pallet.
912 ///
913 /// It is perfectly permissible to import multiple pallet sections into the same pallet,
914 /// which can be done by having multiple `#[import_section(something)]` attributes
915 /// attached to the pallet.
916 ///
917 /// Note that sections are imported by their module name/ident, and should be referred to
918 /// by their _full path_ from the perspective of the target pallet.
919 pub use topsoil_core_procedural::import_section;
920
921 /// Allows defining getter functions on `Pallet` storage.
922 ///
923 /// ## Example
924 ///
925 /// ```
926 /// #[topsoil_core::pallet]
927 /// mod pallet {
928 /// # use topsoil_core::pallet_prelude::*;
929 /// #
930 /// #[pallet::pallet]
931 /// pub struct Pallet<T>(_);
932 ///
933 /// #[pallet::storage]
934 /// #[pallet::getter(fn my_getter_fn_name)]
935 /// pub type MyStorage<T> = StorageValue<_, u32>;
936 /// #
937 /// # #[pallet::config]
938 /// # pub trait Config: topsoil_core::system::Config {}
939 /// }
940 /// ```
941 ///
942 /// See [`pallet::storage`](`topsoil_core::pallet_macros::storage`) for more info.
943 pub use topsoil_core_procedural::getter;
944
945 /// Defines constants that are added to the constant field of
946 /// [`PalletMetadata`](frame_metadata::v15::PalletMetadata) struct for this pallet.
947 ///
948 /// Must be defined like:
949 ///
950 /// ```
951 /// #[topsoil_core::pallet]
952 /// mod pallet {
953 /// # use topsoil_core::pallet_prelude::*;
954 /// #
955 /// #[pallet::pallet]
956 /// pub struct Pallet<T>(_);
957 ///
958 /// # #[pallet::config]
959 /// # pub trait Config: topsoil_core::system::Config {}
960 /// #
961 /// #[pallet::extra_constants]
962 /// impl<T: Config> Pallet<T> // $optional_where_clause
963 /// {
964 /// #[pallet::constant_name(SomeU32ConstantName)]
965 /// /// Some doc
966 /// fn some_u32_constant() -> u32 {
967 /// 100u32
968 /// }
969 /// }
970 /// }
971 /// ```
972 ///
973 /// I.e. a regular rust `impl` block with some optional where clause and functions with 0
974 /// args, 0 generics, and some return type.
975 pub use topsoil_core_procedural::extra_constants;
976
977 #[rustfmt::skip]
978 /// Allows bypassing the `topsoil_core::system::Config` supertrait check.
979 ///
980 /// To bypass the syntactic `topsoil_core::system::Config` supertrait check, use the attribute
981 /// `pallet::disable_frame_system_supertrait_check`.
982 ///
983 /// Note this bypass is purely syntactic, and does not actually remove the requirement that your
984 /// pallet implements `topsoil_core::system::Config`. When using this check, your config is still required to implement
985 /// `topsoil_core::system::Config` either via
986 /// - Implementing a trait that itself implements `topsoil_core::system::Config`
987 /// - Tightly coupling it with another pallet which itself implements `topsoil_core::system::Config`
988 ///
989 /// e.g.
990 ///
991 /// ```
992 /// #[topsoil_core::pallet]
993 /// mod pallet {
994 /// # use topsoil_core::pallet_prelude::*;
995 /// # use topsoil_core::system::pallet_prelude::*;
996 /// trait OtherTrait: topsoil_core::system::Config {}
997 ///
998 /// #[pallet::pallet]
999 /// pub struct Pallet<T>(_);
1000 ///
1001 /// #[pallet::config]
1002 /// #[pallet::disable_frame_system_supertrait_check]
1003 /// pub trait Config: OtherTrait {}
1004 /// }
1005 /// ```
1006 ///
1007 /// To learn more about supertraits, see the
1008 /// [trait_based_programming](../../polkadot_sdk_docs/reference_docs/trait_based_programming/index.html)
1009 /// reference doc.
1010 pub use topsoil_core_procedural::disable_frame_system_supertrait_check;
1011
1012 /// The mandatory attribute allowing definition of configurable types for the pallet.
1013 ///
1014 /// Item must be defined as:
1015 ///
1016 /// ```
1017 /// #[topsoil_core::pallet]
1018 /// mod pallet {
1019 /// # use topsoil_core::pallet_prelude::*;
1020 /// #
1021 /// #[pallet::pallet]
1022 /// pub struct Pallet<T>(_);
1023 ///
1024 /// #[pallet::config]
1025 /// pub trait Config: topsoil_core::system::Config // + $optionally_some_other_supertraits
1026 /// // $optional_where_clause
1027 /// {
1028 /// // config items here
1029 /// }
1030 /// }
1031 /// ```
1032 ///
1033 /// I.e. a regular trait definition named `Config`, with the supertrait
1034 /// [`topsoil_core::system::pallet::Config`](../../topsoil_system/pallet/trait.Config.html), and
1035 /// optionally other supertraits and a where clause. (Specifying other supertraits here is
1036 /// known as [tight coupling](https://docs.substrate.io/reference/how-to-guides/pallet-design/use-tight-coupling/))
1037 ///
1038 /// ## Optional: `with_default`
1039 ///
1040 /// An optional `with_default` argument may also be specified. Doing so will automatically
1041 /// generate a `DefaultConfig` trait inside your pallet which is suitable for use with
1042 /// [`#[derive_impl(..)`](`topsoil_core::derive_impl`) to derive a default testing
1043 /// config:
1044 ///
1045 /// ```
1046 /// #[topsoil_core::pallet]
1047 /// mod pallet {
1048 /// # use topsoil_core::pallet_prelude::*;
1049 /// # use topsoil_core::system::pallet_prelude::*;
1050 /// # use core::fmt::Debug;
1051 /// # use topsoil_core::traits::Contains;
1052 /// #
1053 /// # pub trait SomeMoreComplexBound {}
1054 /// #
1055 /// #[pallet::pallet]
1056 /// pub struct Pallet<T>(_);
1057 ///
1058 /// #[pallet::config(with_default)] // <- with_default is optional
1059 /// pub trait Config: topsoil_core::system::Config {
1060 /// /// A more complex type.
1061 /// #[pallet::no_default] // Example of type where no default should be provided
1062 /// type MoreComplexType: SomeMoreComplexBound;
1063 ///
1064 /// /// A simple type.
1065 /// // Default with bounds is supported for simple types
1066 /// type SimpleType: From<u32>;
1067 /// }
1068 ///
1069 /// #[pallet::event]
1070 /// pub enum Event<T: Config> {
1071 /// SomeEvent(u16, u32),
1072 /// }
1073 /// }
1074 /// ```
1075 ///
1076 /// As shown above:
1077 /// * you may attach the [`#[pallet::no_default]`](`no_default`)
1078 /// attribute to specify that a particular trait item _cannot_ be used as a default when a
1079 /// test `Config` is derived using the [`#[derive_impl(..)]`](`topsoil_core::derive_impl`)
1080 /// attribute macro. This will cause that particular trait item to simply not appear in
1081 /// default testing configs based on this config (the trait item will not be included in
1082 /// `DefaultConfig`).
1083 /// * you may attach the [`#[pallet::no_default_bounds]`](`no_default_bounds`)
1084 /// attribute to specify that a particular trait item can be used as a default when a
1085 /// test `Config` is derived using the [`#[derive_impl(..)]`](`topsoil_core::derive_impl`)
1086 /// attribute macro. But its bounds cannot be enforced at this point and should be
1087 /// discarded when generating the default config trait.
1088 /// * you may not specify any attribute to generate a trait item in the default config
1089 /// trait.
1090 ///
1091 /// In case origin of error is not clear it is recommended to disable all default with
1092 /// [`#[pallet::no_default]`](`no_default`) and enable them one by one.
1093 ///
1094 /// ### `DefaultConfig` Caveats
1095 ///
1096 /// The auto-generated `DefaultConfig` trait:
1097 /// - is always a _subset_ of your pallet's `Config` trait.
1098 /// - can only contain items that don't rely on externalities, such as
1099 /// `topsoil_core::system::Config`.
1100 ///
1101 /// Trait items that _do_ rely on externalities should be marked with
1102 /// [`#[pallet::no_default]`](`no_default`)
1103 ///
1104 /// Consequently:
1105 /// - Any items that rely on externalities _must_ be marked with
1106 /// [`#[pallet::no_default]`](`no_default`) or your trait will fail to compile when used
1107 /// with [`derive_impl`](`topsoil_core::derive_impl`).
1108 /// - Items marked with [`#[pallet::no_default]`](`no_default`) are entirely excluded from
1109 /// the `DefaultConfig` trait, and therefore any impl of `DefaultConfig` doesn't need to
1110 /// implement such items.
1111 ///
1112 /// For more information, see:
1113 /// * [`topsoil_core::derive_impl`].
1114 /// * [`#[pallet::no_default]`](`no_default`)
1115 /// * [`#[pallet::no_default_bounds]`](`no_default_bounds`)
1116 ///
1117 /// ## Optional: `without_automatic_metadata`
1118 ///
1119 /// By default, the associated types of the `Config` trait that require the `TypeInfo` or
1120 /// `Parameter` bounds are included in the metadata of the pallet.
1121 ///
1122 /// The optional `without_automatic_metadata` argument can be used to exclude these
1123 /// associated types from the metadata collection.
1124 ///
1125 /// Furthermore, the `without_automatic_metadata` argument can be used in combination with
1126 /// the [`#[pallet::include_metadata]`](`include_metadata`) attribute to selectively
1127 /// include only certain associated types in the metadata collection.
1128 /// ```
1129 /// #[topsoil_core::pallet]
1130 /// mod pallet {
1131 /// # use topsoil_core::pallet_prelude::*;
1132 /// # use topsoil_core::system::pallet_prelude::*;
1133 /// # use core::fmt::Debug;
1134 /// # use topsoil_core::traits::{Contains, VariantCount};
1135 /// #
1136 /// # pub trait SomeMoreComplexBound {}
1137 /// #
1138 /// #[pallet::pallet]
1139 /// pub struct Pallet<T>(_);
1140 ///
1141 /// #[pallet::config(with_default, without_automatic_metadata)] // <- with_default and without_automatic_metadata are optional
1142 /// pub trait Config: topsoil_core::system::Config {
1143 /// /// The overarching freeze reason.
1144 /// #[pallet::no_default_bounds] // Default with bounds is not supported for RuntimeFreezeReason
1145 /// type RuntimeFreezeReason: Parameter + Member + MaxEncodedLen + Copy + VariantCount;
1146 /// /// A simple type.
1147 /// // Type that would have been included in metadata, but is now excluded.
1148 /// type SimpleType: From<u32> + TypeInfo;
1149 ///
1150 /// // The `pallet::include_metadata` is used to selectively include this type in metadata.
1151 /// #[pallet::include_metadata]
1152 /// type SelectivelyInclude: From<u32> + TypeInfo;
1153 /// }
1154 ///
1155 /// #[pallet::event]
1156 /// pub enum Event<T: Config> {
1157 /// SomeEvent(u16, u32),
1158 /// }
1159 /// }
1160 /// ```
1161 pub use topsoil_core_procedural::config;
1162
1163 /// Allows defining an enum that gets composed as an aggregate enum by `construct_runtime`.
1164 ///
1165 /// The `#[pallet::composite_enum]` attribute allows you to define an enum that gets
1166 /// composed as an aggregate enum by `construct_runtime`. This is similar in principle with
1167 /// [topsoil_core_procedural::event] and [topsoil_core_procedural::error].
1168 ///
1169 /// The attribute currently only supports enum definitions, and identifiers that are named
1170 /// `FreezeReason`, `HoldReason`, `LockId` or `SlashReason`. Arbitrary identifiers for the
1171 /// enum are not supported. The aggregate enum generated by
1172 /// [`topsoil_core::construct_runtime`] will have the name of `RuntimeFreezeReason`,
1173 /// `RuntimeHoldReason`, `RuntimeLockId` and `RuntimeSlashReason` respectively.
1174 ///
1175 /// NOTE: The aggregate enum generated by `construct_runtime` generates a conversion
1176 /// function from the pallet enum to the aggregate enum, and automatically derives the
1177 /// following traits:
1178 ///
1179 /// ```ignore
1180 /// Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, MaxEncodedLen, TypeInfo,
1181 /// Debug
1182 /// ```
1183 ///
1184 /// For ease of usage, when no `#[derive]` attributes are found for the enum under
1185 /// [`#[pallet::composite_enum]`](composite_enum), the aforementioned traits are
1186 /// automatically derived for it. The inverse is also true: if there are any `#[derive]`
1187 /// attributes found for the enum, then no traits will automatically be derived for it.
1188 ///
1189 /// e.g, defining `HoldReason` in a pallet
1190 ///
1191 /// ```
1192 /// #[topsoil_core::pallet]
1193 /// mod pallet {
1194 /// # use topsoil_core::pallet_prelude::*;
1195 /// #
1196 /// #[pallet::pallet]
1197 /// pub struct Pallet<T>(_);
1198 ///
1199 /// #[pallet::composite_enum]
1200 /// pub enum HoldReason {
1201 /// /// The NIS Pallet has reserved it for a non-fungible receipt.
1202 /// #[codec(index = 0)]
1203 /// SomeHoldReason,
1204 /// #[codec(index = 1)]
1205 /// SomeOtherHoldReason,
1206 /// }
1207 /// #
1208 /// # #[pallet::config]
1209 /// # pub trait Config: topsoil_core::system::Config {}
1210 /// }
1211 pub use topsoil_core_procedural::composite_enum;
1212
1213 /// Allows the pallet to validate unsigned transactions.
1214 ///
1215 /// Item must be defined as:
1216 ///
1217 /// ```
1218 /// #[topsoil_core::pallet]
1219 /// mod pallet {
1220 /// # use topsoil_core::pallet_prelude::*;
1221 /// #
1222 /// #[pallet::pallet]
1223 /// pub struct Pallet<T>(_);
1224 ///
1225 /// #[pallet::validate_unsigned]
1226 /// impl<T: Config> subsoil::runtime::traits::ValidateUnsigned for Pallet<T> {
1227 /// type Call = Call<T>;
1228 ///
1229 /// fn validate_unsigned(_source: TransactionSource, _call: &Self::Call) -> TransactionValidity {
1230 /// // Your implementation details here
1231 /// unimplemented!()
1232 /// }
1233 /// }
1234 /// #
1235 /// # #[pallet::config]
1236 /// # pub trait Config: topsoil_core::system::Config {}
1237 /// }
1238 /// ```
1239 ///
1240 /// I.e. a trait implementation with bound `T: Config`, of trait
1241 /// [`ValidateUnsigned`](topsoil_core::pallet_prelude::ValidateUnsigned) for
1242 /// type `Pallet<T>`, and some optional where clause.
1243 ///
1244 /// NOTE: There is also the [`subsoil::runtime::traits::TransactionExtension`] trait that can be
1245 /// used to add some specific logic for transaction validation.
1246 ///
1247 /// ## Macro expansion
1248 ///
1249 /// The macro currently makes no use of this information, but it might use this information
1250 /// in the future to give information directly to [`topsoil_core::construct_runtime`].
1251 pub use topsoil_core_procedural::validate_unsigned;
1252
1253 /// Allows defining view functions on a pallet.
1254 ///
1255 /// A pallet view function is a read-only function providing access to the state of the
1256 /// pallet from both outside and inside the runtime. It should provide a _stable_ interface
1257 /// for querying the state of the pallet, avoiding direct storage access and upgrading
1258 /// along with the runtime.
1259 ///
1260 /// ## Syntax
1261 /// View functions methods must be read-only and always return some output. A
1262 /// `view_functions` impl block only allows methods to be defined inside of
1263 /// it.
1264 ///
1265 /// ## Example
1266 /// ```
1267 /// #[topsoil_core::pallet]
1268 /// pub mod pallet {
1269 /// use topsoil_core::pallet_prelude::*;
1270 ///
1271 /// #[pallet::config]
1272 /// pub trait Config: topsoil_core::system::Config {}
1273 ///
1274 /// #[pallet::pallet]
1275 /// pub struct Pallet<T>(_);
1276 ///
1277 /// #[pallet::storage]
1278 /// pub type SomeMap<T: Config> = StorageMap<_, Twox64Concat, u32, u32, OptionQuery>;
1279 ///
1280 /// #[pallet::view_functions]
1281 /// impl<T: Config> Pallet<T> {
1282 /// /// Retrieve a map storage value by key.
1283 /// pub fn get_value_with_arg(key: u32) -> Option<u32> {
1284 /// SomeMap::<T>::get(key)
1285 /// }
1286 /// }
1287 /// }
1288 /// ```
1289 ///
1290 ///
1291 /// ## Usage and implementation details
1292 /// To allow outside access to pallet view functions, you need to add a runtime API that
1293 /// accepts view function queries and dispatches them to the right pallet. You can do that
1294 /// by implementing the
1295 /// [`RuntimeViewFunction`](topsoil_core::view_functions::runtime_api::RuntimeViewFunction)
1296 /// trait for the runtime inside an [`impl_runtime_apis!`](subsoil::api::impl_runtime_apis)
1297 /// block.
1298 ///
1299 /// The `RuntimeViewFunction` trait implements a hashing-based dispatching mechanism to
1300 /// dispatch view functions to the right method in the right pallet based on their IDs. A
1301 /// view function ID depends both on its pallet and on its method signature, so it remains
1302 /// stable as long as those two elements are not modified. In general, pallet view
1303 /// functions should expose a _stable_ interface and changes to the method signature are
1304 /// strongly discouraged. For more details on the dispatching mechanism, see the
1305 /// [`DispatchViewFunction`](topsoil_core::view_functions::DispatchViewFunction) trait.
1306 pub use topsoil_core_procedural::view_functions;
1307
1308 /// Allows defining a struct implementing the [`Get`](topsoil_core::traits::Get) trait to
1309 /// ease the use of storage types.
1310 ///
1311 /// This attribute is meant to be used alongside [`#[pallet::storage]`](`storage`) to
1312 /// define a storage's default value. This attribute can be used multiple times.
1313 ///
1314 /// Item must be defined as:
1315 ///
1316 /// ```
1317 /// #[topsoil_core::pallet]
1318 /// mod pallet {
1319 /// # use subsoil::runtime::FixedU128;
1320 /// # use topsoil_core::pallet_prelude::*;
1321 /// #
1322 /// #[pallet::pallet]
1323 /// pub struct Pallet<T>(_);
1324 ///
1325 /// #[pallet::storage]
1326 /// pub(super) type SomeStorage<T: Config> =
1327 /// StorageValue<_, FixedU128, ValueQuery, DefaultForSomeValue>;
1328 ///
1329 /// // Define default for ParachainId
1330 /// #[pallet::type_value]
1331 /// pub fn DefaultForSomeValue() -> FixedU128 {
1332 /// FixedU128::from_u32(1)
1333 /// }
1334 /// #
1335 /// # #[pallet::config]
1336 /// # pub trait Config: topsoil_core::system::Config {}
1337 /// }
1338 /// ```
1339 ///
1340 /// ## Macro expansion
1341 ///
1342 /// The macro renames the function to some internal name, generates a struct with the
1343 /// original name of the function and its generic, and implements `Get<$ReturnType>` by
1344 /// calling the user defined function.
1345 pub use topsoil_core_procedural::type_value;
1346
1347 /// Allows defining a storage version for the pallet.
1348 ///
1349 /// Because the `pallet::pallet` macro implements
1350 /// [`GetStorageVersion`](topsoil_core::traits::GetStorageVersion), the current storage
1351 /// version needs to be communicated to the macro. This can be done by using the
1352 /// `pallet::storage_version` attribute:
1353 ///
1354 /// ```
1355 /// #[topsoil_core::pallet]
1356 /// mod pallet {
1357 /// # use topsoil_core::pallet_prelude::StorageVersion;
1358 /// # use topsoil_core::traits::GetStorageVersion;
1359 /// #
1360 /// const STORAGE_VERSION: StorageVersion = StorageVersion::new(5);
1361 ///
1362 /// #[pallet::pallet]
1363 /// #[pallet::storage_version(STORAGE_VERSION)]
1364 /// pub struct Pallet<T>(_);
1365 /// #
1366 /// # #[pallet::config]
1367 /// # pub trait Config: topsoil_core::system::Config {}
1368 /// }
1369 /// ```
1370 ///
1371 /// If not present, the current storage version is set to the default value.
1372 pub use topsoil_core_procedural::storage_version;
1373
1374 /// The `#[pallet::hooks]` attribute allows you to specify a
1375 /// [`topsoil_core::traits::Hooks`] implementation for `Pallet` that specifies
1376 /// pallet-specific logic.
1377 ///
1378 /// The item the attribute attaches to must be defined as follows:
1379 ///
1380 /// ```
1381 /// #[topsoil_core::pallet]
1382 /// mod pallet {
1383 /// # use topsoil_core::pallet_prelude::*;
1384 /// # use topsoil_core::system::pallet_prelude::*;
1385 /// #
1386 /// #[pallet::pallet]
1387 /// pub struct Pallet<T>(_);
1388 ///
1389 /// #[pallet::hooks]
1390 /// impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
1391 /// // Implement hooks here
1392 /// }
1393 /// #
1394 /// # #[pallet::config]
1395 /// # pub trait Config: topsoil_core::system::Config {}
1396 /// }
1397 /// ```
1398 /// I.e. a regular trait implementation with generic bound: `T: Config`, for the trait
1399 /// `Hooks<BlockNumberFor<T>>` (they are defined in preludes), for the type `Pallet<T>`.
1400 ///
1401 /// Optionally, you could add a where clause.
1402 ///
1403 /// ## Macro expansion
1404 ///
1405 /// The macro implements the traits
1406 /// [`OnInitialize`](topsoil_core::traits::OnInitialize),
1407 /// [`OnIdle`](topsoil_core::traits::OnIdle),
1408 /// [`OnFinalize`](topsoil_core::traits::OnFinalize),
1409 /// [`OnRuntimeUpgrade`](topsoil_core::traits::OnRuntimeUpgrade),
1410 /// [`OffchainWorker`](topsoil_core::traits::OffchainWorker), and
1411 /// [`IntegrityTest`](topsoil_core::traits::IntegrityTest) using
1412 /// the provided [`Hooks`](topsoil_core::traits::Hooks) implementation.
1413 ///
1414 /// NOTE: `OnRuntimeUpgrade` is implemented with `Hooks::on_runtime_upgrade` and some
1415 /// additional logic. E.g. logic to write the pallet version into storage.
1416 ///
1417 /// NOTE: The macro also adds some tracing logic when implementing the above traits. The
1418 /// following hooks emit traces: `on_initialize`, `on_finalize` and `on_runtime_upgrade`.
1419 pub use topsoil_core_procedural::hooks;
1420
1421 /// Generates a helper function on `Pallet` that handles deposit events.
1422 ///
1423 /// NOTE: For instantiable pallets, the event must be generic over `T` and `I`.
1424 ///
1425 /// ## Macro expansion
1426 ///
1427 /// The macro will add on enum `Event` the attributes:
1428 /// * `#[derive(`[`topsoil_core::CloneNoBound`]`)]`
1429 /// * `#[derive(`[`topsoil_core::EqNoBound`]`)]`
1430 /// * `#[derive(`[`topsoil_core::PartialEqNoBound`]`)]`
1431 /// * `#[derive(`[`topsoil_core::DebugNoBound`]`)]`
1432 /// * `#[derive(`[`codec::Encode`]`)]`
1433 /// * `#[derive(`[`codec::Decode`]`)]`
1434 ///
1435 /// The macro implements `From<Event<..>>` for ().
1436 ///
1437 /// The macro implements a metadata function on `Event` returning the `EventMetadata`.
1438 ///
1439 /// If `#[pallet::generate_deposit]` is present then the macro implements `fn
1440 /// deposit_event` on `Pallet`.
1441 pub use topsoil_core_procedural::generate_deposit;
1442
1443 /// Allows defining logic to make an extrinsic call feeless.
1444 ///
1445 /// Each dispatchable may be annotated with the `#[pallet::feeless_if($closure)]`
1446 /// attribute, which explicitly defines the condition for the dispatchable to be feeless.
1447 ///
1448 /// The arguments for the closure must be the referenced arguments of the dispatchable
1449 /// function.
1450 ///
1451 /// The closure must return `bool`.
1452 ///
1453 /// ### Example
1454 ///
1455 /// ```
1456 /// #[topsoil_core::pallet(dev_mode)]
1457 /// mod pallet {
1458 /// # use topsoil_core::pallet_prelude::*;
1459 /// # use topsoil_core::system::pallet_prelude::*;
1460 /// #
1461 /// #[pallet::pallet]
1462 /// pub struct Pallet<T>(_);
1463 ///
1464 /// #[pallet::call]
1465 /// impl<T: Config> Pallet<T> {
1466 /// #[pallet::call_index(0)]
1467 /// /// Marks this call as feeless if `foo` is zero.
1468 /// #[pallet::feeless_if(|_origin: &OriginFor<T>, foo: &u32| -> bool {
1469 /// *foo == 0
1470 /// })]
1471 /// pub fn something(
1472 /// _: OriginFor<T>,
1473 /// foo: u32,
1474 /// ) -> DispatchResult {
1475 /// unimplemented!()
1476 /// }
1477 /// }
1478 /// #
1479 /// # #[pallet::config]
1480 /// # pub trait Config: topsoil_core::system::Config {}
1481 /// }
1482 /// ```
1483 ///
1484 /// Please note that this only works for signed dispatchables and requires a transaction
1485 /// extension to wrap the existing payment extension that checks the `feeless_if` condition.
1486 /// Else, this is completely ignored and the dispatchable is still charged.
1487 ///
1488 /// Also this will not allow accountless caller to send a transaction if some transaction
1489 /// extension such as `topsoil_core::system::CheckNonce` is used.
1490 /// Extensions such as `topsoil_core::system::CheckNonce` require a funded account to validate
1491 /// the transaction.
1492 ///
1493 /// ### Macro expansion
1494 ///
1495 /// The macro implements the `CheckIfFeeless` trait on the dispatchable and calls the
1496 /// corresponding closure in the implementation.
1497 pub use topsoil_core_procedural::feeless_if;
1498
1499 /// Allows defining an error enum that will be returned from the dispatchable when an error
1500 /// occurs.
1501 ///
1502 /// The information for this error type is then stored in runtime metadata.
1503 ///
1504 /// Item must be defined as so:
1505 ///
1506 /// ```
1507 /// #[topsoil_core::pallet(dev_mode)]
1508 /// mod pallet {
1509 /// #[pallet::pallet]
1510 /// pub struct Pallet<T>(_);
1511 ///
1512 /// #[pallet::error]
1513 /// pub enum Error<T> {
1514 /// /// SomeFieldLessVariant doc
1515 /// SomeFieldLessVariant,
1516 /// /// SomeVariantWithOneField doc
1517 /// SomeVariantWithOneField(u32),
1518 /// }
1519 /// #
1520 /// # #[pallet::config]
1521 /// # pub trait Config: topsoil_core::system::Config {}
1522 /// }
1523 /// ```
1524 /// I.e. a regular enum named `Error`, with generic `T` and fieldless or multiple-field
1525 /// variants.
1526 ///
1527 /// Any field type in the enum variants must implement [`scale_info::TypeInfo`] in order to
1528 /// be properly used in the metadata, and its encoded size should be as small as possible,
1529 /// preferably 1 byte in size in order to reduce storage size. The error enum itself has an
1530 /// absolute maximum encoded size specified by
1531 /// [`topsoil_core::MAX_MODULE_ERROR_ENCODED_SIZE`].
1532 ///
1533 /// (1 byte can still be 256 different errors. The more specific the error, the easier it
1534 /// is to diagnose problems and give a better experience to the user. Don't skimp on having
1535 /// lots of individual error conditions.)
1536 ///
1537 /// Field types in enum variants must also implement [`topsoil_core::PalletError`],
1538 /// otherwise the pallet will fail to compile. Rust primitive types have already
1539 /// implemented the [`topsoil_core::PalletError`] trait along with some commonly used
1540 /// stdlib types such as [`Option`] and [`core::marker::PhantomData`], and hence
1541 /// in most use cases, a manual implementation is not necessary and is discouraged.
1542 ///
1543 /// The generic `T` must not bound anything and a `where` clause is not allowed. That said,
1544 /// bounds and/or a where clause should not needed for any use-case.
1545 ///
1546 /// ## Macro expansion
1547 ///
1548 /// The macro implements the [`Debug`] trait and functions `as_u8` using variant position,
1549 /// and `as_str` using variant doc.
1550 ///
1551 /// The macro also implements `From<Error<T>>` for `&'static str` and `From<Error<T>>` for
1552 /// `DispatchError`.
1553 ///
1554 /// ## Note on deprecation of Errors
1555 ///
1556 /// - Usage of `deprecated` attribute will propagate deprecation information to the pallet
1557 /// metadata where the item was declared.
1558 /// - For general usage examples of `deprecated` attribute please refer to <https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-deprecated-attribute>
1559 /// - It's possible to deprecated either certain variants inside the `Error` or the whole
1560 /// `Error` itself. If both the `Error` and its variants are deprecated a compile error
1561 /// will be returned.
1562 /// - Usage of `allow(deprecated)` on the item will propagate this attribute to the
1563 /// generated code.
1564 /// - If the item is annotated with `deprecated` attribute then the generated code will be
1565 /// automatically annotated with `allow(deprecated)`
1566 pub use topsoil_core_procedural::error;
1567
1568 /// Allows defining pallet events.
1569 ///
1570 /// Pallet events are stored under the `system` / `events` key when the block is applied
1571 /// (and then replaced when the next block writes it's events).
1572 ///
1573 /// The Event enum can be defined as follows:
1574 ///
1575 /// ```
1576 /// #[topsoil_core::pallet(dev_mode)]
1577 /// mod pallet {
1578 /// # use topsoil_core::pallet_prelude::IsType;
1579 /// #
1580 /// #[pallet::pallet]
1581 /// pub struct Pallet<T>(_);
1582 ///
1583 /// #[pallet::config]
1584 /// pub trait Config: topsoil_core::system::Config {}
1585 ///
1586 /// #[pallet::event]
1587 /// #[pallet::generate_deposit(fn deposit_event)] // Optional
1588 /// pub enum Event<T> {
1589 /// /// SomeEvent doc
1590 /// SomeEvent(u16, u32), // SomeEvent with two fields
1591 /// }
1592 /// }
1593 /// ```
1594 ///
1595 /// I.e. an enum (with named or unnamed fields variant), named `Event`, with generic: none
1596 /// or `T` or `T: Config`, and optional w here clause.
1597 ///
1598 /// Macro expansion automatically appends `From<Event<Self>>` bound to
1599 /// system supertrait's `RuntimeEvent `associated type, i.e:
1600 ///
1601 /// ```rs
1602 /// #[pallet::config]
1603 /// pub trait Config: topsoil_core::system::Config<RuntimeEvent: From<Event<Self>>> {}
1604 /// ```
1605 ///
1606 /// Each field must implement [`Clone`], [`Eq`], [`PartialEq`], [`codec::Encode`],
1607 /// [`codec::Decode`], and [`Debug`] (on std only). For ease of use, bound by the trait
1608 /// `Member`, available in [`topsoil_core::pallet_prelude`].
1609 ///
1610 /// ## Note on deprecation of Events
1611 ///
1612 /// - Usage of `deprecated` attribute will propagate deprecation information to the pallet
1613 /// metadata where the item was declared.
1614 /// - For general usage examples of `deprecated` attribute please refer to <https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-deprecated-attribute>
1615 /// - It's possible to deprecated either certain variants inside the `Event` or the whole
1616 /// `Event` itself. If both the `Event` and its variants are deprecated a compile error
1617 /// will be returned.
1618 /// - Usage of `allow(deprecated)` on the item will propagate this attribute to the
1619 /// generated code.
1620 /// - If the item is annotated with `deprecated` attribute then the generated code will be
1621 /// automatically annotated with `allow(deprecated)`
1622 pub use topsoil_core_procedural::event;
1623
1624 /// Selectively includes associated types in the metadata.
1625 ///
1626 /// The optional attribute allows you to selectively include associated types in the
1627 /// metadata. This can be attached to trait items that implement `TypeInfo`.
1628 ///
1629 /// By default all collectable associated types are included in the metadata.
1630 ///
1631 /// This attribute can be used in combination with the
1632 /// [`#[pallet::config(without_automatic_metadata)]`](`config`).
1633 pub use topsoil_core_procedural::include_metadata;
1634
1635 /// Allows a pallet to declare a set of functions as a *dispatchable extrinsic*.
1636 ///
1637 /// In slightly simplified terms, this macro declares the set of "transactions" of a
1638 /// pallet.
1639 ///
1640 /// > The exact definition of **extrinsic** can be found in
1641 /// > [`subsoil::runtime::generic::UncheckedExtrinsic`].
1642 ///
1643 /// A **dispatchable** is a common term in FRAME, referring to process of constructing a
1644 /// function, and dispatching it with the correct inputs. This is commonly used with
1645 /// extrinsics, for example "an extrinsic has been dispatched". See
1646 /// [`subsoil::runtime::traits::Dispatchable`] and [`crate::traits::UnfilteredDispatchable`].
1647 ///
1648 /// ## Call Enum
1649 ///
1650 /// The macro is called `call` (rather than `#[pallet::extrinsics]`) because of the
1651 /// generation of a `enum Call`. This enum contains only the encoding of the function
1652 /// arguments of the dispatchable, alongside the information needed to route it to the
1653 /// correct function.
1654 ///
1655 /// The macro also ensures that the extrinsic when invoked will be wrapped via
1656 /// [`topsoil_core::storage::with_storage_layer`] to make it transactional. Thus if the
1657 /// extrinsic returns with an error any state changes that had already occurred will be
1658 /// rolled back.
1659 ///
1660 /// ```
1661 /// #[topsoil_core::pallet(dev_mode)]
1662 /// pub mod custom_pallet {
1663 /// # use topsoil_core::pallet_prelude::*;
1664 /// # use topsoil_core::system::pallet_prelude::*;
1665 /// # #[pallet::config]
1666 /// # pub trait Config: topsoil_core::system::Config {}
1667 /// # #[pallet::pallet]
1668 /// # pub struct Pallet<T>(_);
1669 /// # use topsoil_core::traits::BuildGenesisConfig;
1670 /// #[pallet::call]
1671 /// impl<T: Config> Pallet<T> {
1672 /// pub fn some_dispatchable(_origin: OriginFor<T>, _input: u32) -> DispatchResult {
1673 /// Ok(())
1674 /// }
1675 /// pub fn other(_origin: OriginFor<T>, _input: u64) -> DispatchResult {
1676 /// Ok(())
1677 /// }
1678 /// }
1679 ///
1680 /// // generates something like:
1681 /// // enum Call<T: Config> {
1682 /// // some_dispatchable { input: u32 }
1683 /// // other { input: u64 }
1684 /// // }
1685 /// }
1686 ///
1687 /// fn main() {
1688 /// # use topsoil_core::{derive_impl, construct_runtime};
1689 /// # use topsoil_core::__private::codec::Encode;
1690 /// # use topsoil_core::__private::TestExternalities;
1691 /// # use topsoil_core::traits::UnfilteredDispatchable;
1692 /// # impl custom_pallet::Config for Runtime {}
1693 /// # #[derive_impl(topsoil_core::system::config_preludes::TestDefaultConfig)]
1694 /// # impl topsoil_core::system::Config for Runtime {
1695 /// # type Block = topsoil_core::system::mocking::MockBlock<Self>;
1696 /// # }
1697 /// construct_runtime! {
1698 /// pub enum Runtime {
1699 /// System: topsoil_core::system,
1700 /// Custom: custom_pallet
1701 /// }
1702 /// }
1703 ///
1704 /// # TestExternalities::new_empty().execute_with(|| {
1705 /// let origin: RuntimeOrigin = topsoil_core::system::RawOrigin::Signed(10).into();
1706 /// // calling into a dispatchable from within the runtime is simply a function call.
1707 /// let _ = custom_pallet::Pallet::<Runtime>::some_dispatchable(origin.clone(), 10);
1708 ///
1709 /// // calling into a dispatchable from the outer world involves constructing the bytes of
1710 /// let call = custom_pallet::Call::<Runtime>::some_dispatchable { input: 10 };
1711 /// let _ = call.clone().dispatch_bypass_filter(origin);
1712 ///
1713 /// // the routing of a dispatchable is simply done through encoding of the `Call` enum,
1714 /// // which is the index of the variant, followed by the arguments.
1715 /// assert_eq!(call.encode(), vec![0u8, 10, 0, 0, 0]);
1716 ///
1717 /// // notice how in the encoding of the second function, the first byte is different and
1718 /// // referring to the second variant of `enum Call`.
1719 /// let call = custom_pallet::Call::<Runtime>::other { input: 10 };
1720 /// assert_eq!(call.encode(), vec![1u8, 10, 0, 0, 0, 0, 0, 0, 0]);
1721 /// # });
1722 /// }
1723 /// ```
1724 ///
1725 /// Further properties of dispatchable functions are as follows:
1726 ///
1727 /// - Unless if annotated by `dev_mode`, it must contain [`weight`] to denote the
1728 /// pre-dispatch weight consumed.
1729 /// - The dispatchable must declare its index via [`call_index`], which can override the
1730 /// position of a function in `enum Call`.
1731 /// - The first argument is always an `OriginFor` (or `T::RuntimeOrigin`).
1732 /// - The return type is always [`crate::dispatch::DispatchResult`] (or
1733 /// [`crate::dispatch::DispatchResultWithPostInfo`]).
1734 ///
1735 /// **WARNING**: modifying dispatchables, changing their order (i.e. using [`call_index`]),
1736 /// removing some, etc., must be done with care. This will change the encoding of the call,
1737 /// and the call can be stored on-chain (e.g. in `topsoil-scheduler`). Thus, migration
1738 /// might be needed. This is why the use of `call_index` is mandatory by default in FRAME.
1739 ///
1740 /// ## Weight info
1741 ///
1742 /// Each call needs to define a weight.
1743 /// * The weight can be defined explicitly using the attribute `#[pallet::weight($expr)]`
1744 /// (Note that argument of the call are available inside the expression).
1745 /// * Or it can be defined implicitly, the weight info for the calls needs to be specified
1746 /// in the call attribute: `#[pallet::call(weight = $WeightInfo)]`, then each call that
1747 /// doesn't have explicit weight will use `$WeightInfo::$call_name` as the weight.
1748 ///
1749 /// * Or it can be simply ignored when the pallet is in `dev_mode`.
1750 ///
1751 /// ```
1752 /// #[topsoil_core::pallet]
1753 /// mod pallet {
1754 /// use topsoil_core::pallet_prelude::*;
1755 /// use topsoil_core::system::pallet_prelude::*;
1756 ///
1757 /// #[pallet::pallet]
1758 /// pub struct Pallet<T>(_);
1759 ///
1760 /// #[pallet::config]
1761 /// pub trait Config: topsoil_core::system::Config {
1762 /// /// Type for specifying dispatchable weights.
1763 /// type WeightInfo: WeightInfo;
1764 /// }
1765 ///
1766 /// /// The `WeightInfo` trait defines weight functions for dispatchable calls.
1767 /// pub trait WeightInfo {
1768 /// fn do_something() -> Weight;
1769 /// fn do_something_else() -> Weight;
1770 /// }
1771 ///
1772 /// #[pallet::call(weight = <T as Config>::WeightInfo)]
1773 /// impl<T: Config> Pallet<T> {
1774 /// // Explicit weight definition using `#[pallet::weight(...)]`
1775 /// #[pallet::weight(<T as Config>::WeightInfo::do_something())]
1776 /// #[pallet::call_index(0)]
1777 /// pub fn do_something(
1778 /// origin: OriginFor<T>,
1779 /// foo: u32,
1780 /// ) -> DispatchResult {
1781 /// // Function logic here
1782 /// Ok(())
1783 /// }
1784 ///
1785 /// // Implicit weight definition, the macro looks up to the weight info defined in
1786 /// // `#[pallet::call(weight = $WeightInfo)]` attribute. Then use
1787 /// // `$WeightInfo::do_something_else` as the weight function.
1788 /// #[pallet::call_index(1)]
1789 /// pub fn do_something_else(
1790 /// origin: OriginFor<T>,
1791 /// bar: u64,
1792 /// ) -> DispatchResult {
1793 /// // Function logic here
1794 /// Ok(())
1795 /// }
1796 /// }
1797 /// }
1798 /// ```
1799 ///
1800 /// ## Default Behavior
1801 ///
1802 /// If no `#[pallet::call]` exists, then a default implementation corresponding to the
1803 /// following code is automatically generated:
1804 ///
1805 /// ```
1806 /// #[topsoil_core::pallet(dev_mode)]
1807 /// mod pallet {
1808 /// #[pallet::pallet]
1809 /// pub struct Pallet<T>(_);
1810 ///
1811 /// #[pallet::call] // <- automatically generated
1812 /// impl<T: Config> Pallet<T> {} // <- automatically generated
1813 ///
1814 /// #[pallet::config]
1815 /// pub trait Config: topsoil_core::system::Config {}
1816 /// }
1817 /// ```
1818 ///
1819 /// ## Note on deprecation of Calls
1820 ///
1821 /// - Usage of `deprecated` attribute will propagate deprecation information to the pallet
1822 /// metadata where the item was declared.
1823 /// - For general usage examples of `deprecated` attribute please refer to <https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-deprecated-attribute>
1824 /// - Usage of `allow(deprecated)` on the item will propagate this attribute to the
1825 /// generated code.
1826 /// - If the item is annotated with `deprecated` attribute then the generated code will be
1827 /// automatically annotated with `allow(deprecated)`
1828 pub use topsoil_core_procedural::call;
1829
1830 /// Enforce the index of a variant in the generated `enum Call`.
1831 ///
1832 /// See [`call`] for more information.
1833 ///
1834 /// All call indexes start from 0, until it encounters a dispatchable function with a
1835 /// defined call index. The dispatchable function that lexically follows the function with
1836 /// a defined call index will have that call index, but incremented by 1, e.g. if there are
1837 /// 3 dispatchable functions `fn foo`, `fn bar` and `fn qux` in that order, and only `fn
1838 /// bar` has a call index of 10, then `fn qux` will have an index of 11, instead of 1.
1839 pub use topsoil_core_procedural::call_index;
1840
1841 /// Declares the arguments of a [`call`] function to be encoded using
1842 /// [`codec::Compact`].
1843 ///
1844 /// This will results in smaller extrinsic encoding.
1845 ///
1846 /// A common example of `compact` is for numeric values that are often times far far away
1847 /// from their theoretical maximum. For example, in the context of a crypto-currency, the
1848 /// balance of an individual account is oftentimes way less than what the numeric type
1849 /// allows. In all such cases, using `compact` is sensible.
1850 ///
1851 /// ```
1852 /// #[topsoil_core::pallet(dev_mode)]
1853 /// pub mod custom_pallet {
1854 /// # use topsoil_core::pallet_prelude::*;
1855 /// # use topsoil_core::system::pallet_prelude::*;
1856 /// # #[pallet::config]
1857 /// # pub trait Config: topsoil_core::system::Config {}
1858 /// # #[pallet::pallet]
1859 /// # pub struct Pallet<T>(_);
1860 /// # use topsoil_core::traits::BuildGenesisConfig;
1861 /// #[pallet::call]
1862 /// impl<T: Config> Pallet<T> {
1863 /// pub fn some_dispatchable(_origin: OriginFor<T>, #[pallet::compact] _input: u32) -> DispatchResult {
1864 /// Ok(())
1865 /// }
1866 /// }
1867 /// }
1868 pub use topsoil_core_procedural::compact;
1869
1870 /// Allows you to define the genesis configuration for the pallet.
1871 ///
1872 /// Item is defined as either an enum or a struct. It needs to be public and implement the
1873 /// trait [`topsoil_core::traits::BuildGenesisConfig`].
1874 ///
1875 /// See [`genesis_build`] for an example.
1876 pub use topsoil_core_procedural::genesis_config;
1877
1878 /// Allows you to define how the state of your pallet at genesis is built. This
1879 /// takes as input the `GenesisConfig` type (as `self`) and constructs the pallet's initial
1880 /// state.
1881 ///
1882 /// The fields of the `GenesisConfig` can in turn be populated by the chain-spec.
1883 ///
1884 /// ## Example
1885 ///
1886 /// ```
1887 /// #[topsoil_core::pallet]
1888 /// pub mod pallet {
1889 /// # #[pallet::config]
1890 /// # pub trait Config: topsoil_core::system::Config {}
1891 /// # #[pallet::pallet]
1892 /// # pub struct Pallet<T>(_);
1893 /// # use topsoil_core::traits::BuildGenesisConfig;
1894 /// #[pallet::genesis_config]
1895 /// #[derive(topsoil_core::DefaultNoBound)]
1896 /// pub struct GenesisConfig<T: Config> {
1897 /// foo: Vec<T::AccountId>
1898 /// }
1899 ///
1900 /// #[pallet::genesis_build]
1901 /// impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
1902 /// fn build(&self) {
1903 /// // use &self to access fields.
1904 /// let foo = &self.foo;
1905 /// todo!()
1906 /// }
1907 /// }
1908 /// }
1909 /// ```
1910 ///
1911 /// ## Former Usage
1912 ///
1913 /// Prior to <https://github.com/paritytech/substrate/pull/14306>, the following syntax was used.
1914 /// This is deprecated and will soon be removed.
1915 ///
1916 /// ```
1917 /// #[topsoil_core::pallet]
1918 /// pub mod pallet {
1919 /// # #[pallet::config]
1920 /// # pub trait Config: topsoil_core::system::Config {}
1921 /// # #[pallet::pallet]
1922 /// # pub struct Pallet<T>(_);
1923 /// # use topsoil_core::traits::GenesisBuild;
1924 /// #[pallet::genesis_config]
1925 /// #[derive(topsoil_core::DefaultNoBound)]
1926 /// pub struct GenesisConfig<T: Config> {
1927 /// foo: Vec<T::AccountId>
1928 /// }
1929 ///
1930 /// #[pallet::genesis_build]
1931 /// impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
1932 /// fn build(&self) {
1933 /// todo!()
1934 /// }
1935 /// }
1936 /// }
1937 /// ```
1938 pub use topsoil_core_procedural::genesis_build;
1939
1940 /// Allows adding an associated type trait bounded by
1941 /// [`Get`](topsoil_core::pallet_prelude::Get) from [`pallet::config`](`macro@config`)
1942 /// into metadata.
1943 ///
1944 /// ## Example
1945 ///
1946 /// ```
1947 /// #[topsoil_core::pallet]
1948 /// mod pallet {
1949 /// use topsoil_core::pallet_prelude::*;
1950 /// # #[pallet::pallet]
1951 /// # pub struct Pallet<T>(_);
1952 /// #[pallet::config]
1953 /// pub trait Config: topsoil_core::system::Config {
1954 /// /// This is like a normal `Get` trait, but it will be added into metadata.
1955 /// #[pallet::constant]
1956 /// type Foo: Get<u32>;
1957 /// }
1958 /// }
1959 /// ```
1960 ///
1961 /// ## Note on deprecation of constants
1962 ///
1963 /// - Usage of `deprecated` attribute will propagate deprecation information to the pallet
1964 /// metadata where the item was declared.
1965 /// - For general usage examples of `deprecated` attribute please refer to <https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-deprecated-attribute>
1966 /// - Usage of `allow(deprecated)` on the item will propagate this attribute to the
1967 /// generated code.
1968 /// - If the item is annotated with `deprecated` attribute then the generated code will be
1969 /// automatically annotated with `allow(deprecated)`
1970 pub use topsoil_core_procedural::constant;
1971
1972 /// Declares a type alias as a storage item.
1973 ///
1974 /// Storage items are pointers to data stored on-chain (the *blockchain state*), under a
1975 /// specific key. The exact key is dependent on the type of the storage.
1976 ///
1977 /// > From the perspective of this pallet, the entire blockchain state is abstracted behind
1978 /// > a key-value api, namely [`subsoil::io::storage`].
1979 ///
1980 /// ## Storage Types
1981 ///
1982 /// The following storage types are supported by the `#[storage]` macro. For specific
1983 /// information about each storage type, refer to the documentation of the respective type.
1984 ///
1985 /// * [`StorageValue`](crate::storage::types::StorageValue)
1986 /// * [`StorageMap`](crate::storage::types::StorageMap)
1987 /// * [`CountedStorageMap`](crate::storage::types::CountedStorageMap)
1988 /// * [`StorageDoubleMap`](crate::storage::types::StorageDoubleMap)
1989 /// * [`StorageNMap`](crate::storage::types::StorageNMap)
1990 /// * [`CountedStorageNMap`](crate::storage::types::CountedStorageNMap)
1991 ///
1992 /// ## Storage Type Usage
1993 ///
1994 /// The following details are relevant to all of the aforementioned storage types.
1995 /// Depending on the exact storage type, it may require the following generic parameters:
1996 ///
1997 /// * [`Prefix`](#prefixes) - Used to give the storage item a unique key in the underlying
1998 /// storage.
1999 /// * `Key` - Type of the keys used to store the values,
2000 /// * `Value` - Type of the value being stored,
2001 /// * [`Hasher`](#hashers) - Used to ensure the keys of a map are uniformly distributed,
2002 /// * [`QueryKind`](#querykind) - Used to configure how to handle queries to the underlying
2003 /// storage,
2004 /// * `OnEmpty` - Used to handle missing values when querying the underlying storage,
2005 /// * `MaxValues` - _not currently used_.
2006 ///
2007 /// Each `Key` type requires its own designated `Hasher` declaration, so that
2008 /// [`StorageDoubleMap`](topsoil_core::storage::types::StorageDoubleMap) needs two of
2009 /// each, and [`StorageNMap`](topsoil_core::storage::types::StorageNMap) needs `N` such
2010 /// pairs. Since [`StorageValue`](topsoil_core::storage::types::StorageValue) only stores
2011 /// a single element, no configuration of hashers is needed.
2012 ///
2013 /// ### Syntax
2014 ///
2015 /// Two general syntaxes are supported, as demonstrated below:
2016 ///
2017 /// 1. Named type parameters, e.g., `type Foo<T> = StorageValue<Value = u32>`.
2018 /// 2. Positional type parameters, e.g., `type Foo<T> = StorageValue<_, u32>`.
2019 ///
2020 /// In both instances, declaring the generic parameter `<T>` is mandatory. Optionally, it
2021 /// can also be explicitly declared as `<T: Config>`. In the compiled code, `T` will
2022 /// automatically include the trait bound `Config`.
2023 ///
2024 /// Note that in positional syntax, the first generic type parameter must be `_`.
2025 ///
2026 /// #### Example
2027 ///
2028 /// ```
2029 /// #[topsoil_core::pallet]
2030 /// mod pallet {
2031 /// # use topsoil_core::pallet_prelude::*;
2032 /// # #[pallet::config]
2033 /// # pub trait Config: topsoil_core::system::Config {}
2034 /// # #[pallet::pallet]
2035 /// # pub struct Pallet<T>(_);
2036 /// /// Positional syntax, without bounding `T`.
2037 /// #[pallet::storage]
2038 /// pub type Foo<T> = StorageValue<_, u32>;
2039 ///
2040 /// /// Positional syntax, with bounding `T`.
2041 /// #[pallet::storage]
2042 /// pub type Bar<T: Config> = StorageValue<_, u32>;
2043 ///
2044 /// /// Named syntax.
2045 /// #[pallet::storage]
2046 /// pub type Baz<T> = StorageMap<Hasher = Blake2_128Concat, Key = u32, Value = u32>;
2047 /// }
2048 /// ```
2049 ///
2050 /// ### Value Trait Bounds
2051 ///
2052 /// To use a type as the value of a storage type, be it `StorageValue`, `StorageMap` or
2053 /// anything else, you need to meet a number of trait bound constraints.
2054 ///
2055 /// See: <https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_storage_derives/index.html>.
2056 ///
2057 /// Notably, all value types need to implement `Encode`, `Decode`, `MaxEncodedLen` and
2058 /// `TypeInfo`, and possibly `Default`, if
2059 /// [`ValueQuery`](topsoil_core::storage::types::ValueQuery) is used, explained in the
2060 /// next section.
2061 ///
2062 /// ### QueryKind
2063 ///
2064 /// Every storage type mentioned above has a generic type called
2065 /// [`QueryKind`](topsoil_core::storage::types::QueryKindTrait) that determines its
2066 /// "query" type. This refers to the kind of value returned when querying the storage, for
2067 /// instance, through a `::get()` method.
2068 ///
2069 /// There are three types of queries:
2070 ///
2071 /// 1. [`OptionQuery`](topsoil_core::storage::types::OptionQuery): The default query type.
2072 /// It returns `Some(V)` if the value is present, or `None` if it isn't, where `V` is
2073 /// the value type.
2074 /// 2. [`ValueQuery`](topsoil_core::storage::types::ValueQuery): Returns the value itself
2075 /// if present; otherwise, it returns `Default::default()`. This behavior can be
2076 /// adjusted with the `OnEmpty` generic parameter, which defaults to `OnEmpty =
2077 /// GetDefault`.
2078 /// 3. [`ResultQuery`](topsoil_core::storage::types::ResultQuery): Returns `Result<V, E>`,
2079 /// where `V` is the value type.
2080 ///
2081 /// See [`QueryKind`](topsoil_core::storage::types::QueryKindTrait) for further examples.
2082 ///
2083 /// ### Optimized Appending
2084 ///
2085 /// All storage items — such as
2086 /// [`StorageValue`](topsoil_core::storage::types::StorageValue),
2087 /// [`StorageMap`](topsoil_core::storage::types::StorageMap), and their variants—offer an
2088 /// `::append()` method optimized for collections. Using this method avoids the
2089 /// inefficiency of decoding and re-encoding entire collections when adding items. For
2090 /// instance, consider the storage declaration `type MyVal<T> = StorageValue<_, Vec<u8>,
2091 /// ValueQuery>`. With `MyVal` storing a large list of bytes, `::append()` lets you
2092 /// directly add bytes to the end in storage without processing the full list. Depending on
2093 /// the storage type, additional key specifications may be needed.
2094 ///
2095 /// #### Example
2096 #[doc = docify::embed!("src/lib.rs", example_storage_value_append)]
2097 /// Similarly, there also exists a `::try_append()` method, which can be used when handling
2098 /// types where an append operation might fail, such as a
2099 /// [`BoundedVec`](topsoil_core::BoundedVec).
2100 ///
2101 /// #### Example
2102 #[doc = docify::embed!("src/lib.rs", example_storage_value_try_append)]
2103 /// ### Optimized Length Decoding
2104 ///
2105 /// All storage items — such as
2106 /// [`StorageValue`](topsoil_core::storage::types::StorageValue),
2107 /// [`StorageMap`](topsoil_core::storage::types::StorageMap), and their counterparts —
2108 /// incorporate the `::decode_len()` method. This method allows for efficient retrieval of
2109 /// a collection's length without the necessity of decoding the entire dataset.
2110 /// #### Example
2111 #[doc = docify::embed!("src/lib.rs", example_storage_value_decode_len)]
2112 /// ### Hashers
2113 ///
2114 /// For all storage types, except
2115 /// [`StorageValue`](topsoil_core::storage::types::StorageValue), a set of hashers needs
2116 /// to be specified. The choice of hashers is crucial, especially in production chains. The
2117 /// purpose of storage hashers in maps is to ensure the keys of a map are
2118 /// uniformly distributed. An unbalanced map/trie can lead to inefficient performance.
2119 ///
2120 /// In general, hashers are categorized as either cryptographically secure or not. The
2121 /// former is slower than the latter. `Blake2` and `Twox` serve as examples of each,
2122 /// respectively.
2123 ///
2124 /// As a rule of thumb:
2125 ///
2126 /// 1. If the map keys are not controlled by end users, or are cryptographically secure by
2127 /// definition (e.g., `AccountId`), then the use of cryptographically secure hashers is NOT
2128 /// required.
2129 /// 2. If the map keys are controllable by the end users, cryptographically secure hashers
2130 /// should be used.
2131 ///
2132 /// For more information, look at the types that implement
2133 /// [`topsoil_core::StorageHasher`](topsoil_core::StorageHasher).
2134 ///
2135 /// Lastly, it's recommended for hashers with "concat" to have reversible hashes. Refer to
2136 /// the implementors section of
2137 /// [`hash::ReversibleStorageHasher`](topsoil_core::hash::ReversibleStorageHasher).
2138 ///
2139 /// ### Prefixes
2140 ///
2141 /// Internally, every storage type generates a "prefix". This prefix serves as the initial
2142 /// segment of the key utilized to store values in the on-chain state (i.e., the final key
2143 /// used in [`subsoil::io::storage`](subsoil::io::storage)). For all storage types, the following rule
2144 /// applies:
2145 ///
2146 /// > The storage prefix begins with `twox128(pallet_prefix) ++ twox128(STORAGE_PREFIX)`,
2147 /// > where
2148 /// > `pallet_prefix` is the name assigned to the pallet instance in
2149 /// > [`topsoil_core::construct_runtime`](topsoil_core::construct_runtime), and
2150 /// > `STORAGE_PREFIX` is the name of the `type` aliased to a particular storage type, such
2151 /// > as
2152 /// > `Foo` in `type Foo<T> = StorageValue<..>`.
2153 ///
2154 /// For [`StorageValue`](topsoil_core::storage::types::StorageValue), no additional key is
2155 /// required. For map types, the prefix is extended with one or more keys defined by the
2156 /// map.
2157 ///
2158 /// #### Example
2159 #[doc = docify::embed!("src/lib.rs", example_storage_value_map_prefixes)]
2160 /// ## Related Macros
2161 ///
2162 /// The following attribute macros can be used in conjunction with the `#[storage]` macro:
2163 ///
2164 /// * [`macro@getter`]: Creates a custom getter function.
2165 /// * [`macro@storage_prefix`]: Overrides the default prefix of the storage item.
2166 /// * [`macro@unbounded`]: Declares the storage item as unbounded.
2167 /// * [`macro@disable_try_decode_storage`]: Declares that try-runtime checks should not
2168 /// attempt to decode the storage item.
2169 ///
2170 /// #### Example
2171 /// ```
2172 /// #[topsoil_core::pallet]
2173 /// mod pallet {
2174 /// # use topsoil_core::pallet_prelude::*;
2175 /// # #[pallet::config]
2176 /// # pub trait Config: topsoil_core::system::Config {}
2177 /// # #[pallet::pallet]
2178 /// # pub struct Pallet<T>(_);
2179 /// /// A kitchen-sink StorageValue, with all possible additional attributes.
2180 /// #[pallet::storage]
2181 /// #[pallet::getter(fn foo)]
2182 /// #[pallet::storage_prefix = "OtherFoo"]
2183 /// #[pallet::unbounded]
2184 /// #[pallet::disable_try_decode_storage]
2185 /// pub type Foo<T> = StorageValue<_, u32, ValueQuery>;
2186 /// }
2187 /// ```
2188 ///
2189 /// ## Note on deprecation of storage items
2190 ///
2191 /// - Usage of `deprecated` attribute will propagate deprecation information to the pallet
2192 /// metadata where the storage item was declared.
2193 /// - For general usage examples of `deprecated` attribute please refer to <https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-deprecated-attribute>
2194 /// - Usage of `allow(deprecated)` on the item will propagate this attribute to the
2195 /// generated code.
2196 /// - If the item is annotated with `deprecated` attribute then the generated code will be
2197 /// automatically annotated with `allow(deprecated)`
2198 pub use topsoil_core_procedural::storage;
2199
2200 pub use topsoil_core_procedural::{
2201 authorize, task_condition, task_index, task_list, task_weight, tasks_experimental,
2202 weight_of_authorize,
2203 };
2204
2205 /// Allows a pallet to declare a type as an origin.
2206 ///
2207 /// If defined as such, this type will be amalgamated at the runtime level into
2208 /// `RuntimeOrigin`, very similar to [`call`], [`error`] and [`event`]. See
2209 /// [`composite_enum`] for similar cases.
2210 ///
2211 /// Origin is a complex FRAME topics and is further explained in `polkadot_sdk_docs`.
2212 ///
2213 /// ## Syntax Variants
2214 ///
2215 /// ```
2216 /// #[topsoil_core::pallet]
2217 /// mod pallet {
2218 /// # use topsoil_core::pallet_prelude::*;
2219 /// # #[pallet::config]
2220 /// # pub trait Config: topsoil_core::system::Config {}
2221 /// # #[pallet::pallet]
2222 /// # pub struct Pallet<T>(_);
2223 /// /// On the spot declaration.
2224 /// #[pallet::origin]
2225 /// #[derive(PartialEq, Eq, Clone, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)]
2226 /// pub enum Origin {
2227 /// Foo,
2228 /// Bar,
2229 /// }
2230 /// }
2231 /// ```
2232 ///
2233 /// Or, more commonly used:
2234 ///
2235 /// ```
2236 /// #[topsoil_core::pallet]
2237 /// mod pallet {
2238 /// # use topsoil_core::pallet_prelude::*;
2239 /// # #[pallet::config]
2240 /// # pub trait Config: topsoil_core::system::Config {}
2241 /// # #[pallet::pallet]
2242 /// # pub struct Pallet<T>(_);
2243 /// #[derive(PartialEq, Eq, Clone, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)]
2244 /// pub enum RawOrigin {
2245 /// Foo,
2246 /// Bar,
2247 /// }
2248 ///
2249 /// #[pallet::origin]
2250 /// pub type Origin = RawOrigin;
2251 /// }
2252 /// ```
2253 ///
2254 /// ## Warning
2255 ///
2256 /// Modifying any pallet's origin type will cause the runtime level origin type to also
2257 /// change in encoding. If stored anywhere on-chain, this will require a data migration.
2258 ///
2259 /// Read more about origins at the [Origin Reference
2260 /// Docs](../../polkadot_sdk_docs/reference_docs/frame_origin/index.html).
2261 pub use topsoil_core_procedural::origin;
2262}
2263
2264#[deprecated(
2265 note = "Will be removed after July 2023; Use `subsoil::runtime::traits` directly instead."
2266)]
2267pub mod error {
2268 #[doc(hidden)]
2269 pub use subsoil::runtime::traits::{BadOrigin, LookupError};
2270}
2271
2272#[doc(inline)]
2273pub use topsoil_core_procedural::register_default_impl;
2274
2275// Generate a macro that will enable/disable code based on `std` feature being active.
2276subsoil::generate_feature_enabled_macro!(std_enabled, feature = "std", $);
2277// Generate a macro that will enable/disable code based on `try-runtime` feature being active.
2278subsoil::generate_feature_enabled_macro!(try_runtime_enabled, feature = "try-runtime", $);
2279subsoil::generate_feature_enabled_macro!(try_runtime_or_std_enabled, any(feature = "try-runtime", feature = "std"), $);
2280subsoil::generate_feature_enabled_macro!(try_runtime_and_std_not_enabled, all(not(feature = "try-runtime"), not(feature = "std")), $);
2281
2282/// Helper for implementing GenesisBuilder runtime API
2283pub mod genesis_builder_helper;
2284
2285/// Helper for generating the `RuntimeGenesisConfig` instance for presets.
2286pub mod generate_genesis_config;
2287
2288#[cfg(test)]
2289mod test {
2290 // use super::*;
2291 use crate::{
2292 hash::*,
2293 storage::types::{StorageMap, StorageValue, ValueQuery},
2294 traits::{ConstU32, StorageInstance},
2295 BoundedVec,
2296 };
2297 use subsoil::io::{hashing::twox_128, TestExternalities};
2298
2299 struct Prefix;
2300 impl StorageInstance for Prefix {
2301 fn pallet_prefix() -> &'static str {
2302 "test"
2303 }
2304 const STORAGE_PREFIX: &'static str = "foo";
2305 }
2306
2307 struct Prefix1;
2308 impl StorageInstance for Prefix1 {
2309 fn pallet_prefix() -> &'static str {
2310 "test"
2311 }
2312 const STORAGE_PREFIX: &'static str = "MyVal";
2313 }
2314 struct Prefix2;
2315 impl StorageInstance for Prefix2 {
2316 fn pallet_prefix() -> &'static str {
2317 "test"
2318 }
2319 const STORAGE_PREFIX: &'static str = "MyMap";
2320 }
2321
2322 #[docify::export]
2323 #[test]
2324 pub fn example_storage_value_try_append() {
2325 type MyVal = StorageValue<Prefix, BoundedVec<u8, ConstU32<10>>, ValueQuery>;
2326
2327 TestExternalities::default().execute_with(|| {
2328 MyVal::set(BoundedVec::try_from(vec![42, 43]).unwrap());
2329 assert_eq!(MyVal::get(), vec![42, 43]);
2330 // Try to append a single u32 to BoundedVec stored in `MyVal`
2331 crate::assert_ok!(MyVal::try_append(40));
2332 assert_eq!(MyVal::get(), vec![42, 43, 40]);
2333 });
2334 }
2335
2336 #[docify::export]
2337 #[test]
2338 pub fn example_storage_value_append() {
2339 type MyVal = StorageValue<Prefix, Vec<u8>, ValueQuery>;
2340
2341 TestExternalities::default().execute_with(|| {
2342 MyVal::set(vec![42, 43]);
2343 assert_eq!(MyVal::get(), vec![42, 43]);
2344 // Append a single u32 to Vec stored in `MyVal`
2345 MyVal::append(40);
2346 assert_eq!(MyVal::get(), vec![42, 43, 40]);
2347 });
2348 }
2349
2350 #[docify::export]
2351 #[test]
2352 pub fn example_storage_value_decode_len() {
2353 type MyVal = StorageValue<Prefix, BoundedVec<u8, ConstU32<10>>, ValueQuery>;
2354
2355 TestExternalities::default().execute_with(|| {
2356 MyVal::set(BoundedVec::try_from(vec![42, 43]).unwrap());
2357 assert_eq!(MyVal::decode_len().unwrap(), 2);
2358 });
2359 }
2360
2361 #[docify::export]
2362 #[test]
2363 pub fn example_storage_value_map_prefixes() {
2364 type MyVal = StorageValue<Prefix1, u32, ValueQuery>;
2365 type MyMap = StorageMap<Prefix2, Blake2_128Concat, u16, u32, ValueQuery>;
2366 TestExternalities::default().execute_with(|| {
2367 // This example assumes `pallet_prefix` to be "test"
2368 // Get storage key for `MyVal` StorageValue
2369 assert_eq!(
2370 MyVal::hashed_key().to_vec(),
2371 [twox_128(b"test"), twox_128(b"MyVal")].concat()
2372 );
2373 // Get storage key for `MyMap` StorageMap and `key` = 1
2374 let mut k: Vec<u8> = vec![];
2375 k.extend(&twox_128(b"test"));
2376 k.extend(&twox_128(b"MyMap"));
2377 k.extend(&1u16.blake2_128_concat());
2378 assert_eq!(MyMap::hashed_key_for(1).to_vec(), k);
2379 });
2380 }
2381}