Skip to content

Commit c85f2a1

Browse files
moliholyCopilot
andauthored
feat: pop up chain spec cmd (#699)
* feat: upgrade to latest zombienet-sdk version * feat: cd into network's parachain directory * feat: add --raw variant to chain spec * fix: undo feature imports * fix: cd logic Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * test: cd_into_chain_base_dir function --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent a29ac18 commit c85f2a1

File tree

11 files changed

+2464
-422
lines changed

11 files changed

+2464
-422
lines changed

Cargo.lock

Lines changed: 2238 additions & 306 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ symlink = { version = "0.1", default-features = false }
7676
serde_json = { version = "1.0", default-features = false, features = ["preserve_order"] }
7777
serde = { version = "1.0", default-features = false, features = ["derive"] }
7878
srtool-lib = { version = "0.13.2", default-features = false }
79-
zombienet-configuration = { version = "0.3.1", default-features = false }
80-
zombienet-sdk = { version = "0.3.1", default-features = false }
79+
zombienet-configuration = { version = "0.4.1", default-features = false }
80+
zombienet-sdk = { version = "0.4.1", default-features = false }
8181
git2_credentials = "0.13.0"
8282
cumulus-client-cli = { version = "0.22.0", default-features = false }
8383

crates/pop-chains/src/relay.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{DynamicPayload, Error, call};
44
use scale::{Decode, Encode};
55
use sp_core::twox_128;
66
use subxt::{
7-
OnlineClient, PolkadotConfig,
7+
OnlineClient,
88
config::BlockHash,
99
dynamic::{self, Value},
1010
events::StaticEvent,
@@ -16,10 +16,10 @@ use subxt::{
1616
/// # Arguments
1717
/// * `client` - Client for the network which state is to be modified.
1818
/// * `para_ids` - List of ids to build the keys that will be mutated.
19-
pub async fn clear_dmpq(
20-
client: OnlineClient<PolkadotConfig>,
21-
para_ids: &[u32],
22-
) -> Result<impl BlockHash, Error> {
19+
pub async fn clear_dmpq(endpoint: &str, para_ids: &[u32]) -> Result<impl BlockHash, Error> {
20+
let client = OnlineClient::<subxt::PolkadotConfig>::from_url(endpoint)
21+
.await
22+
.map_err(|e| Error::SubXtError(e.into()))?;
2323
// Wait for blocks to be produced.
2424
let mut sub = client
2525
.blocks()

crates/pop-chains/src/up/mod.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ impl NetworkConfiguration {
348348
.collect();
349349

350350
let mut builder = NetworkConfigBuilder::new().with_relaychain(|builder| {
351-
let mut builder = builder.with_chain(relay_chain.chain()).with_node(|builder| {
351+
let mut builder = builder.with_chain(relay_chain.chain()).with_validator(|builder| {
352352
let mut builder = builder
353353
.with_name(validators.first().expect("at least two validators defined above"));
354354
if let Some(port) = port {
@@ -358,7 +358,7 @@ impl NetworkConfiguration {
358358
});
359359

360360
for validator in validators.iter().skip(1) {
361-
builder = builder.with_node(|builder| builder.with_name(validator))
361+
builder = builder.with_validator(|builder| builder.with_name(validator))
362362
}
363363
builder
364364
});
@@ -469,6 +469,12 @@ impl NetworkConfiguration {
469469
if let Some(location) = source.chain_spec_path() {
470470
builder = builder.with_chain_spec_path(location.clone());
471471
}
472+
if let Some(chain_spec_command_output_path) =
473+
source.chain_spec_command_output_path()
474+
{
475+
builder =
476+
builder.with_chain_spec_command_output_path(chain_spec_command_output_path);
477+
}
472478
// Configure chain spec generator
473479
if let Some(command) = chain_spec_generator {
474480
builder = builder.with_chain_spec_command(command);
@@ -482,12 +488,12 @@ impl NetworkConfiguration {
482488
}
483489

484490
// Add nodes from source
485-
let mut builder = builder.with_node(|builder| {
491+
let mut builder = builder.with_validator(|builder| {
486492
let source = nodes.first().expect("expected at least one node");
487493
Self::build_node_from_source(builder, source, binary_path.as_str())
488494
});
489495
for source in nodes.iter().skip(1) {
490-
builder = builder.with_node(|builder| {
496+
builder = builder.with_validator(|builder| {
491497
Self::build_node_from_source(builder, source, binary_path.as_str())
492498
});
493499
}
@@ -546,6 +552,12 @@ impl NetworkConfiguration {
546552
if source.chain_spec_command_is_local() {
547553
builder = builder.chain_spec_command_is_local(true);
548554
}
555+
if let Some(chain_spec_command_output_path) =
556+
source.chain_spec_command_output_path()
557+
{
558+
builder =
559+
builder.with_chain_spec_command_output_path(chain_spec_command_output_path)
560+
}
549561
if let Some(location) = source.chain_spec_path() {
550562
builder = builder.with_chain_spec_path(location.clone());
551563
}
@@ -942,7 +954,7 @@ chain = "paseo-local"
942954
let cache = PathBuf::from(temp_dir.path());
943955
let config = NetworkConfigBuilder::new()
944956
.with_relaychain(|b| {
945-
b.with_chain("paseo-local").with_node(|b| b.with_name("alice"))
957+
b.with_chain("paseo-local").with_validator(|b| b.with_name("alice"))
946958
})
947959
.build()
948960
.unwrap();
@@ -1119,7 +1131,7 @@ command = "polkadot"
11191131
let config = NetworkConfigBuilder::new()
11201132
.with_relaychain(|b| {
11211133
b.with_chain("paseo-local")
1122-
.with_node(|b| b.with_name("alice").with_command("polkadot"))
1134+
.with_validator(|b| b.with_name("alice").with_command("polkadot"))
11231135
})
11241136
.build()
11251137
.unwrap();
@@ -1218,9 +1230,9 @@ command = "polkadot-stable2503"
12181230
let config = NetworkConfigBuilder::new()
12191231
.with_relaychain(|b| {
12201232
b.with_chain("paseo-local")
1221-
.with_node(|b| b.with_name("alice").with_command("polkadot"))
1222-
.with_node(|b| b.with_name("bob").with_command("polkadot"))
1223-
.with_node(|b| b.with_name("charlie").with_command("p0lk4d0t"))
1233+
.with_validator(|b| b.with_name("alice").with_command("polkadot"))
1234+
.with_validator(|b| b.with_name("bob").with_command("polkadot"))
1235+
.with_validator(|b| b.with_name("charlie").with_command("p0lk4d0t"))
12241236
})
12251237
.build()
12261238
.unwrap();
@@ -1927,7 +1939,7 @@ chain = "paseo-local"
19271939
fn initializing_from_network_config_works() -> Result<(), Error> {
19281940
let network_config = NetworkConfigBuilder::new()
19291941
.with_relaychain(|b| {
1930-
b.with_chain("paseo-local").with_node(|b| b.with_name("alice"))
1942+
b.with_chain("paseo-local").with_validator(|b| b.with_name("alice"))
19311943
})
19321944
.build()
19331945
.unwrap();
@@ -2160,6 +2172,7 @@ rpc_port = 9944
21602172
r#"[settings]
21612173
timeout = 1000
21622174
node_spawn_timeout = 300
2175+
tear_down_on_failure = true
21632176
21642177
[relaychain]
21652178
chain = "paseo-local"
@@ -2197,7 +2210,6 @@ balance = 2000000000000
21972210
21982211
[[parachains.collators]]
21992212
name = "asset-hub-2"
2200-
command = "{1}"
22012213
validator = true
22022214
invulnerable = true
22032215
bootnode = false
@@ -2341,6 +2353,7 @@ command = "polkadot-parachain"
23412353
r#"[settings]
23422354
timeout = 1000
23432355
node_spawn_timeout = 300
2356+
tear_down_on_failure = true
23442357
23452358
[relaychain]
23462359
chain = "paseo-local"
@@ -2483,6 +2496,7 @@ max_message_size = 8000
24832496
r#"[settings]
24842497
timeout = 1000
24852498
node_spawn_timeout = 300
2499+
tear_down_on_failure = true
24862500
24872501
[relaychain]
24882502
chain = "paseo-local"
@@ -2619,6 +2633,7 @@ name = "asset-hub"
26192633
r#"[settings]
26202634
timeout = 1000
26212635
node_spawn_timeout = 300
2636+
tear_down_on_failure = true
26222637
26232638
[relaychain]
26242639
chain = "paseo-local"
@@ -2736,6 +2751,7 @@ balances = [["5Ec4AhPKXY9B4ayGshkz2wFMh7N8gP7XKfAvtt1cigpG9FkJ", 420000000000]]
27362751
r#"[settings]
27372752
timeout = 1000
27382753
node_spawn_timeout = 300
2754+
tear_down_on_failure = true
27392755
27402756
[relaychain]
27412757
chain = "paseo-local"

crates/pop-cli/src/commands/build/spec.rs

Lines changed: 72 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ pub struct BuildSpecCommand {
207207
/// based on `runtime`.
208208
#[clap(long, requires = "deterministic")]
209209
pub package: Option<String>,
210+
/// Generate a raw chain specification.
211+
#[arg(long)]
212+
pub(crate) raw: bool,
210213
}
211214

212215
impl BuildSpecCommand {
@@ -258,6 +261,7 @@ impl BuildSpecCommand {
258261
package,
259262
runtime_dir,
260263
is_relay,
264+
raw,
261265
..
262266
} = self;
263267

@@ -508,6 +512,7 @@ impl BuildSpecCommand {
508512
package,
509513
runtime_dir,
510514
use_existing_plain_spec: !prompt,
515+
raw,
511516
})
512517
}
513518
}
@@ -518,7 +523,7 @@ pub struct GenesisArtifacts {
518523
/// Path to the plain text chain specification file.
519524
pub chain_spec: PathBuf,
520525
/// Path to the raw chain specification file.
521-
pub raw_chain_spec: PathBuf,
526+
pub raw_chain_spec: Option<PathBuf>,
522527
/// Optional path to the genesis state file.
523528
pub genesis_state_file: Option<CodePathBuf>,
524529
/// Optional path to the genesis code file.
@@ -570,6 +575,7 @@ pub(crate) struct BuildSpec {
570575
package: String,
571576
runtime_dir: Option<PathBuf>,
572577
use_existing_plain_spec: bool,
578+
raw: bool,
573579
}
574580

575581
impl BuildSpec {
@@ -652,54 +658,66 @@ impl BuildSpec {
652658
));
653659
}
654660

655-
// Generate raw spec.
656-
spinner.set_message("Generating raw chain specification...");
657-
let spec_name = self
658-
.output_file
659-
.file_name()
660-
.and_then(|s| s.to_str())
661-
.unwrap_or(DEFAULT_SPEC_NAME)
662-
.trim_end_matches(".json");
663-
let raw_spec_name = format!("{spec_name}-raw.json");
664-
let raw_chain_spec = builder.generate_raw_chain_spec(&self.output_file, &raw_spec_name)?;
665-
generated_files.push(format!(
666-
"Raw chain specification file generated at: {}",
667-
raw_chain_spec.display()
668-
));
661+
let (raw_chain_spec, genesis_code_file, genesis_state_file) = if self.raw ||
662+
self.genesis_code ||
663+
self.genesis_state
664+
{
665+
// Generate raw spec.
666+
spinner.set_message("Generating raw chain specification...");
667+
let spec_name = self
668+
.output_file
669+
.file_name()
670+
.and_then(|s| s.to_str())
671+
.unwrap_or(DEFAULT_SPEC_NAME)
672+
.trim_end_matches(".json");
673+
let raw_spec_name = format!("{spec_name}-raw.json");
674+
let raw_chain_spec =
675+
builder.generate_raw_chain_spec(&self.output_file, &raw_spec_name)?;
676+
generated_files.push(format!(
677+
"Raw chain specification file generated at: {}",
678+
raw_chain_spec.display()
679+
));
669680

670-
if is_runtime_build {
671-
// The runtime version of the raw chain spec does not include certain parameters, like
672-
// the relay chain, so we have to overwrite them again.
673-
self.customize(&raw_chain_spec)?;
674-
}
681+
if is_runtime_build {
682+
// The runtime version of the raw chain spec does not include certain parameters,
683+
// like the relay chain, so we have to overwrite them again.
684+
self.customize(&raw_chain_spec)?;
685+
}
675686

676-
// Generate genesis artifacts.
677-
let genesis_code_file = if self.genesis_code {
678-
spinner.set_message("Generating genesis code...");
679-
let wasm_file = builder.export_wasm_file(&raw_chain_spec, "genesis-code.wasm")?;
680-
generated_files
681-
.push(format!("WebAssembly runtime file exported at: {}", wasm_file.display()));
682-
Some(wasm_file)
683-
} else {
684-
None
685-
};
686-
let genesis_state_file = if self.genesis_state {
687-
spinner.set_message("Generating genesis state...");
688-
let binary_path = match builder {
689-
ChainSpecBuilder::Runtime { .. } =>
690-
source_polkadot_omni_node_binary(cli, &spinner, &crate::cache()?, true).await?,
691-
ChainSpecBuilder::Node { .. } => builder.artifact_path()?,
687+
// Generate genesis artifacts.
688+
let genesis_code_file = if self.genesis_code {
689+
spinner.set_message("Generating genesis code...");
690+
let wasm_file = builder.export_wasm_file(&raw_chain_spec, "genesis-code.wasm")?;
691+
generated_files
692+
.push(format!("WebAssembly runtime file exported at: {}", wasm_file.display()));
693+
Some(wasm_file)
694+
} else {
695+
None
692696
};
693-
let genesis_state_file = generate_genesis_state_file_with_node(
694-
&binary_path,
695-
&raw_chain_spec,
696-
"genesis-state",
697-
)?;
698-
generated_files
699-
.push(format!("Genesis State file exported at: {}", genesis_state_file.display()));
700-
Some(genesis_state_file)
697+
let genesis_state_file = if self.genesis_state {
698+
spinner.set_message("Generating genesis state...");
699+
let binary_path = match builder {
700+
ChainSpecBuilder::Runtime { .. } =>
701+
source_polkadot_omni_node_binary(cli, &spinner, &crate::cache()?, true)
702+
.await?,
703+
ChainSpecBuilder::Node { .. } => builder.artifact_path()?,
704+
};
705+
let genesis_state_file = generate_genesis_state_file_with_node(
706+
&binary_path,
707+
&raw_chain_spec,
708+
"genesis-state",
709+
)?;
710+
generated_files.push(format!(
711+
"Genesis State file exported at: {}",
712+
genesis_state_file.display()
713+
));
714+
Some(genesis_state_file)
715+
} else {
716+
None
717+
};
718+
(Some(raw_chain_spec), genesis_code_file, genesis_state_file)
701719
} else {
702-
None
720+
(None, None, None)
703721
};
704722

705723
spinner.stop("Chain specification built successfully.");
@@ -786,15 +804,16 @@ fn prepare_output_path(output_path: impl AsRef<Path>) -> anyhow::Result<PathBuf>
786804
.and_then(|ext| ext.to_str())
787805
.map(|ext| ext.eq_ignore_ascii_case("json"))
788806
.unwrap_or(false);
807+
let is_dir = output_path.is_dir();
789808

790-
if !is_json_file {
791-
// Treat as directory.
809+
if is_dir || (!output_path.exists() && !is_json_file) {
810+
// Treat as directory (existing or to-be-created)
792811
if !output_path.exists() {
793812
create_dir_all(&output_path)?;
794813
}
795814
output_path.push(DEFAULT_SPEC_NAME);
796815
} else {
797-
// Treat as file.
816+
// Treat as file; ensure parent dir exists
798817
if let Some(parent_dir) = output_path.parent() &&
799818
!parent_dir.exists()
800819
{
@@ -834,6 +853,7 @@ mod tests {
834853
let runtime_dir = PathBuf::from("./new-runtime-dir");
835854
let path = PathBuf::from("./");
836855
let properties = "tokenSymbol=UNIT,decimals=12,isEthereum=false";
856+
let raw = true;
837857

838858
let mut flags_used = false;
839859
for (build_spec_cmd, chain) in [
@@ -862,6 +882,7 @@ mod tests {
862882
deterministic: Some(deterministic),
863883
package: Some(package.to_string()),
864884
runtime_dir: Some(runtime_dir.clone()),
885+
raw,
865886
},
866887
Some("local".to_string()),
867888
),
@@ -888,6 +909,7 @@ mod tests {
888909
deterministic: Some(deterministic),
889910
package: Some(package.to_string()),
890911
runtime_dir: Some(runtime_dir.clone()),
912+
raw,
891913
},
892914
Some("local".to_string()),
893915
),
@@ -1031,6 +1053,7 @@ mod tests {
10311053
deterministic: None,
10321054
package: Some(package.to_string()),
10331055
runtime_dir: Some(runtime_dir.clone()),
1056+
raw: true,
10341057
},
10351058
// All flags used. Relay
10361059
BuildSpecCommand {
@@ -1054,6 +1077,7 @@ mod tests {
10541077
deterministic: None,
10551078
package: Some(package.to_string()),
10561079
runtime_dir: Some(runtime_dir.clone()),
1080+
raw: true,
10571081
},
10581082
] {
10591083
let mut cli = MockCli::new().expect_confirm(

0 commit comments

Comments
 (0)