Skip to content

Commit

Permalink
feat: clean dmpq state at genesis (#279)
Browse files Browse the repository at this point in the history
* dispatch kill tx

* paseo-local metadata

* chore: address hrmp channels at creation

* clean unnecessary deps

* fix: don't wait for finalisation

* Provide documentation
  • Loading branch information
al3mart authored and evilrobot-01 committed Aug 10, 2024
1 parent f60d438 commit 6130384
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 3 deletions.
24 changes: 23 additions & 1 deletion crates/pop-cli/src/commands/up/parachain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use cliclack::{
use console::{Emoji, Style, Term};
use duct::cmd;
use pop_common::Status;
use pop_parachains::{Error, IndexSet, NetworkNode, Zombienet};
use pop_parachains::{clear_dmpq, Error, IndexSet, NetworkNode, Zombienet};
use std::{path::PathBuf, time::Duration};
use tokio::time::sleep;

Expand Down Expand Up @@ -148,6 +148,28 @@ impl ZombienetCommand {
}

spinner.stop(result);

// Check for any HRMP specified channels
if zombienet.hrmp_channels() {
let spinner = cliclack::spinner();
spinner.start("Readying channels...");
// Allow relay node time to start
tokio::time::sleep(Duration::from_secs(10)).await;
let relay_endpoint = network.relaychain().nodes()[0].client().await?;
let para_ids: Vec<_> =
network.parachains().iter().map(|p| p.para_id()).collect();
tokio::spawn(async move {
if let Err(e) = clear_dmpq(relay_endpoint, &para_ids).await {
spinner.stop("");
outro_cancel(format!("{e}"))?;
}
spinner.stop("Channels ready for initialization.");
tokio::time::sleep(Duration::from_secs(2)).await;
Term::stderr().clear_last_lines(2)?;
Ok::<(), Error>(())
});
}

tokio::signal::ctrl_c().await?;
outro("Done")?;
},
Expand Down
3 changes: 3 additions & 0 deletions crates/pop-parachains/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ glob.workspace = true
serde_json.workspace = true
strum.workspace = true
strum_macros.workspace = true
# Subxt dependenices need to be at least 0.37 because of the new SignedExtension
subxt-signer = { version = "0.37", features = ["subxt", "sr25519"] }
subxt = "0.37"
tar.workspace = true
tempfile.workspace = true
thiserror.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/pop-parachains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub use new_pallet::{create_pallet_template, TemplatePalletConfig};
pub use new_parachain::instantiate_template_dir;
pub use templates::{Config, Parachain, Provider};
pub use up::Zombienet;
pub use utils::helpers::is_initial_endowment_valid;
pub use utils::helpers::{clear_dmpq, is_initial_endowment_valid};
pub use utils::pallet_helpers::resolve_pallet_path;
/// Information about the Node. External export from Zombienet-SDK.
pub use zombienet_sdk::NetworkNode;
10 changes: 9 additions & 1 deletion crates/pop-parachains/src/up/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub struct Zombienet {
relay_chain: RelayChain,
/// The configuration required to launch parachains.
parachains: IndexMap<u32, Parachain>,
/// Whether any HRMP channels are to be pre-opened.
hrmp_channels: bool,
}

impl Zombienet {
Expand Down Expand Up @@ -81,7 +83,7 @@ impl Zombienet {
cache,
)
.await?;
Ok(Self { network_config, relay_chain, parachains })
Ok(Self { network_config, relay_chain, parachains, hrmp_channels: false })
}

/// The binaries required to launch the network.
Expand Down Expand Up @@ -268,6 +270,11 @@ impl Zombienet {
return Ok(relay::default(version, runtime_version, chain, cache).await?);
}

/// Whether any HRMP channels are to be pre-opened.
pub fn hrmp_channels(&self) -> bool {
self.hrmp_channels
}

/// Launches the local network.
pub async fn spawn(&mut self) -> Result<Network<LocalFileSystem>, Error> {
// Symlink polkadot workers
Expand Down Expand Up @@ -296,6 +303,7 @@ impl Zombienet {
let config = self.network_config.configure(&self.relay_chain, &self.parachains)?;
let path = config.path().to_str().expect("temp config file should have a path").into();
let network_config = NetworkConfig::load_from_toml(path)?;
self.hrmp_channels = !network_config.hrmp_channels().is_empty();
Ok(network_config.spawn_native().await?)
}
}
Expand Down
Binary file not shown.
60 changes: 60 additions & 0 deletions crates/pop-parachains/src/utils/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{
io::{self, stdin, stdout, Write},
path::Path,
};
use subxt::{ext::sp_core, OnlineClient, PolkadotConfig};

pub(crate) fn sanitize(target: &Path) -> Result<(), Error> {
if target.exists() {
Expand All @@ -24,6 +25,64 @@ pub(crate) fn sanitize(target: &Path) -> Result<(), Error> {
Ok(())
}

/// Clears the DMPQ state for the given chains.
/// Assumes pallet-sudo is present in the runtime.
///
/// # Arguments
///
/// * `client` - Client for the network which state is to be modified.
/// * `para_ids` - List of ids to build the keys that will be mutated.
pub async fn clear_dmpq(
client: OnlineClient<PolkadotConfig>,
para_ids: &[u32],
) -> Result<(), Box<dyn std::error::Error>> {
use subxt_signer::sr25519::dev;

#[subxt::subxt(runtime_metadata_path = "./src/utils/artifacts/paseo-local.scale")]
mod paseo_local {}
type RuntimeCall = paseo_local::runtime_types::paseo_runtime::RuntimeCall;

let sudo = dev::alice();

// Wait for blocks to be produced.
let mut sub = client.blocks().subscribe_finalized().await.unwrap();
for _ in 0..2 {
sub.next().await;
}

let dmp = sp_core::twox_128("Dmp".as_bytes());
let dmp_queues = sp_core::twox_128("DownwardMessageQueues".as_bytes());
let dmp_queue_heads = sp_core::twox_128("DownwardMessageQueueHeads".as_bytes());

let mut clear_dmq_keys = Vec::<Vec<u8>>::new();
for id in para_ids {
let id = id.to_le_bytes();
// DMP Queue Head
let mut key = dmp.to_vec();
key.extend(&dmp_queue_heads);
key.extend(sp_core::twox_64(&id));
key.extend(id);
clear_dmq_keys.push(key);
// DMP Queue
let mut key = dmp.to_vec();
key.extend(&dmp_queues);
key.extend(sp_core::twox_64(&id));
key.extend(id);
clear_dmq_keys.push(key);
}

// Craft calls to dispatch
let kill_storage =
RuntimeCall::System(paseo_local::system::Call::kill_storage { keys: clear_dmq_keys });
let sudo_call = paseo_local::tx().sudo().sudo(kill_storage);

// Dispatch and watch tx
let _sudo_call_events =
client.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo).await?;

Ok(())
}

/// Check if the initial endowment input by the user is a valid balance.
///
/// # Arguments
Expand Down Expand Up @@ -87,6 +146,7 @@ mod tests {
use super::*;
use crate::generator::parachain::ChainSpec;
use askama::Template;
use std::env::var;
use tempfile::tempdir;

#[test]
Expand Down

0 comments on commit 6130384

Please sign in to comment.