From daba04c031156dcbe5f11a0390b5f7535299ebcd Mon Sep 17 00:00:00 2001 From: Loris Moulin <45130584+l0r1s@users.noreply.github.com> Date: Tue, 3 Oct 2023 12:38:40 +0200 Subject: [PATCH] Feat/genesis overrides (#111) - Added genesis_overrides fields to RelaychainConfig and ParachainConfig builders and added logic to merge it into the specs being created --- crates/configuration/Cargo.toml | 1 + crates/configuration/src/parachain.rs | 19 +++++++++ crates/configuration/src/relaychain.rs | 19 +++++++++ .../orchestrator/src/generators/chain_spec.rs | 40 +++++++++++++++++-- .../src/network_spec/parachain.rs | 4 ++ .../src/network_spec/relaychain.rs | 4 ++ 6 files changed, 83 insertions(+), 4 deletions(-) diff --git a/crates/configuration/Cargo.toml b/crates/configuration/Cargo.toml index 56d70d8..b7525f2 100644 --- a/crates/configuration/Cargo.toml +++ b/crates/configuration/Cargo.toml @@ -12,3 +12,4 @@ thiserror = { workspace = true } anyhow = { workspace = true } serde = { workspace = true, features = ["derive"] } toml = { workspace = true } +serde_json = { workspace = true } diff --git a/crates/configuration/src/parachain.rs b/crates/configuration/src/parachain.rs index 543b778..8dd9c9b 100644 --- a/crates/configuration/src/parachain.rs +++ b/crates/configuration/src/parachain.rs @@ -122,6 +122,7 @@ pub struct ParachainConfig { is_cumulus_based: bool, #[serde(skip_serializing_if = "std::vec::Vec::is_empty", default)] bootnodes_addresses: Vec<Multiaddr>, + genesis_overrides: Option<serde_json::Value>, #[serde(skip_serializing_if = "std::vec::Vec::is_empty", default)] collators: Vec<NodeConfig>, } @@ -197,6 +198,11 @@ impl ParachainConfig { self.genesis_state_generator.as_ref() } + /// The genesis overrides as a JSON value. + pub fn genesis_overrides(&self) -> Option<&serde_json::Value> { + self.genesis_overrides.as_ref() + } + /// The location of a pre-existing chain specification for the parachain. pub fn chain_spec_path(&self) -> Option<&AssetLocation> { self.chain_spec_path.as_ref() @@ -250,6 +256,7 @@ impl Default for ParachainConfigBuilder<Initial> { genesis_wasm_generator: None, genesis_state_path: None, genesis_state_generator: None, + genesis_overrides: None, chain_spec_path: None, is_cumulus_based: true, bootnodes_addresses: vec![], @@ -540,6 +547,18 @@ impl ParachainConfigBuilder<WithId> { } } + /// Set the genesis overrides as a JSON object. + pub fn with_genesis_overrides(self, genesis_overrides: impl Into<serde_json::Value>) -> Self { + Self::transition( + ParachainConfig { + genesis_overrides: Some(genesis_overrides.into()), + ..self.config + }, + self.validation_context, + self.errors, + ) + } + /// Set the location of a pre-existing chain specification for the parachain. pub fn with_chain_spec_path(self, location: impl Into<AssetLocation>) -> Self { Self::transition( diff --git a/crates/configuration/src/relaychain.rs b/crates/configuration/src/relaychain.rs index b087ddc..f226b79 100644 --- a/crates/configuration/src/relaychain.rs +++ b/crates/configuration/src/relaychain.rs @@ -27,6 +27,7 @@ pub struct RelaychainConfig { max_nominations: Option<u8>, #[serde(skip_serializing_if = "std::vec::Vec::is_empty", default)] nodes: Vec<NodeConfig>, + genesis_overrides: Option<serde_json::Value>, } impl RelaychainConfig { @@ -75,6 +76,11 @@ impl RelaychainConfig { self.max_nominations } + /// The genesis overrides as a JSON value. + pub fn genesis_overrides(&self) -> Option<&serde_json::Value> { + self.genesis_overrides.as_ref() + } + /// The nodes of the relay chain. pub fn nodes(&self) -> Vec<&NodeConfig> { self.nodes.iter().collect::<Vec<&NodeConfig>>() @@ -114,6 +120,7 @@ impl Default for RelaychainConfigBuilder<Initial> { chain_spec_path: None, random_nominators_count: None, max_nominations: None, + genesis_overrides: None, nodes: vec![], }, validation_context: Default::default(), @@ -314,6 +321,18 @@ impl RelaychainConfigBuilder<WithChain> { ) } + /// Set the genesis overrides as a JSON object. + pub fn with_genesis_overrides(self, genesis_overrides: impl Into<serde_json::Value>) -> Self { + Self::transition( + RelaychainConfig { + genesis_overrides: Some(genesis_overrides.into()), + ..self.config + }, + self.validation_context, + self.errors, + ) + } + /// Add a new node using a nested [`NodeConfigBuilder`]. pub fn with_node( self, diff --git a/crates/orchestrator/src/generators/chain_spec.rs b/crates/orchestrator/src/generators/chain_spec.rs index f302d65..9497ebf 100644 --- a/crates/orchestrator/src/generators/chain_spec.rs +++ b/crates/orchestrator/src/generators/chain_spec.rs @@ -311,7 +311,13 @@ impl ChainSpec { .map_err(GeneratorError::ChainSpecGeneration)?; // make genesis overrides first. - // override_genesis() + if let Some(overrides) = ¶.genesis_overrides { + if let Some(genesis) = chain_spec_json.pointer_mut(&format!("{}/genesis", pointer)) + { + override_genesis(genesis, overrides); + } + } + clear_authorities(&pointer, &mut chain_spec_json); // Get validators to add as authorities @@ -381,7 +387,12 @@ impl ChainSpec { .map_err(GeneratorError::ChainSpecGeneration)?; // make genesis overrides first. - // override_genesis() + if let Some(overrides) = &relaychain.genesis_overrides { + if let Some(genesis) = chain_spec_json.pointer_mut(&format!("{}/genesis", pointer)) + { + override_genesis(genesis, overrides); + } + } println!( "{:#?}", @@ -596,8 +607,29 @@ fn get_runtime_config_pointer(chain_spec_json: &serde_json::Value) -> Result<Str } // Override `genesis` key if present -fn override_genesis() { - todo!() +fn override_genesis(genesis: &mut serde_json::Value, overrides: &serde_json::Value) { + if let (Some(genesis_obj), Some(overrides_obj)) = + (genesis.as_object_mut(), overrides.as_object()) + { + for overrides_key in overrides_obj.keys() { + // we only want to override keys present in the genesis object + if let Some(genesis_value) = genesis_obj.get_mut(overrides_key) { + match (&genesis_value, overrides_obj.get(overrides_key)) { + // recurse if genesis value is an object + (serde_json::Value::Object(_), Some(overrides_value)) + if overrides_value.is_object() => + { + override_genesis(genesis_value, overrides_value); + }, + // override if genesis value not an object + (_, Some(overrides_value)) => { + *genesis_value = overrides_value.clone(); + }, + _ => {}, + } + } + } + } } fn clear_authorities(runtime_config_ptr: &str, chain_spec_json: &mut serde_json::Value) { diff --git a/crates/orchestrator/src/network_spec/parachain.rs b/crates/orchestrator/src/network_spec/parachain.rs index d5334df..33e1217 100644 --- a/crates/orchestrator/src/network_spec/parachain.rs +++ b/crates/orchestrator/src/network_spec/parachain.rs @@ -57,6 +57,9 @@ pub struct ParachainSpec { /// Genesis wasm to register the parachain pub(crate) genesis_wasm: ParaArtifact, + /// Genesis overrides as JSON value. + pub(crate) genesis_overrides: Option<serde_json::Value>, + /// Collators to spawn pub(crate) collators: Vec<NodeSpec>, } @@ -174,6 +177,7 @@ impl ParachainSpec { initial_balance: config.initial_balance(), genesis_state, genesis_wasm, + genesis_overrides: config.genesis_overrides().cloned(), collators, }; diff --git a/crates/orchestrator/src/network_spec/relaychain.rs b/crates/orchestrator/src/network_spec/relaychain.rs index 1f1fd60..a7adee2 100644 --- a/crates/orchestrator/src/network_spec/relaychain.rs +++ b/crates/orchestrator/src/network_spec/relaychain.rs @@ -43,6 +43,9 @@ pub struct RelaychainSpec { /// Set the max nominators value (used with PoS networks). pub(crate) max_nominations: u8, + /// Genesis overrides as JSON value. + pub(crate) genesis_overrides: Option<serde_json::Value>, + /// Nodes to run. pub(crate) nodes: Vec<NodeSpec>, } @@ -107,6 +110,7 @@ impl RelaychainSpec { chain_spec, random_nominators_count: config.random_nominators_count().unwrap_or(0), max_nominations: config.max_nominations().unwrap_or(24), + genesis_overrides: config.genesis_overrides().cloned(), nodes, }) } -- GitLab