diff --git a/Cargo.lock b/Cargo.lock index 1ea460815c2f..c3cf0b953f7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8148,6 +8148,7 @@ dependencies = [ "polkadot-sdk-frame", "scale-info", "sp-genesis-builder", + "sp-runtime", "substrate-wasm-builder", ] @@ -15048,6 +15049,7 @@ name = "rococo-runtime" version = "7.0.0" dependencies = [ "binary-merkle-tree", + "bitvec", "frame-benchmarking", "frame-executive", "frame-remote-externalities", @@ -15120,6 +15122,7 @@ dependencies = [ "sp-block-builder", "sp-consensus-babe", "sp-consensus-beefy", + "sp-consensus-grandpa", "sp-core", "sp-genesis-builder", "sp-inherents", @@ -15650,7 +15653,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" -version = "27.0.0" +version = "28.0.0" dependencies = [ "array-bytes 6.1.0", "docify", @@ -15674,6 +15677,7 @@ dependencies = [ "sp-keyring", "sp-runtime", "sp-state-machine", + "sp-tracing 16.0.0", "substrate-test-runtime", ] @@ -18813,8 +18817,10 @@ dependencies = [ [[package]] name = "sp-genesis-builder" -version = "0.7.0" +version = "0.8.0" dependencies = [ + "parity-scale-codec", + "scale-info", "serde_json", "sp-api", "sp-runtime", @@ -19450,7 +19456,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "staging-chain-spec-builder" -version = "2.0.0" +version = "3.0.0" dependencies = [ "clap 4.5.3", "log", @@ -19545,6 +19551,7 @@ dependencies = [ "sp-core", "sp-crypto-hashing", "sp-externalities 0.25.0", + "sp-genesis-builder", "sp-inherents", "sp-io", "sp-keyring", @@ -19970,6 +19977,7 @@ dependencies = [ "frame-system", "frame-system-rpc-runtime-api", "futures", + "hex-literal", "log", "pallet-babe", "pallet-balances", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 547d465802ef..9e21d1133237 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -55,7 +55,7 @@ use cumulus_primitives_core::ParaId; use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, ord_parameter_types, parameter_types, traits::{ fungible, fungibles, tokens::imbalance::ResolveAssetTo, AsEnsureOriginWithArg, ConstBool, @@ -1649,12 +1649,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 97928d054843..f3499a8d2921 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -37,7 +37,7 @@ use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, ord_parameter_types, parameter_types, traits::{ fungible, fungibles, @@ -1726,12 +1726,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 6ffb7eb3c948..8db640d49601 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -61,7 +61,7 @@ use cumulus_primitives_core::ParaId; use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ConstBool, ConstU32, ConstU64, ConstU8, TransformOrigin}, weights::{ConstantMultiplier, Weight}, @@ -1451,12 +1451,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 9571cc68a187..909ee6248247 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -55,7 +55,7 @@ use bridge_hub_common::{ use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ConstBool, ConstU32, ConstU64, ConstU8, TransformOrigin}, weights::{ConstantMultiplier, Weight}, @@ -1112,12 +1112,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index b7410071f128..bf702ed6a4be 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -66,7 +66,7 @@ use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ fungible::HoldConsideration, ConstBool, ConstU16, ConstU32, ConstU64, ConstU8, @@ -1062,12 +1062,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 1d2da6806752..56060aa123fc 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -48,7 +48,7 @@ use sp_version::RuntimeVersion; use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ConstBool, ConstU16, ConstU32, ConstU64, ConstU8}, weights::{ConstantMultiplier, Weight}, @@ -794,12 +794,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index 7e489cdd06fe..1c67740ee540 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -38,7 +38,7 @@ use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, TransformOrigin}, weights::{ConstantMultiplier, Weight}, @@ -878,12 +878,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index d54e1be44fc7..696618c37a28 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -38,7 +38,7 @@ use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, TransformOrigin}, weights::{ConstantMultiplier, Weight}, @@ -869,12 +869,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index ca1a915ba740..3391ab0e79c2 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -66,7 +66,7 @@ use cumulus_primitives_core::AggregateMessageOrigin; pub use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Everything, IsInVec, Randomness, @@ -474,12 +474,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 4232d9e41dd4..1434c1b263cc 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -27,7 +27,7 @@ use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Everything, TransformOrigin, @@ -851,12 +851,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 25b17fd502e1..1030527ccd48 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -27,7 +27,7 @@ use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Everything, TransformOrigin, @@ -851,12 +851,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs index 2f4f762408fe..461133f6cfc0 100644 --- a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs @@ -46,7 +46,7 @@ use sp_version::RuntimeVersion; pub use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, IsInVec, Randomness}, weights::{ @@ -370,12 +370,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/starters/shell/src/lib.rs b/cumulus/parachains/runtimes/starters/shell/src/lib.rs index ad79d6849bd5..a3d1629bbe5e 100644 --- a/cumulus/parachains/runtimes/starters/shell/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/shell/src/lib.rs @@ -54,7 +54,7 @@ use sp_version::RuntimeVersion; pub use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, IsInVec, Randomness}, weights::{ @@ -428,12 +428,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index c8c469b76fed..919bfe83e7d7 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -37,7 +37,7 @@ use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, pallet_prelude::Weight, parameter_types, traits::{ @@ -911,12 +911,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index d896d7492b5a..1c55f1354ac5 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -41,7 +41,7 @@ use sp_version::RuntimeVersion; pub use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, ConstU8, Contains, EitherOfDiverse, @@ -824,12 +824,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } diff --git a/cumulus/polkadot-parachain/src/fake_runtime_api/asset_hub_polkadot_aura.rs b/cumulus/polkadot-parachain/src/fake_runtime_api/asset_hub_polkadot_aura.rs index 7778d1bf7d2d..82c02943c5fc 100644 --- a/cumulus/polkadot-parachain/src/fake_runtime_api/asset_hub_polkadot_aura.rs +++ b/cumulus/polkadot-parachain/src/fake_runtime_api/asset_hub_polkadot_aura.rs @@ -189,11 +189,15 @@ sp_api::impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { + fn build_state(_: Vec) -> sp_genesis_builder::Result { unimplemented!() } - fn build_config(_: Vec) -> sp_genesis_builder::Result { + fn get_preset(_id: &Option) -> Option> { + unimplemented!() + } + + fn preset_names() -> Vec { unimplemented!() } } diff --git a/cumulus/polkadot-parachain/src/fake_runtime_api/aura.rs b/cumulus/polkadot-parachain/src/fake_runtime_api/aura.rs index 880f5d760c74..6b718e912164 100644 --- a/cumulus/polkadot-parachain/src/fake_runtime_api/aura.rs +++ b/cumulus/polkadot-parachain/src/fake_runtime_api/aura.rs @@ -189,11 +189,15 @@ sp_api::impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { + fn build_state(_: Vec) -> sp_genesis_builder::Result { unimplemented!() } - fn build_config(_: Vec) -> sp_genesis_builder::Result { + fn get_preset(_id: &Option) -> Option> { + unimplemented!() + } + + fn preset_names() -> Vec { unimplemented!() } } diff --git a/cumulus/test/runtime/src/lib.rs b/cumulus/test/runtime/src/lib.rs index 350c945765b4..b9e80d8eab55 100644 --- a/cumulus/test/runtime/src/lib.rs +++ b/cumulus/test/runtime/src/lib.rs @@ -47,7 +47,7 @@ use sp_version::RuntimeVersion; pub use frame_support::{ construct_runtime, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ConstU8, Randomness}, weights::{ @@ -463,12 +463,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/polkadot/node/service/src/chain_spec.rs b/polkadot/node/service/src/chain_spec.rs index 1b6ba99777b0..1b990af2394b 100644 --- a/polkadot/node/service/src/chain_spec.rs +++ b/polkadot/node/service/src/chain_spec.rs @@ -24,12 +24,10 @@ use polkadot_primitives::{AccountId, AccountPublic, AssignmentId, ValidatorId}; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use sp_consensus_babe::AuthorityId as BabeId; -#[cfg(any(feature = "rococo-native", feature = "westend-native",))] +#[cfg(feature = "westend-native")] use polkadot_primitives::vstaging::SchedulerParams; #[cfg(feature = "rococo-native")] use rococo_runtime as rococo; -#[cfg(feature = "rococo-native")] -use rococo_runtime_constants::currency::UNITS as ROC; use sc_chain_spec::ChainSpecExtension; #[cfg(any(feature = "westend-native", feature = "rococo-native"))] use sc_chain_spec::ChainType; @@ -118,7 +116,7 @@ pub fn wococo_config() -> Result { } /// The default parachains host configuration. -#[cfg(any(feature = "rococo-native", feature = "westend-native",))] +#[cfg(feature = "westend-native")] fn default_parachains_host_configuration( ) -> polkadot_runtime_parachains::configuration::HostConfiguration { @@ -173,7 +171,7 @@ fn default_parachains_host_configuration( } } -#[cfg(any(feature = "rococo-native", feature = "westend-native",))] +#[cfg(feature = "westend-native")] #[test] fn default_parachains_host_configuration_is_consistent() { default_parachains_host_configuration().panic_if_not_consistent(); @@ -198,25 +196,6 @@ fn westend_session_keys( } } -#[cfg(feature = "rococo-native")] -fn rococo_session_keys( - babe: BabeId, - grandpa: GrandpaId, - para_validator: ValidatorId, - para_assignment: AssignmentId, - authority_discovery: AuthorityDiscoveryId, - beefy: BeefyId, -) -> rococo_runtime::SessionKeys { - rococo_runtime::SessionKeys { - babe, - grandpa, - para_validator, - para_assignment, - authority_discovery, - beefy, - } -} - #[cfg(feature = "westend-native")] fn westend_staging_testnet_config_genesis() -> serde_json::Value { use hex_literal::hex; @@ -394,265 +373,6 @@ fn westend_staging_testnet_config_genesis() -> serde_json::Value { }) } -#[cfg(feature = "rococo-native")] -fn rococo_staging_testnet_config_genesis() -> serde_json::Value { - use hex_literal::hex; - use sp_core::crypto::UncheckedInto; - - // subkey inspect "$SECRET" - let endowed_accounts = vec![ - // 5DwBmEFPXRESyEam5SsQF1zbWSCn2kCjyLW51hJHXe9vW4xs - hex!["52bc71c1eca5353749542dfdf0af97bf764f9c2f44e860cd485f1cd86400f649"].into(), - ]; - - // ./scripts/prepare-test-net.sh 8 - let initial_authorities: Vec<( - AccountId, - AccountId, - BabeId, - GrandpaId, - ValidatorId, - AssignmentId, - AuthorityDiscoveryId, - BeefyId, - )> = vec![ - ( - //5EHZkbp22djdbuMFH9qt1DVzSCvqi3zWpj6DAYfANa828oei - hex!["62475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a"].into(), - //5FeSEpi9UYYaWwXXb3tV88qtZkmSdB3mvgj3pXkxKyYLGhcd - hex!["9e6e781a76810fe93187af44c79272c290c2b9e2b8b92ee11466cd79d8023f50"].into(), - //5Fh6rDpMDhM363o1Z3Y9twtaCPfizGQWCi55BSykTQjGbP7H - hex!["a076ef1280d768051f21d060623da3ab5b56944d681d303ed2d4bf658c5bed35"] - .unchecked_into(), - //5CPd3zoV9Aaah4xWucuDivMHJ2nEEmpdi864nPTiyRZp4t87 - hex!["0e6d7d1afbcc6547b92995a394ba0daed07a2420be08220a5a1336c6731f0bfa"] - .unchecked_into(), - //5CP6oGfwqbEfML8efqm1tCZsUgRsJztp9L8ZkEUxA16W8PPz - hex!["0e07a51d3213842f8e9363ce8e444255990a225f87e80a3d651db7841e1a0205"] - .unchecked_into(), - //5HQdwiDh8Qtd5dSNWajNYpwDvoyNWWA16Y43aEkCNactFc2b - hex!["ec60e71fe4a567ef9fef99d4bbf37ffae70564b41aa6f94ef0317c13e0a5477b"] - .unchecked_into(), - //5HbSgM72xVuscsopsdeG3sCSCYdAeM1Tay9p79N6ky6vwDGq - hex!["f49eae66a0ac9f610316906ec8f1a0928e20d7059d76a5ca53cbcb5a9b50dd3c"] - .unchecked_into(), - //5DPSWdgw38Spu315r6LSvYCggeeieBAJtP5A1qzuzKhqmjVu - hex!["034f68c5661a41930c82f26a662276bf89f33467e1c850f2fb8ef687fe43d62276"] - .unchecked_into(), - ), - ( - //5DvH8oEjQPYhzCoQVo7WDU91qmQfLZvxe9wJcrojmJKebCmG - hex!["520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a"].into(), - //5ENZvCRzyXJJYup8bM6yEzb2kQHEb1NDpY2ZEyVGBkCfRdj3 - hex!["6618289af7ae8621981ffab34591e7a6486e12745dfa3fd3b0f7e6a3994c7b5b"].into(), - //5DLjSUfqZVNAADbwYLgRvHvdzXypiV1DAEaDMjcESKTcqMoM - hex!["38757d0de00a0c739e7d7984ef4bc01161bd61e198b7c01b618425c16bb5bd5f"] - .unchecked_into(), - //5HnDVBN9mD6mXyx8oryhDbJtezwNSj1VRXgLoYCBA6uEkiao - hex!["fcd5f87a6fd5707a25122a01b4dac0a8482259df7d42a9a096606df1320df08d"] - .unchecked_into(), - //5EPEWRecy2ApL5n18n3aHyU1956zXTRqaJpzDa9DoqiggNwF - hex!["669a10892119453e9feb4e3f1ee8e028916cc3240022920ad643846fbdbee816"] - .unchecked_into(), - //5ES3fw5X4bndSgLNmtPfSbM2J1kLqApVB2CCLS4CBpM1UxUZ - hex!["68bf52c482630a8d1511f2edd14f34127a7d7082219cccf7fd4c6ecdb535f80d"] - .unchecked_into(), - //5HeXbwb5PxtcRoopPZTp5CQun38atn2UudQ8p2AxR5BzoaXw - hex!["f6f8fe475130d21165446a02fb1dbce3a7bf36412e5d98f4f0473aed9252f349"] - .unchecked_into(), - //5F7nTtN8MyJV4UsXpjg7tHSnfANXZ5KRPJmkASc1ZSH2Xoa5 - hex!["03a90c2bb6d3b7000020f6152fe2e5002fa970fd1f42aafb6c8edda8dacc2ea77e"] - .unchecked_into(), - ), - ( - //5FPMzsezo1PRxYbVpJMWK7HNbR2kUxidsAAxH4BosHa4wd6S - hex!["92ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f"].into(), - //5G6NQidFG7YiXsvV7hQTLGArir9tsYqD4JDxByhgxKvSKwRx - hex!["b235f57244230589523271c27b8a490922ffd7dccc83b044feaf22273c1dc735"].into(), - //5GpZhzAVg7SAtzLvaAC777pjquPEcNy1FbNUAG2nZvhmd6eY - hex!["d2644c1ab2c63a3ad8d40ad70d4b260969e3abfe6d7e6665f50dc9f6365c9d2a"] - .unchecked_into(), - //5HAes2RQYPbYKbLBfKb88f4zoXv6pPA6Ke8CjN7dob3GpmSP - hex!["e1b68fbd84333e31486c08e6153d9a1415b2e7e71b413702b7d64e9b631184a1"] - .unchecked_into(), - //5FtAGDZYJKXkhVhAxCQrXmaP7EE2mGbBMfmKDHjfYDgq2BiU - hex!["a8e61ffacafaf546283dc92d14d7cc70ea0151a5dd81fdf73ff5a2951f2b6037"] - .unchecked_into(), - //5CtK7JHv3h6UQZ44y54skxdwSVBRtuxwPE1FYm7UZVhg8rJV - hex!["244f3421b310c68646e99cdbf4963e02067601f57756b072a4b19431448c186e"] - .unchecked_into(), - //5D4r6YaB6F7A7nvMRHNFNF6zrR9g39bqDJFenrcaFmTCRwfa - hex!["2c57f81fd311c1ab53813c6817fe67f8947f8d39258252663b3384ab4195494d"] - .unchecked_into(), - //5EPoHj8uV4fFKQHYThc6Z9fDkU7B6ih2ncVzQuDdNFb8UyhF - hex!["039d065fe4f9234f0a4f13cc3ae585f2691e9c25afa469618abb6645111f607a53"] - .unchecked_into(), - ), - ( - //5DMNx7RoX6d7JQ38NEM7DWRcW2THu92LBYZEWvBRhJeqcWgR - hex!["38f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a0404"].into(), - //5GGdKNDr9P47dpVnmtq3m8Tvowwf1ot1abw6tPsTYYFoKm2v - hex!["ba0898c1964196474c0be08d364cdf4e9e1d47088287f5235f70b0590dfe1704"].into(), - //5EjkyPCzR2SjhDZq8f7ufsw6TfkvgNRepjCRQFc4TcdXdaB1 - hex!["764186bc30fd5a02477f19948dc723d6d57ab174debd4f80ed6038ec960bfe21"] - .unchecked_into(), - //5DJV3zCBTJBLGNDCcdWrYxWDacSz84goGTa4pFeKVvehEBte - hex!["36be9069cdb4a8a07ecd51f257875150f0a8a1be44a10d9d98dabf10a030aef4"] - .unchecked_into(), - //5F9FsRjpecP9GonktmtFL3kjqNAMKjHVFjyjRdTPa4hbQRZA - hex!["882d72965e642677583b333b2d173ac94b5fd6c405c76184bb14293be748a13b"] - .unchecked_into(), - //5F1FZWZSj3JyTLs8sRBxU6QWyGLSL9BMRtmSKDmVEoiKFxSP - hex!["821271c99c958b9220f1771d9f5e29af969edfa865631dba31e1ab7bc0582b75"] - .unchecked_into(), - //5CtgRR74VypK4h154s369abs78hDUxZSJqcbWsfXvsjcHJNA - hex!["2496f28d887d84705c6dae98aee8bf90fc5ad10bb5545eca1de6b68425b70f7c"] - .unchecked_into(), - //5CPx6dsr11SCJHKFkcAQ9jpparS7FwXQBrrMznRo4Hqv1PXz - hex!["0307d29bbf6a5c4061c2157b44fda33b7bb4ec52a5a0305668c74688cedf288d58"] - .unchecked_into(), - ), - ( - //5C8AL1Zb4bVazgT3EgDxFgcow1L4SJjVu44XcLC9CrYqFN4N - hex!["02a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b16"].into(), - //5FLYy3YKsAnooqE4hCudttAsoGKbVG3hYYBtVzwMjJQrevPa - hex!["90cab33f0bb501727faa8319f0845faef7d31008f178b65054b6629fe531b772"].into(), - //5Et3tfbVf1ByFThNAuUq5pBssdaPPskip5yob5GNyUFojXC7 - hex!["7c94715e5dd8ab54221b1b6b2bfa5666f593f28a92a18e28052531de1bd80813"] - .unchecked_into(), - //5EX1JBghGbQqWohTPU6msR9qZ2nYPhK9r3RTQ2oD1K8TCxaG - hex!["6c878e33b83c20324238d22240f735457b6fba544b383e70bb62a27b57380c81"] - .unchecked_into(), - //5EUNaBpX9mJgcmLQHyG5Pkms6tbDiKuLbeTEJS924Js9cA1N - hex!["6a8570b9c6408e54bacf123cc2bb1b0f087f9c149147d0005badba63a5a4ac01"] - .unchecked_into(), - //5CaZuueRVpMATZG4hkcrgDoF4WGixuz7zu83jeBdY3bgWGaG - hex!["16c69ea8d595e80b6736f44be1eaeeef2ac9c04a803cc4fd944364cb0d617a33"] - .unchecked_into(), - //5DABsdQCDUGuhzVGWe5xXzYQ9rtrVxRygW7RXf9Tsjsw1aGJ - hex!["306ac5c772fe858942f92b6e28bd82fb7dd8cdd25f9a4626c1b0eee075fcb531"] - .unchecked_into(), - //5H91T5mHhoCw9JJG4NjghDdQyhC6L7XcSuBWKD3q3TAhEVvQ - hex!["02fb0330356e63a35dd930bc74525edf28b3bf5eb44aab9e9e4962c8309aaba6a6"] - .unchecked_into(), - ), - ( - //5C8XbDXdMNKJrZSrQURwVCxdNdk8AzG6xgLggbzuA399bBBF - hex!["02ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864"].into(), - //5GsyzFP8qtF8tXPSsjhjxAeU1v7D1PZofuQKN9TdCc7Dp1JM - hex!["d4ffc4c05b47d1115ad200f7f86e307b20b46c50e1b72a912ec4f6f7db46b616"].into(), - //5GHWB8ZDzegLcMW7Gdd1BS6WHVwDdStfkkE4G7KjPjZNJBtD - hex!["bab3cccdcc34401e9b3971b96a662686cf755aa869a5c4b762199ce531b12c5b"] - .unchecked_into(), - //5GzDPGbUM9uH52ZEwydasTj8edokGUJ7vEpoFWp9FE1YNuFB - hex!["d9c056c98ca0e6b4eb7f5c58c007c1db7be0fe1f3776108f797dd4990d1ccc33"] - .unchecked_into(), - //5CmLCFeSurRXXtwMmLcVo7sdJ9EqDguvJbuCYDcHkr3cpqyE - hex!["1efc23c0b51ad609ab670ecf45807e31acbd8e7e5cb7c07cf49ee42992d2867c"] - .unchecked_into(), - //5DnsSy8a8pfE2aFjKBDtKw7WM1V4nfE5sLzP15MNTka53GqS - hex!["4c64d3f06d28adeb36a892fdaccecace150bec891f04694448a60b74fa469c22"] - .unchecked_into(), - //5CZdFnyzZvKetZTeUwj5APAYskVJe4QFiTezo5dQNsrnehGd - hex!["160ea09c5717270e958a3da42673fa011613a9539b2e4ebcad8626bc117ca04a"] - .unchecked_into(), - //5HgoR9JJkdBusxKrrs3zgd3ToppgNoGj1rDyAJp4e7eZiYyT - hex!["020019a8bb188f8145d02fa855e9c36e9914457d37c500e03634b5223aa5702474"] - .unchecked_into(), - ), - ( - //5HinEonzr8MywkqedcpsmwpxKje2jqr9miEwuzyFXEBCvVXM - hex!["fa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a00"].into(), - //5EHJbj6Td6ks5HDnyfN4ttTSi57osxcQsQexm7XpazdeqtV7 - hex!["62145d721967bd88622d08625f0f5681463c0f1b8bcd97eb3c2c53f7660fd513"].into(), - //5EeCsC58XgJ1DFaoYA1WktEpP27jvwGpKdxPMFjicpLeYu96 - hex!["720537e2c1c554654d73b3889c3ef4c3c2f95a65dd3f7c185ebe4afebed78372"] - .unchecked_into(), - //5DnEySxbnppWEyN8cCLqvGjAorGdLRg2VmkY96dbJ1LHFK8N - hex!["4bea0b37e0cce9bddd80835fa2bfd5606f5dcfb8388bbb10b10c483f0856cf14"] - .unchecked_into(), - //5CAC278tFCHAeHYqE51FTWYxHmeLcENSS1RG77EFRTvPZMJT - hex!["042f07fc5268f13c026bbe199d63e6ac77a0c2a780f71cda05cee5a6f1b3f11f"] - .unchecked_into(), - //5HjRTLWcQjZzN3JDvaj1UzjNSayg5ZD9ZGWMstaL7Ab2jjAa - hex!["fab485e87ed1537d089df521edf983a777c57065a702d7ed2b6a2926f31da74f"] - .unchecked_into(), - //5ELv74v7QcsS6FdzvG4vL2NnYDGWmRnJUSMKYwdyJD7Xcdi7 - hex!["64d59feddb3d00316a55906953fb3db8985797472bd2e6c7ea1ab730cc339d7f"] - .unchecked_into(), - //5FaUcPt4fPz93vBhcrCJqmDkjYZ7jCbzAF56QJoCmvPaKrmx - hex!["033f1a6d47fe86f88934e4b83b9fae903b92b5dcf4fec97d5e3e8bf4f39df03685"] - .unchecked_into(), - ), - ( - //5Ey3NQ3dfabaDc16NUv7wRLsFCMDFJSqZFzKVycAsWuUC6Di - hex!["8062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47"].into(), - //5HiWsuSBqt8nS9pnggexXuHageUifVPKPHDE2arTKqhTp1dV - hex!["fa0388fa88f3f0cb43d583e2571fbc0edad57dff3a6fd89775451dd2c2b8ea00"].into(), - //5H168nKX2Yrfo3bxj7rkcg25326Uv3CCCnKUGK6uHdKMdPt8 - hex!["da6b2df18f0f9001a6dcf1d301b92534fe9b1f3ccfa10c49449fee93adaa8349"] - .unchecked_into(), - //5DrA2fZdzmNqT5j6DXNwVxPBjDV9jhkAqvjt6Us3bQHKy3cF - hex!["4ee66173993dd0db5d628c4c9cb61a27b76611ad3c3925947f0d0011ee2c5dcc"] - .unchecked_into(), - //5Gx6YeNhynqn8qkda9QKpc9S7oDr4sBrfAu516d3sPpEt26F - hex!["d822d4088b20dca29a580a577a97d6f024bb24c9550bebdfd7d2d18e946a1c7d"] - .unchecked_into(), - //5DhDcHqwxoes5s89AyudGMjtZXx1nEgrk5P45X88oSTR3iyx - hex!["481538f8c2c011a76d7d57db11c2789a5e83b0f9680dc6d26211d2f9c021ae4c"] - .unchecked_into(), - //5DqAvikdpfRdk5rR35ZobZhqaC5bJXZcEuvzGtexAZP1hU3T - hex!["4e262811acdfe94528bfc3c65036080426a0e1301b9ada8d687a70ffcae99c26"] - .unchecked_into(), - //5E41Znrr2YtZu8bZp3nvRuLVHg3jFksfQ3tXuviLku4wsao7 - hex!["025e84e95ed043e387ddb8668176b42f8e2773ddd84f7f58a6d9bf436a4b527986"] - .unchecked_into(), - ), - ]; - - const ENDOWMENT: u128 = 1_000_000 * ROC; - const STASH: u128 = 100 * ROC; - - serde_json::json!({ - "balances": { - "balances": endowed_accounts - .iter() - .map(|k: &AccountId| (k.clone(), ENDOWMENT)) - .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) - .collect::>(), - }, - "session": { - "keys": initial_authorities - .iter() - .map(|x| { - ( - x.0.clone(), - x.0.clone(), - rococo_session_keys( - x.2.clone(), - x.3.clone(), - x.4.clone(), - x.5.clone(), - x.6.clone(), - x.7.clone(), - ), - ) - }) - .collect::>(), - }, - "babe": { - "epochConfig": Some(rococo_runtime::BABE_GENESIS_EPOCH_CONFIG), - }, - "sudo": { "key": Some(endowed_accounts[0].clone()) }, - "configuration": { - "config": default_parachains_host_configuration(), - }, - "registrar": { - "nextFreeParaId": polkadot_primitives::LOWEST_PUBLIC_ID, - }, - }) -} - /// Westend staging testnet config. #[cfg(feature = "westend-native")] pub fn westend_staging_testnet_config() -> Result { @@ -682,7 +402,7 @@ pub fn rococo_staging_testnet_config() -> Result { .with_name("Rococo Staging Testnet") .with_id("rococo_staging_testnet") .with_chain_type(ChainType::Live) - .with_genesis_config_patch(rococo_staging_testnet_config_genesis()) + .with_genesis_config_preset_name("staging_testnet") .with_telemetry_endpoints( TelemetryEndpoints::new(vec![(ROCOCO_STAGING_TELEMETRY_URL.to_string(), 0)]) .expect("Rococo Staging telemetry url is valid; qed"), @@ -712,7 +432,7 @@ pub fn versi_staging_testnet_config() -> Result { .with_name("Versi Staging Testnet") .with_id("versi_staging_testnet") .with_chain_type(ChainType::Live) - .with_genesis_config_patch(rococo_staging_testnet_config_genesis()) + .with_genesis_config_preset_name("staging_testnet") .with_telemetry_endpoints( TelemetryEndpoints::new(vec![(VERSI_STAGING_TELEMETRY_URL.to_string(), 0)]) .expect("Versi Staging telemetry url is valid; qed"), @@ -769,7 +489,7 @@ pub fn get_authority_keys_from_seed_no_beefy( ) } -#[cfg(any(feature = "westend-native", feature = "rococo-native"))] +#[cfg(feature = "westend-native")] fn testnet_accounts() -> Vec { vec![ get_account_id_from_seed::("Alice"), @@ -855,68 +575,6 @@ pub fn westend_testnet_genesis( }) } -/// Helper function to create rococo runtime `GenesisConfig` patch for testing -#[cfg(feature = "rococo-native")] -pub fn rococo_testnet_genesis( - initial_authorities: Vec<( - AccountId, - AccountId, - BabeId, - GrandpaId, - ValidatorId, - AssignmentId, - AuthorityDiscoveryId, - BeefyId, - )>, - root_key: AccountId, - endowed_accounts: Option>, -) -> serde_json::Value { - let endowed_accounts: Vec = endowed_accounts.unwrap_or_else(testnet_accounts); - - const ENDOWMENT: u128 = 1_000_000 * ROC; - - serde_json::json!({ - "balances": { - "balances": endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>(), - }, - "session": { - "keys": initial_authorities - .iter() - .map(|x| { - ( - x.0.clone(), - x.0.clone(), - rococo_session_keys( - x.2.clone(), - x.3.clone(), - x.4.clone(), - x.5.clone(), - x.6.clone(), - x.7.clone(), - ), - ) - }) - .collect::>(), - }, - "babe": { - "epochConfig": Some(rococo_runtime::BABE_GENESIS_EPOCH_CONFIG), - }, - "sudo": { "key": Some(root_key.clone()) }, - "configuration": { - "config": polkadot_runtime_parachains::configuration::HostConfiguration { - scheduler_params: SchedulerParams { - max_validators_per_core: Some(1), - ..default_parachains_host_configuration().scheduler_params - }, - ..default_parachains_host_configuration() - }, - }, - "registrar": { - "nextFreeParaId": polkadot_primitives::LOWEST_PUBLIC_ID, - } - }) -} - #[cfg(feature = "westend-native")] fn westend_development_config_genesis() -> serde_json::Value { westend_testnet_genesis( @@ -926,15 +584,6 @@ fn westend_development_config_genesis() -> serde_json::Value { ) } -#[cfg(feature = "rococo-native")] -fn rococo_development_config_genesis() -> serde_json::Value { - rococo_testnet_genesis( - vec![get_authority_keys_from_seed("Alice")], - get_account_id_from_seed::("Alice"), - None, - ) -} - /// Westend development config (single validator Alice) #[cfg(feature = "westend-native")] pub fn westend_development_config() -> Result { @@ -960,7 +609,7 @@ pub fn rococo_development_config() -> Result { .with_name("Development") .with_id("rococo_dev") .with_chain_type(ChainType::Development) - .with_genesis_config_patch(rococo_development_config_genesis()) + .with_genesis_config_preset_name("development") .with_protocol_id(DEFAULT_PROTOCOL_ID) .build()) } @@ -975,7 +624,7 @@ pub fn versi_development_config() -> Result { .with_name("Development") .with_id("versi_dev") .with_chain_type(ChainType::Development) - .with_genesis_config_patch(rococo_development_config_genesis()) + .with_genesis_config_preset_name("development") .with_protocol_id("versi") .build()) } @@ -991,7 +640,7 @@ pub fn wococo_development_config() -> Result { .with_name("Development") .with_id("wococo_dev") .with_chain_type(ChainType::Development) - .with_genesis_config_patch(rococo_development_config_genesis()) + .with_genesis_config_preset_name("development") .with_protocol_id(WOCOCO_DEV_PROTOCOL_ID) .build()) } @@ -1020,15 +669,6 @@ pub fn westend_local_testnet_config() -> Result { .build()) } -#[cfg(feature = "rococo-native")] -fn rococo_local_testnet_genesis() -> serde_json::Value { - rococo_testnet_genesis( - vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")], - get_account_id_from_seed::("Alice"), - None, - ) -} - /// Rococo local testnet config (multivalidator Alice + Bob) #[cfg(feature = "rococo-native")] pub fn rococo_local_testnet_config() -> Result { @@ -1039,26 +679,11 @@ pub fn rococo_local_testnet_config() -> Result { .with_name("Rococo Local Testnet") .with_id("rococo_local_testnet") .with_chain_type(ChainType::Local) - .with_genesis_config_patch(rococo_local_testnet_genesis()) + .with_genesis_config_preset_name("local_testnet") .with_protocol_id(DEFAULT_PROTOCOL_ID) .build()) } -/// Wococo is a temporary testnet that uses almost the same runtime as rococo. -#[cfg(feature = "rococo-native")] -fn wococo_local_testnet_genesis() -> serde_json::Value { - rococo_testnet_genesis( - vec![ - get_authority_keys_from_seed("Alice"), - get_authority_keys_from_seed("Bob"), - get_authority_keys_from_seed("Charlie"), - get_authority_keys_from_seed("Dave"), - ], - get_account_id_from_seed::("Alice"), - None, - ) -} - /// Wococo local testnet config (multivalidator Alice + Bob + Charlie + Dave) #[cfg(feature = "rococo-native")] pub fn wococo_local_testnet_config() -> Result { @@ -1069,26 +694,11 @@ pub fn wococo_local_testnet_config() -> Result { .with_name("Wococo Local Testnet") .with_id("wococo_local_testnet") .with_chain_type(ChainType::Local) - .with_genesis_config_patch(wococo_local_testnet_genesis()) + .with_genesis_config_preset_name("wococo_local_testnet") .with_protocol_id(DEFAULT_PROTOCOL_ID) .build()) } -/// `Versi` is a temporary testnet that uses the same runtime as rococo. -#[cfg(feature = "rococo-native")] -fn versi_local_testnet_genesis() -> serde_json::Value { - rococo_testnet_genesis( - vec![ - get_authority_keys_from_seed("Alice"), - get_authority_keys_from_seed("Bob"), - get_authority_keys_from_seed("Charlie"), - get_authority_keys_from_seed("Dave"), - ], - get_account_id_from_seed::("Alice"), - None, - ) -} - /// `Versi` local testnet config (multivalidator Alice + Bob + Charlie + Dave) #[cfg(feature = "rococo-native")] pub fn versi_local_testnet_config() -> Result { @@ -1099,7 +709,7 @@ pub fn versi_local_testnet_config() -> Result { .with_name("Versi Local Testnet") .with_id("versi_local_testnet") .with_chain_type(ChainType::Local) - .with_genesis_config_patch(versi_local_testnet_genesis()) + .with_genesis_config_preset_name("versi_local_testnet") .with_protocol_id("versi") .build()) } diff --git a/polkadot/runtime/rococo/Cargo.toml b/polkadot/runtime/rococo/Cargo.toml index 19cc984e5829..20a914fb8085 100644 --- a/polkadot/runtime/rococo/Cargo.toml +++ b/polkadot/runtime/rococo/Cargo.toml @@ -16,12 +16,15 @@ scale-info = { version = "2.11.1", default-features = false, features = ["derive log = { workspace = true } serde = { workspace = true } serde_derive = { optional = true, workspace = true } +serde_json = { features = ["alloc"], workspace = true } static_assertions = "1.1.0" smallvec = "1.8.0" +bitvec = { version = "1.0.1", default-features = false, features = ["alloc"] } authority-discovery-primitives = { package = "sp-authority-discovery", path = "../../../substrate/primitives/authority-discovery", default-features = false } babe-primitives = { package = "sp-consensus-babe", path = "../../../substrate/primitives/consensus/babe", default-features = false } beefy-primitives = { package = "sp-consensus-beefy", path = "../../../substrate/primitives/consensus/beefy", default-features = false } +grandpa_primitives = { package = "sp-consensus-grandpa", path = "../../../substrate/primitives/consensus/grandpa", default-features = false } binary-merkle-tree = { path = "../../../substrate/utils/binary-merkle-tree", default-features = false } rococo-runtime-constants = { package = "rococo-runtime-constants", path = "constants", default-features = false } sp-api = { path = "../../../substrate/primitives/api", default-features = false } @@ -126,6 +129,7 @@ std = [ "babe-primitives/std", "beefy-primitives/std", "binary-merkle-tree/std", + "bitvec/std", "block-builder-api/std", "frame-benchmarking?/std", "frame-executive/std", @@ -134,6 +138,7 @@ std = [ "frame-system-rpc-runtime-api/std", "frame-system/std", "frame-try-runtime/std", + "grandpa_primitives/std", "inherents/std", "log/std", "offchain-primitives/std", @@ -190,6 +195,7 @@ std = [ "scale-info/std", "serde/std", "serde_derive", + "serde_json/std", "sp-api/std", "sp-arithmetic/std", "sp-core/std", diff --git a/polkadot/runtime/rococo/src/genesis_config_presets.rs b/polkadot/runtime/rococo/src/genesis_config_presets.rs new file mode 100644 index 000000000000..bac6902383e3 --- /dev/null +++ b/polkadot/runtime/rococo/src/genesis_config_presets.rs @@ -0,0 +1,544 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Genesis configs presets for the Rococo runtime + +use crate::{SessionKeys, BABE_GENESIS_EPOCH_CONFIG}; +use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; +use babe_primitives::AuthorityId as BabeId; +use beefy_primitives::ecdsa_crypto::AuthorityId as BeefyId; +use grandpa_primitives::AuthorityId as GrandpaId; +use primitives::{vstaging::SchedulerParams, AccountId, AccountPublic, AssignmentId, ValidatorId}; +use rococo_runtime_constants::currency::UNITS as ROC; +use sp_core::{sr25519, Pair, Public}; +use sp_runtime::traits::IdentifyAccount; +#[cfg(not(feature = "std"))] +use sp_std::alloc::format; +use sp_std::vec::Vec; + +/// Helper function to generate a crypto pair from seed +fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() +} + +/// Helper function to generate an account ID from seed +fn get_account_id_from_seed(seed: &str) -> AccountId +where + AccountPublic: From<::Public>, +{ + AccountPublic::from(get_from_seed::(seed)).into_account() +} + +/// Helper function to generate stash, controller and session key from seed +fn get_authority_keys_from_seed( + seed: &str, +) -> ( + AccountId, + AccountId, + BabeId, + GrandpaId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + BeefyId, +) { + let keys = get_authority_keys_from_seed_no_beefy(seed); + (keys.0, keys.1, keys.2, keys.3, keys.4, keys.5, keys.6, get_from_seed::(seed)) +} + +/// Helper function to generate stash, controller and session key from seed +fn get_authority_keys_from_seed_no_beefy( + seed: &str, +) -> (AccountId, AccountId, BabeId, GrandpaId, ValidatorId, AssignmentId, AuthorityDiscoveryId) { + ( + get_account_id_from_seed::(&format!("{}//stash", seed)), + get_account_id_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + ) +} + +fn testnet_accounts() -> Vec { + Vec::from([ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), + ]) +} + +fn rococo_session_keys( + babe: BabeId, + grandpa: GrandpaId, + para_validator: ValidatorId, + para_assignment: AssignmentId, + authority_discovery: AuthorityDiscoveryId, + beefy: BeefyId, +) -> SessionKeys { + SessionKeys { babe, grandpa, para_validator, para_assignment, authority_discovery, beefy } +} + +fn default_parachains_host_configuration( +) -> runtime_parachains::configuration::HostConfiguration { + use primitives::{ + node_features::FeatureIndex, AsyncBackingParams, MAX_CODE_SIZE, MAX_POV_SIZE, + }; + + runtime_parachains::configuration::HostConfiguration { + validation_upgrade_cooldown: 2u32, + validation_upgrade_delay: 2, + code_retention_period: 1200, + max_code_size: MAX_CODE_SIZE, + max_pov_size: MAX_POV_SIZE, + max_head_data_size: 32 * 1024, + max_upward_queue_count: 8, + max_upward_queue_size: 1024 * 1024, + max_downward_message_size: 1024 * 1024, + max_upward_message_size: 50 * 1024, + max_upward_message_num_per_candidate: 5, + hrmp_sender_deposit: 0, + hrmp_recipient_deposit: 0, + hrmp_channel_max_capacity: 8, + hrmp_channel_max_total_size: 8 * 1024, + hrmp_max_parachain_inbound_channels: 4, + hrmp_channel_max_message_size: 1024 * 1024, + hrmp_max_parachain_outbound_channels: 4, + hrmp_max_message_num_per_candidate: 5, + dispute_period: 6, + no_show_slots: 2, + n_delay_tranches: 25, + needed_approvals: 2, + relay_vrf_modulo_samples: 2, + zeroth_delay_tranche_width: 0, + minimum_validation_upgrade_delay: 5, + async_backing_params: AsyncBackingParams { + max_candidate_depth: 3, + allowed_ancestry_len: 2, + }, + node_features: bitvec::vec::BitVec::from_element( + 1u8 << (FeatureIndex::ElasticScalingMVP as usize), + ), + scheduler_params: SchedulerParams { + lookahead: 2, + group_rotation_frequency: 20, + paras_availability_period: 4, + ..Default::default() + }, + ..Default::default() + } +} + +#[test] +fn default_parachains_host_configuration_is_consistent() { + default_parachains_host_configuration().panic_if_not_consistent(); +} + +fn rococo_testnet_genesis( + initial_authorities: Vec<( + AccountId, + AccountId, + BabeId, + GrandpaId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + BeefyId, + )>, + root_key: AccountId, + endowed_accounts: Option>, +) -> serde_json::Value { + let endowed_accounts: Vec = endowed_accounts.unwrap_or_else(testnet_accounts); + + const ENDOWMENT: u128 = 1_000_000 * ROC; + + serde_json::json!({ + "balances": { + "balances": endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>(), + }, + "session": { + "keys": initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + rococo_session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + x.7.clone(), + ), + ) + }) + .collect::>(), + }, + "babe": { + "epochConfig": Some(BABE_GENESIS_EPOCH_CONFIG), + }, + "sudo": { "key": Some(root_key.clone()) }, + "configuration": { + "config": runtime_parachains::configuration::HostConfiguration { + scheduler_params: SchedulerParams { + max_validators_per_core: Some(1), + ..default_parachains_host_configuration().scheduler_params + }, + ..default_parachains_host_configuration() + }, + }, + "registrar": { + "nextFreeParaId": primitives::LOWEST_PUBLIC_ID, + } + }) +} + +// staging_testnet +fn rococo_staging_testnet_config_genesis() -> serde_json::Value { + use hex_literal::hex; + use sp_core::crypto::UncheckedInto; + + // subkey inspect "$SECRET" + let endowed_accounts = Vec::from([ + // 5DwBmEFPXRESyEam5SsQF1zbWSCn2kCjyLW51hJHXe9vW4xs + hex!["52bc71c1eca5353749542dfdf0af97bf764f9c2f44e860cd485f1cd86400f649"].into(), + ]); + + // ./scripts/prepare-test-net.sh 8 + let initial_authorities: Vec<( + AccountId, + AccountId, + BabeId, + GrandpaId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + BeefyId, + )> = Vec::from([ + ( + //5EHZkbp22djdbuMFH9qt1DVzSCvqi3zWpj6DAYfANa828oei + hex!["62475fe5406a7cb6a64c51d0af9d3ab5c2151bcae982fb812f7a76b706914d6a"].into(), + //5FeSEpi9UYYaWwXXb3tV88qtZkmSdB3mvgj3pXkxKyYLGhcd + hex!["9e6e781a76810fe93187af44c79272c290c2b9e2b8b92ee11466cd79d8023f50"].into(), + //5Fh6rDpMDhM363o1Z3Y9twtaCPfizGQWCi55BSykTQjGbP7H + hex!["a076ef1280d768051f21d060623da3ab5b56944d681d303ed2d4bf658c5bed35"] + .unchecked_into(), + //5CPd3zoV9Aaah4xWucuDivMHJ2nEEmpdi864nPTiyRZp4t87 + hex!["0e6d7d1afbcc6547b92995a394ba0daed07a2420be08220a5a1336c6731f0bfa"] + .unchecked_into(), + //5CP6oGfwqbEfML8efqm1tCZsUgRsJztp9L8ZkEUxA16W8PPz + hex!["0e07a51d3213842f8e9363ce8e444255990a225f87e80a3d651db7841e1a0205"] + .unchecked_into(), + //5HQdwiDh8Qtd5dSNWajNYpwDvoyNWWA16Y43aEkCNactFc2b + hex!["ec60e71fe4a567ef9fef99d4bbf37ffae70564b41aa6f94ef0317c13e0a5477b"] + .unchecked_into(), + //5HbSgM72xVuscsopsdeG3sCSCYdAeM1Tay9p79N6ky6vwDGq + hex!["f49eae66a0ac9f610316906ec8f1a0928e20d7059d76a5ca53cbcb5a9b50dd3c"] + .unchecked_into(), + //5DPSWdgw38Spu315r6LSvYCggeeieBAJtP5A1qzuzKhqmjVu + hex!["034f68c5661a41930c82f26a662276bf89f33467e1c850f2fb8ef687fe43d62276"] + .unchecked_into(), + ), + ( + //5DvH8oEjQPYhzCoQVo7WDU91qmQfLZvxe9wJcrojmJKebCmG + hex!["520b48452969f6ddf263b664de0adb0c729d0e0ad3b0e5f3cb636c541bc9022a"].into(), + //5ENZvCRzyXJJYup8bM6yEzb2kQHEb1NDpY2ZEyVGBkCfRdj3 + hex!["6618289af7ae8621981ffab34591e7a6486e12745dfa3fd3b0f7e6a3994c7b5b"].into(), + //5DLjSUfqZVNAADbwYLgRvHvdzXypiV1DAEaDMjcESKTcqMoM + hex!["38757d0de00a0c739e7d7984ef4bc01161bd61e198b7c01b618425c16bb5bd5f"] + .unchecked_into(), + //5HnDVBN9mD6mXyx8oryhDbJtezwNSj1VRXgLoYCBA6uEkiao + hex!["fcd5f87a6fd5707a25122a01b4dac0a8482259df7d42a9a096606df1320df08d"] + .unchecked_into(), + //5EPEWRecy2ApL5n18n3aHyU1956zXTRqaJpzDa9DoqiggNwF + hex!["669a10892119453e9feb4e3f1ee8e028916cc3240022920ad643846fbdbee816"] + .unchecked_into(), + //5ES3fw5X4bndSgLNmtPfSbM2J1kLqApVB2CCLS4CBpM1UxUZ + hex!["68bf52c482630a8d1511f2edd14f34127a7d7082219cccf7fd4c6ecdb535f80d"] + .unchecked_into(), + //5HeXbwb5PxtcRoopPZTp5CQun38atn2UudQ8p2AxR5BzoaXw + hex!["f6f8fe475130d21165446a02fb1dbce3a7bf36412e5d98f4f0473aed9252f349"] + .unchecked_into(), + //5F7nTtN8MyJV4UsXpjg7tHSnfANXZ5KRPJmkASc1ZSH2Xoa5 + hex!["03a90c2bb6d3b7000020f6152fe2e5002fa970fd1f42aafb6c8edda8dacc2ea77e"] + .unchecked_into(), + ), + ( + //5FPMzsezo1PRxYbVpJMWK7HNbR2kUxidsAAxH4BosHa4wd6S + hex!["92ef83665b39d7a565e11bf8d18d41d45a8011601c339e57a8ea88c8ff7bba6f"].into(), + //5G6NQidFG7YiXsvV7hQTLGArir9tsYqD4JDxByhgxKvSKwRx + hex!["b235f57244230589523271c27b8a490922ffd7dccc83b044feaf22273c1dc735"].into(), + //5GpZhzAVg7SAtzLvaAC777pjquPEcNy1FbNUAG2nZvhmd6eY + hex!["d2644c1ab2c63a3ad8d40ad70d4b260969e3abfe6d7e6665f50dc9f6365c9d2a"] + .unchecked_into(), + //5HAes2RQYPbYKbLBfKb88f4zoXv6pPA6Ke8CjN7dob3GpmSP + hex!["e1b68fbd84333e31486c08e6153d9a1415b2e7e71b413702b7d64e9b631184a1"] + .unchecked_into(), + //5FtAGDZYJKXkhVhAxCQrXmaP7EE2mGbBMfmKDHjfYDgq2BiU + hex!["a8e61ffacafaf546283dc92d14d7cc70ea0151a5dd81fdf73ff5a2951f2b6037"] + .unchecked_into(), + //5CtK7JHv3h6UQZ44y54skxdwSVBRtuxwPE1FYm7UZVhg8rJV + hex!["244f3421b310c68646e99cdbf4963e02067601f57756b072a4b19431448c186e"] + .unchecked_into(), + //5D4r6YaB6F7A7nvMRHNFNF6zrR9g39bqDJFenrcaFmTCRwfa + hex!["2c57f81fd311c1ab53813c6817fe67f8947f8d39258252663b3384ab4195494d"] + .unchecked_into(), + //5EPoHj8uV4fFKQHYThc6Z9fDkU7B6ih2ncVzQuDdNFb8UyhF + hex!["039d065fe4f9234f0a4f13cc3ae585f2691e9c25afa469618abb6645111f607a53"] + .unchecked_into(), + ), + ( + //5DMNx7RoX6d7JQ38NEM7DWRcW2THu92LBYZEWvBRhJeqcWgR + hex!["38f3c2f38f6d47f161e98c697bbe3ca0e47c033460afda0dda314ab4222a0404"].into(), + //5GGdKNDr9P47dpVnmtq3m8Tvowwf1ot1abw6tPsTYYFoKm2v + hex!["ba0898c1964196474c0be08d364cdf4e9e1d47088287f5235f70b0590dfe1704"].into(), + //5EjkyPCzR2SjhDZq8f7ufsw6TfkvgNRepjCRQFc4TcdXdaB1 + hex!["764186bc30fd5a02477f19948dc723d6d57ab174debd4f80ed6038ec960bfe21"] + .unchecked_into(), + //5DJV3zCBTJBLGNDCcdWrYxWDacSz84goGTa4pFeKVvehEBte + hex!["36be9069cdb4a8a07ecd51f257875150f0a8a1be44a10d9d98dabf10a030aef4"] + .unchecked_into(), + //5F9FsRjpecP9GonktmtFL3kjqNAMKjHVFjyjRdTPa4hbQRZA + hex!["882d72965e642677583b333b2d173ac94b5fd6c405c76184bb14293be748a13b"] + .unchecked_into(), + //5F1FZWZSj3JyTLs8sRBxU6QWyGLSL9BMRtmSKDmVEoiKFxSP + hex!["821271c99c958b9220f1771d9f5e29af969edfa865631dba31e1ab7bc0582b75"] + .unchecked_into(), + //5CtgRR74VypK4h154s369abs78hDUxZSJqcbWsfXvsjcHJNA + hex!["2496f28d887d84705c6dae98aee8bf90fc5ad10bb5545eca1de6b68425b70f7c"] + .unchecked_into(), + //5CPx6dsr11SCJHKFkcAQ9jpparS7FwXQBrrMznRo4Hqv1PXz + hex!["0307d29bbf6a5c4061c2157b44fda33b7bb4ec52a5a0305668c74688cedf288d58"] + .unchecked_into(), + ), + ( + //5C8AL1Zb4bVazgT3EgDxFgcow1L4SJjVu44XcLC9CrYqFN4N + hex!["02a2d8cfcf75dda85fafc04ace3bcb73160034ed1964c43098fb1fe831de1b16"].into(), + //5FLYy3YKsAnooqE4hCudttAsoGKbVG3hYYBtVzwMjJQrevPa + hex!["90cab33f0bb501727faa8319f0845faef7d31008f178b65054b6629fe531b772"].into(), + //5Et3tfbVf1ByFThNAuUq5pBssdaPPskip5yob5GNyUFojXC7 + hex!["7c94715e5dd8ab54221b1b6b2bfa5666f593f28a92a18e28052531de1bd80813"] + .unchecked_into(), + //5EX1JBghGbQqWohTPU6msR9qZ2nYPhK9r3RTQ2oD1K8TCxaG + hex!["6c878e33b83c20324238d22240f735457b6fba544b383e70bb62a27b57380c81"] + .unchecked_into(), + //5EUNaBpX9mJgcmLQHyG5Pkms6tbDiKuLbeTEJS924Js9cA1N + hex!["6a8570b9c6408e54bacf123cc2bb1b0f087f9c149147d0005badba63a5a4ac01"] + .unchecked_into(), + //5CaZuueRVpMATZG4hkcrgDoF4WGixuz7zu83jeBdY3bgWGaG + hex!["16c69ea8d595e80b6736f44be1eaeeef2ac9c04a803cc4fd944364cb0d617a33"] + .unchecked_into(), + //5DABsdQCDUGuhzVGWe5xXzYQ9rtrVxRygW7RXf9Tsjsw1aGJ + hex!["306ac5c772fe858942f92b6e28bd82fb7dd8cdd25f9a4626c1b0eee075fcb531"] + .unchecked_into(), + //5H91T5mHhoCw9JJG4NjghDdQyhC6L7XcSuBWKD3q3TAhEVvQ + hex!["02fb0330356e63a35dd930bc74525edf28b3bf5eb44aab9e9e4962c8309aaba6a6"] + .unchecked_into(), + ), + ( + //5C8XbDXdMNKJrZSrQURwVCxdNdk8AzG6xgLggbzuA399bBBF + hex!["02ea6bfa8b23b92fe4b5db1063a1f9475e3acd0ab61e6b4f454ed6ba00b5f864"].into(), + //5GsyzFP8qtF8tXPSsjhjxAeU1v7D1PZofuQKN9TdCc7Dp1JM + hex!["d4ffc4c05b47d1115ad200f7f86e307b20b46c50e1b72a912ec4f6f7db46b616"].into(), + //5GHWB8ZDzegLcMW7Gdd1BS6WHVwDdStfkkE4G7KjPjZNJBtD + hex!["bab3cccdcc34401e9b3971b96a662686cf755aa869a5c4b762199ce531b12c5b"] + .unchecked_into(), + //5GzDPGbUM9uH52ZEwydasTj8edokGUJ7vEpoFWp9FE1YNuFB + hex!["d9c056c98ca0e6b4eb7f5c58c007c1db7be0fe1f3776108f797dd4990d1ccc33"] + .unchecked_into(), + //5CmLCFeSurRXXtwMmLcVo7sdJ9EqDguvJbuCYDcHkr3cpqyE + hex!["1efc23c0b51ad609ab670ecf45807e31acbd8e7e5cb7c07cf49ee42992d2867c"] + .unchecked_into(), + //5DnsSy8a8pfE2aFjKBDtKw7WM1V4nfE5sLzP15MNTka53GqS + hex!["4c64d3f06d28adeb36a892fdaccecace150bec891f04694448a60b74fa469c22"] + .unchecked_into(), + //5CZdFnyzZvKetZTeUwj5APAYskVJe4QFiTezo5dQNsrnehGd + hex!["160ea09c5717270e958a3da42673fa011613a9539b2e4ebcad8626bc117ca04a"] + .unchecked_into(), + //5HgoR9JJkdBusxKrrs3zgd3ToppgNoGj1rDyAJp4e7eZiYyT + hex!["020019a8bb188f8145d02fa855e9c36e9914457d37c500e03634b5223aa5702474"] + .unchecked_into(), + ), + ( + //5HinEonzr8MywkqedcpsmwpxKje2jqr9miEwuzyFXEBCvVXM + hex!["fa373e25a1c4fe19c7148acde13bc3db1811cf656dc086820f3dda736b9c4a00"].into(), + //5EHJbj6Td6ks5HDnyfN4ttTSi57osxcQsQexm7XpazdeqtV7 + hex!["62145d721967bd88622d08625f0f5681463c0f1b8bcd97eb3c2c53f7660fd513"].into(), + //5EeCsC58XgJ1DFaoYA1WktEpP27jvwGpKdxPMFjicpLeYu96 + hex!["720537e2c1c554654d73b3889c3ef4c3c2f95a65dd3f7c185ebe4afebed78372"] + .unchecked_into(), + //5DnEySxbnppWEyN8cCLqvGjAorGdLRg2VmkY96dbJ1LHFK8N + hex!["4bea0b37e0cce9bddd80835fa2bfd5606f5dcfb8388bbb10b10c483f0856cf14"] + .unchecked_into(), + //5CAC278tFCHAeHYqE51FTWYxHmeLcENSS1RG77EFRTvPZMJT + hex!["042f07fc5268f13c026bbe199d63e6ac77a0c2a780f71cda05cee5a6f1b3f11f"] + .unchecked_into(), + //5HjRTLWcQjZzN3JDvaj1UzjNSayg5ZD9ZGWMstaL7Ab2jjAa + hex!["fab485e87ed1537d089df521edf983a777c57065a702d7ed2b6a2926f31da74f"] + .unchecked_into(), + //5ELv74v7QcsS6FdzvG4vL2NnYDGWmRnJUSMKYwdyJD7Xcdi7 + hex!["64d59feddb3d00316a55906953fb3db8985797472bd2e6c7ea1ab730cc339d7f"] + .unchecked_into(), + //5FaUcPt4fPz93vBhcrCJqmDkjYZ7jCbzAF56QJoCmvPaKrmx + hex!["033f1a6d47fe86f88934e4b83b9fae903b92b5dcf4fec97d5e3e8bf4f39df03685"] + .unchecked_into(), + ), + ( + //5Ey3NQ3dfabaDc16NUv7wRLsFCMDFJSqZFzKVycAsWuUC6Di + hex!["8062e9c21f1d92926103119f7e8153cebdb1e5ab3e52d6f395be80bb193eab47"].into(), + //5HiWsuSBqt8nS9pnggexXuHageUifVPKPHDE2arTKqhTp1dV + hex!["fa0388fa88f3f0cb43d583e2571fbc0edad57dff3a6fd89775451dd2c2b8ea00"].into(), + //5H168nKX2Yrfo3bxj7rkcg25326Uv3CCCnKUGK6uHdKMdPt8 + hex!["da6b2df18f0f9001a6dcf1d301b92534fe9b1f3ccfa10c49449fee93adaa8349"] + .unchecked_into(), + //5DrA2fZdzmNqT5j6DXNwVxPBjDV9jhkAqvjt6Us3bQHKy3cF + hex!["4ee66173993dd0db5d628c4c9cb61a27b76611ad3c3925947f0d0011ee2c5dcc"] + .unchecked_into(), + //5Gx6YeNhynqn8qkda9QKpc9S7oDr4sBrfAu516d3sPpEt26F + hex!["d822d4088b20dca29a580a577a97d6f024bb24c9550bebdfd7d2d18e946a1c7d"] + .unchecked_into(), + //5DhDcHqwxoes5s89AyudGMjtZXx1nEgrk5P45X88oSTR3iyx + hex!["481538f8c2c011a76d7d57db11c2789a5e83b0f9680dc6d26211d2f9c021ae4c"] + .unchecked_into(), + //5DqAvikdpfRdk5rR35ZobZhqaC5bJXZcEuvzGtexAZP1hU3T + hex!["4e262811acdfe94528bfc3c65036080426a0e1301b9ada8d687a70ffcae99c26"] + .unchecked_into(), + //5E41Znrr2YtZu8bZp3nvRuLVHg3jFksfQ3tXuviLku4wsao7 + hex!["025e84e95ed043e387ddb8668176b42f8e2773ddd84f7f58a6d9bf436a4b527986"] + .unchecked_into(), + ), + ]); + + const ENDOWMENT: u128 = 1_000_000 * ROC; + const STASH: u128 = 100 * ROC; + + serde_json::json!({ + "balances": { + "balances": endowed_accounts + .iter() + .map(|k: &AccountId| (k.clone(), ENDOWMENT)) + .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) + .collect::>(), + }, + "session": { + "keys": initial_authorities + .into_iter() + .map(|x| { + ( + x.0.clone(), + x.0, + rococo_session_keys( + x.2, + x.3, + x.4, + x.5, + x.6, + x.7, + ), + ) + }) + .collect::>(), + }, + "babe": { + "epochConfig": Some(BABE_GENESIS_EPOCH_CONFIG), + }, + "sudo": { "key": Some(endowed_accounts[0].clone()) }, + "configuration": { + "config": default_parachains_host_configuration(), + }, + "registrar": { + "nextFreeParaId": primitives::LOWEST_PUBLIC_ID, + }, + }) +} + +//development +fn rococo_development_config_genesis() -> serde_json::Value { + rococo_testnet_genesis( + Vec::from([get_authority_keys_from_seed("Alice")]), + get_account_id_from_seed::("Alice"), + None, + ) +} + +//local_testnet +fn rococo_local_testnet_genesis() -> serde_json::Value { + rococo_testnet_genesis( + Vec::from([get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")]), + get_account_id_from_seed::("Alice"), + None, + ) +} + +/// `Versi` is a temporary testnet that uses the same runtime as rococo. +// versi_local_testnet +fn versi_local_testnet_genesis() -> serde_json::Value { + rococo_testnet_genesis( + Vec::from([ + get_authority_keys_from_seed("Alice"), + get_authority_keys_from_seed("Bob"), + get_authority_keys_from_seed("Charlie"), + get_authority_keys_from_seed("Dave"), + ]), + get_account_id_from_seed::("Alice"), + None, + ) +} + +/// Wococo is a temporary testnet that uses almost the same runtime as rococo. +//wococo_local_testnet +fn wococo_local_testnet_genesis() -> serde_json::Value { + rococo_testnet_genesis( + Vec::from([ + get_authority_keys_from_seed("Alice"), + get_authority_keys_from_seed("Bob"), + get_authority_keys_from_seed("Charlie"), + get_authority_keys_from_seed("Dave"), + ]), + get_account_id_from_seed::("Alice"), + None, + ) +} + +/// Provides the JSON representation of predefined genesis config for given `id`. +pub fn get_preset(id: &sp_genesis_builder::PresetId) -> Option> { + let patch = match id.try_into() { + Ok("local_testnet") => rococo_local_testnet_genesis(), + Ok("development") => rococo_development_config_genesis(), + Ok("staging_testnet") => rococo_staging_testnet_config_genesis(), + Ok("wococo_local_testnet") => wococo_local_testnet_genesis(), + Ok("versi_local_testnet") => versi_local_testnet_genesis(), + _ => return None, + }; + Some( + serde_json::to_string(&patch) + .expect("serialization to json is expected to work. qed.") + .into_bytes(), + ) +} diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 471bb891e00e..4633a0099947 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -20,6 +20,11 @@ // `construct_runtime!` does a lot of recursion and requires us to increase the limit. #![recursion_limit = "512"] +use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; +use beefy_primitives::{ + ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}, + mmr::{BeefyDataProvider, MmrLeafVersion}, +}; use pallet_nis::WithMaximumOf; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use primitives::{ @@ -40,9 +45,6 @@ use runtime_common::{ traits::{Leaser, OnSwap}, BlockHashCount, BlockLength, SlowAdjustingFeeUpdate, }; -use scale_info::TypeInfo; -use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*}; - use runtime_parachains::{ assigner_coretime as parachains_assigner_coretime, assigner_on_demand as parachains_assigner_on_demand, configuration as parachains_configuration, @@ -56,16 +58,13 @@ use runtime_parachains::{ scheduler as parachains_scheduler, session_info as parachains_session_info, shared as parachains_shared, }; - -use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; -use beefy_primitives::{ - ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}, - mmr::{BeefyDataProvider, MmrLeafVersion}, -}; +use scale_info::TypeInfo; +use sp_genesis_builder::PresetId; +use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*}; use frame_support::{ construct_runtime, derive_impl, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ fungible::HoldConsideration, Contains, EitherOf, EitherOfDiverse, EverythingBut, @@ -127,6 +126,7 @@ use xcm_fee_payment_runtime_api::Error as XcmPaymentApiError; #[cfg(test)] mod tests; +mod genesis_config_presets; mod validator_manager; impl_runtime_weights!(rococo_runtime_constants); @@ -2363,12 +2363,22 @@ sp_api::impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) + } + + fn get_preset(id: &Option) -> Option> { + get_preset::(id, &genesis_config_presets::get_preset) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn preset_names() -> Vec { + vec![ + PresetId::from("local_testnet"), + PresetId::from("development"), + PresetId::from("staging_testnet"), + PresetId::from("wococo_local_testnet"), + PresetId::from("versi_local_testnet"), + ] } } } diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index 40aa4a1d4997..f01382509501 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -43,7 +43,7 @@ use frame_election_provider_support::{ }; use frame_support::{ construct_runtime, derive_impl, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{KeyOwnerProofSystem, WithdrawReasons}, }; @@ -1171,12 +1171,16 @@ sp_api::impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 4de1dbc16e09..a64c0e80bd2f 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -28,7 +28,7 @@ use beefy_primitives::{ use frame_election_provider_support::{bounds::ElectionBoundsBuilder, onchain, SequentialPhragmen}; use frame_support::{ derive_impl, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ fungible::HoldConsideration, ConstU32, Contains, EitherOf, EitherOfDiverse, EverythingBut, @@ -2515,12 +2515,16 @@ sp_api::impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/prdoc/pr_2714.prdoc b/prdoc/pr_2714.prdoc new file mode 100644 index 000000000000..f5f6e61c656e --- /dev/null +++ b/prdoc/pr_2714.prdoc @@ -0,0 +1,23 @@ +title: GenesisConfig presets for runtime + +doc: + - audience: Runtime Dev + description: | + 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, + - (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. + + - audience: Node Dev + description: | + The `ChainSpecBuilder` is extended with `with_genesis_config_preset_name` method which allows to build chain-spec using named preset provided by the runtime. + +crates: + - name: sp-genesis-builder + bump: minor + - name: staging-chain-spec-builder + bump: major + - name: sc-chain-spec + bump: major diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index 6346063b9d27..09fa64d58948 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -58,6 +58,7 @@ sp-api = { path = "../../../primitives/api" } sp-core = { path = "../../../primitives/core" } sp-runtime = { path = "../../../primitives/runtime" } sp-timestamp = { path = "../../../primitives/timestamp" } +sp-genesis-builder = { path = "../../../primitives/genesis-builder" } sp-inherents = { path = "../../../primitives/inherents" } sp-keyring = { path = "../../../primitives/keyring" } sp-keystore = { path = "../../../primitives/keystore" } diff --git a/substrate/bin/node/cli/tests/basic.rs b/substrate/bin/node/cli/tests/basic.rs index 525ab2e39c12..a9eea84d9260 100644 --- a/substrate/bin/node/cli/tests/basic.rs +++ b/substrate/bin/node/cli/tests/basic.rs @@ -838,10 +838,16 @@ fn should_import_block_with_test_client() { #[test] fn default_config_as_json_works() { let mut t = new_test_ext(compact_code_unwrap()); - let r = executor_call(&mut t, "GenesisBuilder_create_default_config", &vec![]) - .0 - .unwrap(); - let r = Vec::::decode(&mut &r[..]).unwrap(); + let r = executor_call( + &mut t, + "GenesisBuilder_get_preset", + &None::<&sp_genesis_builder::PresetId>.encode(), + ) + .0 + .unwrap(); + let r = Option::>::decode(&mut &r[..]) + .unwrap() + .expect("default config is there"); let json = String::from_utf8(r.into()).expect("returned value is json. qed."); let expected = include_str!("res/default_genesis_config.json").to_string(); diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 5ed5e7943f69..09326de27328 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -31,7 +31,7 @@ use frame_support::{ derive_impl, dispatch::DispatchClass, dynamic_params::{dynamic_pallet_params, dynamic_params}, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, instances::{Instance1, Instance2}, ord_parameter_types, pallet_prelude::Get, @@ -3194,12 +3194,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/substrate/bin/utils/chain-spec-builder/Cargo.toml b/substrate/bin/utils/chain-spec-builder/Cargo.toml index c126a76b763f..5c8a3ab4e89a 100644 --- a/substrate/bin/utils/chain-spec-builder/Cargo.toml +++ b/substrate/bin/utils/chain-spec-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "staging-chain-spec-builder" -version = "2.0.0" +version = "3.0.0" authors.workspace = true edition.workspace = true build = "build.rs" diff --git a/substrate/bin/utils/chain-spec-builder/bin/main.rs b/substrate/bin/utils/chain-spec-builder/bin/main.rs index 986293179a91..8d6425a46c77 100644 --- a/substrate/bin/utils/chain-spec-builder/bin/main.rs +++ b/substrate/bin/utils/chain-spec-builder/bin/main.rs @@ -18,14 +18,24 @@ use chain_spec_builder::{ generate_chain_spec_for_runtime, ChainSpecBuilder, ChainSpecBuilderCmd, ConvertToRawCmd, - UpdateCodeCmd, VerifyCmd, + DisplayPresetCmd, ListPresetsCmd, UpdateCodeCmd, VerifyCmd, }; use clap::Parser; -use sc_chain_spec::{update_code_in_json_chain_spec, GenericChainSpec}; +use sc_chain_spec::{ + update_code_in_json_chain_spec, GenericChainSpec, GenesisConfigBuilderRuntimeCaller, +}; use staging_chain_spec_builder as chain_spec_builder; use std::fs; -fn main() -> Result<(), String> { +//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(); @@ -71,6 +81,36 @@ fn main() -> Result<(), String> { let _ = serde_json::from_str::(&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 = 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(()) } diff --git a/substrate/bin/utils/chain-spec-builder/src/lib.rs b/substrate/bin/utils/chain-spec-builder/src/lib.rs index dbd0437921ff..7982da76227a 100644 --- a/substrate/bin/utils/chain-spec-builder/src/lib.rs +++ b/substrate/bin/utils/chain-spec-builder/src/lib.rs @@ -28,51 +28,84 @@ //! See [`ChainSpecBuilderCmd`] for a list of available commands. //! //! ## Typical use-cases. -//! ##### Get default config from runtime. +//! ##### Generate chains-spec using default config from runtime. //! -//! Query the default genesis config from the provided `runtime.wasm` and use it in the chain -//! spec. The tool allows specifying where to write the chain spec, and optionally also where the -//! write the default genesis state config (which is `/dev/stdout` in the following example): -//! ```text -//! chain-spec-builder --chain_spec_path ./my_chain_spec.json create -r runtime.wasm default /dev/stdout +//! Query the default genesis config from the provided `runtime.wasm` and use it in the chain +//! spec. +//! ```bash +//! chain-spec-builder create -r runtime.wasm default //! ``` -//! -//! _Note:_ [`GenesisBuilder::create_default_config`][sp-genesis-builder-create] runtime function is +//! +//! _Note:_ [`GenesisBuilder::get_preset`][sp-genesis-builder-get-preset] runtime function is //! called. //! //! +//! ##### Display the runtime's default `GenesisConfig` +//! +//! Displays the content of the runtime's default `GenesisConfig` +//! ```bash +//! chain-spec-builder display-preset -r runtime.wasm +//! ``` +//! +//! _Note:_ [`GenesisBuilder::get_preset`][sp-genesis-builder-get-preset] runtime function is called. +//! +//! ##### Display the `GenesisConfig` preset with given name +//! +//! Displays the content of the `GenesisConfig` preset for given name +//! ```bash +//! chain-spec-builder display-preset -r runtime.wasm -p "staging" +//! ``` +//! +//! _Note:_ [`GenesisBuilder::get_preset`][sp-genesis-builder-get-preset] runtime function is called. +//! +//! ##### List the names of `GenesisConfig` presets provided by runtime. +//! +//! Displays the names of the presets of `GenesisConfigs` provided by runtime. +//! ```bash +//! chain-spec-builder list-presets -r runtime.wasm +//! ``` +//! +//! _Note:_ [`GenesisBuilder::preset_names`][sp-genesis-builder-list] 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: +//! ```bash +//! chain-spec-builder create -r runtime.wasm named-preset "staging" +//! ``` +//! +//! _Note:_ [`GenesisBuilder::get_preset`][sp-genesis-builder-get-preset] and [`GenesisBuilder::build_state`][sp-genesis-builder-build] 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: -//! //! ```bash //! chain-spec-builder create -s -r runtime.wasm patch patch.json //! ``` -//! -//! _Note:_ [`GenesisBuilder::build_config`][sp-genesis-builder-build] runtime function is called. +//! +//! _Note:_ [`GenesisBuilder::build_state`][sp-genesis-builder-build] runtime function is 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: -//! //! ```bash //! chain-spec-builder create -s -r runtime.wasm full full-genesis-config.json //! ``` -//! -//! _Note_: [`GenesisBuilder::build_config`][sp-genesis-builder-build] runtime function is called. +//! +//! _Note_: [`GenesisBuilder::build_state`][sp-genesis-builder-build] runtime function is called. //! //! ##### Generate human readable chain spec using provided genesis config patch. //! ```bash //! chain-spec-builder create -r runtime.wasm patch patch.json //! ``` -//! +//! //! ##### Generate human readable chain spec using provided full genesis config. -//! //! ```bash //! chain-spec-builder create -r runtime.wasm full full-genesis-config.json //! ``` -//! +//! //! ##### Extra tools. //! The `chain-spec-builder` provides also some extra utilities: [`VerifyCmd`], [`ConvertToRawCmd`], //! [`UpdateCodeCmd`]. @@ -80,8 +113,9 @@ //! [`sc-chain-spec`]: ../sc_chain_spec/index.html //! [`node-cli`]: ../node_cli/index.html //! [`sp-genesis-builder`]: ../sp_genesis_builder/index.html -//! [sp-genesis-builder-create]: ../sp_genesis_builder/trait.GenesisBuilder.html#method.create_default_config -//! [sp-genesis-builder-build]: ../sp_genesis_builder/trait.GenesisBuilder.html#method.build_config +//! [sp-genesis-builder-build]: ../sp_genesis_builder/trait.GenesisBuilder.html#method.build_state +//! [sp-genesis-builder-list]: ../sp_genesis_builder/trait.GenesisBuilder.html#method.preset_names +//! [sp-genesis-builder-get-preset]: ../sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset use std::{fs, path::PathBuf}; @@ -107,6 +141,8 @@ pub enum ChainSpecBuilderCmd { Verify(VerifyCmd), UpdateCode(UpdateCodeCmd), ConvertToRaw(ConvertToRawCmd), + ListPresets(ListPresetsCmd), + DisplayPreset(DisplayPresetCmd), } /// Create a new chain spec by interacting with the provided runtime wasm blob. @@ -137,6 +173,7 @@ enum GenesisBuildAction { Patch(PatchCmd), Full(FullCmd), Default(DefaultCmd), + NamedPreset(NamedPresetCmd), } /// Patches the runtime's default genesis config with provided patch. @@ -157,10 +194,12 @@ struct FullCmd { /// default genesis config may not be valid. For some runtimes initial values should be added there /// (e.g. session keys, babe epoch). #[derive(Parser, Debug, Clone)] -struct DefaultCmd { - /// If provided stores the default genesis config json file at given path (in addition to - /// chain-spec). - default_config_path: Option, +struct DefaultCmd {} + +/// Uses named preset provided by runtime to build the chains spec. +#[derive(Parser, Debug, Clone)] +struct NamedPresetCmd { + preset_name: String, } /// Updates the code in the provided input chain spec. @@ -182,6 +221,25 @@ pub struct ConvertToRawCmd { pub input_chain_spec: PathBuf, } +/// Lists available presets +#[derive(Parser, Debug, Clone)] +pub struct ListPresetsCmd { + /// The path to runtime wasm blob. + #[arg(long, short)] + pub runtime_wasm_path: PathBuf, +} + +/// Displays given preset +#[derive(Parser, Debug, Clone)] +pub struct DisplayPresetCmd { + /// The path to runtime wasm blob. + #[arg(long, short)] + pub runtime_wasm_path: PathBuf, + /// Preset to be displayed. If none is given default will be displayed. + #[arg(long, short)] + pub preset_name: Option, +} + /// Verifies the provided input chain spec. /// /// Silently checks if given input chain spec can be converted to raw. It allows to check if all @@ -204,6 +262,8 @@ pub fn generate_chain_spec_for_runtime(cmd: &CreateCmd) -> Result + builder.with_genesis_config_preset_name(&preset_name), GenesisBuildAction::Patch(PatchCmd { ref patch_path }) => { let patch = fs::read(patch_path.as_path()) .map_err(|e| format!("patch file {patch_path:?} shall be readable: {e}"))?; @@ -218,16 +278,12 @@ pub fn generate_chain_spec_for_runtime(cmd: &CreateCmd) -> Result { + GenesisBuildAction::Default(DefaultCmd {}) => { let caller: GenesisConfigBuilderRuntimeCaller = GenesisConfigBuilderRuntimeCaller::new(&code[..]); let default_config = caller .get_default_config() .map_err(|e| format!("getting default config from runtime should work: {e}"))?; - default_config_path.clone().map(|path| { - fs::write(path.as_path(), serde_json::to_string_pretty(&default_config).unwrap()) - .map_err(|err| err.to_string()) - }); builder.with_genesis_config(default_config) }, }; diff --git a/substrate/client/chain-spec/Cargo.toml b/substrate/client/chain-spec/Cargo.toml index f569b5f14a66..84320f17d7cb 100644 --- a/substrate/client/chain-spec/Cargo.toml +++ b/substrate/client/chain-spec/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sc-chain-spec" -version = "27.0.0" +version = "28.0.0" authors.workspace = true edition.workspace = true license = "GPL-3.0-or-later WITH Classpath-exception-2.0" @@ -33,6 +33,7 @@ sp-genesis-builder = { path = "../../primitives/genesis-builder" } sp-runtime = { path = "../../primitives/runtime" } sp-state-machine = { path = "../../primitives/state-machine" } log = { workspace = true } +sp-tracing = { path = "../../primitives/tracing" } array-bytes = { version = "6.1" } docify = "0.2.8" diff --git a/substrate/client/chain-spec/res/chain_spec_as_json_fails_with_invalid_config.err b/substrate/client/chain-spec/res/chain_spec_as_json_fails_with_invalid_config.err new file mode 100644 index 000000000000..826b515b77d3 --- /dev/null +++ b/substrate/client/chain-spec/res/chain_spec_as_json_fails_with_invalid_config.err @@ -0,0 +1,114 @@ +Invalid JSON blob: unknown field `babex`, expected one of `system`, `babe`, `substrateTest`, `balances` at line 2 column 9 for blob: +{ + "babex": { + "authorities": [ + [ + "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + 1 + ], + [ + "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", + 1 + ], + [ + "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y", + 1 + ] + ], + "epochConfig": { + "allowed_slots": "PrimaryAndSecondaryPlainSlots", + "c": [ + 3, + 10 + ] + } + }, + "balances": { + "balances": [ + [ + "5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH", + 100000000000000000 + ], + [ + "5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o", + 100000000000000000 + ], + [ + "5Dfis6XL8J2P6JHUnUtArnFWndn62SydeP8ee8sG2ky9nfm9", + 100000000000000000 + ], + [ + "5F4H97f7nQovyrbiq4ZetaaviNwThSVcFobcA5aGab6167dK", + 100000000000000000 + ], + [ + "5DiDShBWa1fQx6gLzpf3SFBhMinCoyvHM1BWjPNsmXS8hkrW", + 100000000000000000 + ], + [ + "5EFb84yH9tpcFuiKUcsmdoF7xeeY3ajG1ZLQimxQoFt9HMKR", + 100000000000000000 + ], + [ + "5DZLHESsfGrJ5YzT3HuRPXsSNb589xQ4Unubh1mYLodzKdVY", + 100000000000000000 + ], + [ + "5GHJzqvG6tXnngCpG7B12qjUvbo5e4e9z8Xjidk3CQZHxTPZ", + 100000000000000000 + ], + [ + "5CUnSsgAyLND3bxxnfNhgWXSe9Wn676JzLpGLgyJv858qhoX", + 100000000000000000 + ], + [ + "5CVKn7HAZW1Ky4r7Vkgsr7VEW88C2sHgUNDiwHY9Ct2hjU8q", + 100000000000000000 + ], + [ + "5H673aukQ4PeDe1U2nuv1bi32xDEziimh3PZz7hDdYUB7TNz", + 100000000000000000 + ], + [ + "5HTe9L15LJryjUAt1jZXZCBPnzbbGnpvFwbjE3NwCWaAqovf", + 100000000000000000 + ], + [ + "5D7LFzGpMwHPyDBavkRbWSKWTtJhCaPPZ379wWLT23bJwXJz", + 100000000000000000 + ], + [ + "5CLepMARnEgtVR1EkUuJVUvKh97gzergpSxUU3yKGx1v6EwC", + 100000000000000000 + ], + [ + "5Chb2UhfvZpmjjEziHbFbotM4quX32ZscRV6QJBt1rUKzz51", + 100000000000000000 + ], + [ + "5HmRp3i3ZZk7xsAvbi8hyXVP6whSMnBJGebVC4FsiZVhx52e", + 100000000000000000 + ], + [ + "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + 100000000000000000 + ], + [ + "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", + 100000000000000000 + ], + [ + "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y", + 100000000000000000 + ] + ] + }, + "substrateTest": { + "authorities": [ + "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", + "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y" + ] + }, + "system": {} +} \ No newline at end of file diff --git a/substrate/client/chain-spec/res/substrate_test_runtime_from_named_preset.json b/substrate/client/chain-spec/res/substrate_test_runtime_from_named_preset.json new file mode 100644 index 000000000000..a98600a5577b --- /dev/null +++ b/substrate/client/chain-spec/res/substrate_test_runtime_from_named_preset.json @@ -0,0 +1,35 @@ +{ + "name": "TestName", + "id": "test_id", + "chainType": "Local", + "bootNodes": [], + "telemetryEndpoints": null, + "protocolId": null, + "properties": null, + "codeSubstitutes": {}, + "genesis": { + "runtimeGenesis": { + "patch": { + "balances": { + "balances": [ + [ + "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", + 1000000000000000 + ], + [ + "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y", + 1000000000000000 + ] + ] + }, + "substrateTest": { + "authorities": [ + "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL" + ] + } + }, + "code": "0x0" + } + } +} diff --git a/substrate/client/chain-spec/src/chain_spec.rs b/substrate/client/chain-spec/src/chain_spec.rs index 4ec8527de264..a9cdce4bf955 100644 --- a/substrate/client/chain-spec/src/chain_spec.rs +++ b/substrate/client/chain-spec/src/chain_spec.rs @@ -40,15 +40,26 @@ use std::{ sync::Arc, }; -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -enum GenesisBuildAction { +enum GenesisBuildAction { Patch(json::Value), Full(json::Value), + NamedPreset(String, PhantomData), +} + +impl Clone for GenesisBuildAction { + fn clone(&self) -> Self { + match self { + Self::Patch(ref p) => Self::Patch(p.clone()), + Self::Full(ref f) => Self::Full(f.clone()), + Self::NamedPreset(ref p, _) => Self::NamedPreset(p.clone(), Default::default()), + } + } } #[allow(deprecated)] -enum GenesisSource { +enum GenesisSource { File(PathBuf), Binary(Cow<'static, [u8]>), /// factory function + code @@ -56,10 +67,10 @@ enum GenesisSource { Factory(Arc G + Send + Sync>, Vec), Storage(Storage), /// build action + code - GenesisBuilderApi(GenesisBuildAction, Vec), + GenesisBuilderApi(GenesisBuildAction, Vec), } -impl Clone for GenesisSource { +impl Clone for GenesisSource { fn clone(&self) -> Self { match *self { Self::File(ref path) => Self::File(path.clone()), @@ -71,7 +82,7 @@ impl Clone for GenesisSource { } } -impl GenesisSource { +impl GenesisSource { fn resolve(&self) -> Result, String> { /// helper container for deserializing genesis from the JSON file (ChainSpec JSON file is /// also supported here) @@ -118,6 +129,13 @@ impl GenesisSource { json_blob: RuntimeGenesisConfigJson::Patch(patch.clone()), code: code.clone(), })), + Self::GenesisBuilderApi(GenesisBuildAction::NamedPreset(name, _), code) => { + let patch = RuntimeCaller::::new(&code[..]).get_named_preset(Some(name))?; + Ok(Genesis::RuntimeGenesis(RuntimeGenesisInner { + json_blob: RuntimeGenesisConfigJson::Patch(patch), + code: code.clone(), + })) + }, } } } @@ -331,13 +349,13 @@ pub struct ChainSpecBuilder { name: String, id: String, chain_type: ChainType, - genesis_build_action: GenesisBuildAction, + genesis_build_action: GenesisBuildAction, boot_nodes: Option>, telemetry_endpoints: Option, protocol_id: Option, fork_id: Option, properties: Option, - _genesis: PhantomData<(G, EHF)>, + _genesis: PhantomData, } impl ChainSpecBuilder { @@ -425,6 +443,13 @@ impl ChainSpecBuilder { self } + /// Sets the name of runtime-provided JSON patch for runtime's GenesisConfig. + pub fn with_genesis_config_preset_name(mut self, name: &str) -> Self { + self.genesis_build_action = + GenesisBuildAction::NamedPreset(name.to_string(), Default::default()); + self + } + /// Sets the full runtime's GenesisConfig JSON. pub fn with_genesis_config(mut self, config: json::Value) -> Self { self.genesis_build_action = GenesisBuildAction::Full(config); @@ -463,7 +488,7 @@ impl ChainSpecBuilder { /// runtime is using the non-standard host function during genesis state creation. pub struct ChainSpec { client_spec: ClientSpec, - genesis: GenesisSource, + genesis: GenesisSource, _host_functions: PhantomData, } @@ -1009,7 +1034,30 @@ mod tests { assert!(raw_chain_spec.is_ok()); } - #[docify::export] + #[test] + fn generate_chain_spec_with_named_preset_works() { + sp_tracing::try_init_simple(); + let output: ChainSpec<()> = ChainSpec::builder( + substrate_test_runtime::wasm_binary_unwrap().into(), + Default::default(), + ) + .with_name("TestName") + .with_id("test_id") + .with_chain_type(ChainType::Local) + .with_genesis_config_preset_name("staging") + .build(); + + let actual = output.as_json(false).unwrap(); + let expected = + from_str::(include_str!("../res/substrate_test_runtime_from_named_preset.json")) + .unwrap(); + + //wasm blob may change overtime so let's zero it. Also ensure it is there: + let actual = zeroize_code_key_in_json(false, actual.as_str()); + + assert_eq!(actual, expected); + } + #[test] fn generate_chain_spec_with_patch_works() { let output = ChainSpec::<()>::builder( @@ -1089,6 +1137,8 @@ mod tests { #[test] fn chain_spec_as_json_fails_with_invalid_config() { + let expected_error_message = + include_str!("../res/chain_spec_as_json_fails_with_invalid_config.err"); let j = include_str!("../../../test-utils/runtime/res/default_genesis_config_invalid_2.json"); let output = ChainSpec::<()>::builder( @@ -1101,10 +1151,9 @@ mod tests { .with_genesis_config(from_str(j).unwrap()) .build(); - assert_eq!( - output.as_json(true), - Err("Invalid JSON blob: unknown field `babex`, expected one of `system`, `babe`, `substrateTest`, `balances` at line 1 column 8".to_string()) - ); + let result = output.as_json(true); + + assert_eq!(result.err().unwrap(), expected_error_message); } #[test] diff --git a/substrate/client/chain-spec/src/genesis_config_builder.rs b/substrate/client/chain-spec/src/genesis_config_builder.rs index 61f065e213cb..13a2f3c072f5 100644 --- a/substrate/client/chain-spec/src/genesis_config_builder.rs +++ b/substrate/client/chain-spec/src/genesis_config_builder.rs @@ -26,7 +26,7 @@ use sp_core::{ storage::Storage, traits::{CallContext, CodeExecutor, Externalities, FetchRuntimeCode, RuntimeCode}, }; -use sp_genesis_builder::Result as BuildResult; +use sp_genesis_builder::{PresetId, Result as BuildResult}; use sp_state_machine::BasicExternalities; use std::borrow::Cow; @@ -84,30 +84,46 @@ where /// Returns a json representation of the default `RuntimeGenesisConfig` provided by the /// `runtime`. /// - /// Calls [`GenesisBuilder::create_default_config`](sp_genesis_builder::GenesisBuilder::create_default_config) in the `runtime`. + /// Calls [`GenesisBuilder::get_preset`](sp_genesis_builder::GenesisBuilder::get_preset) in the + /// `runtime` with `None` argument. pub fn get_default_config(&self) -> core::result::Result { + self.get_named_preset(None) + } + + /// Returns a JSON blob representation of the builtin `GenesisConfig` identified by `id`. + /// + /// Calls [`GenesisBuilder::get_preset`](sp_genesis_builder::GenesisBuilder::get_preset) + /// provided by the `runtime`. + pub fn get_named_preset(&self, id: Option<&String>) -> core::result::Result { let mut t = BasicExternalities::new_empty(); let call_result = self - .call(&mut t, "GenesisBuilder_create_default_config", &[]) + .call(&mut t, "GenesisBuilder_get_preset", &id.encode()) .map_err(|e| format!("wasm call error {e}"))?; - let default_config = Vec::::decode(&mut &call_result[..]) + + let named_preset = Option::>::decode(&mut &call_result[..]) .map_err(|e| format!("scale codec error: {e}"))?; - Ok(from_slice(&default_config[..]).expect("returned value is json. qed.")) + + if let Some(named_preset) = named_preset { + Ok(from_slice(&named_preset[..]).expect("returned value is json. qed.")) + } else { + Err(format!("The preset with name {id:?} is not available.")) + } } - /// Builds `RuntimeGenesisConfig` from given json blob and returns the genesis state. - /// - /// Calls [`GenesisBuilder::build_config`](sp_genesis_builder::GenesisBuilder::build_config) - /// provided by the `runtime`. + /// Calls [`sp_genesis_builder::GenesisBuilder::build_state`] provided by runtime. pub fn get_storage_for_config(&self, config: Value) -> core::result::Result { let mut ext = BasicExternalities::new_empty(); + let json_pretty_str = serde_json::to_string_pretty(&config) + .map_err(|e| format!("json to string failed: {e}"))?; + let call_result = self - .call(&mut ext, "GenesisBuilder_build_config", &config.to_string().encode()) + .call(&mut ext, "GenesisBuilder_build_state", &json_pretty_str.encode()) .map_err(|e| format!("wasm call error {e}"))?; BuildResult::decode(&mut &call_result[..]) - .map_err(|e| format!("scale codec error: {e}"))??; + .map_err(|e| format!("scale codec error: {e}"))? + .map_err(|e| format!("{e} for blob:\n{}", json_pretty_str))?; Ok(ext.into_storages()) } @@ -137,6 +153,25 @@ where crate::json_patch::merge(&mut config, patch); self.get_storage_for_config(config) } + + pub fn get_storage_for_named_preset( + &self, + name: Option<&String>, + ) -> core::result::Result { + self.get_storage_for_patch(self.get_named_preset(name)?) + } + + pub fn preset_names(&self) -> core::result::Result, String> { + let mut t = BasicExternalities::new_empty(); + let call_result = self + .call(&mut t, "GenesisBuilder_preset_names", &vec![]) + .map_err(|e| format!("wasm call error {e}"))?; + + let preset_names = Vec::::decode(&mut &call_result[..]) + .map_err(|e| format!("scale codec error: {e}"))?; + + Ok(preset_names) + } } #[cfg(test)] @@ -144,6 +179,17 @@ mod tests { use super::*; use serde_json::{from_str, json}; pub use sp_consensus_babe::{AllowedSlots, BabeEpochConfiguration}; + pub use sp_genesis_builder::PresetId; + + #[test] + fn list_presets_works() { + sp_tracing::try_init_simple(); + let presets = + ::new(substrate_test_runtime::wasm_binary_unwrap()) + .preset_names() + .unwrap(); + assert_eq!(presets, vec![PresetId::from("foobar"), PresetId::from("staging"),]); + } #[test] fn get_default_config_works() { @@ -155,6 +201,17 @@ mod tests { assert_eq!(from_str::(expected).unwrap(), config); } + #[test] + fn get_named_preset_works() { + sp_tracing::try_init_simple(); + let config = + ::new(substrate_test_runtime::wasm_binary_unwrap()) + .get_named_preset(Some(&"foobar".to_string())) + .unwrap(); + let expected = r#"{"foo":"bar"}"#; + assert_eq!(from_str::(expected).unwrap(), config); + } + #[test] fn get_storage_for_patch_works() { let patch = json!({ diff --git a/substrate/client/chain-spec/src/lib.rs b/substrate/client/chain-spec/src/lib.rs index 6da5fd26d526..abe01dafd924 100644 --- a/substrate/client/chain-spec/src/lib.rs +++ b/substrate/client/chain-spec/src/lib.rs @@ -181,7 +181,7 @@ //! the node needs to interact with the runtime. //! //! This interaction involves passing the runtime genesis config JSON blob to the runtime using the -//! [`sp_genesis_builder::GenesisBuilder::build_config`] function. During this operation, the +//! [`sp_genesis_builder::GenesisBuilder::build_state`] function. During this operation, the //! runtime converts the JSON representation of the genesis config into [`sp_io::storage`] items. It //! is a crucial step for computing the storage root hash, which is a key component in determining //! the genesis hash. @@ -325,7 +325,7 @@ mod chain_spec; mod extension; mod genesis_block; mod genesis_config_builder; -mod json_patch; +pub mod json_patch; pub use self::{ chain_spec::{ diff --git a/substrate/frame/support/src/genesis_builder_helper.rs b/substrate/frame/support/src/genesis_builder_helper.rs index b2594d183ec5..7389c5a787d7 100644 --- a/substrate/frame/support/src/genesis_builder_helper.rs +++ b/substrate/frame/support/src/genesis_builder_helper.rs @@ -19,26 +19,39 @@ //! //! Provides common logic. For more info refer to [`sp_genesis_builder::GenesisBuilder`]. +extern crate alloc; + +use alloc::vec::Vec; use frame_support::traits::BuildGenesisConfig; -use sp_genesis_builder::Result as BuildResult; +use sp_genesis_builder::{PresetId, Result as BuildResult}; use sp_runtime::format_runtime_string; -/// Get the default `GenesisConfig` as a JSON blob. For more info refer to -/// [`sp_genesis_builder::GenesisBuilder::create_default_config`] -pub fn create_default_config() -> sp_std::vec::Vec -where - GC: BuildGenesisConfig + Default, -{ - serde_json::to_string(&GC::default()) - .expect("serialization to json is expected to work. qed.") - .into_bytes() -} - /// Build `GenesisConfig` from a JSON blob not using any defaults and store it in the storage. For -/// more info refer to [`sp_genesis_builder::GenesisBuilder::build_config`]. -pub fn build_config(json: sp_std::vec::Vec) -> BuildResult { +/// more info refer to [`sp_genesis_builder::GenesisBuilder::build_state`]. +pub fn build_state(json: Vec) -> BuildResult { let gc = serde_json::from_slice::(&json) .map_err(|e| format_runtime_string!("Invalid JSON blob: {}", e))?; ::build(&gc); Ok(()) } + +/// Get the default `GenesisConfig` as a JSON blob if `name` is None. +/// +/// Query of named presets is delegetaed to provided `preset_for_name` closure. For more info refer +/// to [`sp_genesis_builder::GenesisBuilder::get_preset`]. +pub fn get_preset( + name: &Option, + preset_for_name: impl FnOnce(&sp_genesis_builder::PresetId) -> Option>, +) -> Option> +where + GC: BuildGenesisConfig + Default, +{ + name.as_ref().map_or( + Some( + serde_json::to_string(&GC::default()) + .expect("serialization to json is expected to work. qed.") + .into_bytes(), + ), + preset_for_name, + ) +} diff --git a/substrate/primitives/genesis-builder/Cargo.toml b/substrate/primitives/genesis-builder/Cargo.toml index 5a8f1c2962ce..96e995532941 100644 --- a/substrate/primitives/genesis-builder/Cargo.toml +++ b/substrate/primitives/genesis-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sp-genesis-builder" -version = "0.7.0" +version = "0.8.0" authors.workspace = true edition.workspace = true license = "Apache-2.0" @@ -16,10 +16,19 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] +codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["bytes"] } +scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } + sp-api = { path = "../api", default-features = false } sp-runtime = { path = "../runtime", default-features = false } serde_json = { features = ["alloc", "arbitrary_precision"], workspace = true } [features] default = ["std"] -std = ["serde_json/std", "sp-api/std", "sp-runtime/std"] +std = [ + "codec/std", + "scale-info/std", + "serde_json/std", + "sp-api/std", + "sp-runtime/std", +] diff --git a/substrate/primitives/genesis-builder/src/lib.rs b/substrate/primitives/genesis-builder/src/lib.rs index 4970042187ce..2cbac305b4d9 100644 --- a/substrate/primitives/genesis-builder/src/lib.rs +++ b/substrate/primitives/genesis-builder/src/lib.rs @@ -19,39 +19,83 @@ //! Substrate genesis config builder //! -//! This Runtime API allows to construct `RuntimeGenesisConfig`, in particular: -//! - serialize the runtime default `RuntimeGenesisConfig` struct into json format, -//! - put the RuntimeGenesisConfig struct into the storage. Internally this operation calls -//! `GenesisBuild::build` function for all runtime pallets, which is typically provided by -//! pallet's author. -//! - deserialize the `RuntimeGenesisConfig` from given json blob and put `RuntimeGenesisConfig` -//! into the state storage. Allows to build customized configuration. +//! For FRAME based runtimes, this runtime interface provides means to interact with +//! `RuntimeGenesisConfig`. Runtime provides a default `RuntimeGenesisConfig` structure in a form of +//! the JSON blob. //! -//! Providing externalities with empty storage and putting `RuntimeGenesisConfig` into storage -//! allows to catch and build the raw storage of `RuntimeGenesisConfig` which is the foundation for -//! genesis block. +//! For non-FRAME runtimes this interface is intended to build genesis state of the runtime basing +//! on some input arbitrary bytes array. This documentation uses term `RuntimeGenesisConfig`, which +//! for non-FRAME runtimes may be understood as the runtime-side entity representing initial runtime +//! configuration. The representation of the preset is an arbitrary `Vec` and does not +//! necessarily have to represent a JSON blob. +//! +//! The runtime may provide a number of partial predefined `RuntimeGenesisConfig` configurations in +//! the form of patches which shall be applied on top of the default `RuntimeGenesisConfig`. The +//! patch is a JSON blob, which essentially comprises the list of key-value pairs that are to be +//! customized in the default runtime genesis config. These predefined configurations are referred +//! to as presets. +//! +//! This allows the runtime to provide a number of predefined configs (e.g. for different +//! testnets or development) without neccessity to leak the runtime types outside the itself (e.g. +//! node or chain-spec related tools). +//! +//! This Runtime API allows to interact with `RuntimeGenesisConfig`, in particular: +//! - provide the list of available preset names, +//! - provide a number of named presets of `RuntimeGenesisConfig`, +//! - provide a JSON represention of the default `RuntimeGenesisConfig` (by simply serializing the +//! default `RuntimeGenesisConfig` struct into JSON format), +//! - deserialize the full `RuntimeGenesisConfig` from given JSON blob and put the resulting +//! `RuntimeGenesisConfig` structure into the state storage creating the initial runtime's state. +//! Allows to build customized genesis. This operation internally calls `GenesisBuild::build` +//! function for all runtime pallets. +//! +//! Providing externalities with an empty storage and putting `RuntimeGenesisConfig` into storage +//! (by calling `build_state`) allows to construct the raw storage of `RuntimeGenesisConfig` +//! which is the foundation for genesis block. extern crate alloc; +use alloc::vec::Vec; /// The result type alias, used in build methods. `Err` contains formatted error message. pub type Result = core::result::Result<(), sp_runtime::RuntimeString>; +/// The type representing preset ID. +pub type PresetId = sp_runtime::RuntimeString; + sp_api::decl_runtime_apis! { /// API to interact with RuntimeGenesisConfig for the runtime pub trait GenesisBuilder { - /// Creates the default `RuntimeGenesisConfig` and returns it as a JSON blob. + /// Build `RuntimeGenesisConfig` from a JSON blob not using any defaults and store it in the + /// storage. + /// + /// In the case of a FRAME-based runtime, this function deserializes the full `RuntimeGenesisConfig` from the given JSON blob and + /// puts it into the storage. If the provided JSON blob is incorrect or incomplete or the + /// deserialization fails, an error is returned. /// - /// This function instantiates the default `RuntimeGenesisConfig` struct for the runtime and serializes it into a JSON - /// blob. It returns a `Vec` containing the JSON representation of the default `RuntimeGenesisConfig`. - fn create_default_config() -> alloc::vec::Vec; + /// Please note that provided JSON blob must contain all `RuntimeGenesisConfig` fields, no + /// defaults will be used. + fn build_state(json: Vec) -> Result; - /// Build `RuntimeGenesisConfig` from a JSON blob not using any defaults and store it in the storage. + /// Returns a JSON blob representation of the built-in `RuntimeGenesisConfig` identified by + /// `id`. /// - /// This function deserializes the full `RuntimeGenesisConfig` from the given JSON blob and puts it into the storage. - /// If the provided JSON blob is incorrect or incomplete or the deserialization fails, an error is returned. - /// It is recommended to log any errors encountered during the process. + /// If `id` is `None` the function returns JSON blob representation of the default + /// `RuntimeGenesisConfig` struct of the runtime. Implementation must provide default + /// `RuntimeGenesisConfig`. + /// + /// Otherwise function returns a JSON representation of the built-in, named + /// `RuntimeGenesisConfig` preset identified by `id`, or `None` if such preset does not + /// exists. Returned `Vec` contains bytes of JSON blob (patch) which comprises a list of + /// (potentially nested) key-value pairs that are intended for customizing the default + /// runtime genesis config. The patch shall be merged (rfc7386) with the JSON representation + /// of the default `RuntimeGenesisConfig` to create a comprehensive genesis config that can + /// be used in `build_state` method. + fn get_preset(id: &Option) -> Option>; + + /// Returns a list of identifiers for available builtin `RuntimeGenesisConfig` presets. /// - /// Please note that provided json blob must contain all `RuntimeGenesisConfig` fields, no defaults will be used. - fn build_config(json: alloc::vec::Vec) -> Result; + /// The presets from the list can be queried with [`GenesisBuilder::get_preset`] method. If + /// no named presets are provided by the runtime the list is empty. + fn preset_names() -> Vec; } } diff --git a/substrate/test-utils/runtime/Cargo.toml b/substrate/test-utils/runtime/Cargo.toml index ffbd59f39ad2..2c91a3186ce5 100644 --- a/substrate/test-utils/runtime/Cargo.toml +++ b/substrate/test-utils/runtime/Cargo.toml @@ -50,7 +50,9 @@ sp-externalities = { path = "../../primitives/externalities", default-features = # 3rd party array-bytes = { version = "6.1", optional = true } +serde_json = { workspace = true, features = ["alloc"] } log = { workspace = true } +hex-literal = { version = "0.4.1" } [dev-dependencies] futures = "0.3.30" diff --git a/substrate/test-utils/runtime/src/lib.rs b/substrate/test-utils/runtime/src/lib.rs index 7148d2b2fc0f..370aa0034fcd 100644 --- a/substrate/test-utils/runtime/src/lib.rs +++ b/substrate/test-utils/runtime/src/lib.rs @@ -27,11 +27,14 @@ pub mod extrinsic; pub mod genesismap; pub mod substrate_test_pallet; +use alloc::boxed::Box; +#[cfg(not(feature = "std"))] +use alloc::{vec, vec::Vec}; use codec::{Decode, Encode}; use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ConstU32, ConstU64}, weights::{ @@ -44,10 +47,8 @@ use frame_system::{ CheckNonce, CheckWeight, }; use scale_info::TypeInfo; - -use alloc::boxed::Box; -#[cfg(not(feature = "std"))] -use alloc::{vec, vec::Vec}; +use sp_application_crypto::Ss58Codec; +use sp_keyring::AccountKeyring; use sp_application_crypto::{ecdsa, ed25519, sr25519, RuntimeAppPublic}; use sp_core::{OpaqueMetadata, RuntimeDebug}; @@ -57,8 +58,10 @@ use sp_trie::{ }; use trie_db::{Trie, TrieMut}; +use serde_json::json; use sp_api::{decl_runtime_apis, impl_runtime_apis}; pub use sp_core::hash::H256; +use sp_genesis_builder::PresetId; use sp_inherents::{CheckInherentsResult, InherentData}; use sp_runtime::{ create_runtime_str, impl_opaque_keys, @@ -93,7 +96,7 @@ pub mod wasm_binary_logging_disabled { #[cfg(feature = "std")] pub fn wasm_binary_unwrap() -> &'static [u8] { WASM_BINARY.expect( - "Development wasm binary is not available. Testing is only supported with the flag \ + "Development wasm binary is not available. Testing is only supported with the flag disabled.", ) } @@ -102,7 +105,7 @@ pub fn wasm_binary_unwrap() -> &'static [u8] { #[cfg(feature = "std")] pub fn wasm_binary_logging_disabled_unwrap() -> &'static [u8] { wasm_binary_logging_disabled::WASM_BINARY.expect( - "Development wasm binary is not available. Testing is only supported with the flag \ + "Development wasm binary is not available. Testing is only supported with the flag disabled.", ) } @@ -725,12 +728,42 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(name: &Option) -> Option> { + get_preset::(name, |name| { + let patch = match name.try_into() { + Ok("staging") => { + let endowed_accounts: Vec = vec![ + AccountKeyring::Bob.public().into(), + AccountKeyring::Charlie.public().into(), + ]; + + json!({ + "balances": { + "balances": endowed_accounts.into_iter().map(|k| (k, 10 * currency::DOLLARS)).collect::>(), + }, + "substrateTest": { + "authorities": [ + AccountKeyring::Alice.public().to_ss58check(), + AccountKeyring::Ferdie.public().to_ss58check() + ], + } + }) + }, + Ok("foobar") => json!({"foo":"bar"}), + _ => return None, + }; + Some(serde_json::to_string(&patch) + .expect("serialization to json is expected to work. qed.") + .into_bytes()) + }) + } + + fn preset_names() -> Vec { + vec![PresetId::from("foobar"), PresetId::from("staging")] } } } @@ -836,7 +869,6 @@ fn test_witness(proof: StorageProof, root: crate::Hash) { pub mod storage_key_generator { use super::*; use sp_core::Pair; - use sp_keyring::AccountKeyring; /// Generate hex string without prefix pub(super) fn hex(x: T) -> String @@ -1026,7 +1058,6 @@ mod tests { use sp_api::{ApiExt, ProvideRuntimeApi}; use sp_consensus::BlockOrigin; use sp_core::{storage::well_known_keys::HEAP_PAGES, traits::CallContext}; - use sp_keyring::AccountKeyring; use sp_runtime::{ traits::{Hash as _, SignedExtension}, transaction_validity::{InvalidTransaction, ValidTransaction}, @@ -1177,7 +1208,7 @@ mod tests { fn check_substrate_check_signed_extension_works() { sp_tracing::try_init_simple(); new_test_ext().execute_with(|| { - let x = sp_keyring::AccountKeyring::Alice.into(); + let x = AccountKeyring::Alice.into(); let info = DispatchInfo::default(); let len = 0_usize; assert_eq!( @@ -1242,7 +1273,7 @@ mod tests { let default_minimal_json = r#"{"system":{},"babe":{"authorities":[],"epochConfig":{"c": [ 3, 10 ],"allowed_slots":"PrimaryAndSecondaryPlainSlots"}},"substrateTest":{"authorities":[]},"balances":{"balances":[]}}"#; let mut t = BasicExternalities::new_empty(); - executor_call(&mut t, "GenesisBuilder_build_config", &default_minimal_json.encode()) + executor_call(&mut t, "GenesisBuilder_build_state", &default_minimal_json.encode()) .unwrap(); let mut keys = t.into_storages().top.keys().cloned().map(hex).collect::>(); @@ -1290,21 +1321,60 @@ mod tests { fn default_config_as_json_works() { sp_tracing::try_init_simple(); let mut t = BasicExternalities::new_empty(); - let r = executor_call(&mut t, "GenesisBuilder_create_default_config", &vec![]).unwrap(); - let r = Vec::::decode(&mut &r[..]).unwrap(); + let r = executor_call(&mut t, "GenesisBuilder_get_preset", &None::<&PresetId>.encode()) + .unwrap(); + let r = Option::>::decode(&mut &r[..]) + .unwrap() + .expect("default config is there"); let json = String::from_utf8(r.into()).expect("returned value is json. qed."); let expected = r#"{"system":{},"babe":{"authorities":[],"epochConfig":{"c":[1,4],"allowed_slots":"PrimaryAndSecondaryVRFSlots"}},"substrateTest":{"authorities":[]},"balances":{"balances":[]}}"#; assert_eq!(expected.to_string(), json); } + #[test] + fn preset_names_listing_works() { + sp_tracing::try_init_simple(); + let mut t = BasicExternalities::new_empty(); + let r = executor_call(&mut t, "GenesisBuilder_preset_names", &vec![]).unwrap(); + let r = Vec::::decode(&mut &r[..]).unwrap(); + assert_eq!(r, vec![PresetId::from("foobar"), PresetId::from("staging"),]); + log::info!("r: {:#?}", r); + } + + #[test] + fn named_config_works() { + sp_tracing::try_init_simple(); + let f = |cfg_name: &str, expected: &str| { + let mut t = BasicExternalities::new_empty(); + let name = cfg_name.to_string(); + let r = executor_call( + &mut t, + "GenesisBuilder_get_preset", + &Some(name.as_bytes()).encode(), + ) + .unwrap(); + let r = Option::>::decode(&mut &r[..]).unwrap(); + let json = + String::from_utf8(r.unwrap().into()).expect("returned value is json. qed."); + log::info!("json: {:#?}", json); + assert_eq!(expected.to_string(), json); + }; + + f("foobar", r#"{"foo":"bar"}"#); + f( + "staging", + r#"{"balances":{"balances":[["5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",1000000000000000],["5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",1000000000000000]]},"substrateTest":{"authorities":["5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY","5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL"]}}"#, + ); + } + #[test] fn build_config_from_json_works() { sp_tracing::try_init_simple(); let j = include_str!("../res/default_genesis_config.json"); let mut t = BasicExternalities::new_empty(); - let r = executor_call(&mut t, "GenesisBuilder_build_config", &j.encode()).unwrap(); + let r = executor_call(&mut t, "GenesisBuilder_build_state", &j.encode()).unwrap(); let r = BuildResult::decode(&mut &r[..]); assert!(r.is_ok()); @@ -1323,7 +1393,7 @@ mod tests { sp_tracing::try_init_simple(); let j = include_str!("../res/default_genesis_config_invalid.json"); let mut t = BasicExternalities::new_empty(); - let r = executor_call(&mut t, "GenesisBuilder_build_config", &j.encode()).unwrap(); + let r = executor_call(&mut t, "GenesisBuilder_build_state", &j.encode()).unwrap(); let r = BuildResult::decode(&mut &r[..]).unwrap(); log::info!("result: {:#?}", r); assert_eq!(r, Err( @@ -1338,7 +1408,7 @@ mod tests { sp_tracing::try_init_simple(); let j = include_str!("../res/default_genesis_config_invalid_2.json"); let mut t = BasicExternalities::new_empty(); - let r = executor_call(&mut t, "GenesisBuilder_build_config", &j.encode()).unwrap(); + let r = executor_call(&mut t, "GenesisBuilder_build_state", &j.encode()).unwrap(); let r = BuildResult::decode(&mut &r[..]).unwrap(); assert_eq!(r, Err( sp_runtime::RuntimeString::Owned( @@ -1353,7 +1423,7 @@ mod tests { let j = include_str!("../res/default_genesis_config_incomplete.json"); let mut t = BasicExternalities::new_empty(); - let r = executor_call(&mut t, "GenesisBuilder_build_config", &j.encode()).unwrap(); + let r = executor_call(&mut t, "GenesisBuilder_build_state", &j.encode()).unwrap(); let r = core::result::Result::<(), sp_runtime::RuntimeString>::decode(&mut &r[..]).unwrap(); assert_eq!( @@ -1388,8 +1458,11 @@ mod tests { sp_tracing::try_init_simple(); let mut t = BasicExternalities::new_empty(); - let r = executor_call(&mut t, "GenesisBuilder_create_default_config", &vec![]).unwrap(); - let r = Vec::::decode(&mut &r[..]).unwrap(); + let r = executor_call(&mut t, "GenesisBuilder_get_preset", &None::<&PresetId>.encode()) + .unwrap(); + let r = Option::>::decode(&mut &r[..]) + .unwrap() + .expect("default config is there"); let mut default_config: serde_json::Value = serde_json::from_slice(&r[..]).expect("returned value is json. qed."); @@ -1418,7 +1491,7 @@ mod tests { let mut t = BasicExternalities::new_empty(); executor_call( &mut t, - "GenesisBuilder_build_config", + "GenesisBuilder_build_state", &default_config.to_string().encode(), ) .unwrap(); @@ -1436,8 +1509,8 @@ mod tests { let authority_key_vec = Vec::::decode(&mut &value[..]).unwrap(); assert_eq!(authority_key_vec.len(), 2); - assert_eq!(authority_key_vec[0], sp_keyring::AccountKeyring::Ferdie.public()); - assert_eq!(authority_key_vec[1], sp_keyring::AccountKeyring::Alice.public()); + assert_eq!(authority_key_vec[0], AccountKeyring::Ferdie.public()); + assert_eq!(authority_key_vec[1], AccountKeyring::Alice.public()); //Babe|Authorities let value: Vec = get_from_storage( diff --git a/templates/minimal/runtime/Cargo.toml b/templates/minimal/runtime/Cargo.toml index e7f88ca47af7..ceac8a498533 100644 --- a/templates/minimal/runtime/Cargo.toml +++ b/templates/minimal/runtime/Cargo.toml @@ -31,6 +31,7 @@ pallet-transaction-payment-rpc-runtime-api = { path = "../../../substrate/frame/ # genesis builder that allows us to interact with runtime genesis config sp-genesis-builder = { path = "../../../substrate/primitives/genesis-builder", default-features = false } +sp-runtime = { path = "../../../substrate/primitives/runtime", default-features = false, features = ["serde"] } # local pallet templates pallet-minimal-template = { path = "../pallets/template", default-features = false } @@ -55,5 +56,6 @@ std = [ "pallet-minimal-template/std", "sp-genesis-builder/std", + "sp-runtime/std", "substrate-wasm-builder", ] diff --git a/templates/minimal/runtime/src/lib.rs b/templates/minimal/runtime/src/lib.rs index f386169130ce..794f30a054a8 100644 --- a/templates/minimal/runtime/src/lib.rs +++ b/templates/minimal/runtime/src/lib.rs @@ -23,7 +23,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); use frame::{ deps::frame_support::{ - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, weights::{FixedFee, NoFee}, }, prelude::*, @@ -221,12 +221,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } } diff --git a/templates/parachain/runtime/src/apis.rs b/templates/parachain/runtime/src/apis.rs index 74c7476e1520..b13ba278fae6 100644 --- a/templates/parachain/runtime/src/apis.rs +++ b/templates/parachain/runtime/src/apis.rs @@ -25,7 +25,7 @@ // External crates imports use frame_support::{ - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, weights::Weight, }; use pallet_aura::Authorities; @@ -264,12 +264,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + Default::default() } } } diff --git a/templates/solochain/runtime/src/lib.rs b/templates/solochain/runtime/src/lib.rs index f3353d19be6a..93a56fb0ad78 100644 --- a/templates/solochain/runtime/src/lib.rs +++ b/templates/solochain/runtime/src/lib.rs @@ -18,7 +18,7 @@ use sp_std::prelude::*; use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use frame_support::genesis_builder_helper::{build_config, create_default_config}; +use frame_support::genesis_builder_helper::{build_state, get_preset}; pub use frame_support::{ construct_runtime, derive_impl, parameter_types, traits::{ @@ -575,12 +575,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + vec![] } } }