fix(zombienet): Ed25519 detection for asset-hub-pezkuwichain

Change Ed25519 AURA key detection from 'asset-hub-polkadot' to
'asset-hub-pezkuwi' to properly generate Ed25519 keys for
asset-hub-pezkuwichain collators.

This fixes the teyrchain collation issue where AURA keys were
being generated with Sr25519 instead of Ed25519.

Changes:
- chain_spec.rs: Update chain ID check for Ed25519 detection
- keystore.rs: Rename parameter for clarity
- keystore_key_types.rs: Update function parameters and docs
- spawner.rs: Update Ed25519 detection logic
This commit is contained in:
2026-01-04 12:00:19 +03:00
parent c96c2ca199
commit 0dce964c7b
4 changed files with 30 additions and 30 deletions
@@ -1349,16 +1349,16 @@ fn add_authorities(
nodes: &[&NodeSpec], nodes: &[&NodeSpec],
session_key: SessionKeyType, session_key: SessionKeyType,
) { ) {
let asset_hub_polkadot = chain_spec_json let is_asset_hub_pezkuwi = chain_spec_json
.get("id") .get("id")
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.map(|id| id.starts_with("asset-hub-polkadot")) .map(|id| id.starts_with("asset-hub-pezkuwi"))
.unwrap_or_default(); .unwrap_or_default();
if let Some(val) = chain_spec_json.pointer_mut(runtime_config_ptr) { if let Some(val) = chain_spec_json.pointer_mut(runtime_config_ptr) {
if let Some(session_keys) = val.pointer_mut("/session/keys") { if let Some(session_keys) = val.pointer_mut("/session/keys") {
let keys: Vec<GenesisNodeKey> = nodes let keys: Vec<GenesisNodeKey> = nodes
.iter() .iter()
.map(|node| get_node_keys(node, session_key, asset_hub_polkadot)) .map(|node| get_node_keys(node, session_key, is_asset_hub_pezkuwi))
.collect(); .collect();
*session_keys = json!(keys); *session_keys = json!(keys);
} else { } else {
@@ -1891,7 +1891,7 @@ mod tests {
} }
#[test] #[test]
fn get_node_keys_supports_asset_hub_polkadot() { fn get_node_keys_supports_asset_hub_pezkuwi() {
let mut name = String::from("luca"); let mut name = String::from("luca");
let seed = format!("//{}{name}", name.remove(0).to_uppercase()); let seed = format!("//{}{name}", name.remove(0).to_uppercase());
let accounts = let accounts =
@@ -19,7 +19,7 @@ use crate::{
/// * `acc` - The node accounts containing the seed and public keys /// * `acc` - The node accounts containing the seed and public keys
/// * `node_files_path` - The path where keystore files will be created /// * `node_files_path` - The path where keystore files will be created
/// * `scoped_fs` - The scoped filesystem for file operations /// * `scoped_fs` - The scoped filesystem for file operations
/// * `asset_hub_polkadot` - Whether this is for asset-hub-polkadot (affects aura key scheme) /// * `is_asset_hub_pezkuwi` - Whether this is for asset-hub-pezkuwi (affects aura key scheme)
/// * `keystore_key_types` - Optional list of key type specifications /// * `keystore_key_types` - Optional list of key type specifications
/// ///
/// If `keystore_key_types` is empty, all default key types will be generated. /// If `keystore_key_types` is empty, all default key types will be generated.
@@ -28,7 +28,7 @@ pub async fn generate<'a, T>(
acc: &NodeAccounts, acc: &NodeAccounts,
node_files_path: impl AsRef<Path>, node_files_path: impl AsRef<Path>,
scoped_fs: &ScopedFilesystem<'a, T>, scoped_fs: &ScopedFilesystem<'a, T>,
asset_hub_polkadot: bool, is_asset_hub_pezkuwi: bool,
keystore_key_types: Vec<&str>, keystore_key_types: Vec<&str>,
) -> Result<Vec<PathBuf>, GeneratorError> ) -> Result<Vec<PathBuf>, GeneratorError>
where where
@@ -39,7 +39,7 @@ where
let mut filenames = vec![]; let mut filenames = vec![];
// Parse the key type specifications // Parse the key type specifications
let key_types = parse_keystore_key_types(&keystore_key_types, asset_hub_polkadot); let key_types = parse_keystore_key_types(&keystore_key_types, is_asset_hub_pezkuwi);
let futures: Vec<_> = key_types let futures: Vec<_> = key_types
.iter() .iter()
@@ -163,7 +163,7 @@ mod tests {
struct TestCase { struct TestCase {
name: &'static str, name: &'static str,
key_types: Vec<&'static str>, key_types: Vec<&'static str>,
asset_hub_polkadot: bool, is_asset_hub_pezkuwi: bool,
expected_prefix: &'static str, expected_prefix: &'static str,
expected_public_key: &'static str, expected_public_key: &'static str,
} }
@@ -172,28 +172,28 @@ mod tests {
TestCase { TestCase {
name: "explicit scheme override (gran_sr)", name: "explicit scheme override (gran_sr)",
key_types: vec!["gran_sr"], key_types: vec!["gran_sr"],
asset_hub_polkadot: false, is_asset_hub_pezkuwi: false,
expected_prefix: "6772616e", // "gran" in hex expected_prefix: "6772616e", // "gran" in hex
expected_public_key: "sr_public_key", expected_public_key: "sr_public_key",
}, },
TestCase { TestCase {
name: "aura with asset_hub_polkadot uses ed", name: "aura with is_asset_hub_pezkuwi uses ed",
key_types: vec!["aura"], key_types: vec!["aura"],
asset_hub_polkadot: true, is_asset_hub_pezkuwi: true,
expected_prefix: "61757261", // "aura" in hex expected_prefix: "61757261", // "aura" in hex
expected_public_key: "ed_public_key", expected_public_key: "ed_public_key",
}, },
TestCase { TestCase {
name: "aura without asset_hub_polkadot uses sr", name: "aura without is_asset_hub_pezkuwi uses sr",
key_types: vec!["aura"], key_types: vec!["aura"],
asset_hub_polkadot: false, is_asset_hub_pezkuwi: false,
expected_prefix: "61757261", // "aura" in hex expected_prefix: "61757261", // "aura" in hex
expected_public_key: "sr_public_key", expected_public_key: "sr_public_key",
}, },
TestCase { TestCase {
name: "custom key type with explicit ec scheme", name: "custom key type with explicit ec scheme",
key_types: vec!["cust_ec"], key_types: vec!["cust_ec"],
asset_hub_polkadot: false, is_asset_hub_pezkuwi: false,
expected_prefix: "63757374", // "cust" in hex expected_prefix: "63757374", // "cust" in hex
expected_public_key: "ec_public_key", expected_public_key: "ec_public_key",
}, },
@@ -206,7 +206,7 @@ mod tests {
let key_types: Vec<&str> = tc.key_types.clone(); let key_types: Vec<&str> = tc.key_types.clone();
let res = let res =
generate(&accounts, "node1", &scoped_fs, tc.asset_hub_polkadot, key_types).await; generate(&accounts, "node1", &scoped_fs, tc.is_asset_hub_pezkuwi, key_types).await;
assert!(res.is_ok(), "[{}] Expected Ok but got: {:?}", tc.name, res.err()); assert!(res.is_ok(), "[{}] Expected Ok but got: {:?}", tc.name, res.err());
let filenames = res.unwrap(); let filenames = res.unwrap();
@@ -63,12 +63,12 @@ impl KeystoreKeyType {
} }
/// Returns the default predefined key schemes for known key types. /// Returns the default predefined key schemes for known key types.
/// Special handling for `aura` when `is_asset_hub_polkadot` is true. /// Special handling for `aura` when `is_asset_hub_pezkuwi` is true.
fn get_predefined_schemes(is_asset_hub_polkadot: bool) -> HashMap<&'static str, KeyScheme> { fn get_predefined_schemes(is_asset_hub_pezkuwi: bool) -> HashMap<&'static str, KeyScheme> {
let mut schemes = HashMap::new(); let mut schemes = HashMap::new();
// aura has special handling for asset-hub-polkadot // aura has special handling for asset-hub-pezkuwi
if is_asset_hub_polkadot { if is_asset_hub_pezkuwi {
schemes.insert("aura", KeyScheme::Ed); schemes.insert("aura", KeyScheme::Ed);
} else { } else {
schemes.insert("aura", KeyScheme::Sr); schemes.insert("aura", KeyScheme::Sr);
@@ -130,9 +130,9 @@ fn parse_key_spec(spec: &str, predefined: &HashMap<&str, KeyScheme>) -> Option<K
/// If the resulting list is empty, returns the default keystore key types. /// If the resulting list is empty, returns the default keystore key types.
pub fn parse_keystore_key_types<T: AsRef<str>>( pub fn parse_keystore_key_types<T: AsRef<str>>(
specs: &[T], specs: &[T],
is_asset_hub_polkadot: bool, is_asset_hub_pezkuwi: bool,
) -> Vec<KeystoreKeyType> { ) -> Vec<KeystoreKeyType> {
let predefined_schemes = get_predefined_schemes(is_asset_hub_polkadot); let predefined_schemes = get_predefined_schemes(is_asset_hub_pezkuwi);
let parsed: Vec<KeystoreKeyType> = specs let parsed: Vec<KeystoreKeyType> = specs
.iter() .iter()
@@ -140,15 +140,15 @@ pub fn parse_keystore_key_types<T: AsRef<str>>(
.collect(); .collect();
if parsed.is_empty() { if parsed.is_empty() {
get_default_keystore_key_types(is_asset_hub_polkadot) get_default_keystore_key_types(is_asset_hub_pezkuwi)
} else { } else {
parsed parsed
} }
} }
/// Returns the default keystore key types when none are specified. /// Returns the default keystore key types when none are specified.
pub fn get_default_keystore_key_types(is_asset_hub_polkadot: bool) -> Vec<KeystoreKeyType> { pub fn get_default_keystore_key_types(is_asset_hub_pezkuwi: bool) -> Vec<KeystoreKeyType> {
let predefined_schemes = get_predefined_schemes(is_asset_hub_polkadot); let predefined_schemes = get_predefined_schemes(is_asset_hub_pezkuwi);
let default_keys = [ let default_keys = [
"aura", "babe", "imon", "gran", "audi", "asgn", "para", "beef", "nmbs", "rand", "rate", "aura", "babe", "imon", "gran", "audi", "asgn", "para", "beef", "nmbs", "rand", "rate",
"mixn", "bcsv", "ftsv", "mixn", "bcsv", "ftsv",
@@ -236,15 +236,15 @@ mod tests {
} }
#[test] #[test]
fn full_workflow_asset_hub_polkadot() { fn full_workflow_asset_hub_pezkuwi() {
// For asset-hub-polkadot, aura should default to ed // For asset-hub-pezkuwi, aura should default to ed
let specs = vec!["aura".to_string(), "babe".to_string()]; let specs = vec!["aura".to_string(), "babe".to_string()];
let res = parse_keystore_key_types(&specs, true); let res = parse_keystore_key_types(&specs, true);
assert_eq!(res.len(), 2); assert_eq!(res.len(), 2);
assert_eq!(res[0].key_type, "aura"); assert_eq!(res[0].key_type, "aura");
assert_eq!(res[0].scheme, KeyScheme::Ed); // ed for asset-hub-polkadot assert_eq!(res[0].scheme, KeyScheme::Ed); // ed for asset-hub-pezkuwi
assert_eq!(res[1].key_type, "babe"); assert_eq!(res[1].key_type, "babe");
assert_eq!(res[1].scheme, KeyScheme::Sr); assert_eq!(res[1].scheme, KeyScheme::Sr);
@@ -65,14 +65,14 @@ where
// Generate keystore for node // Generate keystore for node
let node_files_path = let node_files_path =
if let Some(para) = ctx.parachain { para.id.to_string() } else { node.name.clone() }; if let Some(para) = ctx.parachain { para.id.to_string() } else { node.name.clone() };
let asset_hub_polkadot = let is_asset_hub_pezkuwi =
ctx.parachain_id.map(|id| id.starts_with("asset-hub-polkadot")).unwrap_or_default(); ctx.parachain_id.map(|id| id.starts_with("asset-hub-pezkuwi")).unwrap_or_default();
let keystore_key_types = node.keystore_key_types.iter().map(String::as_str).collect(); let keystore_key_types = node.keystore_key_types.iter().map(String::as_str).collect();
let key_filenames = generators::generate_node_keystore( let key_filenames = generators::generate_node_keystore(
&node.accounts, &node.accounts,
&node_files_path, &node_files_path,
ctx.scoped_fs, ctx.scoped_fs,
asset_hub_polkadot, is_asset_hub_pezkuwi,
keystore_key_types, keystore_key_types,
) )
.await .await