mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 16:57:58 +00:00
f910a15c1c
The runtime now can provide a number of predefined presets of `RuntimeGenesisConfig` struct. This presets are intended to be used in different deployments, e.g.: `local`, `staging`, etc, and should be included into the corresponding chain-specs. Having `GenesisConfig` presets in runtime allows to fully decouple node from runtime types (the problem is described in #1984). **Summary of changes:** - The `GenesisBuilder` API was adjusted to enable this functionality (and provide better naming - #150): ```rust fn preset_names() -> Vec<PresetId>; fn get_preset(id: Option<PresetId>) -> Option<serde_json::Value>; //`None` means default fn build_state(value: serde_json::Value); pub struct PresetId(Vec<u8>); ``` - **Breaking change**: Old `create_default_config` method was removed, `build_config` was renamed to `build_state`. As a consequence a node won't be able to interact with genesis config for older runtimes. The cleanup was made for sake of API simplicity. Also IMO maintaining compatibility with old API is not so crucial. - Reference implementation was provided for `substrate-test-runtime` and `rococo` runtimes. For rococo new [`genesis_configs_presets`](https://github.com/paritytech/polkadot-sdk/blob/3b41d66b97c5ff0ec4a1989da5ffd8b9f3f588e3/polkadot/runtime/rococo/src/genesis_config_presets.rs#L530) module was added and is used in `GenesisBuilder` [_presets-related_](https://github.com/paritytech/polkadot-sdk/blob/3b41d66b97c5ff0ec4a1989da5ffd8b9f3f588e3/polkadot/runtime/rococo/src/lib.rs#L2462-L2485) methods. - The `chain-spec-builder` util was also improved and allows to ([_doc_](https://github.com/paritytech/polkadot-sdk/blob/3b41d66b97c5ff0ec4a1989da5ffd8b9f3f588e3/substrate/bin/utils/chain-spec-builder/src/lib.rs#L19)): - list presets provided by given runtime (`list-presets`), - display preset or default config provided by the runtime (`display-preset`), - build chain-spec using named preset (`create ... named-preset`), - The `ChainSpecBuilder` is extended with [`with_genesis_config_preset_name`](https://github.com/paritytech/polkadot-sdk/blob/3b41d66b97c5ff0ec4a1989da5ffd8b9f3f588e3/substrate/client/chain-spec/src/chain_spec.rs#L447) method which allows to build chain-spec using named preset provided by the runtime. Sample usage on the node side [here](https://github.com/paritytech/polkadot-sdk/blob/2caffaae803e08a3d5b46c860e8016da023ff4ce/polkadot/node/service/src/chain_spec.rs#L404). Implementation of #1984. fixes: #150 part of: #25 --------- Co-authored-by: Sebastian Kunert <skunert49@gmail.com> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
117 lines
4.4 KiB
Rust
117 lines
4.4 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
|
|
// This program 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.
|
|
|
|
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
use chain_spec_builder::{
|
|
generate_chain_spec_for_runtime, ChainSpecBuilder, ChainSpecBuilderCmd, ConvertToRawCmd,
|
|
DisplayPresetCmd, ListPresetsCmd, UpdateCodeCmd, VerifyCmd,
|
|
};
|
|
use clap::Parser;
|
|
use sc_chain_spec::{
|
|
update_code_in_json_chain_spec, GenericChainSpec, GenesisConfigBuilderRuntimeCaller,
|
|
};
|
|
use staging_chain_spec_builder as chain_spec_builder;
|
|
use std::fs;
|
|
|
|
//avoid error message escaping
|
|
fn main() {
|
|
match inner_main() {
|
|
Err(e) => eprintln!("{}", format!("{e}")),
|
|
_ => {},
|
|
}
|
|
}
|
|
|
|
fn inner_main() -> Result<(), String> {
|
|
sp_tracing::try_init_simple();
|
|
|
|
let builder = ChainSpecBuilder::parse();
|
|
let chain_spec_path = builder.chain_spec_path.to_path_buf();
|
|
|
|
match builder.command {
|
|
ChainSpecBuilderCmd::Create(cmd) => {
|
|
let chain_spec_json = generate_chain_spec_for_runtime(&cmd)?;
|
|
fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?;
|
|
},
|
|
ChainSpecBuilderCmd::UpdateCode(UpdateCodeCmd {
|
|
ref input_chain_spec,
|
|
ref runtime_wasm_path,
|
|
}) => {
|
|
let chain_spec = GenericChainSpec::<()>::from_json_file(input_chain_spec.clone())?;
|
|
|
|
let mut chain_spec_json =
|
|
serde_json::from_str::<serde_json::Value>(&chain_spec.as_json(false)?)
|
|
.map_err(|e| format!("Conversion to json failed: {e}"))?;
|
|
update_code_in_json_chain_spec(
|
|
&mut chain_spec_json,
|
|
&fs::read(runtime_wasm_path.as_path())
|
|
.map_err(|e| format!("Wasm blob file could not be read: {e}"))?[..],
|
|
);
|
|
|
|
let chain_spec_json = serde_json::to_string_pretty(&chain_spec_json)
|
|
.map_err(|e| format!("to pretty failed: {e}"))?;
|
|
fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?;
|
|
},
|
|
ChainSpecBuilderCmd::ConvertToRaw(ConvertToRawCmd { ref input_chain_spec }) => {
|
|
let chain_spec = GenericChainSpec::<()>::from_json_file(input_chain_spec.clone())?;
|
|
|
|
let chain_spec_json =
|
|
serde_json::from_str::<serde_json::Value>(&chain_spec.as_json(true)?)
|
|
.map_err(|e| format!("Conversion to json failed: {e}"))?;
|
|
|
|
let chain_spec_json = serde_json::to_string_pretty(&chain_spec_json)
|
|
.map_err(|e| format!("Conversion to pretty failed: {e}"))?;
|
|
fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?;
|
|
},
|
|
ChainSpecBuilderCmd::Verify(VerifyCmd { ref input_chain_spec }) => {
|
|
let chain_spec = GenericChainSpec::<()>::from_json_file(input_chain_spec.clone())?;
|
|
let _ = serde_json::from_str::<serde_json::Value>(&chain_spec.as_json(true)?)
|
|
.map_err(|e| format!("Conversion to json failed: {e}"))?;
|
|
},
|
|
ChainSpecBuilderCmd::ListPresets(ListPresetsCmd { runtime_wasm_path }) => {
|
|
let code = fs::read(runtime_wasm_path.as_path())
|
|
.map_err(|e| format!("wasm blob shall be readable {e}"))?;
|
|
let caller: GenesisConfigBuilderRuntimeCaller =
|
|
GenesisConfigBuilderRuntimeCaller::new(&code[..]);
|
|
let presets = caller
|
|
.preset_names()
|
|
.map_err(|e| format!("getting default config from runtime should work: {e}"))?;
|
|
let presets: Vec<String> = presets
|
|
.into_iter()
|
|
.map(|preset| {
|
|
String::from(
|
|
TryInto::<&str>::try_into(&preset)
|
|
.unwrap_or_else(|_| "cannot display preset id")
|
|
.to_string(),
|
|
)
|
|
})
|
|
.collect();
|
|
println!("{presets:#?}");
|
|
},
|
|
ChainSpecBuilderCmd::DisplayPreset(DisplayPresetCmd { runtime_wasm_path, preset_name }) => {
|
|
let code = fs::read(runtime_wasm_path.as_path())
|
|
.map_err(|e| format!("wasm blob shall be readable {e}"))?;
|
|
let caller: GenesisConfigBuilderRuntimeCaller =
|
|
GenesisConfigBuilderRuntimeCaller::new(&code[..]);
|
|
let preset = caller
|
|
.get_named_preset(preset_name.as_ref())
|
|
.map_err(|e| format!("getting default config from runtime should work: {e}"))?;
|
|
println!("{preset}");
|
|
},
|
|
};
|
|
Ok(())
|
|
}
|