diff --git a/polkadot/node/service/src/chain_spec.rs b/polkadot/node/service/src/chain_spec.rs index 8e7172509e..6d6900f12b 100644 --- a/polkadot/node/service/src/chain_spec.rs +++ b/polkadot/node/service/src/chain_spec.rs @@ -880,6 +880,7 @@ fn rococo_staging_testnet_config_genesis(wasm_binary: &[u8]) -> rococo_runtime:: paras: vec![], _phdata: Default::default(), }, + parachains_hrmp: Default::default(), parachains_configuration: rococo_runtime::ParachainsConfigurationConfig { config: polkadot_runtime_parachains::configuration::HostConfiguration { validation_upgrade_frequency: 1u32, @@ -1473,6 +1474,7 @@ pub fn rococo_testnet_genesis( ..Default::default() }, }, + parachains_hrmp: Default::default(), parachains_paras: rococo_runtime::ParasConfig { paras: vec![], _phdata: Default::default(), diff --git a/polkadot/runtime/parachains/src/hrmp.rs b/polkadot/runtime/parachains/src/hrmp.rs index 8e80400087..62d635a20e 100644 --- a/polkadot/runtime/parachains/src/hrmp.rs +++ b/polkadot/runtime/parachains/src/hrmp.rs @@ -299,6 +299,51 @@ decl_storage! { /// block number. HrmpChannelDigests: map hasher(twox_64_concat) ParaId => Vec<(T::BlockNumber, Vec)>; } + add_extra_genesis { + /// Preopen the given HRMP channels. + /// + /// The values in the tuple corresponds to `(sender, recipient, max_capacity, max_message_size)`, + /// i.e. similar to `init_open_channel`. In fact, the initialization is performed as if + /// the `init_open_channel` and `accept_open_channel` were called with the respective parameters + /// and the session change take place. + /// + /// As such, each channel initializer should satisfy the same constraints, namely: + /// + /// 1. `max_capacity` and `max_message_size` should be within the limits set by the configuration module. + /// 2. `sender` and `recipient` must be valid paras. + config(preopen_hrmp_channels): Vec<(ParaId, ParaId, u32, u32)>; + build(|config| { + initialize_storage::(&config.preopen_hrmp_channels); + }) + } +} + +#[cfg(feature = "std")] +fn initialize_storage(preopen_hrmp_channels: &[(ParaId, ParaId, u32, u32)]) { + let host_config = configuration::Module::::config(); + for &(sender, recipient, max_capacity, max_message_size) in preopen_hrmp_channels { + if let Err(err) = preopen_hrmp_channel::(sender, recipient, max_capacity, max_message_size) { + panic!("failed to initialize the genesis storage: {:?}", err); + } + } + >::process_hrmp_open_channel_requests(&host_config); +} + +#[cfg(feature = "std")] +fn preopen_hrmp_channel( + sender: ParaId, + recipient: ParaId, + max_capacity: u32, + max_message_size: u32 +) -> DispatchResult { + >::init_open_channel( + sender, + recipient, + max_capacity, + max_message_size, + )?; + >::accept_open_channel(recipient, sender)?; + Ok(()) } decl_error! { diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 96cb82d82f..6de4302b98 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -218,7 +218,7 @@ construct_runtime! { Initializer: parachains_initializer::{Pallet, Call, Storage}, Dmp: parachains_dmp::{Pallet, Call, Storage}, Ump: parachains_ump::{Pallet, Call, Storage}, - Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event}, + Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config}, SessionInfo: parachains_session_info::{Pallet, Call, Storage}, // Parachain Onboarding Pallets