Skip to content

Commit b69a2cb

Browse files
tsenovillamoliholy
authored andcommitted
fix: allow pop build spec to specify the runtime path as argument (#687)
1 parent d1fd257 commit b69a2cb

File tree

17 files changed

+410
-456
lines changed

17 files changed

+410
-456
lines changed

Cargo.lock

Lines changed: 24 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ git2 = { version = "0.18", default-features = true, features = ["vendored-openss
3434
glob = { version = "0.3.1", default-features = false }
3535
log = { version = "0.4.20", default-features = false }
3636
mockito = { version = "1.4.0", default-features = false }
37+
rustilities = "3.0.0"
3738
tar = { version = "0.4.40", default-features = false }
3839
tempfile = { version = "3.10", default-features = false }
3940
thiserror = { version = "1.0.58", default-features = false }

crates/pop-chains/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ url.workspace = true
2525

2626
askama.workspace = true
2727
indexmap.workspace = true
28+
rustilities = { workspace = true, features = ["manifest"] }
2829
scale.workspace = true
2930
scale-info.workspace = true
3031
scale-value.workspace = true

crates/pop-chains/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,13 @@ use std::path::Path;
4848
4949
let path = Path::new("./"); // Location of the parachain project.
5050
let builder = ChainSpecBuilder::Node { node_path: path.join("node"), default_bootnode: false, profile: Profile::Release };
51+
let spec_name = "MySpec";
52+
let spec_id = "my_spec";
5153
// Build the node binary first
5254
builder.build(&[]).unwrap();
5355
// Generate a plain chain specification file of a parachain
5456
let plain_chain_spec_path = path.join("plain-parachain-chainspec.json");
55-
builder.generate_plain_chain_spec("dev", &plain_chain_spec_path).unwrap();
57+
builder.generate_plain_chain_spec("dev", &plain_chain_spec_path, Some(spec_name), Some(spec_id)).unwrap();
5658
// Customize your chain specification
5759
let mut chain_spec = ChainSpec::from(&plain_chain_spec_path).unwrap();
5860
chain_spec.replace_para_id(2002);
@@ -72,11 +74,13 @@ use std::path::Path;
7274
7375
let path = Path::new("./"); // Location of the parachain project.
7476
let builder = ChainSpecBuilder::Node { node_path: path.join("node"), default_bootnode: false, profile: Profile::Release };
77+
let spec_name = "MySpec";
78+
let spec_id = "my_spec";
7579
// Build the node binary first
7680
let binary_path = builder.build(&[]).unwrap();
7781
// Generate a plain chain specification file of a parachain
7882
let plain_chain_spec_path = path.join("plain-parachain-chainspec.json");
79-
builder.generate_plain_chain_spec("dev", &plain_chain_spec_path).unwrap();
83+
builder.generate_plain_chain_spec("dev", &plain_chain_spec_path, Some(spec_name), Some(spec_id)).unwrap();
8084
// Generate a raw chain specification file of a parachain
8185
let chain_spec = builder.generate_raw_chain_spec(&plain_chain_spec_path, "raw-parachain-chainspec.json").unwrap();
8286
// Export the WebAssembly runtime for the parachain.

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

Lines changed: 124 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
use crate::errors::{Error, handle_command_error};
44
use anyhow::{Result, anyhow};
55
use duct::cmd;
6-
use pop_common::{
7-
Profile, account_id::convert_to_evm_accounts, find_workspace_toml, manifest::from_path,
8-
};
6+
use pop_common::{Profile, account_id::convert_to_evm_accounts, manifest::from_path};
97
use sc_chain_spec::{GenericChainSpec, NoExtension};
108
use serde_json::{Value, json};
119
use sp_core::bytes::to_hex;
@@ -87,7 +85,7 @@ impl ChainSpecBuilder {
8785
pub fn artifact_path(&self) -> Result<PathBuf> {
8886
let manifest = from_path(&self.path())?;
8987
let package = manifest.package().name();
90-
let root_folder = find_workspace_toml(&self.path())
88+
let root_folder = rustilities::manifest::find_workspace_manifest(self.path())
9189
.ok_or(anyhow::anyhow!("Not inside a workspace"))?
9290
.parent()
9391
.expect("Path to Cargo.toml workspace root folder must exist")
@@ -117,10 +115,14 @@ impl ChainSpecBuilder {
117115
/// # Arguments
118116
/// * `chain_or_preset` - The chain (when using a node) or preset (when using a runtime) name.
119117
/// * `output_file` - The path where the chain spec should be written.
118+
/// * `name` - The name to be used on the chain spec if specified.
119+
/// * `id` - The ID to be used on the chain spec if specified.
120120
pub fn generate_plain_chain_spec(
121121
&self,
122122
chain_or_preset: &str,
123123
output_file: &Path,
124+
name: Option<&str>,
125+
id: Option<&str>,
124126
) -> Result<(), Error> {
125127
match self {
126128
ChainSpecBuilder::Node { default_bootnode, .. } => generate_plain_chain_spec_with_node(
@@ -133,6 +135,8 @@ impl ChainSpecBuilder {
133135
fs::read(self.artifact_path()?)?,
134136
output_file,
135137
chain_or_preset,
138+
name,
139+
id,
136140
),
137141
}
138142
}
@@ -329,16 +333,27 @@ pub fn generate_raw_chain_spec_with_runtime(
329333
/// * `wasm` - The WebAssembly runtime bytes.
330334
/// * `plain_chain_spec` - The path where the plain chain specification should be written.
331335
/// * `preset` - Preset name for genesis configuration.
336+
/// * `name` - The name to be used on the chain spec if specified.
337+
/// * `id` - The ID to be used on the chain spec if specified.
332338
pub fn generate_plain_chain_spec_with_runtime(
333339
wasm: Vec<u8>,
334340
plain_chain_spec: &Path,
335341
preset: &str,
342+
name: Option<&str>,
343+
id: Option<&str>,
336344
) -> Result<(), Error> {
337-
let chain_spec = GenericChainSpec::<NoExtension>::builder(&wasm[..], None)
338-
.with_genesis_config_preset_name(preset.trim())
339-
.build()
340-
.as_json(false)
341-
.map_err(|e| anyhow::anyhow!(e))?;
345+
let mut chain_spec = GenericChainSpec::<NoExtension>::builder(&wasm[..], None)
346+
.with_genesis_config_preset_name(preset.trim());
347+
348+
if let Some(name) = name {
349+
chain_spec = chain_spec.with_name(name);
350+
}
351+
352+
if let Some(id) = id {
353+
chain_spec = chain_spec.with_id(id);
354+
}
355+
356+
let chain_spec = chain_spec.build().as_json(false).map_err(|e| anyhow::anyhow!(e))?;
342357
fs::write(plain_chain_spec, chain_spec)?;
343358

344359
Ok(())
@@ -781,6 +796,8 @@ mod tests {
781796
use strum::VariantArray;
782797
use tempfile::{Builder, TempDir, tempdir};
783798

799+
static MOCK_WASM: &[u8] = include_bytes!("../../../../tests/runtimes/base_parachain.wasm");
800+
784801
fn setup_template_and_instantiate() -> Result<TempDir> {
785802
let temp_dir = tempdir().expect("Failed to create temp dir");
786803
let config = Config {
@@ -1055,6 +1072,104 @@ mod tests {
10551072
Ok(())
10561073
}
10571074

1075+
#[tokio::test]
1076+
async fn generate_plain_chain_spec_with_runtime_works_with_name_and_id_override() -> Result<()>
1077+
{
1078+
let temp_dir =
1079+
setup_template_and_instantiate().expect("Failed to setup template and instantiate");
1080+
// Test generate chain spec
1081+
let plain_chain_spec = &temp_dir.path().join("plain-parachain-chainspec.json");
1082+
generate_plain_chain_spec_with_runtime(
1083+
Vec::from(MOCK_WASM),
1084+
plain_chain_spec,
1085+
"local_testnet",
1086+
Some("POP Chain Spec"),
1087+
Some("pop-chain-spec"),
1088+
)?;
1089+
assert!(plain_chain_spec.exists());
1090+
let raw_chain_spec =
1091+
generate_raw_chain_spec_with_runtime(plain_chain_spec, "raw-parachain-chainspec.json")?;
1092+
assert!(raw_chain_spec.exists());
1093+
let content = fs::read_to_string(raw_chain_spec.clone()).expect("Could not read file");
1094+
assert!(content.contains("\"name\": \"POP Chain Spec\""));
1095+
assert!(content.contains("\"id\": \"pop-chain-spec\""));
1096+
assert!(content.contains("\"bootNodes\": []"));
1097+
Ok(())
1098+
}
1099+
1100+
#[tokio::test]
1101+
async fn generate_plain_chain_spec_with_runtime_works_with_name_override() -> Result<()> {
1102+
let temp_dir =
1103+
setup_template_and_instantiate().expect("Failed to setup template and instantiate");
1104+
// Test generate chain spec
1105+
let plain_chain_spec = &temp_dir.path().join("plain-parachain-chainspec.json");
1106+
generate_plain_chain_spec_with_runtime(
1107+
Vec::from(MOCK_WASM),
1108+
plain_chain_spec,
1109+
"local_testnet",
1110+
Some("POP Chain Spec"),
1111+
None,
1112+
)?;
1113+
assert!(plain_chain_spec.exists());
1114+
let raw_chain_spec =
1115+
generate_raw_chain_spec_with_runtime(plain_chain_spec, "raw-parachain-chainspec.json")?;
1116+
assert!(raw_chain_spec.exists());
1117+
let content = fs::read_to_string(raw_chain_spec.clone()).expect("Could not read file");
1118+
assert!(content.contains("\"name\": \"POP Chain Spec\""));
1119+
assert!(content.contains("\"id\": \"dev\""));
1120+
assert!(content.contains("\"bootNodes\": []"));
1121+
Ok(())
1122+
}
1123+
1124+
#[tokio::test]
1125+
async fn generate_plain_chain_spec_with_runtime_works_with_id_override() -> Result<()> {
1126+
let temp_dir =
1127+
setup_template_and_instantiate().expect("Failed to setup template and instantiate");
1128+
// Test generate chain spec
1129+
let plain_chain_spec = &temp_dir.path().join("plain-parachain-chainspec.json");
1130+
generate_plain_chain_spec_with_runtime(
1131+
Vec::from(MOCK_WASM),
1132+
plain_chain_spec,
1133+
"local_testnet",
1134+
None,
1135+
Some("pop-chain-spec"),
1136+
)?;
1137+
assert!(plain_chain_spec.exists());
1138+
let raw_chain_spec =
1139+
generate_raw_chain_spec_with_runtime(plain_chain_spec, "raw-parachain-chainspec.json")?;
1140+
assert!(raw_chain_spec.exists());
1141+
let content = fs::read_to_string(raw_chain_spec.clone()).expect("Could not read file");
1142+
assert!(content.contains("\"name\": \"Development\""));
1143+
assert!(content.contains("\"id\": \"pop-chain-spec\""));
1144+
assert!(content.contains("\"bootNodes\": []"));
1145+
Ok(())
1146+
}
1147+
1148+
#[tokio::test]
1149+
async fn generate_plain_chain_spec_with_runtime_works_without_name_and_id_override()
1150+
-> Result<()> {
1151+
let temp_dir =
1152+
setup_template_and_instantiate().expect("Failed to setup template and instantiate");
1153+
// Test generate chain spec
1154+
let plain_chain_spec = &temp_dir.path().join("plain-parachain-chainspec.json");
1155+
generate_plain_chain_spec_with_runtime(
1156+
Vec::from(MOCK_WASM),
1157+
plain_chain_spec,
1158+
"local_testnet",
1159+
None,
1160+
None,
1161+
)?;
1162+
assert!(plain_chain_spec.exists());
1163+
let raw_chain_spec =
1164+
generate_raw_chain_spec_with_runtime(plain_chain_spec, "raw-parachain-chainspec.json")?;
1165+
assert!(raw_chain_spec.exists());
1166+
let content = fs::read_to_string(raw_chain_spec.clone()).expect("Could not read file");
1167+
assert!(content.contains("\"name\": \"Development\""));
1168+
assert!(content.contains("\"id\": \"dev\""));
1169+
assert!(content.contains("\"bootNodes\": []"));
1170+
Ok(())
1171+
}
1172+
10581173
#[tokio::test]
10591174
async fn fails_to_generate_plain_chain_spec_when_file_missing() -> Result<()> {
10601175
let temp_dir =

crates/pop-cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ duct.workspace = true
2626
env_logger.workspace = true
2727
os_info.workspace = true
2828
reqwest.workspace = true
29+
rustilities = { workspace = true, features = ["manifest"]}
2930
serde = { workspace = true, features = ["derive"] }
3031
serde_json.workspace = true
3132
strum.workspace = true

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::{PACKAGE, PARACHAIN};
44
use crate::{
55
cli,
66
common::{
7-
builds::create_chain_spec_builder,
7+
builds::{ChainPath, create_chain_spec_builder},
88
runtime::Feature::{Benchmark, TryRuntime},
99
},
1010
style::style,
@@ -65,7 +65,12 @@ impl BuildChain {
6565

6666
// Build parachain.
6767
cli.warning("NOTE: this may take some time...")?;
68-
let builder = create_chain_spec_builder(&self.path, &self.profile, false, cli)?;
68+
let builder = create_chain_spec_builder(
69+
ChainPath::Base(self.path.to_path_buf()),
70+
&self.profile,
71+
false,
72+
cli,
73+
)?;
6974
let features_arr: Vec<_> = features.into_iter().map(|s| s.to_string()).collect();
7075
let binary = builder.build(features_arr.as_slice())?;
7176
cli.info(format!("The {project} was built in {} mode.", self.profile))?;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
runtime::{build_runtime, ensure_runtime_binary_exists},
99
},
1010
};
11-
use pop_common::{Profile, find_workspace_toml};
11+
use pop_common::Profile;
1212
use std::{
1313
collections::HashSet,
1414
path::{Path, PathBuf},
@@ -89,7 +89,7 @@ impl BuildRuntime {
8989
if self.profile == Profile::Debug {
9090
cli.warning("NOTE: this command now defaults to DEBUG builds. Please use `--release` (or simply `-r`) for a release build...")?;
9191
}
92-
let workspace_root = find_workspace_toml(&self.path);
92+
let workspace_root = rustilities::manifest::find_workspace_manifest(&self.path);
9393
let target_path = self
9494
.profile
9595
.target_directory(&workspace_root.unwrap_or(self.path.to_path_buf()))

0 commit comments

Comments
 (0)