From 89d76af0e88a27606a8a47a19784d51fffc9b980 Mon Sep 17 00:00:00 2001 From: Iulian Barbu <14218860+iulianbarbu@users.noreply.github.com> Date: Fri, 22 Aug 2025 15:59:14 +0300 Subject: [PATCH] BACKPORT-CONFLICT --- cumulus/polkadot-omni-node/README.md | 76 +++++++ .../lib/src/common/chain_spec.rs | 102 +++++++++ .../polkadot-parachain-lib/src/cli.rs | 2 +- .../polkadot-parachain-lib/src/common/spec.rs | 63 ++++++ .../src/chain_spec/asset_hubs.rs | 28 ++- .../src/chain_spec/bridge_hubs.rs | 28 ++- .../src/chain_spec/collectives.rs | 8 + .../src/chain_spec/coretime.rs | 19 ++ .../src/chain_spec/glutton.rs | 13 ++ .../src/chain_spec/penpal.rs | 4 + .../src/chain_spec/people.rs | 67 +++++- .../src/chain_spec/rococo_parachain.rs | 8 + .../src/chain_spec/yet_another_parachain.rs | 105 +++++++++ prdoc/pr_9201.prdoc | 16 ++ .../utils/chain-spec-builder/README.docify.md | 168 +++++++++++++++ .../bin/utils/chain-spec-builder/README.md | 202 ++++++++++++++++++ .../bin/utils/chain-spec-builder/src/lib.rs | 117 ++++++++++ 17 files changed, 1013 insertions(+), 13 deletions(-) create mode 100644 cumulus/polkadot-omni-node/README.md create mode 100644 cumulus/polkadot-omni-node/lib/src/common/chain_spec.rs create mode 100644 cumulus/polkadot-parachain/src/chain_spec/yet_another_parachain.rs create mode 100644 prdoc/pr_9201.prdoc create mode 100644 substrate/bin/utils/chain-spec-builder/README.docify.md diff --git a/cumulus/polkadot-omni-node/README.md b/cumulus/polkadot-omni-node/README.md new file mode 100644 index 0000000000000..9031ec375dee3 --- /dev/null +++ b/cumulus/polkadot-omni-node/README.md @@ -0,0 +1,76 @@ +# Polkadot Omni Node + +This is a white labeled implementation based on [`polkadot-omni-node-lib`](https://crates.io/crates/polkadot-omni-node-lib). +It can be used to start a parachain node from a provided chain spec file. It is only compatible with runtimes that use block +number `u32` and `Aura` consensus. + +## Installation + +Download & expose it via `PATH`: + +```bash +# Download and set it on PATH. +wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-omni-node +chmod +x polkadot-omni-node +export PATH="$PATH:`pwd`" +``` + +Compile & install via `cargo`: + +```bash +# Assuming ~/.cargo/bin is on the PATH +cargo install polkadot-omni-node --locked +``` + +## Usage + +A basic example for an Omni Node run starts from a runtime which implements the [`sp_genesis_builder::GenesisBuilder`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html). +The interface mandates the runtime to expose a [`named-preset`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/#generate-chain-spec-using-runtime-provided-genesis-config-preset). + +### 1. Install chain-spec-builder + +**Note**: `chain-spec-builder` binary is published on [`crates.io`](https://crates.io) under +[`staging-chain-spec-builder`](https://crates.io/crates/staging-chain-spec-builder) due to a name conflict. +Install it with `cargo` like bellow : + +```bash +cargo install staging-chain-spec-builder --locked +``` + +### 2. Generate a chain spec + +Omni Node requires the chain spec to include a JSON key named `relay_chain`. It is set to a chain id, +representing the chain name, e.g. `westend`, `paseo`, `rococo`, `polkadot`, or `kusama`, but +there are also local variants that can be used for testing, like `rococo-local` or `westend-local`. The +local variants are available only for a build of `polkadot-omni-node` with +`westend-native` and `rococo-native` features respectively. + + +Additionaly, the `--para-id` flag can be used to set the JSON key named `para_id`. This flag is used +by nodes to determine the parachain id, and it is especially useful when the parachain id can not be +fetched from the runtime, when the state points to a runtime that does not implement the +`cumulus_primitives_core::GetParachainInfo` runtime API. It is recommended for runtimes to implement +the runtime API and be upgraded on chain. + +Example command bellow: + +```bash +chain-spec-builder create --relay-chain --para-id -r named-preset +``` + +### 3. Run Omni Node + +And now with the generated chain spec we can start the node in development mode like so: + +```bash +polkadot-omni-node --dev --chain +``` + +## Useful links + +* [`Omni Node Polkadot SDK Docs`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/omni_node/index.html) +* [`Chain Spec Genesis Reference Docs`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/chain_spec_genesis/index.html) +* [`polkadot-parachain-bin`](https://crates.io/crates/polkadot-parachain-bin) +* [`polkadot-sdk-parachain-template`](https://github.com/paritytech/polkadot-sdk-parachain-template) +* [`frame-omni-bencher`](https://crates.io/crates/frame-omni-bencher) +* [`staging-chain-spec-builder`](https://crates.io/crates/staging-chain-spec-builder) diff --git a/cumulus/polkadot-omni-node/lib/src/common/chain_spec.rs b/cumulus/polkadot-omni-node/lib/src/common/chain_spec.rs new file mode 100644 index 0000000000000..2a55d75785238 --- /dev/null +++ b/cumulus/polkadot-omni-node/lib/src/common/chain_spec.rs @@ -0,0 +1,102 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Chain spec primitives. + +pub use sc_chain_spec::ChainSpec; +use sc_chain_spec::ChainSpecExtension; +use serde::{Deserialize, Serialize}; +use std::fmt::Debug; + +/// Helper trait used for loading/building a chain spec starting from the chain ID. +pub trait LoadSpec { + /// Load/Build a chain spec starting from the chain ID. + fn load_spec(&self, id: &str) -> Result, String>; +} + +/// Default implementation for `LoadSpec` that just reads a chain spec from the disk. +pub struct DiskChainSpecLoader; + +impl LoadSpec for DiskChainSpecLoader { + fn load_spec(&self, path: &str) -> Result, String> { + Ok(Box::new(GenericChainSpec::from_json_file(path.into())?)) + } +} + +/// Generic extensions for Parachain ChainSpecs used for extracting the extensions from chain specs. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecExtension)] +pub struct Extensions { + /// The relay chain of the Parachain. It is kept here only for compatibility reasons until + /// people migrate to using the new `Extensions` struct and associated logic in the node + /// corresponding to pulling the parachain id from the runtime. + #[serde(alias = "relayChain", alias = "RelayChain")] + relay_chain: String, + /// The id of the Parachain. + #[serde(alias = "paraId", alias = "ParaId")] + para_id: Option, +} + +impl Extensions { + /// Try to get the extension from the given `ChainSpec`. + pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> { + sc_chain_spec::get_extension(chain_spec.extensions()) + } + + /// Create the extensions only with the relay_chain. + pub fn new_with_relay_chain(relay_chain: String) -> Self { + Extensions { relay_chain, para_id: None } + } + + /// Initialize extensions based on given parameters. + pub fn new(relay_chain: String, para_id: u32) -> Self { + Extensions { relay_chain, para_id: Some(para_id) } + } + + /// Para id field getter + pub fn para_id(&self) -> Option { + self.para_id + } + + /// Relay chain field getter + pub fn relay_chain(&self) -> String { + self.relay_chain.clone() + } +} + +/// Generic chain spec for all polkadot-parachain runtimes +pub type GenericChainSpec = sc_service::GenericChainSpec; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_decode_extension_camel_and_snake_case() { + let camel_case = r#"{"relayChain":"relay","paraId":1}"#; + let snake_case = r#"{"relay_chain":"relay","para_id":1}"#; + let pascal_case = r#"{"RelayChain":"relay","ParaId":1}"#; + let para_id_missing = r#"{"RelayChain":"westend"}"#; + + let camel_case_extension: Extensions = serde_json::from_str(camel_case).unwrap(); + let snake_case_extension: Extensions = serde_json::from_str(snake_case).unwrap(); + let pascal_case_extension: Extensions = serde_json::from_str(pascal_case).unwrap(); + let missing_paraid_extension: Extensions = serde_json::from_str(para_id_missing).unwrap(); + assert_eq!(camel_case_extension, snake_case_extension); + assert_eq!(snake_case_extension, pascal_case_extension); + assert_eq!(missing_paraid_extension.relay_chain, "westend".to_string()); + assert!(missing_paraid_extension.para_id.is_none()); + } +} diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/cli.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/cli.rs index 349dc01d8a4f2..fd1d073fb0d90 100644 --- a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/cli.rs +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/cli.rs @@ -230,7 +230,7 @@ impl RelayChainCli { let base = FromArgMatches::from_arg_matches(&matches).unwrap_or_else(|e| e.exit()); let extension = Extensions::try_get(&*para_config.chain_spec); - let chain_id = extension.map(|e| e.relay_chain.clone()); + let chain_id = extension.map(|e| e.relay_chain()); let base_path = para_config.base_path.path().join("polkadot"); Self { base, chain_id, base_path: Some(base_path), _phantom: Default::default() } diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs index 0c0230296eb8f..835510a349070 100644 --- a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs @@ -6,6 +6,7 @@ // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. +<<<<<<< HEAD:cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs // Cumulus 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 @@ -20,6 +21,19 @@ use crate::common::{ types::{ ParachainBackend, ParachainBlockImport, ParachainClient, ParachainHostFunctions, ParachainService, +======= +use crate::{ + chain_spec::Extensions, + common::{ + command::NodeCommandRunner, + rpc::BuildRpcExtensions, + statement_store::{build_statement_store, new_statement_handler_proto}, + types::{ + ParachainBackend, ParachainBlockImport, ParachainClient, ParachainHostFunctions, + ParachainService, + }, + ConstructNodeRuntimeApi, NodeBlock, NodeExtraArgs, +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)):cumulus/polkadot-omni-node/lib/src/common/spec.rs }, ConstructNodeRuntimeApi, NodeBlock, NodeExtraArgs, }; @@ -39,7 +53,14 @@ use sc_network::{config::FullNetworkConfiguration, NetworkBackend, NetworkBlock} use sc_service::{Configuration, ImportQueue, PartialComponents, TaskManager}; use sc_sysinfo::HwBench; use sc_telemetry::{TelemetryHandle, TelemetryWorker}; +<<<<<<< HEAD:cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs use sc_transaction_pool::FullPool; +======= +use sc_tracing::tracing::Instrument; +use sc_transaction_pool::TransactionPoolHandle; +use sc_transaction_pool_api::OffchainTransactionPoolFactory; +use sp_api::{ApiExt, ProvideRuntimeApi}; +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)):cumulus/polkadot-omni-node/lib/src/common/spec.rs use sp_keystore::KeystorePtr; use std::{future::Future, pin::Pin, sync::Arc, time::Duration}; @@ -109,7 +130,49 @@ pub(crate) trait NodeSpec { type StartConsensus: StartConsensus; +<<<<<<< HEAD:cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs const SYBIL_RESISTANCE: CollatorSybilResistance; +======= + /// Retrieves parachain id. + fn parachain_id( + client: &ParachainClient, + parachain_config: &Configuration, + ) -> Option { + let best_hash = client.chain_info().best_hash; + let para_id = if client + .runtime_api() + .has_api::>(best_hash) + .ok() + .filter(|has_api| *has_api) + .is_some() + { + client + .runtime_api() + .parachain_id(best_hash) + .inspect_err(|err| { + log::error!( + "`cumulus_primitives_core::GetParachainInfo` runtime API call errored with {}", + err + ); + }) + .ok()? + } else { + ParaId::from( + Extensions::try_get(&*parachain_config.chain_spec).and_then(|ext| ext.para_id())?, + ) + }; + + let parachain_account = + AccountIdConversion::::into_account_truncating( + ¶_id, + ); + + info!("🪪 Parachain id: {:?}", para_id); + info!("🧾 Parachain Account: {}", parachain_account); + + Some(para_id) + } +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)):cumulus/polkadot-omni-node/lib/src/common/spec.rs /// Starts a `ServiceBuilder` for a full service. /// diff --git a/cumulus/polkadot-parachain/src/chain_spec/asset_hubs.rs b/cumulus/polkadot-parachain/src/chain_spec/asset_hubs.rs index 699c0b5ce775d..e0ff0e073c24a 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/asset_hubs.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/asset_hubs.rs @@ -25,7 +25,11 @@ pub fn asset_hub_westend_development_config() -> GenericChainSpec { GenericChainSpec::builder( asset_hub_westend_runtime::WASM_BINARY .expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: "westend".into(), para_id: 1000 }, +======= + Extensions::new_with_relay_chain("westend".into()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name("Westend Asset Hub Development") .with_id("asset-hub-westend-dev") @@ -43,7 +47,11 @@ pub fn asset_hub_westend_local_config() -> GenericChainSpec { GenericChainSpec::builder( asset_hub_westend_runtime::WASM_BINARY .expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: "westend-local".into(), para_id: 1000 }, +======= + Extensions::new_with_relay_chain("westend-local".into()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name("Westend Asset Hub Local") .with_id("asset-hub-westend-local") @@ -61,7 +69,11 @@ pub fn asset_hub_westend_config() -> GenericChainSpec { GenericChainSpec::builder( asset_hub_westend_runtime::WASM_BINARY .expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: "westend".into(), para_id: 1000 }, +======= + Extensions::new_with_relay_chain("westend".into()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name("Westend Asset Hub") .with_id("asset-hub-westend") @@ -80,7 +92,6 @@ pub fn asset_hub_rococo_development_config() -> GenericChainSpec { properties, "Rococo Asset Hub Development", "asset-hub-rococo-dev", - 1000, ) } @@ -88,11 +99,14 @@ fn asset_hub_rococo_like_development_config( properties: sc_chain_spec::Properties, name: &str, chain_id: &str, - para_id: u32, ) -> GenericChainSpec { GenericChainSpec::builder( asset_hub_rococo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: "rococo-dev".into(), para_id }, +======= + Extensions::new_with_relay_chain("rococo-dev".into()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name(name) .with_id(chain_id) @@ -111,7 +125,6 @@ pub fn asset_hub_rococo_local_config() -> GenericChainSpec { properties, "Rococo Asset Hub Local", "asset-hub-rococo-local", - 1000, ) } @@ -119,11 +132,14 @@ fn asset_hub_rococo_like_local_config( properties: sc_chain_spec::Properties, name: &str, chain_id: &str, - para_id: u32, ) -> GenericChainSpec { GenericChainSpec::builder( asset_hub_rococo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: "rococo-local".into(), para_id }, +======= + Extensions::new_with_relay_chain("rococo-local".into()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name(name) .with_id(chain_id) @@ -140,7 +156,11 @@ pub fn asset_hub_rococo_genesis_config() -> GenericChainSpec { let para_id = 1000; GenericChainSpec::builder( asset_hub_rococo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: "rococo".into(), para_id }, +======= + Extensions::new_with_relay_chain("rococo".into()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name("Rococo Asset Hub") .with_id("asset-hub-rococo") diff --git a/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs b/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs index af399be9eacf1..b96a4cf541714 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs @@ -14,8 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . +<<<<<<< HEAD use cumulus_primitives_core::ParaId; use polkadot_parachain_lib::chain_spec::GenericChainSpec; +======= +use polkadot_omni_node_lib::chain_spec::GenericChainSpec; +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) use sc_chain_spec::{ChainSpec, ChainType}; use std::str::FromStr; @@ -77,14 +81,12 @@ impl BridgeHubRuntimeType { westend::BRIDGE_HUB_WESTEND_LOCAL, "Westend BridgeHub Local", "westend-local", - ParaId::new(1002), ChainType::Local, ))), BridgeHubRuntimeType::WestendDevelopment => Ok(Box::new(westend::local_config( westend::BRIDGE_HUB_WESTEND_DEVELOPMENT, "Westend BridgeHub Development", "westend-dev", - ParaId::new(1002), ChainType::Development, ))), BridgeHubRuntimeType::Rococo => Ok(Box::new(GenericChainSpec::from_json_bytes( @@ -94,7 +96,6 @@ impl BridgeHubRuntimeType { rococo::BRIDGE_HUB_ROCOCO_LOCAL, "Rococo BridgeHub Local", "rococo-local", - ParaId::new(1013), |_| (), ChainType::Local, ))), @@ -102,7 +103,6 @@ impl BridgeHubRuntimeType { rococo::BRIDGE_HUB_ROCOCO_DEVELOPMENT, "Rococo BridgeHub Development", "rococo-dev", - ParaId::new(1013), |_| (), ChainType::Development, ))), @@ -126,8 +126,13 @@ fn ensure_id(id: &str) -> Result<&str, String> { /// Sub-module for Rococo setup pub mod rococo { +<<<<<<< HEAD use super::{ChainType, ParaId}; use polkadot_parachain_lib::chain_spec::{Extensions, GenericChainSpec}; +======= + use super::ChainType; + use polkadot_omni_node_lib::chain_spec::{Extensions, GenericChainSpec}; +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) pub(crate) const BRIDGE_HUB_ROCOCO: &str = "bridge-hub-rococo"; pub(crate) const BRIDGE_HUB_ROCOCO_LOCAL: &str = "bridge-hub-rococo-local"; @@ -137,7 +142,6 @@ pub mod rococo { id: &str, chain_name: &str, relay_chain: &str, - para_id: ParaId, modify_props: ModifyProperties, chain_type: ChainType, ) -> GenericChainSpec { @@ -151,7 +155,11 @@ pub mod rococo { GenericChainSpec::builder( bridge_hub_rococo_runtime::WASM_BINARY .expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() }, +======= + Extensions::new_with_relay_chain(relay_chain.to_string()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name(chain_name) .with_id(super::ensure_id(id).expect("invalid id")) @@ -174,8 +182,13 @@ pub mod kusama { /// Sub-module for Westend setup. pub mod westend { +<<<<<<< HEAD use super::{ChainType, ParaId}; use polkadot_parachain_lib::chain_spec::{Extensions, GenericChainSpec}; +======= + use super::ChainType; + use polkadot_omni_node_lib::chain_spec::{Extensions, GenericChainSpec}; +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) pub(crate) const BRIDGE_HUB_WESTEND: &str = "bridge-hub-westend"; pub(crate) const BRIDGE_HUB_WESTEND_LOCAL: &str = "bridge-hub-westend-local"; @@ -185,7 +198,6 @@ pub mod westend { id: &str, chain_name: &str, relay_chain: &str, - para_id: ParaId, chain_type: ChainType, ) -> GenericChainSpec { let mut properties = sc_chain_spec::Properties::new(); @@ -195,7 +207,11 @@ pub mod westend { GenericChainSpec::builder( bridge_hub_westend_runtime::WASM_BINARY .expect("WASM binary was not build, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() }, +======= + Extensions::new_with_relay_chain(relay_chain.to_string()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name(chain_name) .with_id(super::ensure_id(id).expect("invalid id")) diff --git a/cumulus/polkadot-parachain/src/chain_spec/collectives.rs b/cumulus/polkadot-parachain/src/chain_spec/collectives.rs index 227e15fdff8d2..d4b6eb92370a7 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/collectives.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/collectives.rs @@ -27,7 +27,11 @@ pub fn collectives_westend_development_config() -> GenericChainSpec { GenericChainSpec::builder( collectives_westend_runtime::WASM_BINARY .expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: "westend-dev".into(), para_id: 1001 }, +======= + Extensions::new_with_relay_chain("westend-dev".into()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name("Westend Collectives Development") .with_id("collectives_westend_dev") @@ -48,7 +52,11 @@ pub fn collectives_westend_local_config() -> GenericChainSpec { GenericChainSpec::builder( collectives_westend_runtime::WASM_BINARY .expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: "westend-local".into(), para_id: 1001 }, +======= + Extensions::new_with_relay_chain("westend-local".into()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name("Westend Collectives Local") .with_id("collectives_westend_local") diff --git a/cumulus/polkadot-parachain/src/chain_spec/coretime.rs b/cumulus/polkadot-parachain/src/chain_spec/coretime.rs index fec3f56e6d352..5e1e5876386f1 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/coretime.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/coretime.rs @@ -180,6 +180,7 @@ pub mod rococo { GenericChainSpec::builder( wasm_binary, +<<<<<<< HEAD Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() }, ) .with_name(&chain_name) @@ -238,6 +239,20 @@ pub mod rococo { "key": Some(get_account_id_from_seed::("Alice")), }, }) +======= + Extensions::new_with_relay_chain(relay_chain.to_string()), + ) + .with_name(&chain_name) + .with_id(runtime_type.into()) + .with_chain_type(chain_type.clone()) + .with_genesis_config_preset_name(match chain_type { + ChainType::Development => sp_genesis_builder::DEV_RUNTIME_PRESET, + ChainType::Local => sp_genesis_builder::LOCAL_TESTNET_RUNTIME_PRESET, + _ => panic!("chain_type: {chain_type:?} not supported here!"), + }) + .with_properties(properties) + .build() +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) } } @@ -270,7 +285,11 @@ pub mod westend { GenericChainSpec::builder( coretime_westend_runtime::WASM_BINARY .expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() }, +======= + Extensions::new_with_relay_chain(relay_chain.to_string()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name(&chain_name) .with_id(runtime_type.into()) diff --git a/cumulus/polkadot-parachain/src/chain_spec/glutton.rs b/cumulus/polkadot-parachain/src/chain_spec/glutton.rs index 136411b93e8bc..fd1fa84d96cd9 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/glutton.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/glutton.rs @@ -74,6 +74,7 @@ pub fn glutton_westend_config(para_id: ParaId) -> GenericChainSpec { GenericChainSpec::builder( glutton_westend_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: "westend".into(), para_id: para_id.into() }, ) .with_name(format!("Glutton {}", para_id).as_str()) @@ -88,6 +89,18 @@ pub fn glutton_westend_config(para_id: ParaId) -> GenericChainSpec { )) .with_protocol_id(format!("glutton-westend-{}", para_id).as_str()) .with_properties(properties) +======= + Extensions::new_with_relay_chain(relay_chain.into()), + ) + .with_name(&chain_type_name(para_id, &chain_type)) + .with_id(&chain_id(para_id, &chain_type)) + .with_chain_type(chain_type.clone()) + .with_genesis_config_preset_name(match chain_type { + ChainType::Development => sp_genesis_builder::DEV_RUNTIME_PRESET, + ChainType::Local => sp_genesis_builder::LOCAL_TESTNET_RUNTIME_PRESET, + _ => panic!("chain_type: {chain_type:?} not supported here!"), + }) +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) .build() } diff --git a/cumulus/polkadot-parachain/src/chain_spec/penpal.rs b/cumulus/polkadot-parachain/src/chain_spec/penpal.rs index 5645bf06b67b2..77cfcaed28593 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/penpal.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/penpal.rs @@ -30,10 +30,14 @@ pub fn get_penpal_chain_spec(id: ParaId, relay_chain: &str) -> GenericChainSpec GenericChainSpec::builder( penpal_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: relay_chain.into(), // You MUST set this to the correct network! para_id: id.into(), }, +======= + Extensions::new_with_relay_chain(relay_chain.into()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name("Penpal Parachain") .with_id(&format!("penpal-{}", relay_chain.replace("-local", ""))) diff --git a/cumulus/polkadot-parachain/src/chain_spec/people.rs b/cumulus/polkadot-parachain/src/chain_spec/people.rs index 3c1150d95422b..8ab558a58d6bd 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/people.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/people.rs @@ -14,10 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . +<<<<<<< HEAD use cumulus_primitives_core::ParaId; use parachains_common::Balance as PeopleBalance; use polkadot_parachain_lib::chain_spec::GenericChainSpec; use sc_chain_spec::ChainSpec; +======= +use polkadot_omni_node_lib::chain_spec::GenericChainSpec; +use sc_chain_spec::{ChainSpec, ChainType}; +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) use std::str::FromStr; /// Collects all supported People configurations. @@ -73,13 +78,21 @@ impl PeopleRuntimeType { rococo::PEOPLE_ROCOCO_LOCAL, "Rococo People Local", "rococo-local", +<<<<<<< HEAD ParaId::new(1004), +======= + ChainType::Local, +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ))), PeopleRuntimeType::RococoDevelopment => Ok(Box::new(rococo::local_config( rococo::PEOPLE_ROCOCO_DEVELOPMENT, "Rococo People Development", "rococo-development", +<<<<<<< HEAD ParaId::new(1004), +======= + ChainType::Development, +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ))), PeopleRuntimeType::Westend => Ok(Box::new(GenericChainSpec::from_json_bytes( &include_bytes!("../../chain-specs/people-westend.json")[..], @@ -88,13 +101,21 @@ impl PeopleRuntimeType { westend::PEOPLE_WESTEND_LOCAL, "Westend People Local", "westend-local", +<<<<<<< HEAD ParaId::new(1004), +======= + ChainType::Local, +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ))), PeopleRuntimeType::WestendDevelopment => Ok(Box::new(westend::local_config( westend::PEOPLE_WESTEND_DEVELOPMENT, "Westend People Development", "westend-development", +<<<<<<< HEAD ParaId::new(1004), +======= + ChainType::Development, +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ))), other => Err(std::format!( "No default config present for {:?}, you should provide a chain-spec as json file!", @@ -119,12 +140,16 @@ fn ensure_id(id: &str) -> Result<&str, String> { /// Sub-module for Rococo setup. pub mod rococo { +<<<<<<< HEAD use super::{ParaId, PeopleBalance}; use crate::chain_spec::{ get_account_id_from_seed, get_collator_keys_from_seed, SAFE_XCM_VERSION, }; use parachains_common::{AccountId, AuraId}; use polkadot_parachain_lib::chain_spec::{Extensions, GenericChainSpec}; +======= + use polkadot_omni_node_lib::chain_spec::{Extensions, GenericChainSpec}; +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) use sc_chain_spec::ChainType; use sp_core::sr25519; @@ -134,10 +159,14 @@ pub mod rococo { const PEOPLE_ROCOCO_ED: PeopleBalance = people_rococo_runtime::ExistentialDeposit::get(); pub fn local_config( - id: &str, + spec_id: &str, chain_name: &str, relay_chain: &str, +<<<<<<< HEAD para_id: ParaId, +======= + chain_type: ChainType, +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) -> GenericChainSpec { let mut properties = sc_chain_spec::Properties::new(); properties.insert("ss58Format".into(), 42.into()); @@ -147,6 +176,7 @@ pub mod rococo { GenericChainSpec::builder( people_rococo_runtime::WASM_BINARY .expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() }, ) .with_name(chain_name) @@ -180,6 +210,18 @@ pub mod rococo { ], para_id, )) +======= + Extensions::new_with_relay_chain(relay_chain.to_string()), + ) + .with_name(chain_name) + .with_id(super::ensure_id(spec_id).expect("invalid id")) + .with_chain_type(chain_type.clone()) + .with_genesis_config_preset_name(match chain_type { + ChainType::Development => sp_genesis_builder::DEV_RUNTIME_PRESET, + ChainType::Local => sp_genesis_builder::LOCAL_TESTNET_RUNTIME_PRESET, + _ => panic!("chain_type: {chain_type:?} not supported here!"), + }) +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) .with_properties(properties) .build() } @@ -229,12 +271,16 @@ pub mod rococo { /// Sub-module for Westend setup. pub mod westend { +<<<<<<< HEAD use super::{ParaId, PeopleBalance}; use crate::chain_spec::{ get_account_id_from_seed, get_collator_keys_from_seed, SAFE_XCM_VERSION, }; use parachains_common::{AccountId, AuraId}; use polkadot_parachain_lib::chain_spec::{Extensions, GenericChainSpec}; +======= + use polkadot_omni_node_lib::chain_spec::{Extensions, GenericChainSpec}; +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) use sc_chain_spec::ChainType; use sp_core::sr25519; @@ -244,10 +290,14 @@ pub mod westend { const PEOPLE_WESTEND_ED: PeopleBalance = people_westend_runtime::ExistentialDeposit::get(); pub fn local_config( - id: &str, + spec_id: &str, chain_name: &str, relay_chain: &str, +<<<<<<< HEAD para_id: ParaId, +======= + chain_type: ChainType, +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) -> GenericChainSpec { let mut properties = sc_chain_spec::Properties::new(); properties.insert("ss58Format".into(), 42.into()); @@ -257,6 +307,7 @@ pub mod westend { GenericChainSpec::builder( people_westend_runtime::WASM_BINARY .expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() }, ) .with_name(chain_name) @@ -290,6 +341,18 @@ pub mod westend { ], para_id, )) +======= + Extensions::new_with_relay_chain(relay_chain.to_string()), + ) + .with_name(chain_name) + .with_id(super::ensure_id(spec_id).expect("invalid id")) + .with_chain_type(chain_type.clone()) + .with_genesis_config_preset_name(match chain_type { + ChainType::Development => sp_genesis_builder::DEV_RUNTIME_PRESET, + ChainType::Local => sp_genesis_builder::LOCAL_TESTNET_RUNTIME_PRESET, + _ => panic!("chain_type: {chain_type:?} not supported here!"), + }) +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) .with_properties(properties) .build() } diff --git a/cumulus/polkadot-parachain/src/chain_spec/rococo_parachain.rs b/cumulus/polkadot-parachain/src/chain_spec/rococo_parachain.rs index 251926838d246..4be0e95ebaee1 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/rococo_parachain.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/rococo_parachain.rs @@ -28,7 +28,11 @@ use sp_core::{crypto::UncheckedInto, sr25519}; pub fn rococo_parachain_local_config() -> GenericChainSpec { GenericChainSpec::builder( rococo_parachain_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: "rococo-local".into(), para_id: 1000 }, +======= + Extensions::new_with_relay_chain("rococo-local".into()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name("Rococo Parachain Local") .with_id("local_testnet") @@ -59,7 +63,11 @@ pub fn staging_rococo_parachain_local_config() -> GenericChainSpec { #[allow(deprecated)] GenericChainSpec::builder( rococo_parachain_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), +<<<<<<< HEAD Extensions { relay_chain: "rococo-local".into(), para_id: 1000 }, +======= + Extensions::new_with_relay_chain("rococo-local".into()), +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) ) .with_name("Staging Rococo Parachain Local") .with_id("staging_testnet") diff --git a/cumulus/polkadot-parachain/src/chain_spec/yet_another_parachain.rs b/cumulus/polkadot-parachain/src/chain_spec/yet_another_parachain.rs new file mode 100644 index 0000000000000..3905f8d62b7a0 --- /dev/null +++ b/cumulus/polkadot-parachain/src/chain_spec/yet_another_parachain.rs @@ -0,0 +1,105 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! ChainSpecs dedicated to parachain setups for testing and example purposes +use parachains_common::AccountId; +use polkadot_omni_node_lib::chain_spec::{Extensions, GenericChainSpec}; +use sc_chain_spec::ChainType; +use sp_core::{hex2array, sr25519::Pair as SrPair, Pair}; +use sp_keyring::Sr25519Keyring as Keyring; + +const NUM_ACCOUNT_PAIRS: usize = 16000; + +fn derive_accounts(n: usize, seed: String) -> Vec { + let t = std::cmp::min( + n, + std::thread::available_parallelism().unwrap_or(1usize.try_into().unwrap()).get(), + ); + + let mut tn = (0..t).cycle(); + let mut tranges: Vec<_> = (0..t).map(|_| Vec::new()).collect(); + (0..n).for_each(|i| tranges[tn.next().unwrap()].push(i)); + let mut threads = Vec::new(); + + tranges.into_iter().for_each(|chunk| { + let seed = seed.clone(); + threads.push(std::thread::spawn(move || { + chunk + .into_iter() + .map(move |i| { + let derivation = format!("{seed}/{i}"); + ::from_string(&derivation, None).unwrap() + }) + .collect::>() + })); + }); + + threads.into_iter().flat_map(|h| h.join().unwrap()).collect() +} + +pub fn yet_another_parachain_config( + relay: impl Into, + chain_type: ChainType, + para_id: u32, +) -> GenericChainSpec { + // > subkey inspect --network kusama --public \ + // 6205a2a2aecb71c13d8ad3197e12c10bcdcaa0c9f176997bc236c6b39143aa15 + // + // Network ID/Version: kusama + // Public key (hex): 0x6205a2a2aecb71c13d8ad3197e12c10bcdcaa0c9f176997bc236c6b39143aa15 + // Account ID: 0x6205a2a2aecb71c13d8ad3197e12c10bcdcaa0c9f176997bc236c6b39143aa15 + // Public key (SS58): EnqtFmsXcGdSnWk5JWUMXyPVamjiFQurXxcNgJEg1C3sw6W + // SS58 Address: EnqtFmsXcGdSnWk5JWUMXyPVamjiFQurXxcNgJEg1C3sw6W + let yap_sudo: AccountId = + hex2array!("6205a2a2aecb71c13d8ad3197e12c10bcdcaa0c9f176997bc236c6b39143aa15").into(); + let mut endowed_accounts = vec![ + yap_sudo.clone(), + Keyring::Alice.to_account_id(), + Keyring::Bob.to_account_id(), + Keyring::AliceStash.to_account_id(), + Keyring::BobStash.to_account_id(), + ]; + + endowed_accounts.extend( + derive_accounts(NUM_ACCOUNT_PAIRS, "//Sender".into()) + .into_iter() + .map(|k| k.public().into()), + ); + endowed_accounts.extend( + derive_accounts(NUM_ACCOUNT_PAIRS, "//Receiver".into()) + .into_iter() + .map(|k| k.public().into()), + ); + + GenericChainSpec::builder( + yet_another_parachain_runtime::WASM_BINARY + .expect("WASM binary was not built, please build it!"), + Extensions::new_with_relay_chain(relay.into()), + ) + .with_name("Yet Another Parachain") + .with_id("yet_another_parachain") + .with_chain_type(chain_type) + .with_genesis_config_preset_name(sp_genesis_builder::LOCAL_TESTNET_RUNTIME_PRESET) + .with_genesis_config_patch(serde_json::json!({ + "balances": { + "balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 60)).collect::>(), + }, + "sudo": { "key": Some(yap_sudo) }, + "parachainInfo": { + "parachainId": para_id, + }, + })) + .build() +} diff --git a/prdoc/pr_9201.prdoc b/prdoc/pr_9201.prdoc new file mode 100644 index 0000000000000..c08444c78683d --- /dev/null +++ b/prdoc/pr_9201.prdoc @@ -0,0 +1,16 @@ +title: '`polkadot-parachain`: fixes and changes related to GetParachainInfo' +doc: +- audience: Node Dev + description: |- + - Provides some updated to the asset-hub-westend-local chain specification, by adding appropriate genesis patch for parachainInfo. + - refactors the logic related to fetching `para_id` with the node, so that when failing to use `GetParachainInfo::parachain_id` we also get a log with the error (before defaulting to `para_id` extracted from chain spec). + - removes comments/deprecation notices throughout the code that introduce para-id flag removal (from chain-spec-builder and support for parsing it from chain specifications) +crates: +- name: polkadot-parachain-bin + bump: patch +- name: polkadot-omni-node-lib + bump: major +- name: polkadot-omni-node + bump: patch +- name: staging-chain-spec-builder + bump: patch diff --git a/substrate/bin/utils/chain-spec-builder/README.docify.md b/substrate/bin/utils/chain-spec-builder/README.docify.md new file mode 100644 index 0000000000000..1b0f78d278c55 --- /dev/null +++ b/substrate/bin/utils/chain-spec-builder/README.docify.md @@ -0,0 +1,168 @@ +# Chain Spec Builder + +Substrate's chain spec builder utility. + +A chain-spec is short for `chain-specification`. See the [`sc-chain-spec`](https://crates.io/docs.rs/sc-chain-spec/latest/sc_chain_spec) +for more information. + +_Note:_ this binary is a more flexible alternative to the `build-spec` subcommand, contained in typical Substrate-based nodes. +This particular binary is capable of interacting with [`sp-genesis-builder`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/index.html) +implementation of any provided runtime allowing to build chain-spec JSON files. + +See [`ChainSpecBuilderCmd`](https://docs.rs/staging-chain-spec-builder/6.0.0/staging_chain_spec_builder/enum.ChainSpecBuilderCmd.html) +for a list of available commands. + +## Installation + +```bash +cargo install staging-chain-spec-builder --locked +``` + +_Note:_ `chain-spec-builder` binary is published on [crates.io](https://crates.io) under +[`staging-chain-spec-builder`](https://crates.io/crates/staging-chain-spec-builder) due to a name conflict. + +## Usage + +Please note that below usage is backed by integration tests. The commands' examples are wrapped +around by the `bash!(...)` macro calls. + +### Note for `CreateCmd`'s `para-id` flag + + +Runtimes relying on generating the chain specification with this tool should +implement `cumulus_primitives_core::GetParachainInfo` trait, a new runtime API +designed to provide the parachain ID from the `parachain-info` +pallet. The `para-id` flag can be used though if the runtime does not implement +the runtime API, and the parachain id will be fetched by the node from chain +specification. This can be especially useful when syncing a node from a state +where the runtime does not implement `cumulus_primitives_core::GetParachainInfo`. + +For reference, generating a chain specification with a `para_id` field can be +done like below: + +```bash +chain-spec-builder -c "/dev/stdout" create --relay-chain "dev" --para-id 1000 -r $runtime_path named-preset "staging" +``` + +### Generate chains-spec using default config from runtime + +Query the default genesis config from the provided runtime WASM blob and use it in the chain spec. + + + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime function is called. + +### Display the runtime's default `GenesisConfig` + + + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime function is called. + +### Display the `GenesisConfig` preset with given name + + + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime function is called. + +### List the names of `GenesisConfig` presets provided by runtime + + + +_Note:_ [`GenesisBuilder::preset_names`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.preset_names) +runtime function is called. + +### Generate chain spec using runtime provided genesis config preset + +Patch the runtime's default genesis config with the named preset provided by the runtime and generate the plain +version of chain spec: + + + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime functions are called. + +### Generate raw storage chain spec using genesis config patch + +Patch the runtime's default genesis config with provided `patch.json` and generate raw +storage (`-s`) version of chain spec: + + + +Refer to [_patch file_](#patch-file) for some details on the patch file format. + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +and +[`GenesisBuilder::build_state`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.build_state) +runtime functions are called. + +### Generate raw storage chain spec using full genesis config + +Build the chain spec using provided full genesis config json file. No defaults will be used: + + + +Refer to [_full config file_](#full-genesis-config-file) for some details on the full file format. + +_Note_: [`GenesisBuilder::build_state`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.build_state) +runtime function is called. + +### Generate human readable chain spec using provided genesis config patch + + + +Refer to [_patch file_](#patch-file) for some details on the patch file format. + +### Generate human readable chain spec using provided full genesis config + + + +Refer to [_full config file_](#full-genesis-config-file) for some details on the full file format. + +## Patch and full genesis config files + +This section provides details on the files that can be used with `create patch` or `create full` subcommands. + +### Patch file + +The patch file for genesis config contains the key-value pairs valid for given runtime, that needs to be customized, + e.g: + +```ignore +{ + "balances": { + "balances": [ + [ + "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", + 1000000000000000 + ], + [ + "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y", + 1000000000000000 + ], + [ + "5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b", + 5000000000000000 + ] + ] + }, + "sudo": { + "key": "5Ff3iXP75ruzroPWRP2FYBHWnmGGBSb63857BgnzCoXNxfPo" + } +} +``` + +The rest of genesis config keys will be initialized with default values. + +### Full genesis config file + +The full genesis config file must contain values for _all_ the keys present in the genesis config for given runtime. The +format of the file is similar to patch format. Example is not provided here as it heavily depends on the runtime. + +### Extra tools + +The `chain-spec-builder` provides also some extra utilities: [`VerifyCmd`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/struct.VerifyCmd.html), +[`ConvertToRawCmd`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/struct.ConvertToRawCmd.html), +[`UpdateCodeCmd`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/struct.UpdateCodeCmd.html). diff --git a/substrate/bin/utils/chain-spec-builder/README.md b/substrate/bin/utils/chain-spec-builder/README.md index 96e931ea4daad..a52d9225c5bd2 100644 --- a/substrate/bin/utils/chain-spec-builder/README.md +++ b/substrate/bin/utils/chain-spec-builder/README.md @@ -2,4 +2,206 @@ ## Release +<<<<<<< HEAD Polkadot SDK stable2409 +======= +_Note:_ this binary is a more flexible alternative to the `build-spec` subcommand, contained in typical Substrate-based nodes. +This particular binary is capable of interacting with [`sp-genesis-builder`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/index.html) +implementation of any provided runtime allowing to build chain-spec JSON files. + +See [`ChainSpecBuilderCmd`](https://docs.rs/staging-chain-spec-builder/6.0.0/staging_chain_spec_builder/enum.ChainSpecBuilderCmd.html) +for a list of available commands. + +## Installation + +```bash +cargo install staging-chain-spec-builder --locked +``` + +_Note:_ `chain-spec-builder` binary is published on [crates.io](https://crates.io) under +[`staging-chain-spec-builder`](https://crates.io/crates/staging-chain-spec-builder) due to a name conflict. + +## Usage + +Please note that below usage is backed by integration tests. The commands' examples are wrapped +around by the `bash!(...)` macro calls. + +### Note for `CreateCmd`'s `para-id` flag + + +Runtimes relying on generating the chain specification with this tool should +implement `cumulus_primitives_core::GetParachainInfo` trait, a new runtime API +designed to provide the parachain ID from the `parachain-info` +pallet. The `para-id` flag can be used though if the runtime does not implement +the runtime API, and the parachain id will be fetched by the node from chain +specification. This can be especially useful when syncing a node from a state +where the runtime does not implement `cumulus_primitives_core::GetParachainInfo`. + +For reference, generating a chain specification with a `para_id` field can be +done like below: + +```bash +chain-spec-builder -c "/dev/stdout" create --relay-chain "dev" --para-id 1000 -r $runtime_path named-preset "staging" +``` + +### Generate chains-spec using default config from runtime + +Query the default genesis config from the provided runtime WASM blob and use it in the chain spec. + +```rust,ignore +bash!( + chain-spec-builder -c "/dev/stdout" create -r $runtime_path default +) +``` + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime function is called. + +### Display the runtime's default `GenesisConfig` + +```rust,ignore +bash!( + chain-spec-builder display-preset -r $runtime_path +) +``` + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime function is called. + +### Display the `GenesisConfig` preset with given name + +```rust,ignore +fn cmd_display_preset(runtime_path: &str) -> String { + bash!( + chain-spec-builder display-preset -r $runtime_path -p "staging" + ) +} +``` + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime function is called. + +### List the names of `GenesisConfig` presets provided by runtime + +```rust,ignore +bash!( + chain-spec-builder list-presets -r $runtime_path +) +``` + +_Note:_ [`GenesisBuilder::preset_names`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.preset_names) +runtime function is called. + +### Generate chain spec using runtime provided genesis config preset + +Patch the runtime's default genesis config with the named preset provided by the runtime and generate the plain +version of chain spec: + +```rust,ignore +bash!( + chain-spec-builder -c "/dev/stdout" create --relay-chain "dev" -r $runtime_path named-preset "staging" +) +``` + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime functions are called. + +### Generate raw storage chain spec using genesis config patch + +Patch the runtime's default genesis config with provided `patch.json` and generate raw +storage (`-s`) version of chain spec: + +```rust,ignore +bash!( + chain-spec-builder -c "/dev/stdout" create -s -r $runtime_path patch "tests/input/patch.json" +) +``` + +Refer to [_patch file_](#patch-file) for some details on the patch file format. + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +and +[`GenesisBuilder::build_state`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.build_state) +runtime functions are called. + +### Generate raw storage chain spec using full genesis config + +Build the chain spec using provided full genesis config json file. No defaults will be used: + +```rust,ignore +bash!( + chain-spec-builder -c "/dev/stdout" create -s -r $runtime_path full "tests/input/full.json" +) +``` + +Refer to [_full config file_](#full-genesis-config-file) for some details on the full file format. + +_Note_: [`GenesisBuilder::build_state`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.build_state) +runtime function is called. + +### Generate human readable chain spec using provided genesis config patch + +```rust,ignore +bash!( + chain-spec-builder -c "/dev/stdout" create -r $runtime_path patch "tests/input/patch.json" +) +``` + +Refer to [_patch file_](#patch-file) for some details on the patch file format. + +### Generate human readable chain spec using provided full genesis config + +```rust,ignore +bash!( + chain-spec-builder -c "/dev/stdout" create -r $runtime_path full "tests/input/full.json" +) +``` + +Refer to [_full config file_](#full-genesis-config-file) for some details on the full file format. + +## Patch and full genesis config files + +This section provides details on the files that can be used with `create patch` or `create full` subcommands. + +### Patch file + +The patch file for genesis config contains the key-value pairs valid for given runtime, that needs to be customized, + e.g: + +```ignore +{ + "balances": { + "balances": [ + [ + "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", + 1000000000000000 + ], + [ + "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y", + 1000000000000000 + ], + [ + "5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b", + 5000000000000000 + ] + ] + }, + "sudo": { + "key": "5Ff3iXP75ruzroPWRP2FYBHWnmGGBSb63857BgnzCoXNxfPo" + } +} +``` + +The rest of genesis config keys will be initialized with default values. + +### Full genesis config file + +The full genesis config file must contain values for _all_ the keys present in the genesis config for given runtime. The +format of the file is similar to patch format. Example is not provided here as it heavily depends on the runtime. + +### Extra tools + +The `chain-spec-builder` provides also some extra utilities: [`VerifyCmd`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/struct.VerifyCmd.html), +[`ConvertToRawCmd`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/struct.ConvertToRawCmd.html), +[`UpdateCodeCmd`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/struct.UpdateCodeCmd.html). +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) diff --git a/substrate/bin/utils/chain-spec-builder/src/lib.rs b/substrate/bin/utils/chain-spec-builder/src/lib.rs index 6c679f109a002..72fa020fae6ef 100644 --- a/substrate/bin/utils/chain-spec-builder/src/lib.rs +++ b/substrate/bin/utils/chain-spec-builder/src/lib.rs @@ -158,6 +158,15 @@ pub struct CreateCmd { /// The chain type. #[arg(value_enum, short = 't', default_value = "live")] chain_type: ChainType, +<<<<<<< HEAD +======= + /// The para ID for your chain. + #[arg(long, value_enum, short = 'p', requires = "relay_chain")] + pub para_id: Option, + /// The relay chain you wish to connect to. + #[arg(long, value_enum, short = 'c')] + pub relay_chain: Option, +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) /// The path to runtime wasm blob. #[arg(long, short)] runtime_wasm_path: PathBuf, @@ -279,10 +288,20 @@ pub struct VerifyCmd { pub input_chain_spec: PathBuf, } +<<<<<<< HEAD /// Processes `CreateCmd` and returns JSON version of `ChainSpec`. pub fn generate_chain_spec_for_runtime(cmd: &CreateCmd) -> Result { let code = fs::read(cmd.runtime_wasm_path.as_path()) .map_err(|e| format!("wasm blob shall be readable {e}"))?; +======= +#[derive(Deserialize, Serialize, Clone)] +pub struct ParachainExtension { + /// The relay chain of the Parachain. + pub relay_chain: String, + /// The id of the Parachain. + pub para_id: Option, +} +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)) let chain_type = &cmd.chain_type; @@ -330,3 +349,101 @@ pub fn generate_chain_spec_for_runtime(cmd: &CreateCmd) -> Result chain_spec.as_json(false), } } +<<<<<<< HEAD +======= + +impl CreateCmd { + /// Returns the associated runtime code. + /// + /// If the code blob was previously set, returns it. Otherwise reads the file. + fn get_runtime_code(&self) -> Result, String> { + Ok(if let Some(code) = self.code.clone() { + code + } else { + fs::read(self.runtime.as_path()) + .map_err(|e| format!("wasm blob shall be readable {e}"))? + .into() + }) + } +} + +/// Parses chain properties passed as a comma-separated KEY=VALUE pairs. +fn parse_properties(raw: &String, props: &mut sc_chain_spec::Properties) -> Result<(), String> { + for pair in raw.split(',') { + let mut iter = pair.splitn(2, '='); + let key = iter + .next() + .ok_or_else(|| format!("Invalid chain property key: {pair}"))? + .trim() + .to_owned(); + let value_str = iter + .next() + .ok_or_else(|| format!("Invalid chain property value for key: {key}"))? + .trim(); + + // Try to parse as bool, number, or fallback to String + let value = match value_str.parse::() { + Ok(b) => Value::Bool(b), + Err(_) => match value_str.parse::() { + Ok(i) => Value::Number(i.into()), + Err(_) => Value::String(value_str.to_string()), + }, + }; + + props.insert(key, value); + } + Ok(()) +} + +/// Processes `CreateCmd` and returns string representation of JSON version of `ChainSpec`. +pub fn generate_chain_spec_for_runtime(cmd: &CreateCmd) -> Result { + let code = cmd.get_runtime_code()?; + + let chain_type = &cmd.chain_type; + + let mut properties = sc_chain_spec::Properties::new(); + for raw in &cmd.properties { + parse_properties(raw, &mut properties)?; + } + + let builder = ChainSpec::builder(&code[..], Default::default()) + .with_name(&cmd.chain_name[..]) + .with_id(&cmd.chain_id[..]) + .with_properties(properties) + .with_chain_type(chain_type.clone()); + + let chain_spec_json_string = process_action(&cmd, &code[..], builder)?; + let parachain_properties = cmd.relay_chain.as_ref().map(|rc| { + cmd.para_id + .map(|para_id| { + serde_json::json!({ + "relay_chain": rc, + "para_id": para_id, + }) + }) + .unwrap_or(serde_json::json!({ + "relay_chain": rc, + })) + }); + + let chain_spec = parachain_properties + .map(|props| { + let chain_spec_json_blob = serde_json::from_str(chain_spec_json_string.as_str()) + .map_err(|e| format!("deserialization a json failed {e}")); + chain_spec_json_blob.and_then(|mut cs| { + json_patch::merge(&mut cs, props); + serde_json::to_string_pretty(&cs).map_err(|e| format!("to pretty failed: {e}")) + }) + }) + .unwrap_or(Ok(chain_spec_json_string)); + chain_spec +} + +/// Extract any chain spec and convert it to JSON +fn extract_chain_spec_json(input_chain_spec: &Path) -> Result { + let chain_spec = &fs::read(input_chain_spec) + .map_err(|e| format!("Provided chain spec could not be read: {e}"))?; + + serde_json::from_slice(&chain_spec).map_err(|e| format!("Conversion to json failed: {e}")) +} +>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201))