From 78f2f2f5f126ca6097ce3defcc2e86943a39bd19 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Fri, 8 Sep 2023 12:51:27 +0200 Subject: [PATCH 01/10] RuntimeCode: doc fixed --- substrate/primitives/core/src/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/primitives/core/src/traits.rs b/substrate/primitives/core/src/traits.rs index 40137053ab75..9815c84f3396 100644 --- a/substrate/primitives/core/src/traits.rs +++ b/substrate/primitives/core/src/traits.rs @@ -91,7 +91,7 @@ pub struct RuntimeCode<'a> { /// /// If `None` are given, the default value of the executor will be used. pub heap_pages: Option, - /// The SCALE encoded hash of `code`. + /// The hash of `code`. /// /// The hashing algorithm isn't that important, as long as all runtime /// code instances use the same. From 36f15ef128380a9dfe41ba607dc9dcd5d531e6c4 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Mon, 4 Nov 2024 13:56:06 +0100 Subject: [PATCH 02/10] runtimes: presets improved --- .../src/genesis_config_presets.rs | 3 +- .../src/genesis_config_presets.rs | 20 +- .../src/genesis_config_presets.rs | 37 +- .../src/genesis_config_presets.rs | 41 +-- .../src/genesis_config_presets.rs | 20 +- .../packages/guides/first-runtime/src/lib.rs | 8 +- .../rococo/src/genesis_config_presets.rs | 34 +- .../westend/src/genesis_config_presets.rs | 18 +- .../support/src/generate_genesis_config.rs | 317 +++++++++++++++--- templates/minimal/runtime/src/lib.rs | 7 +- .../runtime/src/genesis_config_presets.rs | 17 +- .../runtime/src/genesis_config_presets.rs | 9 +- 12 files changed, 332 insertions(+), 199 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs index d15dd971a819..61512e75b22b 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs @@ -40,11 +40,12 @@ fn asset_hub_rococo_genesis( }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { - invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(), + invulnerables: invulnerables.clone().into_iter().map(|(acc, _)| acc).collect(), candidacy_bond: ASSET_HUB_ROCOCO_ED * 16, }, session: SessionConfig { keys: invulnerables + .clone() .into_iter() .map(|(acc, aura)| { ( diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs index 758ce3f40609..04244c05ad53 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs @@ -18,6 +18,7 @@ use crate::*; use alloc::{vec, vec::Vec}; use cumulus_primitives_core::ParaId; +use frame_support::build_struct_json_patch; use hex_literal::hex; use parachains_common::{AccountId, AuraId}; use sp_core::crypto::UncheckedInto; @@ -35,18 +36,18 @@ fn asset_hub_westend_genesis( endowment: Balance, id: ParaId, ) -> serde_json::Value { - let config = RuntimeGenesisConfig { + build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k| (k, endowment)).collect(), }, - parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, + parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { - invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(), + invulnerables: invulnerables.clone().into_iter().map(|(acc, _)| acc).collect(), candidacy_bond: ASSET_HUB_WESTEND_ED * 16, - ..Default::default() }, session: SessionConfig { keys: invulnerables + .clone() .into_iter() .map(|(acc, aura)| { ( @@ -56,16 +57,9 @@ fn asset_hub_westend_genesis( ) }) .collect(), - ..Default::default() }, - polkadot_xcm: PolkadotXcmConfig { - safe_xcm_version: Some(SAFE_XCM_VERSION), - ..Default::default() - }, - ..Default::default() - }; - - serde_json::to_value(config).expect("Could not build genesis config.") + polkadot_xcm: PolkadotXcmConfig { safe_xcm_version: Some(SAFE_XCM_VERSION) }, + }) } /// Encapsulates names of predefined presets. diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs index d1b599967bf3..86674317d5c4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs @@ -18,6 +18,7 @@ use crate::*; use alloc::{vec, vec::Vec}; use cumulus_primitives_core::ParaId; +use frame_support::build_struct_json_patch; use parachains_common::{AccountId, AuraId}; use sp_genesis_builder::PresetId; use sp_keyring::Sr25519Keyring; @@ -33,7 +34,7 @@ fn bridge_hub_rococo_genesis( asset_hub_para_id: ParaId, opened_bridges: Vec<(Location, InteriorLocation, Option)>, ) -> serde_json::Value { - let config = RuntimeGenesisConfig { + build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts .iter() @@ -41,14 +42,14 @@ fn bridge_hub_rococo_genesis( .map(|k| (k, 1u128 << 60)) .collect::>(), }, - parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, + parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { - invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(), + invulnerables: invulnerables.clone().into_iter().map(|(acc, _)| acc).collect(), candidacy_bond: BRIDGE_HUB_ROCOCO_ED * 16, - ..Default::default() }, session: SessionConfig { keys: invulnerables + .clone() .into_iter() .map(|(acc, aura)| { ( @@ -58,33 +59,15 @@ fn bridge_hub_rococo_genesis( ) }) .collect(), - ..Default::default() - }, - polkadot_xcm: PolkadotXcmConfig { - safe_xcm_version: Some(SAFE_XCM_VERSION), - ..Default::default() - }, - bridge_westend_grandpa: BridgeWestendGrandpaConfig { - owner: bridges_pallet_owner.clone(), - ..Default::default() }, + polkadot_xcm: PolkadotXcmConfig { safe_xcm_version: Some(SAFE_XCM_VERSION) }, + bridge_westend_grandpa: BridgeWestendGrandpaConfig { owner: bridges_pallet_owner.clone() }, bridge_westend_messages: BridgeWestendMessagesConfig { owner: bridges_pallet_owner.clone(), - ..Default::default() - }, - xcm_over_bridge_hub_westend: XcmOverBridgeHubWestendConfig { - opened_bridges, - ..Default::default() }, - ethereum_system: EthereumSystemConfig { - para_id: id, - asset_hub_para_id, - ..Default::default() - }, - ..Default::default() - }; - - serde_json::to_value(config).expect("Could not build genesis config.") + xcm_over_bridge_hub_westend: XcmOverBridgeHubWestendConfig { opened_bridges }, + ethereum_system: EthereumSystemConfig { para_id: id, asset_hub_para_id }, + }) } /// Provides the JSON representation of predefined genesis config for given `id`. diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs index 2949ae01fdcc..c6ef1f4e4289 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs @@ -18,6 +18,7 @@ use crate::*; use alloc::{vec, vec::Vec}; use cumulus_primitives_core::ParaId; +use frame_support::build_struct_json_patch; use parachains_common::{AccountId, AuraId}; use sp_genesis_builder::PresetId; use sp_keyring::Sr25519Keyring; @@ -33,7 +34,7 @@ fn bridge_hub_westend_genesis( asset_hub_para_id: ParaId, opened_bridges: Vec<(Location, InteriorLocation, Option)>, ) -> serde_json::Value { - let config = RuntimeGenesisConfig { + build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts .iter() @@ -41,14 +42,14 @@ fn bridge_hub_westend_genesis( .map(|k| (k, 1u128 << 60)) .collect::>(), }, - parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, + parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { - invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(), + invulnerables: invulnerables.clone().into_iter().map(|(acc, _)| acc).collect(), candidacy_bond: BRIDGE_HUB_WESTEND_ED * 16, - ..Default::default() }, session: SessionConfig { keys: invulnerables + .clone() .into_iter() .map(|(acc, aura)| { ( @@ -58,33 +59,13 @@ fn bridge_hub_westend_genesis( ) }) .collect(), - ..Default::default() }, - polkadot_xcm: PolkadotXcmConfig { - safe_xcm_version: Some(SAFE_XCM_VERSION), - ..Default::default() - }, - bridge_rococo_grandpa: BridgeRococoGrandpaConfig { - owner: bridges_pallet_owner.clone(), - ..Default::default() - }, - bridge_rococo_messages: BridgeRococoMessagesConfig { - owner: bridges_pallet_owner.clone(), - ..Default::default() - }, - xcm_over_bridge_hub_rococo: XcmOverBridgeHubRococoConfig { - opened_bridges, - ..Default::default() - }, - ethereum_system: EthereumSystemConfig { - para_id: id, - asset_hub_para_id, - ..Default::default() - }, - ..Default::default() - }; - - serde_json::to_value(config).expect("Could not build genesis config.") + polkadot_xcm: PolkadotXcmConfig { safe_xcm_version: Some(SAFE_XCM_VERSION) }, + bridge_rococo_grandpa: BridgeRococoGrandpaConfig { owner: bridges_pallet_owner.clone() }, + bridge_rococo_messages: BridgeRococoMessagesConfig { owner: bridges_pallet_owner.clone() }, + xcm_over_bridge_hub_rococo: XcmOverBridgeHubRococoConfig { opened_bridges }, + ethereum_system: EthereumSystemConfig { para_id: id, asset_hub_para_id }, + }) } /// Provides the JSON representation of predefined genesis config for given `id`. diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs index aec8e96cedc0..24a00d5074a5 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs @@ -18,6 +18,7 @@ use crate::*; use alloc::{vec, vec::Vec}; use cumulus_primitives_core::ParaId; +use frame_support::build_struct_json_patch; use parachains_common::{AccountId, AuraId}; use sp_genesis_builder::PresetId; use sp_keyring::Sr25519Keyring; @@ -30,7 +31,7 @@ fn collectives_westend_genesis( endowed_accounts: Vec, id: ParaId, ) -> serde_json::Value { - let config = RuntimeGenesisConfig { + build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts .iter() @@ -38,14 +39,14 @@ fn collectives_westend_genesis( .map(|k| (k, COLLECTIVES_WESTEND_ED * 4096)) .collect::>(), }, - parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, + parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { - invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(), + invulnerables: invulnerables.clone().into_iter().map(|(acc, _)| acc).collect(), candidacy_bond: COLLECTIVES_WESTEND_ED * 16, - ..Default::default() }, session: SessionConfig { keys: invulnerables + .clone() .into_iter() .map(|(acc, aura)| { ( @@ -55,16 +56,9 @@ fn collectives_westend_genesis( ) }) .collect(), - ..Default::default() }, - polkadot_xcm: PolkadotXcmConfig { - safe_xcm_version: Some(SAFE_XCM_VERSION), - ..Default::default() - }, - ..Default::default() - }; - - serde_json::to_value(config).expect("Could not build genesis config.") + polkadot_xcm: PolkadotXcmConfig { safe_xcm_version: Some(SAFE_XCM_VERSION) }, + }) } /// Provides the JSON representation of predefined genesis config for given `id`. diff --git a/docs/sdk/packages/guides/first-runtime/src/lib.rs b/docs/sdk/packages/guides/first-runtime/src/lib.rs index 92d51962b6fe..6faab14e49e7 100644 --- a/docs/sdk/packages/guides/first-runtime/src/lib.rs +++ b/docs/sdk/packages/guides/first-runtime/src/lib.rs @@ -130,23 +130,21 @@ pub mod genesis_config_presets { interface::{Balance, MinimumBalance}, BalancesConfig, RuntimeGenesisConfig, SudoConfig, }; + use frame::deps::frame_support::build_struct_json_patch; use serde_json::Value; /// Returns a development genesis config preset. #[docify::export] pub fn development_config_genesis() -> Value { let endowment = >::get().max(1) * 1000; - let config = RuntimeGenesisConfig { + build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: AccountKeyring::iter() .map(|a| (a.to_account_id(), endowment)) .collect::>(), }, sudo: SudoConfig { key: Some(AccountKeyring::Alice.to_account_id()) }, - ..Default::default() - }; - - serde_json::to_value(config).expect("Could not build genesis config.") + }) } /// Get the set of the available genesis config presets. diff --git a/polkadot/runtime/rococo/src/genesis_config_presets.rs b/polkadot/runtime/rococo/src/genesis_config_presets.rs index d609548aed27..ef05da39c4d9 100644 --- a/polkadot/runtime/rococo/src/genesis_config_presets.rs +++ b/polkadot/runtime/rococo/src/genesis_config_presets.rs @@ -23,6 +23,7 @@ use crate::{ #[cfg(not(feature = "std"))] use alloc::format; use alloc::{vec, vec::Vec}; +use frame_support::build_struct_json_patch; use polkadot_primitives::{AccountId, AssignmentId, SchedulerParams, ValidatorId}; use rococo_runtime_constants::currency::UNITS as ROC; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; @@ -163,7 +164,7 @@ fn rococo_testnet_genesis( const ENDOWMENT: u128 = 1_000_000 * ROC; - let config = RuntimeGenesisConfig { + build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>(), }, @@ -185,9 +186,8 @@ fn rococo_testnet_genesis( ) }) .collect::>(), - ..Default::default() }, - babe: BabeConfig { epoch_config: BABE_GENESIS_EPOCH_CONFIG, ..Default::default() }, + babe: BabeConfig { epoch_config: BABE_GENESIS_EPOCH_CONFIG }, sudo: SudoConfig { key: Some(root_key.clone()) }, configuration: ConfigurationConfig { config: polkadot_runtime_parachains::configuration::HostConfiguration { @@ -198,14 +198,8 @@ fn rococo_testnet_genesis( ..default_parachains_host_configuration() }, }, - registrar: RegistrarConfig { - next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID, - ..Default::default() - }, - ..Default::default() - }; - - serde_json::to_value(config).expect("Could not build genesis config.") + registrar: RegistrarConfig { next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID }, + }) } // staging_testnet @@ -214,7 +208,7 @@ fn rococo_staging_testnet_config_genesis() -> serde_json::Value { use sp_core::crypto::UncheckedInto; // subkey inspect "$SECRET" - let endowed_accounts = Vec::from([ + let endowed_accounts: Vec = Vec::from([ // 5DwBmEFPXRESyEam5SsQF1zbWSCn2kCjyLW51hJHXe9vW4xs hex!["52bc71c1eca5353749542dfdf0af97bf764f9c2f44e860cd485f1cd86400f649"].into(), ]); @@ -427,7 +421,7 @@ fn rococo_staging_testnet_config_genesis() -> serde_json::Value { const ENDOWMENT: u128 = 1_000_000 * ROC; const STASH: u128 = 100 * ROC; - let config = RuntimeGenesisConfig { + build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts .iter() @@ -437,22 +431,16 @@ fn rococo_staging_testnet_config_genesis() -> serde_json::Value { }, session: SessionConfig { keys: initial_authorities + .clone() .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::>(), - ..Default::default() }, - babe: BabeConfig { epoch_config: BABE_GENESIS_EPOCH_CONFIG, ..Default::default() }, + babe: BabeConfig { epoch_config: BABE_GENESIS_EPOCH_CONFIG }, sudo: SudoConfig { key: Some(endowed_accounts[0].clone()) }, configuration: ConfigurationConfig { config: default_parachains_host_configuration() }, - registrar: RegistrarConfig { - next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID, - ..Default::default() - }, - ..Default::default() - }; - - serde_json::to_value(config).expect("Could not build genesis config.") + registrar: RegistrarConfig { next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID }, + }) } //development diff --git a/polkadot/runtime/westend/src/genesis_config_presets.rs b/polkadot/runtime/westend/src/genesis_config_presets.rs index a9e22898ddb4..a3f25b4527a2 100644 --- a/polkadot/runtime/westend/src/genesis_config_presets.rs +++ b/polkadot/runtime/westend/src/genesis_config_presets.rs @@ -222,7 +222,7 @@ fn westend_staging_testnet_config_genesis() -> serde_json::Value { // // SECRET_SEED="slow awkward present example safe bundle science ocean cradle word tennis earn" // subkey inspect -n polkadot "$SECRET_SEED" - let endowed_accounts = vec![ + let endowed_accounts: Vec = vec![ // 15S75FkhCWEowEGfxWwVfrW3LQuy8w8PNhVmrzfsVhCMjUh1 hex!["c416837e232d9603e83162ef4bda08e61580eeefe60fe92fc044aa508559ae42"].into(), ]; @@ -338,7 +338,7 @@ fn westend_staging_testnet_config_genesis() -> serde_json::Value { const ENDOWMENT: u128 = 1_000_000 * WND; const STASH: u128 = 100 * WND; - let config = RuntimeGenesisConfig { + build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts .iter() @@ -364,7 +364,6 @@ fn westend_staging_testnet_config_genesis() -> serde_json::Value { ) }) .collect::>(), - ..Default::default() }, staking: StakingConfig { validator_count: 50, @@ -376,19 +375,12 @@ fn westend_staging_testnet_config_genesis() -> serde_json::Value { invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect::>(), force_era: Forcing::ForceNone, slash_reward_fraction: Perbill::from_percent(10), - ..Default::default() }, - babe: BabeConfig { epoch_config: BABE_GENESIS_EPOCH_CONFIG, ..Default::default() }, + babe: BabeConfig { epoch_config: BABE_GENESIS_EPOCH_CONFIG }, sudo: SudoConfig { key: Some(endowed_accounts[0].clone()) }, configuration: ConfigurationConfig { config: default_parachains_host_configuration() }, - registrar: RegistrarConfig { - next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID, - ..Default::default() - }, - ..Default::default() - }; - - serde_json::to_value(config).expect("Could not build genesis config.") + registrar: RegistrarConfig { next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID }, + }) } //development diff --git a/substrate/frame/support/src/generate_genesis_config.rs b/substrate/frame/support/src/generate_genesis_config.rs index fc21e76c7427..6d52483f13ec 100644 --- a/substrate/frame/support/src/generate_genesis_config.rs +++ b/substrate/frame/support/src/generate_genesis_config.rs @@ -23,41 +23,44 @@ use alloc::{borrow::Cow, format, string::String}; /// Represents the initialization method of a field within a struct. /// -/// This enum provides information about how it was initialized and the field name (as a `String`). +/// This enum provides information about how it was initialized. /// /// Intended to be used in `build_struct_json_patch` macro. #[derive(Debug)] -pub enum InitializedField<'a> { +pub enum InitilizationType { /// The field was partially initialized (e.g., specific fields within the struct were set /// manually). - Partial(Cow<'a, str>), - /// The field was fully initialized (e.g., using `new()` or `default()` like methods). - Full(Cow<'a, str>), + Partial, + /// The field was fully initialized (e.g., using `new()` or `default()` like methods + Full, } +/// This struct provides information about how the struct field was initialized and the field name +/// (as a `&str`). +/// +/// Intended to be used in `build_struct_json_patch` macro. +#[derive(Debug)] +pub struct InitializedField<'a>(InitilizationType, Cow<'a, str>); + impl<'a> InitializedField<'a> { /// Returns a name of the field. pub fn get_name(&'a self) -> &'a str { - match self { - Self::Partial(s) | Self::Full(s) => s, - } + &self.1 } /// Injects a prefix to the field name. pub fn add_prefix(&mut self, prefix: &str) { - match self { - Self::Partial(s) | Self::Full(s) => *s = format!("{prefix}.{s}").into(), - }; + self.1 = format!("{prefix}.{}", self.1).into() } /// Creates new partial field instiance. pub fn partial(s: &'a str) -> Self { - Self::Partial(s.into()) + Self(InitilizationType::Partial, s.into()) } /// Creates new full field instiance. pub fn full(s: &'a str) -> Self { - Self::Full(s.into()) + Self(InitilizationType::Full, s.into()) } } @@ -73,9 +76,15 @@ impl PartialEq for InitializedField<'_> { .map(|c| c.to_ascii_uppercase()) .eq(camel_chars.map(|c| c.to_ascii_uppercase())) } - match self { - InitializedField::Partial(field_name) | InitializedField::Full(field_name) => - field_name == other || compare_keys(field_name.chars(), other.chars()), + *self.1 == *other || compare_keys(self.1.chars(), other.chars()) + } +} + +impl<'a> From<(InitilizationType, &'a str)> for InitializedField<'a> { + fn from(value: (InitilizationType, &'a str)) -> Self { + match value.0 { + InitilizationType::Full => InitializedField::full(value.1), + InitilizationType::Partial => InitializedField::partial(value.1), } } } @@ -104,8 +113,8 @@ pub fn retain_initialized_fields( let current_key = if current_root.is_empty() { key.clone() } else { format!("{current_root}.{key}") }; match keys_to_retain.iter().find(|key| **key == current_key) { - Some(InitializedField::Full(_)) => true, - Some(InitializedField::Partial(_)) => { + Some(InitializedField(InitilizationType::Full, _)) => true, + Some(InitializedField(InitilizationType::Partial, _)) => { retain_initialized_fields(value, keys_to_retain, current_key.clone()); true }, @@ -211,26 +220,33 @@ macro_rules! build_struct_json_patch { $($struct_type:ident)::+ { $($tail:tt)* } ) => { { - let mut keys = $crate::__private::Vec::<$crate::generate_genesis_config::InitializedField>::default(); + let mut __keys = $crate::__private::Vec::<$crate::generate_genesis_config::InitializedField>::default(); #[allow(clippy::needless_update)] - let struct_instance = $crate::build_struct_json_patch!($($struct_type)::+, keys @ { $($tail)* }); - let mut json_value = - $crate::__private::serde_json::to_value(struct_instance).expect("serialization to json should work. qed"); - $crate::generate_genesis_config::retain_initialized_fields(&mut json_value, &keys, Default::default()); - json_value + let __struct_instance = $crate::build_struct_json_patch!($($struct_type)::+, __keys @ { $($tail)* }).0; + let mut __json_value = + $crate::__private::serde_json::to_value(__struct_instance).expect("serialization to json should work. qed"); + $crate::generate_genesis_config::retain_initialized_fields(&mut __json_value, &__keys, Default::default()); + __json_value } }; ($($struct_type:ident)::+, $all_keys:ident @ { $($tail:tt)* }) => { - $($struct_type)::+ { - ..$crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*) + { + let __value = $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*); + ( + $($struct_type)::+ { ..__value.0 }, + __value.1 + ) } }; ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $($type:ident)::+ { $keyi:ident : $value:tt } ) => { - $($struct_type)::+ { + ( + $($struct_type)::+ { $key: { $all_keys.push($crate::generate_genesis_config::InitializedField::partial(stringify!($key))); $all_keys.push( - $crate::generate_genesis_config::InitializedField::full(concat!(stringify!($key), ".", stringify!($keyi))) + $crate::generate_genesis_config::InitializedField::full( + concat!(stringify!($key), ".", stringify!($keyi)) + ) ); $($type)::+ { $keyi:$value, @@ -238,59 +254,126 @@ macro_rules! build_struct_json_patch { } }, ..Default::default() - } + }, + $crate::generate_genesis_config::InitilizationType::Partial + ) }; ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $($type:ident)::+ { $($body:tt)* } ) => { - $($struct_type)::+ { + ( + $($struct_type)::+ { $key: { - $all_keys.push($crate::generate_genesis_config::InitializedField::partial(stringify!($key))); - let mut inner_keys = $crate::__private::Vec::<$crate::generate_genesis_config::InitializedField>::default(); - let value = $crate::build_struct_json_patch!($($type)::+, inner_keys @ { $($body)* }); - for i in inner_keys.iter_mut() { + let mut __inner_keys = + $crate::__private::Vec::<$crate::generate_genesis_config::InitializedField>::default(); + let __value = $crate::build_struct_json_patch!($($type)::+, __inner_keys @ { $($body)* }); + for i in __inner_keys.iter_mut() { i.add_prefix(stringify!($key)); }; - $all_keys.extend(inner_keys); - value + $all_keys.push((__value.1,stringify!($key)).into()); + $all_keys.extend(__inner_keys); + __value.0 }, ..Default::default() - } + }, + $crate::generate_genesis_config::InitilizationType::Partial + ) }; ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $($type:ident)::+ { $($body:tt)* }, $($tail:tt)* ) => { - $($struct_type)::+ { + { + let __update = $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*); + ( + $($struct_type)::+ { $key : { - $all_keys.push($crate::generate_genesis_config::InitializedField::partial(stringify!($key))); - let mut inner_keys = $crate::__private::Vec::<$crate::generate_genesis_config::InitializedField>::default(); - let value = $crate::build_struct_json_patch!($($type)::+, inner_keys @ { $($body)* }); - for i in inner_keys.iter_mut() { + let mut __inner_keys = + $crate::__private::Vec::<$crate::generate_genesis_config::InitializedField>::default(); + let __value = $crate::build_struct_json_patch!($($type)::+, __inner_keys @ { $($body)* }); + $all_keys.push((__value.1,stringify!($key)).into()); + + for i in __inner_keys.iter_mut() { i.add_prefix(stringify!($key)); }; - $all_keys.extend(inner_keys); - value + $all_keys.extend(__inner_keys); + __value.0 }, - .. $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*) + .. __update.0 + }, + __update.1 + ) } }; ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $value:expr, $($tail:tt)* ) => { - $($struct_type)::+ { + { + let __update = $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*); + ( + $($struct_type)::+ { $key: { - $all_keys.push($crate::generate_genesis_config::InitializedField::full(stringify!($key))); + $all_keys.push($crate::generate_genesis_config::InitializedField::full( + stringify!($key)) + ); $value }, - ..$crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*) + ..__update.0 + }, + __update.1 + ) } }; ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $value:expr ) => { - $($struct_type)::+ { + ( + $($struct_type)::+ { $key: { $all_keys.push($crate::generate_genesis_config::InitializedField::full(stringify!($key))); $value }, ..Default::default() + }, + $crate::generate_genesis_config::InitilizationType::Partial + ) + }; + // field init shorthand + ($($struct_type:ident)::+, $all_keys:ident @ $key:ident, $($tail:tt)* ) => { + { + let __update = $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*); + ( + $($struct_type)::+ { + $key: { + $all_keys.push($crate::generate_genesis_config::InitializedField::full( + stringify!($key)) + ); + $key + }, + ..__update.0 + }, + __update.1 + ) } }; - + ($($struct_type:ident)::+, $all_keys:ident @ $key:ident ) => { + ( + $($struct_type)::+ { + $key: { + $all_keys.push($crate::generate_genesis_config::InitializedField::full(stringify!($key))); + $key + }, + ..Default::default() + }, + $crate::generate_genesis_config::InitilizationType::Partial + ) + }; + ($($struct_type:ident)::+, $all_keys:ident @ ..$update:expr ) => { + ( + $($struct_type)::+ { + ..{ println!("{:?}", $all_keys); $update } + }, + $crate::generate_genesis_config::InitilizationType::Full + ) + }; ($($struct_type:ident)::+, $all_keys:ident @ $(,)?) => { - $($struct_type)::+ { ..Default::default() } + ( + $($struct_type)::+ { + ..Default::default() + }, + $crate::generate_genesis_config::InitilizationType::Partial + ) }; } @@ -705,6 +788,138 @@ mod test { ); } + #[test] + fn test_generate_config_macro_field_init_shorthand() { + { + let x = 5; + test!(TestStruct { s: S { x } }, { "s": { "x": 5 } }); + } + { + let s = nested_mod::InsideMod { a: 34, b: 8 }; + test!( + TestStruct { + t: nested_mod::InsideMod { a: 32 }, + u: nested_mod::nested_mod2::nested_mod3::InsideMod3 { + s, + a: 32, + } + }, + { + "t" : { "a": 32 }, + "u" : { "a": 32, "s": { "a": 34, "b": 8} } + } + ); + } + { + let s = nested_mod::InsideMod { a: 34, b: 8 }; + test!( + TestStruct { + t: nested_mod::InsideMod { a: 32 }, + u: nested_mod::nested_mod2::nested_mod3::InsideMod3 { + a: 32, + s, + } + }, + { + "t" : { "a": 32 }, + "u" : { "a": 32, "s": { "a": 34, "b": 8} } + } + ); + } + } + + #[test] + fn test_generate_config_macro_struct_update() { + { + let s = S { x: 5 }; + test!(TestStruct { s: S { ..s } }, { "s": { "x": 5 } }); + } + { + mod nested { + use super::*; + pub fn function() -> S { + S { x: 5 } + } + } + test!(TestStruct { s: S { ..nested::function() } }, { "s": { "x": 5 } }); + } + { + let s = nested_mod::InsideMod { a: 34, b: 8 }; + let s1 = nested_mod::InsideMod { a: 34, b: 8 }; + test!( + TestStruct { + t: nested_mod::InsideMod { ..s1 }, + u: nested_mod::nested_mod2::nested_mod3::InsideMod3 { + s, + a: 32, + } + }, + { + "t" : { "a": 34, "b": 8 }, + "u" : { "a": 32, "s": { "a": 34, "b": 8} } + } + ); + } + { + let i3 = nested_mod::nested_mod2::nested_mod3::InsideMod3 { + a: 1, + b: 2, + s: nested_mod::InsideMod { a: 55, b: 88 }, + }; + test!( + TestStruct { + t: nested_mod::InsideMod { a: 32 }, + u: nested_mod::nested_mod2::nested_mod3::InsideMod3 { + a: 32, + ..i3 + } + }, + { + "t" : { "a": 32 }, + "u" : { "a": 32, "b": 2, "s": { "a": 55, "b": 88} } + } + ); + } + { + let s = nested_mod::InsideMod { a: 34, b: 8 }; + test!( + TestStruct { + t: nested_mod::InsideMod { a: 32 }, + u: nested_mod::nested_mod2::nested_mod3::InsideMod3 { + a: 32, + s: nested_mod::InsideMod { + b: 66, + ..s + } + } + }, + { + "t" : { "a": 32 }, + "u" : { "a": 32, "s": { "a": 34, "b": 66} } + } + ); + } + { + let s = nested_mod::InsideMod { a: 34, b: 8 }; + test!( + TestStruct { + t: nested_mod::InsideMod { a: 32 }, + u: nested_mod::nested_mod2::nested_mod3::InsideMod3 { + s: nested_mod::InsideMod { + b: 66, + ..s + }, + a: 32 + } + }, + { + "t" : { "a": 32 }, + "u" : { "a": 32, "s": { "a": 34, "b": 66} } + } + ); + } + } + #[test] fn test_generate_config_macro_with_nested_mods() { test!( diff --git a/templates/minimal/runtime/src/lib.rs b/templates/minimal/runtime/src/lib.rs index 304e50af2508..981e656e0c62 100644 --- a/templates/minimal/runtime/src/lib.rs +++ b/templates/minimal/runtime/src/lib.rs @@ -51,17 +51,14 @@ pub mod genesis_config_presets { /// Returns a development genesis config preset. pub fn development_config_genesis() -> Value { let endowment = >::get().max(1) * 1000; - let config = RuntimeGenesisConfig { + frame_support::build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: AccountKeyring::iter() .map(|a| (a.to_account_id(), endowment)) .collect::>(), }, sudo: SudoConfig { key: Some(AccountKeyring::Alice.to_account_id()) }, - ..Default::default() - }; - - serde_json::to_value(config).expect("Could not build genesis config.") + }) } /// Get the set of the available genesis config presets. diff --git a/templates/parachain/runtime/src/genesis_config_presets.rs b/templates/parachain/runtime/src/genesis_config_presets.rs index 394bde0be770..19f4d157bdf1 100644 --- a/templates/parachain/runtime/src/genesis_config_presets.rs +++ b/templates/parachain/runtime/src/genesis_config_presets.rs @@ -8,6 +8,7 @@ use alloc::{vec, vec::Vec}; use polkadot_sdk::{staging_xcm as xcm, *}; use cumulus_primitives_core::ParaId; +use frame_support::build_struct_json_patch; use parachains_common::AuraId; use serde_json::Value; use sp_genesis_builder::PresetId; @@ -29,7 +30,7 @@ fn testnet_genesis( root: AccountId, id: ParaId, ) -> Value { - let config = RuntimeGenesisConfig { + build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts .iter() @@ -37,11 +38,10 @@ fn testnet_genesis( .map(|k| (k, 1u128 << 60)) .collect::>(), }, - parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, + parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect::>(), candidacy_bond: EXISTENTIAL_DEPOSIT * 16, - ..Default::default() }, session: SessionConfig { keys: invulnerables @@ -54,17 +54,10 @@ fn testnet_genesis( ) }) .collect::>(), - ..Default::default() - }, - polkadot_xcm: PolkadotXcmConfig { - safe_xcm_version: Some(SAFE_XCM_VERSION), - ..Default::default() }, + polkadot_xcm: PolkadotXcmConfig { safe_xcm_version: Some(SAFE_XCM_VERSION) }, sudo: SudoConfig { key: Some(root) }, - ..Default::default() - }; - - serde_json::to_value(config).expect("Could not build genesis config.") + }) } fn local_testnet_genesis() -> Value { diff --git a/templates/solochain/runtime/src/genesis_config_presets.rs b/templates/solochain/runtime/src/genesis_config_presets.rs index 693ae5c2221f..ec513b1ee14f 100644 --- a/templates/solochain/runtime/src/genesis_config_presets.rs +++ b/templates/solochain/runtime/src/genesis_config_presets.rs @@ -17,6 +17,7 @@ use crate::{AccountId, BalancesConfig, RuntimeGenesisConfig, SudoConfig}; use alloc::{vec, vec::Vec}; +use frame_support::build_struct_json_patch; use serde_json::Value; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_consensus_grandpa::AuthorityId as GrandpaId; @@ -29,7 +30,7 @@ fn testnet_genesis( endowed_accounts: Vec, root: AccountId, ) -> Value { - let config = RuntimeGenesisConfig { + build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts .iter() @@ -42,13 +43,9 @@ fn testnet_genesis( }, grandpa: pallet_grandpa::GenesisConfig { authorities: initial_authorities.iter().map(|x| (x.1.clone(), 1)).collect::>(), - ..Default::default() }, sudo: SudoConfig { key: Some(root) }, - ..Default::default() - }; - - serde_json::to_value(config).expect("Could not build genesis config.") + }) } /// Return the development genesis config. From 496334e7c9cc1d645d67e2343b30e40e1c24e177 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:36:33 +0100 Subject: [PATCH 03/10] prdoc added + fix --- prdoc/pr_6349.prdoc | 13 +++++++++++++ .../frame/support/src/generate_genesis_config.rs | 7 +------ 2 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 prdoc/pr_6349.prdoc diff --git a/prdoc/pr_6349.prdoc b/prdoc/pr_6349.prdoc new file mode 100644 index 000000000000..62d8c0a51cd6 --- /dev/null +++ b/prdoc/pr_6349.prdoc @@ -0,0 +1,13 @@ +title: "runtimes: presets are provided as config patches" + +doc: + - audience: Runtime Dev + description: | + This PR introduces usage of build_struct_json_patch macro in all + runtimes (also guides) within the code base. It also fixes macro to support + field init shorthand, and Struct Update syntax which were missing in original + implementation. + +crates: + - name: frame-support + bump: patch diff --git a/substrate/frame/support/src/generate_genesis_config.rs b/substrate/frame/support/src/generate_genesis_config.rs index 6d52483f13ec..f9a37069b0c8 100644 --- a/substrate/frame/support/src/generate_genesis_config.rs +++ b/substrate/frame/support/src/generate_genesis_config.rs @@ -362,7 +362,7 @@ macro_rules! build_struct_json_patch { ($($struct_type:ident)::+, $all_keys:ident @ ..$update:expr ) => { ( $($struct_type)::+ { - ..{ println!("{:?}", $all_keys); $update } + ..{ $update } }, $crate::generate_genesis_config::InitilizationType::Full ) @@ -484,11 +484,8 @@ mod test { macro_rules! test { ($($struct:ident)::+ { $($v:tt)* }, { $($j:tt)* } ) => {{ - println!("--"); let expected = serde_json::json!({ $($j)* }); - println!("json: {}", serde_json::to_string_pretty(&expected).unwrap()); let value = build_struct_json_patch!($($struct)::+ { $($v)* }); - println!("gc: {}", serde_json::to_string_pretty(&value).unwrap()); assert_eq!(value, expected); }}; } @@ -1012,7 +1009,6 @@ mod retain_keys_test { ( $s:literal ) => { let field = InitializedField::full($s); let cc = inflector::cases::camelcase::to_camel_case($s); - println!("field: {:?}, cc: {}", field, cc); assert_eq!(field,cc); } ; ( &[ $f:literal $(, $r:literal)* ]) => { @@ -1023,7 +1019,6 @@ mod retain_keys_test { .map(|s| inflector::cases::camelcase::to_camel_case(s)) .collect::>() .join("."); - println!("field: {:?}, cc: {}", field, cc); assert_eq!(field,cc); } ; ); From 8ce2a3f9874d01a37a5d8c84d9aa79f063e55362 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Mon, 4 Nov 2024 15:16:39 +0100 Subject: [PATCH 04/10] fix --- templates/parachain/runtime/src/genesis_config_presets.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/templates/parachain/runtime/src/genesis_config_presets.rs b/templates/parachain/runtime/src/genesis_config_presets.rs index 19f4d157bdf1..f1a7e35703e0 100644 --- a/templates/parachain/runtime/src/genesis_config_presets.rs +++ b/templates/parachain/runtime/src/genesis_config_presets.rs @@ -33,8 +33,8 @@ fn testnet_genesis( build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts - .iter() - .cloned() + .clone() + .into_iter() .map(|k| (k, 1u128 << 60)) .collect::>(), }, @@ -45,6 +45,7 @@ fn testnet_genesis( }, session: SessionConfig { keys: invulnerables + .clone() .into_iter() .map(|(acc, aura)| { ( From 6990460808dbf18aa81a7d5cfe58763b81a8e3a1 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:51:16 +0100 Subject: [PATCH 05/10] Revert "RuntimeCode: doc fixed" This reverts commit 78f2f2f5f126ca6097ce3defcc2e86943a39bd19. --- substrate/primitives/core/src/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/primitives/core/src/traits.rs b/substrate/primitives/core/src/traits.rs index 851d89103914..69f7eb368234 100644 --- a/substrate/primitives/core/src/traits.rs +++ b/substrate/primitives/core/src/traits.rs @@ -90,7 +90,7 @@ pub struct RuntimeCode<'a> { /// /// If `None` are given, the default value of the executor will be used. pub heap_pages: Option, - /// The hash of `code`. + /// The SCALE encoded hash of `code`. /// /// The hashing algorithm isn't that important, as long as all runtime /// code instances use the same. From 0d6ff4361e80a919bf5930a81259002302e5efd3 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:58:08 +0100 Subject: [PATCH 06/10] primitives/core/src/traits.rs checked out to origin/master --- substrate/primitives/core/src/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/primitives/core/src/traits.rs b/substrate/primitives/core/src/traits.rs index 69f7eb368234..851d89103914 100644 --- a/substrate/primitives/core/src/traits.rs +++ b/substrate/primitives/core/src/traits.rs @@ -90,7 +90,7 @@ pub struct RuntimeCode<'a> { /// /// If `None` are given, the default value of the executor will be used. pub heap_pages: Option, - /// The SCALE encoded hash of `code`. + /// The hash of `code`. /// /// The hashing algorithm isn't that important, as long as all runtime /// code instances use the same. From b830709470075c800dcc17173ea960103a73515b Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Tue, 5 Nov 2024 11:43:15 +0100 Subject: [PATCH 07/10] improvements (execution order fix) + formatting --- .../src/genesis_config_presets.rs | 3 +- .../src/genesis_config_presets.rs | 3 +- .../src/genesis_config_presets.rs | 3 +- .../src/genesis_config_presets.rs | 3 +- .../src/genesis_config_presets.rs | 3 +- .../rococo/src/genesis_config_presets.rs | 1 - .../support/src/generate_genesis_config.rs | 304 ++++++++++++++---- .../runtime/src/genesis_config_presets.rs | 5 +- 8 files changed, 248 insertions(+), 77 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs index 61512e75b22b..d15dd971a819 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/genesis_config_presets.rs @@ -40,12 +40,11 @@ fn asset_hub_rococo_genesis( }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { - invulnerables: invulnerables.clone().into_iter().map(|(acc, _)| acc).collect(), + invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(), candidacy_bond: ASSET_HUB_ROCOCO_ED * 16, }, session: SessionConfig { keys: invulnerables - .clone() .into_iter() .map(|(acc, aura)| { ( diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs index 04244c05ad53..d6f748283d46 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs @@ -42,12 +42,11 @@ fn asset_hub_westend_genesis( }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { - invulnerables: invulnerables.clone().into_iter().map(|(acc, _)| acc).collect(), + invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(), candidacy_bond: ASSET_HUB_WESTEND_ED * 16, }, session: SessionConfig { keys: invulnerables - .clone() .into_iter() .map(|(acc, aura)| { ( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs index 86674317d5c4..d99ff2b15a60 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs @@ -44,12 +44,11 @@ fn bridge_hub_rococo_genesis( }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { - invulnerables: invulnerables.clone().into_iter().map(|(acc, _)| acc).collect(), + invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(), candidacy_bond: BRIDGE_HUB_ROCOCO_ED * 16, }, session: SessionConfig { keys: invulnerables - .clone() .into_iter() .map(|(acc, aura)| { ( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs index c6ef1f4e4289..aea8364cc274 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs @@ -44,12 +44,11 @@ fn bridge_hub_westend_genesis( }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { - invulnerables: invulnerables.clone().into_iter().map(|(acc, _)| acc).collect(), + invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(), candidacy_bond: BRIDGE_HUB_WESTEND_ED * 16, }, session: SessionConfig { keys: invulnerables - .clone() .into_iter() .map(|(acc, aura)| { ( diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs index 24a00d5074a5..8d9ded155127 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/genesis_config_presets.rs @@ -41,12 +41,11 @@ fn collectives_westend_genesis( }, parachain_info: ParachainInfoConfig { parachain_id: id }, collator_selection: CollatorSelectionConfig { - invulnerables: invulnerables.clone().into_iter().map(|(acc, _)| acc).collect(), + invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(), candidacy_bond: COLLECTIVES_WESTEND_ED * 16, }, session: SessionConfig { keys: invulnerables - .clone() .into_iter() .map(|(acc, aura)| { ( diff --git a/polkadot/runtime/rococo/src/genesis_config_presets.rs b/polkadot/runtime/rococo/src/genesis_config_presets.rs index ef05da39c4d9..1b58904586e4 100644 --- a/polkadot/runtime/rococo/src/genesis_config_presets.rs +++ b/polkadot/runtime/rococo/src/genesis_config_presets.rs @@ -431,7 +431,6 @@ fn rococo_staging_testnet_config_genesis() -> serde_json::Value { }, session: SessionConfig { keys: initial_authorities - .clone() .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::>(), diff --git a/substrate/frame/support/src/generate_genesis_config.rs b/substrate/frame/support/src/generate_genesis_config.rs index f9a37069b0c8..283840d70c7c 100644 --- a/substrate/frame/support/src/generate_genesis_config.rs +++ b/substrate/frame/support/src/generate_genesis_config.rs @@ -217,152 +217,143 @@ pub fn retain_initialized_fields( #[macro_export] macro_rules! build_struct_json_patch { ( - $($struct_type:ident)::+ { $($tail:tt)* } + $($struct_type:ident)::+ { $($body:tt)* } ) => { { let mut __keys = $crate::__private::Vec::<$crate::generate_genesis_config::InitializedField>::default(); #[allow(clippy::needless_update)] - let __struct_instance = $crate::build_struct_json_patch!($($struct_type)::+, __keys @ { $($tail)* }).0; + let __struct_instance = $crate::build_struct_json_patch!($($struct_type)::+, __keys @ { $($body)* }).0; let mut __json_value = $crate::__private::serde_json::to_value(__struct_instance).expect("serialization to json should work. qed"); $crate::generate_genesis_config::retain_initialized_fields(&mut __json_value, &__keys, Default::default()); __json_value } }; - ($($struct_type:ident)::+, $all_keys:ident @ { $($tail:tt)* }) => { + ($($struct_type:ident)::+, $all_keys:ident @ { $($body:tt)* }) => { { - let __value = $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*); + let __value = $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($body)*); ( $($struct_type)::+ { ..__value.0 }, __value.1 ) } }; - ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $($type:ident)::+ { $keyi:ident : $value:tt } ) => { + ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $($type:ident)::+ { $($body:tt)* } ) => { ( $($struct_type)::+ { - $key: { - $all_keys.push($crate::generate_genesis_config::InitializedField::partial(stringify!($key))); - $all_keys.push( - $crate::generate_genesis_config::InitializedField::full( - concat!(stringify!($key), ".", stringify!($keyi)) - ) - ); - $($type)::+ { - $keyi:$value, - ..Default::default() - } - }, - ..Default::default() - }, - $crate::generate_genesis_config::InitilizationType::Partial - ) - }; - ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $($type:ident)::+ { $($body:tt)* } ) => { - ( - $($struct_type)::+ { - $key: { + $key: { let mut __inner_keys = $crate::__private::Vec::<$crate::generate_genesis_config::InitializedField>::default(); let __value = $crate::build_struct_json_patch!($($type)::+, __inner_keys @ { $($body)* }); for i in __inner_keys.iter_mut() { - i.add_prefix(stringify!($key)); - }; + i.add_prefix(stringify!($key)); + }; $all_keys.push((__value.1,stringify!($key)).into()); $all_keys.extend(__inner_keys); __value.0 - }, - ..Default::default() + }, + ..Default::default() }, $crate::generate_genesis_config::InitilizationType::Partial ) }; - ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $($type:ident)::+ { $($body:tt)* }, $($tail:tt)* ) => { + ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $($type:ident)::+ { $($body:tt)* }, $($tail:tt)*) => { { - let __update = $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*); + let mut __initialization_type; ( $($struct_type)::+ { - $key : { + $key : { let mut __inner_keys = $crate::__private::Vec::<$crate::generate_genesis_config::InitializedField>::default(); let __value = $crate::build_struct_json_patch!($($type)::+, __inner_keys @ { $($body)* }); $all_keys.push((__value.1,stringify!($key)).into()); for i in __inner_keys.iter_mut() { - i.add_prefix(stringify!($key)); - }; + i.add_prefix(stringify!($key)); + }; $all_keys.extend(__inner_keys); __value.0 - }, - .. __update.0 + }, + .. { + let (__value, __tmp) = + $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*); + __initialization_type = __tmp; + __value + } }, - __update.1 + __initialization_type ) } }; - ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $value:expr, $($tail:tt)* ) => { + ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $value:expr, $($tail:tt)* ) => { { - let __update = $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*); + let mut __initialization_type; ( $($struct_type)::+ { - $key: { + $key: { $all_keys.push($crate::generate_genesis_config::InitializedField::full( stringify!($key)) ); - $value - }, - ..__update.0 + $value + }, + .. { + let (__value, __tmp) = + $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*); + __initialization_type = __tmp; + __value + } }, - __update.1 + __initialization_type ) } }; - ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $value:expr ) => { + ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $value:expr ) => { ( $($struct_type)::+ { - $key: { - $all_keys.push($crate::generate_genesis_config::InitializedField::full(stringify!($key))); - $value - }, - ..Default::default() + $key: { + $all_keys.push($crate::generate_genesis_config::InitializedField::full(stringify!($key))); + $value + }, + ..Default::default() }, $crate::generate_genesis_config::InitilizationType::Partial ) }; // field init shorthand - ($($struct_type:ident)::+, $all_keys:ident @ $key:ident, $($tail:tt)* ) => { + ($($struct_type:ident)::+, $all_keys:ident @ $key:ident, $($tail:tt)* ) => { { let __update = $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*); ( $($struct_type)::+ { - $key: { + $key: { $all_keys.push($crate::generate_genesis_config::InitializedField::full( stringify!($key)) ); - $key - }, + $key + }, ..__update.0 }, __update.1 ) } }; - ($($struct_type:ident)::+, $all_keys:ident @ $key:ident ) => { + ($($struct_type:ident)::+, $all_keys:ident @ $key:ident ) => { ( $($struct_type)::+ { - $key: { - $all_keys.push($crate::generate_genesis_config::InitializedField::full(stringify!($key))); - $key - }, - ..Default::default() + $key: { + $all_keys.push($crate::generate_genesis_config::InitializedField::full(stringify!($key))); + $key + }, + ..Default::default() }, $crate::generate_genesis_config::InitilizationType::Partial ) }; - ($($struct_type:ident)::+, $all_keys:ident @ ..$update:expr ) => { + // update struct + ($($struct_type:ident)::+, $all_keys:ident @ ..$update:expr ) => { ( $($struct_type)::+ { - ..{ $update } + ..$update }, $crate::generate_genesis_config::InitilizationType::Full ) @@ -495,6 +486,7 @@ mod test { let t = 5; const C: u32 = 5; test!(TestStruct { b: 5 }, { "b": 5 }); + test!(TestStruct { b: 5, }, { "b": 5 }); #[allow(unused_braces)] { test!(TestStruct { b: { 4 + 34 } } , { "b": 38 }); @@ -917,6 +909,192 @@ mod test { } } + #[test] + fn test_generate_config_macro_with_execution_order() { + #[derive(Debug, Default, serde::Serialize, serde::Deserialize, PartialEq)] + struct X { + x: Vec, + x2: Vec, + y2: Y, + } + #[derive(Debug, Default, serde::Serialize, serde::Deserialize, PartialEq)] + struct Y { + y: Vec, + } + #[derive(Debug, Default, serde::Serialize, serde::Deserialize, PartialEq)] + struct Z { + a: u32, + x: X, + y: Y, + } + { + let v = vec![1, 2, 3]; + test!(Z { a: 0, x: X { x: v }, }, { + "a": 0, "x": { "x": [1,2,3] } + }); + } + { + let v = vec![1, 2, 3]; + test!(Z { a: 3, x: X { x: v.clone() }, y: Y { y: v } }, { + "a": 3, "x": { "x": [1,2,3] }, "y": { "y": [1,2,3] } + }); + } + { + let v = vec![1, 2, 3]; + test!(Z { a: 3, x: X { y2: Y { y: v.clone() }, x: v.clone() }, y: Y { y: v } }, { + "a": 3, "x": { "x": [1,2,3], "y2":{ "y":[1,2,3] } }, "y": { "y": [1,2,3] } + }); + } + { + let v = vec![1, 2, 3]; + test!(Z { a: 3, y: Y { y: v.clone() }, x: X { y2: Y { y: v.clone() }, x: v }, }, { + "a": 3, "x": { "x": [1,2,3], "y2":{ "y":[1,2,3] } }, "y": { "y": [1,2,3] } + }); + } + { + let v = vec![1, 2, 3]; + test!( + Z { + y: Y { + y: v.clone() + }, + x: X { + y2: Y { + y: v.clone() + }, + x: v.clone(), + x2: v.clone() + }, + }, + { + "x": { + "x": [1,2,3], + "x2": [1,2,3], + "y2": { + "y":[1,2,3] + } + }, + "y": { + "y": [1,2,3] + } + }); + } + { + let v = vec![1, 2, 3]; + test!( + Z { + y: Y { + y: v.clone() + }, + x: X { + y2: Y { + y: v.clone() + }, + x: v + }, + }, + { + "x": { + "x": [1,2,3], + "y2": { + "y":[1,2,3] + } + }, + "y": { + "y": [1,2,3] + } + }); + } + { + let mut v = vec![0, 1, 2]; + let f = |vec: &mut Vec| -> Vec { + vec.iter_mut().for_each(|x| *x += 1); + vec.clone() + }; + let z = Z { + a: 0, + y: Y { y: f(&mut v) }, + x: X { y2: Y { y: f(&mut v) }, x: f(&mut v), x2: vec![] }, + }; + let z_expected = Z { + a: 0, + y: Y { y: vec![1, 2, 3] }, + x: X { y2: Y { y: vec![2, 3, 4] }, x: vec![3, 4, 5], x2: vec![] }, + }; + assert_eq!(z, z_expected); + v = vec![0, 1, 2]; + println!("{z:?}"); + test!( + Z { + y: Y { + y: f(&mut v) + }, + x: X { + y2: Y { + y: f(&mut v) + }, + x: f(&mut v) + }, + }, + { + "y": { + "y": [1,2,3] + }, + "x": { + "y2": { + "y":[2,3,4] + }, + "x": [3,4,5], + }, + }); + } + { + let mut v = vec![0, 1, 2]; + let f = |vec: &mut Vec| -> Vec { + vec.iter_mut().for_each(|x| *x += 1); + vec.clone() + }; + let z = Z { + a: 0, + y: Y { y: f(&mut v) }, + x: X { y2: Y { y: f(&mut v) }, x: f(&mut v), x2: f(&mut v) }, + }; + let z_expected = Z { + a: 0, + y: Y { y: vec![1, 2, 3] }, + x: X { y2: Y { y: vec![2, 3, 4] }, x: vec![3, 4, 5], x2: vec![4, 5, 6] }, + }; + assert_eq!(z, z_expected); + v = vec![0, 1, 2]; + println!("{z:?}"); + test!( + Z { + y: Y { + y: f(&mut v) + }, + x: X { + y2: Y { + y: f(&mut v) + }, + x: f(&mut v), + x2: f(&mut v) + }, + }, + { + "y": { + "y": [1,2,3] + }, + "x": { + "y2": { + "y":[2,3,4] + }, + "x": [3,4,5], + "x2": [4,5,6], + }, + }); + } + } + #[test] fn test_generate_config_macro_with_nested_mods() { test!( diff --git a/templates/parachain/runtime/src/genesis_config_presets.rs b/templates/parachain/runtime/src/genesis_config_presets.rs index 6d12aff5f4ec..6d84c06e4477 100644 --- a/templates/parachain/runtime/src/genesis_config_presets.rs +++ b/templates/parachain/runtime/src/genesis_config_presets.rs @@ -35,8 +35,8 @@ fn testnet_genesis( build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts - .clone() - .into_iter() + .iter() + .cloned() .map(|k| (k, 1u128 << 60)) .collect::>(), }, @@ -47,7 +47,6 @@ fn testnet_genesis( }, session: SessionConfig { keys: invulnerables - .clone() .into_iter() .map(|(acc, aura)| { ( From 0cf718c08fd46d3bde38f520166011fb608be0ad Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Tue, 5 Nov 2024 11:47:37 +0100 Subject: [PATCH 08/10] removed redundant type --- polkadot/runtime/rococo/src/genesis_config_presets.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/runtime/rococo/src/genesis_config_presets.rs b/polkadot/runtime/rococo/src/genesis_config_presets.rs index 1b58904586e4..6d6dc3d43d72 100644 --- a/polkadot/runtime/rococo/src/genesis_config_presets.rs +++ b/polkadot/runtime/rococo/src/genesis_config_presets.rs @@ -208,7 +208,7 @@ fn rococo_staging_testnet_config_genesis() -> serde_json::Value { use sp_core::crypto::UncheckedInto; // subkey inspect "$SECRET" - let endowed_accounts: Vec = Vec::from([ + let endowed_accounts = Vec::from([ // 5DwBmEFPXRESyEam5SsQF1zbWSCn2kCjyLW51hJHXe9vW4xs hex!["52bc71c1eca5353749542dfdf0af97bf764f9c2f44e860cd485f1cd86400f649"].into(), ]); From e1345b7b42c4844175ed38a3e4de45f6197bf594 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:21:33 +0100 Subject: [PATCH 09/10] prdoc --- prdoc/pr_6349.prdoc | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/prdoc/pr_6349.prdoc b/prdoc/pr_6349.prdoc index 62d8c0a51cd6..105b103e4040 100644 --- a/prdoc/pr_6349.prdoc +++ b/prdoc/pr_6349.prdoc @@ -10,4 +10,36 @@ doc: crates: - name: frame-support + bump: minor + validate: false + + - name: westend-runtime + bump: patch + + - name: rococo-runtime + bump: patch + + - name: asset-hub-westend-runtime bump: patch + + - name: bridge-hub-rococo-runtime + bump: patch + + - name: bridge-hub-westend-runtime + bump: patch + + - name: collectives-westend-runtime + bump: patch + + - name: minimal-template-runtime + bump: patch + + - name: solochain-template-runtime + bump: patch + + - name: parachain-template-runtime + bump: patch + + - name: polkadot-sdk-docs-first-runtime + bump: patch + From bd65a7a625da41b4ca40e07896c2c0a7eb714836 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:16:48 +0100 Subject: [PATCH 10/10] Update prdoc/pr_6349.prdoc --- prdoc/pr_6349.prdoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/prdoc/pr_6349.prdoc b/prdoc/pr_6349.prdoc index 105b103e4040..40f02712c99a 100644 --- a/prdoc/pr_6349.prdoc +++ b/prdoc/pr_6349.prdoc @@ -10,8 +10,7 @@ doc: crates: - name: frame-support - bump: minor - validate: false + bump: major - name: westend-runtime bump: patch