referrerpolicy=no-referrer-when-downgrade

polkadot_sdk_docs/reference_docs/
chain_spec_genesis.rs

1//! # What is a chain specification
2//!
3//! A chain specification file defines the set of properties that are required to run the node as
4//! part of the chain. The chain specification consists of two main parts:
5//! - initial state of the runtime,
6//! - network / logical properties of the chain, the most important property being the list of
7//!   bootnodes.
8//!
9//! This document describes how the initial state is handled in pallets and runtime, and how to
10//! interact with the runtime in order to build the genesis state.
11//!
12//! For more information on chain specification and its properties, refer to
13//! [`sc_chain_spec#from-initial-state-to-raw-genesis`].
14//!
15//! The initial genesis state can be provided in the following formats:
16//!   - full
17//!   - patch
18//!   - raw
19//!
20//! Each of the formats is explained in [_chain-spec-format_][`sc_chain_spec#chain-spec-formats`].
21//!
22//!
23//! # `GenesisConfig` for `pallet`
24//!
25//! Every frame pallet may have its initial state which is defined by the `GenesisConfig` internal
26//! struct. It is a regular Rust struct, annotated with the [`pallet::genesis_config`] attribute.
27#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pallet_bar_GenesisConfig)]
28//!
29//! The struct shall be defined within the pallet `mod`, as in the following code:
30#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pallet_bar)]
31//!
32//! The initial state conveyed in  the `GenesisConfig` struct is transformed into state storage
33//! items by means of the [`BuildGenesisConfig`] trait, which shall be implemented for the pallet's
34//! `GenesisConfig` struct. The [`pallet::genesis_build`] attribute shall be attached to the `impl`
35//! block:
36#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pallet_bar_build)]
37//!
38//! `GenesisConfig` may also contain more complicated types, including nested structs or enums, as
39//! in the example for `pallet_foo`:
40#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pallet_foo_GenesisConfig)]
41//!
42//! Note that [`serde`] attributes can be used to control how the data
43//! structures are stored into JSON. In the following example, the [`sp_core::bytes`] function is
44//! used to serialize the `values` field.
45#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", SomeFooData2)]
46//!
47//! Please note that fields of `GenesisConfig` may not be directly mapped to storage items. In the
48//! following example, the initial struct fields are used to compute (sum) the value that will be
49//! stored in the state as `ProcessedEnumValue`:
50#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pallet_foo_build)]
51//!
52//! # `GenesisConfig` for `runtimes`
53//!
54//! The runtime genesis config struct consists of configs for every pallet. For the [_demonstration
55//! runtime_][`chain_spec_guide_runtime`] used in this guide, it consists of `SystemConfig`,
56//! `BarConfig`, and `FooConfig`. This structure was automatically generated by a macro and it can
57//! be sneak-peeked here: [`RuntimeGenesisConfig`]. For further reading on generated runtime
58//! types, refer to [`frame_runtime_types`].
59//!
60//! The macro automatically adds an attribute that renames all the fields to [`camelCase`]. It is a
61//! good practice to add it to nested structures too, to have the naming of the JSON keys consistent
62//! across the chain-spec file.
63//!
64//! ## `Default` for `GenesisConfig`
65//!
66//! `GenesisConfig` of all pallets must implement the `Default` trait. These are aggregated into
67//! the runtime's `RuntimeGenesisConfig`'s `Default`.
68//!
69//! The default value of `RuntimeGenesisConfig` can be queried by the [`GenesisBuilder::get_preset`]
70//! function provided by the runtime with `id:None`.
71//!
72//! A default value for `RuntimeGenesisConfig` usually is not operational. This is because for some
73//! pallets it is not possible to define good defaults (e.g. an initial set of authorities).
74//!
75//! A default value is a base upon which a patch for `GenesisConfig` is applied. A good description
76//! of how it exactly works is provided in [`get_storage_for_patch`] (and also in
77//! [`GenesisBuilder::get_preset`]). A patch can be provided as an external file (manually created)
78//! or as a built-in runtime preset. More info on presets is in the material to follow.
79//!
80//! ## Implementing `GenesisBuilder` for runtime
81//!
82//! The runtime exposes a dedicated runtime API for interacting with its genesis config:
83//! [`sp_genesis_builder::GenesisBuilder`]. The implementation shall be provided within
84//! the [`sp_api::impl_runtime_apis`] macro, typically making use of some helpers provided:
85//! [`build_state`], [`get_preset`].
86//! A typical implementation of [`sp_genesis_builder::GenesisBuilder`] looks as follows:
87#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/runtime.rs", runtime_impl)]
88//!
89//! Please note that two functions are customized: `preset_names` and `get_preset`. The first one
90//! just provides a `Vec` of the names of supported presets, while the latter delegates the call
91//! to a function that maps the name to an actual preset:
92//! [`chain_spec_guide_runtime::presets::get_builtin_preset`]
93#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/presets.rs", get_builtin_preset)]
94//!
95//! ## Genesis state presets for runtime
96//!
97//! The runtime may provide many flavors of initial genesis state. This may be useful for predefined
98//! testing networks, local development, or CI integration tests. Predefined genesis state may
99//! contain a list of pre-funded accounts, predefined authorities for consensus, sudo key, and many
100//! others useful for testing.
101//!
102//! Internally, presets can be provided in a number of ways:
103//! - using [`build_struct_json_patch`] macro (**recommended**):
104#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/presets.rs", preset_2)]
105//! - JSON using runtime types to serialize values:
106#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/presets.rs", preset_3)]
107//! - JSON in string form:
108#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/presets.rs", preset_1)]
109//!
110//! It is worth noting that a preset does not have to be the full `RuntimeGenesisConfig`, in that
111//! sense that it does not have to contain all the keys of the struct. The preset is actually a JSON
112//! patch that will be merged with the default value of `RuntimeGenesisConfig`. This approach should
113//! simplify maintenance of built-in presets. The following example illustrates a runtime genesis
114//! config patch with a single key built using [`build_struct_json_patch`] macro:
115#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/presets.rs", preset_4)]
116//! This results in the following JSON blob:
117#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", preset_4_json)]
118//!
119//!
120//! ## Note on the importance of testing presets
121//!
122//! It is recommended to always test presets by adding tests that convert the preset into the
123//! raw storage. Converting to raw storage involves the deserialization of the provided JSON blob,
124//! which enforces the verification of the preset. The following code shows one of the approaches
125//! that can be taken for testing:
126#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/presets.rs", check_presets)]
127//!
128//! ## Note on the importance of using the `deny_unknown_fields` attribute
129//!
130//! It is worth noting that when manually building preset JSON blobs it is easy to make a
131//! hard-to-spot mistake, as in the following example ([`FooStruct`] does not contain `fieldC`):
132#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/presets.rs", preset_invalid)]
133//! Even though `preset_invalid` contains a key that does not exist, the deserialization of the JSON
134//! blob does not fail. The misspelling is silently ignored due to the lack of the
135//! [`deny_unknown_fields`] attribute on the [`FooStruct`] struct, which is internally used in
136//! `GenesisConfig`.
137#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/presets.rs", invalid_preset_works)]
138//!
139//! To avoid this problem [`build_struct_json_patch`] macro shall be used whenever possible (it
140//! internally instantiates the struct before serializang it JSON blob, so all unknown fields shall
141//! be caught at compilation time).
142//!
143//! ## Runtime `GenesisConfig` raw format
144//!
145//! A raw format of genesis config contains just the state's keys and values as they are stored in
146//! the storage. This format is used to directly initialize the genesis storage. This format is
147//! useful for long-term running chains, where the `GenesisConfig` structure for pallets may be
148//! evolving over time. The JSON representation created at some point in time may no longer be
149//! deserializable in the future, making a chain specification useless. The raw format is
150//! recommended for production chains.
151//!
152//! For a detailed description of how the raw format is built, please refer to
153//! [_chain-spec-raw-genesis_][`sc_chain_spec#from-initial-state-to-raw-genesis`]. Plain and
154//! corresponding raw examples of chain-spec are given in
155//! [_chain-spec-examples_][`sc_chain_spec#json-chain-specification-example`].
156//! The [`chain_spec_builder`] util supports building the raw storage.
157//!
158//! # Interacting with the tool
159//!
160//! The [`chain_spec_builder`] util allows interaction with the runtime in order to list or display
161//! presets and build the chain specification file. It is possible to use the tool with the
162//! [_demonstration runtime_][`chain_spec_guide_runtime`]. To build the required packages, just run
163//! the following command:
164//!
165//! ```ignore
166//! cargo build -p staging-chain-spec-builder -p chain-spec-guide-runtime --release
167//! ```
168//!
169//! The `chain-spec-builder` util can also be installed with `cargo install`:
170//!
171//! ```ignore
172//! cargo install staging-chain-spec-builder
173//! cargo build -p chain-spec-guide-runtime --release
174//! ```
175//! Here are some examples in the form of rust tests:
176//! ## Listing available preset names:
177#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", cmd_list_presets)]
178//! ## Displaying preset with given name
179#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", cmd_get_preset)]
180//! ## Building a solo chain-spec (the default) using given preset
181#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", cmd_generate_chain_spec)]
182//! ## Building a parachain chain-spec using given preset
183#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", cmd_generate_para_chain_spec)]
184//!
185//! [`RuntimeGenesisConfig`]:
186//!     chain_spec_guide_runtime::runtime::RuntimeGenesisConfig
187//! [`FooStruct`]:
188//!     chain_spec_guide_runtime::pallets::FooStruct
189//! [`impl_runtime_apis`]: frame::runtime::prelude::impl_runtime_apis
190//! [`build_state`]: frame_support::genesis_builder_helper::build_state
191//! [`get_preset`]: frame_support::genesis_builder_helper::get_preset
192//! [`pallet::genesis_build`]: frame_support::pallet_macros::genesis_build
193//! [`pallet::genesis_config`]: frame_support::pallet_macros::genesis_config
194//! [`build_struct_json_patch`]: frame_support::build_struct_json_patch
195//! [`BuildGenesisConfig`]: frame_support::traits::BuildGenesisConfig
196//! [`serde`]: https://serde.rs/field-attrs.html
197//! [`get_storage_for_patch`]: sc_chain_spec::GenesisConfigBuilderRuntimeCaller::get_storage_for_patch
198//! [`GenesisBuilder::get_preset`]: sp_genesis_builder::GenesisBuilder::get_preset
199//! [`deny_unknown_fields`]: https://serde.rs/container-attrs.html#deny_unknown_fields
200//! [`camelCase`]: https://serde.rs/container-attrs.html#rename_all