paritytech / polkadot-sdk

The Parity Polkadot Blockchain SDK
https://polkadot.network/
1.78k stars 642 forks source link

Only customized fields in preset json blob? #5700

Open michalkucharczyk opened 4 days ago

michalkucharczyk commented 4 days ago

Probably not super important, but wanted to know your opinion on that, so I am leaving it here for your consideration.

This is about how to provide preset's JSON and what is potential outcome.

There are two approaches.

JSON blob, containing only overridden fields ``` fn preset() -> serde_json::Value { serde_json::json!({ "balances": BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k| (k, 1u128 << 60)).collect::>(), }, "parachainInfo": ParachainInfoConfig { parachain_id: id, ..Default::default() }, "collatorSelection": CollatorSelectionConfig { invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(), candidacy_bond: BRIDGE_HUB_ROCOCO_ED * 16, ..Default::default() }, "session": SessionConfig { keys: invulnerables .into_iter() .map(|(acc, aura)| { ( acc.clone(), // account id acc, // validator id SessionKeys { aura }, // session keys ) }) .collect(), ..Default::default() }, "polkadotXcm": PolkadotXcmConfig { safe_xcm_version: Some(SAFE_XCM_VERSION), ..Default::default() }, "bridgeWestendGrandpa": BridgeWestendGrandpaConfig { owner: bridges_pallet_owner.clone(), ..Default::default() }, "bridgeWestendMessages": BridgeWestendMessagesConfig { owner: bridges_pallet_owner.clone(), ..Default::default() }, "ethereumSystem": EthereumSystemConfig { para_id: id, asset_hub_para_id, ..Default::default() } }) } ```

and second:

full `RuntimeGenesisConfig` blob, containing defaults and overwritten fields: ``` fn preset() -> serde_json::Value { let config = RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed_accounts .iter() .cloned() .map(|k| (k, 1u128 << 60)) .collect::>(), }, parachain_info: ParachainInfoConfig { parachain_id: id, ..Default::default() }, collator_selection: CollatorSelectionConfig { invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(), candidacy_bond: BRIDGE_HUB_ROCOCO_ED * 16, ..Default::default() }, session: SessionConfig { keys: invulnerables .into_iter() .map(|(acc, aura)| { ( acc.clone(), // account id acc, // validator id SessionKeys { aura }, // session keys ) }) .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() }, bridge_westend_messages: BridgeWestendMessagesConfig { owner: bridges_pallet_owner.clone(), ..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.") } ```

When we generate two two runtime wasm blobs using two above approaches, and then we use chain-spec-builder display-preset util to get the json preset representation, and we display the diff, we will get following:

$ diff f.json j.json
2,5d1
<   "aura": {
<     "authorities": []
<   },
<   "auraExt": {},
58,68d53
<   "bridgePolkadotBulletinGrandpa": {
<     "initData": null,
<     "owner": null
<   },
<   "bridgePolkadotBulletinMessages": {
<     "openedLanes": [],
<     "operatingMode": {
<       "Basic": "Normal"
<     },
<     "owner": null
<   },
80,83d64
<   "bridgeWestendParachains": {
<     "operatingMode": "Normal",
<     "owner": null
<   },
99d79
<   "parachainSystem": {},
121,130d100
<   },
<   "system": {},
<   "transactionPayment": {
<     "multiplier": "1000000000000000000"
<   },
<   "xcmOverBridgeHubWestend": {
<     "openedBridges": []
<   },
<   "xcmOverPolkadotBulletin": {
<     "openedBridges": []

So the preset constructed from the full RuntimeGenesisConfig struct contains some fields that are just defaults and were not actually customized.

In practice, in most cases that should not matter, but it potentially may lead to some strange behavior - e.g. imagine fetching the preset to the file, then using it to against different runtime version (e.g. newer version with transactionPayment::multiplier updated) where defaults are changed may lead to some strange situation.

On the other hand - using JSON approach may lead to invalid JSON (and we would addition coverage in tests).

tagging @kianenigma , @bkchr.

Originally posted by @michalkucharczyk in https://github.com/paritytech/polkadot-sdk/issues/5327#issuecomment-2343335131

michalkucharczyk commented 4 days ago

some proposal from #5327 discussion: https://github.com/paritytech/polkadot-sdk/pull/5327#issuecomment-2345356582