Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update parachain templates #297

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
12610ef
feat: include new parachain template and remove old one for Parity
AlexD10S Aug 28, 2024
31ac60d
fix: tests
AlexD10S Aug 29, 2024
fec60a8
fix: order in test
AlexD10S Aug 29, 2024
392bdd9
fix: export PATH
AlexD10S Sep 4, 2024
c085a66
chore: merge main
AlexD10S Sep 6, 2024
ba6b7e0
Merge branch 'main' into alex/parity-template
AlexD10S Sep 12, 2024
e5ab436
chore: bump zombienet-sdk version
AlexD10S Sep 12, 2024
5da07ef
fix: remove parity evm
AlexD10S Sep 12, 2024
6070af6
fix: missing changes
AlexD10S Sep 12, 2024
dbf1ee7
fix: parse collator and parachain-template-node without path for spawn
AlexD10S Sep 12, 2024
d83700d
chore: remove set PATH
AlexD10S Sep 12, 2024
316de33
refactor: functionality and test
AlexD10S Sep 12, 2024
9f2076b
refactor: prefix for external templates
AlexD10S Sep 17, 2024
7addd9b
fix: deprecate old command for generating parity contracts template
AlexD10S Sep 18, 2024
d40ec06
test: update configure_works test to test new functionality
AlexD10S Sep 18, 2024
7017d63
test: fix unit tests templates
AlexD10S Sep 18, 2024
9871fe2
fix: show deprecation message and fixes
AlexD10S Sep 18, 2024
2b549c4
chore: merge main
AlexD10S Sep 18, 2024
7fbb66b
docs: improve comments
AlexD10S Sep 18, 2024
abfca64
refactor: nitpicks in parachain description
AlexD10S Sep 22, 2024
34ff183
fix: logic for substrate-contracts-node without path in config file
AlexD10S Sep 22, 2024
1898075
chore: merge latest changes
AlexD10S Jan 14, 2025
a68dd5f
feat: support v3.0.0 of OpenZeppelin templates
AlexD10S Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions crates/pop-cli/src/commands/new/parachain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,9 @@ async fn guide_user_to_generate_parachain(verify: bool) -> Result<NewParachainCo
provider,
provider.name(),
format!(
"{} {} available option(s) {}",
"{} {} available option(s)",
provider.description(),
provider.templates().len(),
if provider.name() == "Parity" { "[deprecated]" } else { "" }
provider.templates().len()
),
);
}
Expand Down Expand Up @@ -257,7 +256,7 @@ fn display_select_options(provider: &Provider) -> Result<&Parachain> {
if i == 0 {
prompt = prompt.initial_value(template);
}
prompt = prompt.item(template, template.name(), template.description());
prompt = prompt.item(template, template.name(), template.description().trim());
}
Ok(prompt.interact()?)
}
Expand Down Expand Up @@ -471,11 +470,11 @@ mod tests {
fn test_is_template_supported() -> Result<()> {
is_template_supported(&Provider::Pop, &Parachain::Standard)?;
assert!(is_template_supported(&Provider::Pop, &Parachain::ParityContracts).is_err());
assert!(is_template_supported(&Provider::Pop, &Parachain::ParityFPT).is_err());
assert!(is_template_supported(&Provider::Pop, &Parachain::ParityGeneric).is_err());

assert!(is_template_supported(&Provider::Parity, &Parachain::Standard).is_err());
is_template_supported(&Provider::Parity, &Parachain::ParityContracts)?;
is_template_supported(&Provider::Parity, &Parachain::ParityFPT)
is_template_supported(&Provider::Parity, &Parachain::ParityGeneric)
}

#[test]
Expand Down
60 changes: 34 additions & 26 deletions crates/pop-parachains/src/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@
message = "Pop",
detailed_message = "An all-in-one tool for Polkadot development."
)]
Pop,

Check warning on line 19 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a variant

warning: missing documentation for a variant --> crates/pop-parachains/src/templates.rs:19:2 | 19 | Pop, | ^^^
#[strum(
ascii_case_insensitive,
serialize = "openzeppelin",
message = "OpenZeppelin",
detailed_message = "The standard for secure blockchain applications."
)]
OpenZeppelin,

Check warning on line 26 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a variant

warning: missing documentation for a variant --> crates/pop-parachains/src/templates.rs:26:2 | 26 | OpenZeppelin, | ^^^^^^^^^^^^
#[strum(
ascii_case_insensitive,
serialize = "parity",
message = "Parity",
detailed_message = "Solutions for a trust-free world."
)]
Parity,

Check warning on line 33 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a variant

warning: missing documentation for a variant --> crates/pop-parachains/src/templates.rs:33:2 | 33 | Parity, | ^^^^^^
}

impl Type<Parachain> for Provider {
Expand All @@ -38,7 +38,7 @@
match &self {
Provider::Pop => Some(Parachain::Standard),
Provider::OpenZeppelin => Some(Parachain::OpenZeppelinGeneric),
Provider::Parity => Some(Parachain::ParityContracts),
Provider::Parity => Some(Parachain::ParityGeneric),
}
}
}
Expand All @@ -46,9 +46,9 @@
/// Configurable settings for parachain generation.
#[derive(Debug, Clone, PartialEq)]
pub struct Config {
pub symbol: String,

Check warning on line 49 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a struct field

warning: missing documentation for a struct field --> crates/pop-parachains/src/templates.rs:49:2 | 49 | pub symbol: String, | ^^^^^^^^^^^^^^^^^^
pub decimals: u8,

Check warning on line 50 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a struct field

warning: missing documentation for a struct field --> crates/pop-parachains/src/templates.rs:50:2 | 50 | pub decimals: u8, | ^^^^^^^^^^^^^^^^
pub initial_endowment: String,

Check warning on line 51 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a struct field

warning: missing documentation for a struct field --> crates/pop-parachains/src/templates.rs:51:2 | 51 | pub initial_endowment: String, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}

/// Templates supported.
Expand Down Expand Up @@ -130,12 +130,12 @@
Provider = "OpenZeppelin",
Repository = "https://github.com/OpenZeppelin/polkadot-runtime-templates",
Network = "./zombienet-config/devnet.toml",
SupportedVersions = "v1.0.0,v2.0.1,v2.0.3",
SupportedVersions = "v1.0.0,v2.0.1,v2.0.3,v3.0.0",
IsAudited = "true",
License = "GPL-3.0"
)
)]
OpenZeppelinGeneric,

Check warning on line 138 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a variant

warning: missing documentation for a variant --> crates/pop-parachains/src/templates.rs:138:2 | 138 | OpenZeppelinGeneric, | ^^^^^^^^^^^^^^^^^^^
// OpenZeppelin EVM
#[strum(
serialize = "openzeppelin/evm-template",
Expand All @@ -145,38 +145,38 @@
Provider = "OpenZeppelin",
Repository = "https://github.com/OpenZeppelin/polkadot-runtime-templates",
Network = "./zombienet-config/devnet.toml",
SupportedVersions = "v2.0.3",
SupportedVersions = "v2.0.3,v3.0.0",
IsAudited = "true",
License = "GPL-3.0"
)
)]
OpenZeppelinEVM,

Check warning on line 153 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a variant

warning: missing documentation for a variant --> crates/pop-parachains/src/templates.rs:153:2 | 153 | OpenZeppelinEVM, | ^^^^^^^^^^^^^^^
/// Minimal Substrate node configured for smart contracts via pallet-contracts.
/// The Parachain-Ready Template From Polkadot SDK.
#[strum(
serialize = "cpt",
message = "Contracts",
detailed_message = "Minimal Substrate node configured for smart contracts via pallet-contracts.",
serialize = "paritytech/polkadot-sdk-parachain-template",
message = "Polkadot SDK's Parachain Template",
detailed_message = "The Parachain-Ready Template From Polkadot SDK.",
props(
Provider = "Parity",
Repository = "https://github.com/paritytech/substrate-contracts-node",
Repository = "https://github.com/paritytech/polkadot-sdk-parachain-template",
Network = "./zombienet.toml",
License = "Unlicense"
)
)]
ParityContracts,
/// Template node for a Frontier (EVM) based parachain.
ParityGeneric,
/// Minimal Substrate node configured for smart contracts via pallet-contracts.
#[strum(
serialize = "fpt",
message = "EVM",
detailed_message = "Template node for a Frontier (EVM) based parachain.",
serialize = "paritytech/substrate-contracts-node",
message = "Contracts",
detailed_message = "Minimal Substrate node configured for smart contracts via pallet-contracts.",
props(
Provider = "Parity",
Repository = "https://github.com/paritytech/frontier-parachain-template",
Network = "./zombienet-config.toml",
Repository = "https://github.com/paritytech/substrate-contracts-node",
Network = "./zombienet.toml",
License = "Unlicense"
)
)]
ParityFPT,
ParityContracts,
// templates for unit tests below
#[cfg(test)]
#[strum(
Expand Down Expand Up @@ -215,21 +215,21 @@
self.get_str("Network")
}

pub fn supported_versions(&self) -> Option<Vec<&str>> {

Check warning on line 218 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a method

warning: missing documentation for a method --> crates/pop-parachains/src/templates.rs:218:2 | 218 | pub fn supported_versions(&self) -> Option<Vec<&str>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
self.get_str("SupportedVersions").map(|s| s.split(',').collect())
}

pub fn is_supported_version(&self, version: &str) -> bool {

Check warning on line 222 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a method

warning: missing documentation for a method --> crates/pop-parachains/src/templates.rs:222:2 | 222 | pub fn is_supported_version(&self, version: &str) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// if `SupportedVersion` is None, then all versions are supported. Otherwise, ensure version
// is present.
self.supported_versions().map_or(true, |versions| versions.contains(&version))
}

pub fn is_audited(&self) -> bool {

Check warning on line 228 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a method

warning: missing documentation for a method --> crates/pop-parachains/src/templates.rs:228:2 | 228 | pub fn is_audited(&self) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
self.get_str("IsAudited").map_or(false, |s| s == "true")

Check warning on line 229 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

this `map_or` is redundant

warning: this `map_or` is redundant --> crates/pop-parachains/src/templates.rs:229:3 | 229 | self.get_str("IsAudited").map_or(false, |s| s == "true") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(self.get_str("IsAudited") == Some("true"))` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_or
}

pub fn license(&self) -> Option<&str> {

Check warning on line 232 in crates/pop-parachains/src/templates.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a method

warning: missing documentation for a method --> crates/pop-parachains/src/templates.rs:232:2 | 232 | pub fn license(&self) -> Option<&str> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
self.get_str("License")
}

Expand All @@ -256,8 +256,9 @@
// openzeppelin
("openzeppelin/generic-template".to_string(), OpenZeppelinGeneric),
("openzeppelin/evm-template".to_string(), OpenZeppelinEVM),
("cpt".to_string(), ParityContracts),
("fpt".to_string(), ParityFPT),
// pàrity
("paritytech/polkadot-sdk-parachain-template".to_string(), ParityGeneric),
("paritytech/substrate-contracts-node".to_string(), ParityContracts),
("test_01".to_string(), TestTemplate01),
("test_02".to_string(), TestTemplate02),
])
Expand All @@ -271,8 +272,8 @@
(EVM, "evm".to_string()),
(OpenZeppelinGeneric, "generic-template".to_string()),
(OpenZeppelinEVM, "evm-template".to_string()),
(ParityContracts, "cpt".to_string()),
(ParityFPT, "fpt".to_string()),
(ParityGeneric, "polkadot-sdk-parachain-template".to_string()),
(ParityContracts, "substrate-contracts-node".to_string()),
(TestTemplate01, "test_01".to_string()),
(TestTemplate02, "test_02".to_string()),
])
Expand All @@ -297,8 +298,15 @@
"polkadot-generic-runtime-template".to_string(),
"https://github.com/OpenZeppelin/polkadot-runtime-templates",
),
(
"paritytech/polkadot-sdk-parachain-template".to_string(),
"https://github.com/paritytech/polkadot-sdk-parachain-template",
),
(
"paritytech/substrate-contracts-node".to_string(),
"https://github.com/paritytech/substrate-contracts-node",
),
("cpt".to_string(), "https://github.com/paritytech/substrate-contracts-node"),
("fpt".to_string(), "https://github.com/paritytech/frontier-parachain-template"),
("test_01".to_string(), ""),
("test_02".to_string(), ""),
])
Expand All @@ -312,8 +320,8 @@
(EVM, Some("./network.toml")),
(OpenZeppelinGeneric, Some("./zombienet-config/devnet.toml")),
(OpenZeppelinEVM, Some("./zombienet-config/devnet.toml")),
(ParityGeneric, Some("./zombienet.toml")),
(ParityContracts, Some("./zombienet.toml")),
(ParityFPT, Some("./zombienet-config.toml")),
(TestTemplate01, Some("")),
(TestTemplate02, Some("")),
]
Expand All @@ -328,8 +336,8 @@
(EVM, Some("Unlicense")),
(OpenZeppelinGeneric, Some("GPL-3.0")),
(OpenZeppelinEVM, Some("GPL-3.0")),
(ParityGeneric, Some("Unlicense")),
(ParityContracts, Some("Unlicense")),
(ParityFPT, Some("Unlicense")),
(TestTemplate01, Some("Unlicense")),
(TestTemplate02, Some("GPL-3.0")),
]
Expand All @@ -343,7 +351,7 @@
assert_eq!(Provider::Pop.provides(&template), true);
assert_eq!(Provider::Parity.provides(&template), false);
}
if matches!(template, ParityContracts | ParityFPT) {
if matches!(template, ParityContracts | ParityGeneric) {
assert_eq!(Provider::Pop.provides(&template), false);
assert_eq!(Provider::Parity.provides(&template), true)
}
Expand Down Expand Up @@ -397,15 +405,15 @@
let mut provider = Provider::Pop;
assert_eq!(provider.default_template(), Some(Standard));
provider = Provider::Parity;
assert_eq!(provider.default_template(), Some(ParityContracts));
assert_eq!(provider.default_template(), Some(ParityGeneric));
}

#[test]
fn test_templates_of_provider() {
let mut provider = Provider::Pop;
assert_eq!(provider.templates(), [&Standard, &Assets, &Contracts, &EVM]);
provider = Provider::Parity;
assert_eq!(provider.templates(), [&ParityContracts, &ParityFPT]);
assert_eq!(provider.templates(), [&ParityGeneric, &ParityContracts]);
}

#[test]
Expand Down
130 changes: 129 additions & 1 deletion crates/pop-parachains/src/up/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@
}
}
}
// Check if collator has defined command
if let Some(collator) = table.get("collator").and_then(|i| i.as_table()) {
if let Some(command) =
NetworkConfiguration::command(collator).and_then(|i| i.as_str())
{
return Some(Item::Value(Value::String(Formatted::new(command.into()))));
}
}

// Otherwise default to polkadot-parachain
Some(Item::Value(Value::String(Formatted::new("polkadot-parachain".into()))))
Expand Down Expand Up @@ -206,6 +214,16 @@
continue;
}

// Check if command references a parachain template binary without a specified path
// (e.g. Polkadot SDK parachain template)
if command == "parachain-template-node" || command == "substrate-contracts-node" {
let binary_path = PathBuf::from("./target/release").join(&command);
if !binary_path.exists() {
return Err(Error::MissingBinary(command));
}
paras.insert(id, Parachain::from_local(id, binary_path, chain)?);
continue;
}
return Err(Error::MissingBinary(command));
}
Ok(paras)
Expand Down Expand Up @@ -479,6 +497,12 @@
}
}
}
// Resolve individual collator command to binary
if let Some(collator) = table.get_mut("collator").and_then(|p| p.as_table_mut()) {
AlexD10S marked this conversation as resolved.
Show resolved Hide resolved
if let Some(command) = NetworkConfiguration::command_mut(collator) {
*command = value(&path)
}
}
}
}

Expand Down Expand Up @@ -618,12 +642,12 @@
/// * `path` - The path to start searching.
fn resolve_manifest(package: &str, path: &Path) -> Result<Option<PathBuf>, Error> {
let matches_package = |config: &DocumentMut| {
config
.get("package")
.and_then(|i| i.as_table())
.and_then(|t| t.get("name"))
.and_then(|i| i.as_str())
.map_or(false, |n| n == package)

Check warning on line 650 in crates/pop-parachains/src/up/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

this `map_or` is redundant

warning: this `map_or` is redundant --> crates/pop-parachains/src/up/mod.rs:645:3 | 645 | / config 646 | | .get("package") 647 | | .and_then(|i| i.as_table()) 648 | | .and_then(|t| t.get("name")) 649 | | .and_then(|i| i.as_str()) 650 | | .map_or(false, |n| n == package) | |____________________________________________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_or help: use a standard comparison instead | 645 ~ (config 646 ~ .get("package") 647 ~ .and_then(|i| i.as_table()) 648 ~ .and_then(|t| t.get("name")) 649 ~ .and_then(|i| i.as_str()) == Some(package)) |
};

let mut manifest = Some(path);
Expand Down Expand Up @@ -676,7 +700,11 @@
mod tests {
use super::*;
use anyhow::Result;
use std::{env::current_dir, fs::File, io::Write};
use std::{
env::current_dir,
fs::{create_dir_all, remove_dir, remove_file, File},
io::Write,
};
use tempfile::tempdir;

pub(crate) const VERSION: &str = "stable2409";
Expand Down Expand Up @@ -1123,6 +1151,77 @@
Ok(())
}

#[tokio::test]
async fn new_with_local_parachain_without_path_works() -> Result<()> {
let temp_dir = tempdir()?;
let cache = PathBuf::from(temp_dir.path());
let config = Builder::new().suffix(".toml").tempfile()?;
writeln!(
config.as_file(),
r#"
[relaychain]
chain = "rococo-local"

[[parachains]]
id = 1000

[parachains.collator]
name = "collator"
command = "parachain-template-node"

[[parachains]]
id = 2000

[parachains.collator]
name = "collator"
command = "substrate-contracts-node"
"#
)?;
assert!(matches!(
Zombienet::new(&cache, config.path().to_str().unwrap(), None, None, None, None, None).await,
Err(Error::MissingBinary(command))
if command == "parachain-template-node"
));
// Create the binaries in the hardcoded path
let parachain_template = PathBuf::from("target/release/parachain-template-node");
create_dir_all(parachain_template.parent().unwrap())?;
File::create(&parachain_template)?;
let parachain_contracts_template =
PathBuf::from("target/release/substrate-contracts-node");
File::create(&parachain_contracts_template)?;

let zombienet = Zombienet::new(
&cache,
config.path().to_str().unwrap(),
None,
None,
None,
None,
None,
)
.await?;
// Remove the binary hardcoded path
remove_file(&parachain_template)?;
remove_file(&parachain_contracts_template)?;
remove_dir(parachain_template.parent().unwrap())?;

assert_eq!(zombienet.parachains.len(), 2);
let parachain = &zombienet.parachains.get(&1000).unwrap().binary;
assert_eq!(parachain.name(), "parachain-template-node");
assert_eq!(parachain.path(), Path::new("./target/release/parachain-template-node"));
assert_eq!(parachain.version(), None);
assert!(matches!(parachain, Binary::Local { .. }));
let contract_parachain = &zombienet.parachains.get(&2000).unwrap().binary;
assert_eq!(contract_parachain.name(), "substrate-contracts-node");
assert_eq!(
contract_parachain.path(),
Path::new("./target/release/substrate-contracts-node")
);
assert_eq!(contract_parachain.version(), None);
assert!(matches!(contract_parachain, Binary::Local { .. }));
Ok(())
}

#[tokio::test]
async fn new_with_collator_command_works() -> Result<()> {
let temp_dir = tempdir()?;
Expand Down Expand Up @@ -1619,6 +1718,14 @@
[[parachains.collators]]
name = "collator"
command = "./target/release/parachain-template-node"

[[parachains]]
id = 2002
default_command = "./target/release/parachain-template-node"

[parachains.collator]
name = "collator"
command = "./target/release/parachain-template-node"
"#
)?;
let mut network_config = NetworkConfiguration::from(config.path())?;
Expand Down Expand Up @@ -1688,6 +1795,19 @@
chain_spec_generator: None,
},
),
(
2002,
Parachain {
id: 2002,
binary: Binary::Local {
name: "parachain-template-node".to_string(),
path: parachain_template.to_path_buf(),
manifest: None,
},
chain: None,
chain_spec_generator: None,
},
),
]
.into(),
)?;
Expand Down Expand Up @@ -1733,6 +1853,14 @@
name = "collator"
command = "{3}"

[[parachains]]
id = 2002
default_command = "{3}"

[parachains.collator]
name = "collator"
command = "{3}"

[settings]
timeout = 1000
node_spawn_timeout = 300
Expand Down
Loading