1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. // Substrate is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Substrate is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Substrate. If not, see <http://www.gnu.org/licenses/>. // tag::description[] //! Proc macro of Support code for the runtime. // end::description[] #![recursion_limit="512"] extern crate proc_macro; mod storage; mod construct_runtime; use proc_macro::TokenStream; /// Declares strongly-typed wrappers around codec-compatible types in storage. /// /// ## Example /// /// ```nocompile /// decl_storage! { /// trait Store for Module<T: Trait> as Example { /// Foo get(fn foo) config(): u32=12; /// Bar: map hasher(blake2_256) u32 => u32; /// pub Zed build(|config| vec![(0, 0)]): linked_map hasher(blake2_256) u32 => u32; /// } /// } /// ``` /// /// Declaration is set with the header `(pub) trait Store for Module<T: Trait> as Example`, /// with `Store` a (pub) trait generated associating each storage item to the `Module` and /// `as Example` setting the prefix used for storage items of this module. `Example` must be unique: /// another module with the same name and the same inner storage item name will conflict. /// `Example` is called the module prefix. /// /// note: For instantiable modules the module prefix is prepended with instance /// prefix. Instance prefix is "" for default instance and "Instance$n" for instance number $n. /// Thus, instance 3 of module Example has a module prefix of `Instance3Example` /// /// Basic storage consists of a name and a type; supported types are: /// /// * Value: `Foo: type`: Implements the /// [`StorageValue`](../frame_support/storage/trait.StorageValue.html) trait using the /// [`StorageValue generator`](../frame_support/storage/generator/trait.StorageValue.html). /// /// The generator is implemented with: /// * `module_prefix`: module_prefix /// * `storage_prefix`: storage_name /// /// Thus the storage value is finally stored at: /// ```nocompile /// Twox128(module_prefix) ++ Twox128(storage_prefix) /// ``` /// /// * Map: `Foo: map hasher($hash) type => type`: Implements the /// [`StorageMap`](../frame_support/storage/trait.StorageMap.html) trait using the /// [`StorageMap generator`](../frame_support/storage/generator/trait.StorageMap.html). /// And [`StoragePrefixedMap`](../frame_support/storage/trait.StoragePrefixedMap.html). /// /// `$hash` representing a choice of hashing algorithms available in the /// [`Hashable`](../frame_support/trait.Hashable.html) trait. /// /// `blake2_256` and `blake2_128_concat` are strong hasher. One should use another hasher /// with care, see generator documentation. /// /// The generator is implemented with: /// * `module_prefix`: $module_prefix /// * `storage_prefix`: storage_name /// * `Hasher`: $hash /// /// Thus the keys are stored at: /// ```nocompile /// twox128(module_prefix) ++ twox128(storage_prefix) ++ hasher(encode(key)) /// ``` /// /// * Linked map: `Foo: linked_map hasher($hash) type => type`: Implements the /// [`StorageLinkedMap`](../frame_support/storage/trait.StorageLinkedMap.html) trait using the /// [`StorageLinkedMap generator`](../frame_support/storage/generator/trait.StorageLinkedMap.html). /// And [`StoragePrefixedMap`](../frame_support/storage/trait.StoragePrefixedMap.html). /// /// `$hash` representing a choice of hashing algorithms available in the /// [`Hashable`](../frame_support/trait.Hashable.html) trait. /// /// `blake2_256` and `blake2_128_concat` are strong hasher. One should use another hasher /// with care, see generator documentation. /// /// All key formatting logic can be accessed in a type-agnostic format via the /// `KeyFormat` trait, which /// is implemented for the storage linked map type as well. /// /// The generator key format is implemented with: /// * `module_prefix`: $module_prefix /// * `storage_prefix`: storage_name /// * `head_prefix`: `"HeadOf" ++ storage_name` /// * `Hasher`: $hash /// /// Thus the keys are stored at: /// ```nocompile /// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher(encode(key)) /// ``` /// and head is stored at: /// ```nocompile /// Twox128(module_prefix) ++ Twox128(head_prefix) /// ``` /// /// * Double map: `Foo: double_map hasher($hash1) u32, hasher($hash2) u32 => u32`: Implements the /// [`StorageDoubleMap`](../frame_support/storage/trait.StorageDoubleMap.html) trait using the /// [`StorageDoubleMap generator`](../frame_support/storage/generator/trait.StorageDoubleMap.html). /// And [`StoragePrefixedMap`](../frame_support/storage/trait.StoragePrefixedMap.html). /// /// `$hash1` and `$hash2` representing choices of hashing algorithms available in the /// [`Hashable`](../frame_support/trait.Hashable.html) trait. They must be chosen with care, see /// generator documentation. /// /// If the first key is untrusted, a cryptographic `hasher` such as `blake2_256` or /// `blake2_128_concat` must be used. /// Otherwise, other values of all storage items can be compromised. /// /// If the second key is untrusted, a cryptographic `hasher` such as `blake2_256` or /// `blake2_128_concat` must be used. /// Otherwise, other items in storage with the same first key can be compromised. /// /// The generator is implemented with: /// * `module_prefix`: $module_prefix /// * `storage_prefix`: storage_name /// * `Hasher1`: $hash1 /// * `Hasher2`: $hash2 /// /// Thus keys are stored at: /// ```nocompile /// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher1(encode(key1)) ++ Hasher2(encode(key2)) /// ``` /// /// Supported hashers (ordered from least to best security): /// /// * `twox_64_concat` - TwoX with 64bit + key concatenated. /// * `twox_128` - TwoX with 128bit. /// * `twox_256` - TwoX with with 256bit. /// * `blake2_128_concat` - Blake2 with 128bit + key concatenated. /// * `blake2_128` - Blake2 with 128bit. /// * `blake2_256` - Blake2 with 256bit. /// /// Basic storage can be extended as such: /// /// `#vis #name get(fn #getter) config(#field_name) build(#closure): #type = #default;` /// /// * `#vis`: Set the visibility of the structure. `pub` or nothing. /// * `#name`: Name of the storage item, used as a prefix in storage. /// * [optional] `get(fn #getter)`: Implements the function #getter to `Module`. /// * [optional] `config(#field_name)`: `field_name` is optional if get is set. /// Will include the item in `GenesisConfig`. /// * [optional] `build(#closure)`: Closure called with storage overlays. /// * `#type`: Storage type. /// * [optional] `#default`: Value returned when none. /// /// Storage items are accessible in multiple ways: /// /// * The structure: `Foo` or `Foo::<T>` depending if the value type is generic or not. /// * The `Store` trait structure: `<Module<T> as Store>::Foo` /// * The getter on the module that calls get on the structure: `Module::<T>::foo()` /// /// ## GenesisConfig /// /// An optional `GenesisConfig` struct for storage initialization can be defined, either /// when at least one storage field requires default initialization /// (both `get` and `config` or `build`), or specifically as in: /// /// ```nocompile /// decl_storage! { /// trait Store for Module<T: Trait> as Example { /// /// // Your storage items /// } /// add_extra_genesis { /// config(genesis_field): GenesisFieldType; /// config(genesis_field2): GenesisFieldType; /// ... /// build(|_: &Self| { /// // Modification of storage /// }) /// } /// } /// ``` /// /// This struct can be exposed as `ExampleConfig` by the `construct_runtime!` macro like follows: /// /// ```nocompile /// construct_runtime!( /// pub enum Runtime with ... { /// ..., /// Example: example::{Module, Storage, ..., Config<T>}, /// ..., /// } /// ); /// ``` /// /// ### Module with Instances /// /// The `decl_storage!` macro supports building modules with instances with the following syntax /// (`DefaultInstance` type is optional): /// /// ```nocompile /// trait Store for Module<T: Trait<I>, I: Instance=DefaultInstance> as Example {} /// ``` /// /// Accessing the structure no requires the instance as generic parameter: /// * `Foo::<I>` if the value type is not generic /// * `Foo::<T, I>` if the value type is generic /// /// ## Where clause /// /// This macro supports a where clause which will be replicated to all generated types. /// /// ```nocompile /// trait Store for Module<T: Trait> as Example where T::AccountId: std::fmt::Display {} /// ``` /// /// ## Limitations /// /// # Instancing and generic `GenesisConfig` /// /// If your module supports instancing and you see an error like `parameter `I` is never used` for /// your `decl_storage!`, you are hitting a limitation of the current implementation. You probably /// try to use an associated type of a non-instantiable trait. To solve this, add the following to /// your macro call: /// /// ```nocompile /// add_extra_genesis { /// config(phantom): std::marker::PhantomData<I>, /// } /// ... /// /// This adds a field to your `GenesisConfig` with the name `phantom` that you can initialize with /// `Default::default()`. /// #[proc_macro] pub fn decl_storage(input: TokenStream) -> TokenStream { storage::decl_storage_impl(input) } /// Construct a runtime, with the given name and the given modules. /// /// The parameters here are specific types for `Block`, `NodeBlock`, and `UncheckedExtrinsic` /// and the modules that are used by the runtime. /// `Block` is the block type that is used in the runtime and `NodeBlock` is the block type /// that is used in the node. For instance they can differ in the extrinsics type. /// /// # Example: /// /// ```nocompile /// construct_runtime!( /// pub enum Runtime where /// Block = Block, /// NodeBlock = runtime::Block, /// UncheckedExtrinsic = UncheckedExtrinsic /// { /// System: system::{Module, Call, Event<T>, Config<T>}, /// Test: test::{Module, Call}, /// Test2: test_with_long_module::{Module}, /// /// // Module with instances /// Test3_Instance1: test3::<Instance1>::{Module, Call, Storage, Event<T, I>, Config<T, I>, Origin<T, I>}, /// Test3_DefaultInstance: test3::{Module, Call, Storage, Event<T>, Config<T>, Origin<T>}, /// } /// ) /// ``` /// /// The identifier `System` is the name of the pallet and the lower case identifier `system` is the /// name of the Rust module/crate for this Substrate module. The identifiers between the braces are /// the module parts provided by the pallet. It is important to list these parts here to export /// them correctly in the metadata or to make the pallet usable in the runtime. /// /// We provide support for the following module parts in a pallet: /// /// - `Module` /// - `Call` /// - `Storage` /// - `Event` or `Event<T>` (if the event is generic) /// - `Origin` or `Origin<T>` (if the origin is generic) /// - `Config` or `Config<T>` (if the config is generic) /// - `Inherent ( $(CALL),* )` - If the module provides/can check inherents. The optional parameter /// is for modules that use a `Call` from a different module as /// inherent. /// - `ValidateUnsigned` - If the module validates unsigned extrinsics. /// /// # Note /// /// The population of the genesis storage depends on the order of modules. So, if one of your /// modules depends on another module, the module that is depended upon needs to come before /// the module depending on it. #[proc_macro] pub fn construct_runtime(input: TokenStream) -> TokenStream { construct_runtime::construct_runtime(input) }