feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
mod multiple_blocks_per_slot;
|
||||
mod pov_recovery;
|
||||
mod slot_based_authoring;
|
||||
mod slot_based_rp_offset;
|
||||
mod upgrade_to_3_cores;
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use anyhow::anyhow;
|
||||
|
||||
use crate::utils::initialize_network;
|
||||
|
||||
use cumulus_zombienet_sdk_helpers::{assert_finality_lag, assert_para_throughput, assign_cores};
|
||||
use pezkuwi_primitives::Id as ParaId;
|
||||
use serde_json::json;
|
||||
use zombienet_sdk::{
|
||||
subxt::{OnlineClient, PolkadotConfig},
|
||||
NetworkConfig, NetworkConfigBuilder,
|
||||
};
|
||||
|
||||
const PARA_ID: u32 = 2400;
|
||||
|
||||
/// This test spawns a teyrchain network.
|
||||
/// Initially, one core is assigned. We expect the teyrchain to produce 1 block per relay.
|
||||
/// As we increase the number of cores via `assign_core`, we expect the block pace to increase too.
|
||||
/// **Note:** The runtime in use here has 6s slot duration, so multiple blocks will be produced per
|
||||
/// slot.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn elastic_scaling_multiple_blocks_per_slot() -> Result<(), anyhow::Error> {
|
||||
let _ = env_logger::try_init_from_env(
|
||||
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
||||
);
|
||||
|
||||
log::info!("Spawning network");
|
||||
let config = build_network_config().await?;
|
||||
let network = initialize_network(config).await?;
|
||||
|
||||
let relay_node = network.get_node("validator-0")?;
|
||||
let para_node_elastic = network.get_node("collator-1")?;
|
||||
|
||||
let relay_client: OnlineClient<PolkadotConfig> = relay_node.wait_client().await?;
|
||||
assert_para_throughput(
|
||||
&relay_client,
|
||||
10,
|
||||
[(ParaId::from(PARA_ID), 3..18)].into_iter().collect(),
|
||||
)
|
||||
.await?;
|
||||
assert_finality_lag(¶_node_elastic.wait_client().await?, 5).await?;
|
||||
|
||||
assign_cores(relay_node, PARA_ID, vec![2, 3]).await?;
|
||||
|
||||
assert_para_throughput(
|
||||
&relay_client,
|
||||
15,
|
||||
[(ParaId::from(PARA_ID), 39..46)].into_iter().collect(),
|
||||
)
|
||||
.await?;
|
||||
assert_finality_lag(¶_node_elastic.wait_client().await?, 20).await?;
|
||||
|
||||
assign_cores(relay_node, PARA_ID, vec![4, 5, 6]).await?;
|
||||
|
||||
assert_para_throughput(
|
||||
&relay_client,
|
||||
10,
|
||||
[(ParaId::from(PARA_ID), 52..61)].into_iter().collect(),
|
||||
)
|
||||
.await?;
|
||||
assert_finality_lag(¶_node_elastic.wait_client().await?, 30).await?;
|
||||
log::info!("Test finished successfully");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn build_network_config() -> Result<NetworkConfig, anyhow::Error> {
|
||||
// images are not relevant for `native`, but we leave it here in case we use `k8s` some day
|
||||
let images = zombienet_sdk::environment::get_images_from_env();
|
||||
log::info!("Using images: {images:?}");
|
||||
|
||||
NetworkConfigBuilder::new()
|
||||
.with_relaychain(|r| {
|
||||
let r = r
|
||||
.with_chain("pezkuwichain-local")
|
||||
.with_default_command("pezkuwi")
|
||||
.with_default_image(images.polkadot.as_str())
|
||||
.with_default_args(vec![("-lteyrchain=trace").into()])
|
||||
.with_default_resources(|resources| {
|
||||
// These settings are applicable only for `k8s` provider.
|
||||
// Leaving them in case we switch to `k8s` some day.
|
||||
resources.with_request_cpu(4).with_request_memory("4G")
|
||||
})
|
||||
.with_genesis_overrides(json!({
|
||||
"configuration": {
|
||||
"config": {
|
||||
"scheduler_params": {
|
||||
"num_cores": 7,
|
||||
"max_validators_per_core": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
// Have to set a `with_node` outside of the loop below, so that `r` has the right
|
||||
// type.
|
||||
.with_node(|node| node.with_name("validator-0"));
|
||||
(1..9).fold(r, |acc, i| acc.with_node(|node| node.with_name(&format!("validator-{i}"))))
|
||||
})
|
||||
.with_teyrchain(|p| {
|
||||
p.with_id(PARA_ID)
|
||||
.with_default_command("test-teyrchain")
|
||||
.with_default_image(images.pezcumulus.as_str())
|
||||
.with_chain("elastic-scaling-multi-block-slot")
|
||||
.with_default_args(vec![
|
||||
("--authoring").into(),
|
||||
("slot-based").into(),
|
||||
("-lteyrchain=trace,aura=debug").into(),
|
||||
])
|
||||
.with_collator(|n| n.with_name("collator-0"))
|
||||
.with_collator(|n| n.with_name("collator-1"))
|
||||
.with_collator(|n| n.with_name("collator-2"))
|
||||
})
|
||||
.with_global_settings(|global_settings| match std::env::var("ZOMBIENET_SDK_BASE_DIR") {
|
||||
Ok(val) => global_settings.with_base_dir(val),
|
||||
_ => global_settings,
|
||||
})
|
||||
.build()
|
||||
.map_err(|e| {
|
||||
let errs = e.into_iter().map(|e| e.to_string()).collect::<Vec<_>>().join(" ");
|
||||
anyhow!("config errs: {errs}")
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use anyhow::anyhow;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use crate::utils::{initialize_network, BEST_BLOCK_METRIC};
|
||||
|
||||
use cumulus_zombienet_sdk_helpers::{
|
||||
assert_para_is_registered, assert_para_throughput, assign_cores,
|
||||
};
|
||||
use pezkuwi_primitives::Id as ParaId;
|
||||
use serde_json::json;
|
||||
use zombienet_orchestrator::network::node::LogLineCountOptions;
|
||||
use zombienet_sdk::{
|
||||
subxt::{OnlineClient, PolkadotConfig},
|
||||
NetworkConfig, NetworkConfigBuilder, RegistrationStrategy,
|
||||
};
|
||||
|
||||
const PARA_ID: u32 = 2100;
|
||||
|
||||
/// This test checks if teyrchain node is importing blocks using PoV recovery even
|
||||
/// after more cores have been assigned for the teyrchain.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn elastic_scaling_pov_recovery() -> Result<(), anyhow::Error> {
|
||||
let _ = env_logger::try_init_from_env(
|
||||
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
||||
);
|
||||
|
||||
log::info!("Spawning network with relay chain only");
|
||||
let config = build_network_config().await?;
|
||||
let mut network = initialize_network(config).await?;
|
||||
|
||||
let alice = network.get_node("alice")?;
|
||||
let collator_elastic = network.get_node("collator-elastic")?;
|
||||
|
||||
log::info!("Checking if alice is up");
|
||||
assert!(alice.wait_until_is_up(60u64).await.is_ok());
|
||||
|
||||
log::info!("Checking if collator-elastic is up");
|
||||
assert!(collator_elastic.wait_until_is_up(60u64).await.is_ok());
|
||||
|
||||
assign_cores(alice, PARA_ID, vec![0, 1]).await?;
|
||||
|
||||
log::info!("Waiting 20 blocks to register teyrchain");
|
||||
// Wait 20 blocks and register teyrchain. This part is important for pov-recovery.
|
||||
// We need to make sure that the recovering node is able to see all relay-chain
|
||||
// notifications containing the candidates to recover.
|
||||
assert!(alice
|
||||
.wait_metric_with_timeout(BEST_BLOCK_METRIC, |b| b >= 20.0, 250u64)
|
||||
.await
|
||||
.is_ok());
|
||||
|
||||
log::info!("Registering teyrchain para_id = {PARA_ID}");
|
||||
let relay_client: OnlineClient<PolkadotConfig> = alice.wait_client().await?;
|
||||
network.register_parachain(PARA_ID).await?;
|
||||
|
||||
log::info!("Ensuring teyrchain is registered within 30 blocks");
|
||||
assert_para_is_registered(&relay_client, ParaId::from(PARA_ID), 30).await?;
|
||||
|
||||
log::info!("Ensuring teyrchain making progress");
|
||||
assert_para_throughput(
|
||||
&relay_client,
|
||||
20,
|
||||
[(ParaId::from(PARA_ID), 40..65)].into_iter().collect(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let collator_elastic = network.get_node("collator-elastic")?;
|
||||
|
||||
log::info!("Checking block production");
|
||||
assert!(collator_elastic
|
||||
.wait_metric_with_timeout(BEST_BLOCK_METRIC, |b| b >= 40.0, 225u64)
|
||||
.await
|
||||
.is_ok());
|
||||
|
||||
// We want to make sure that none of the consensus hook checks fail, even if the chain makes
|
||||
// progress. If below log line occurred 1 or more times then test failed.
|
||||
log::info!("Ensuring none of the consensus hook checks fail at {}", collator_elastic.name());
|
||||
let result = collator_elastic
|
||||
.wait_log_line_count_with_timeout(
|
||||
"set_validation_data inherent needs to be present in every block",
|
||||
false,
|
||||
LogLineCountOptions::no_occurences_within_timeout(Duration::from_secs(10)),
|
||||
)
|
||||
.await?;
|
||||
|
||||
assert!(result.success(), "Consensus hook failed at {}: {:?}", collator_elastic.name(), result);
|
||||
|
||||
// Wait (up to 10 seconds) until pattern occurs more than 35 times
|
||||
let options = LogLineCountOptions {
|
||||
predicate: Arc::new(|n| n > 35),
|
||||
timeout: Duration::from_secs(10),
|
||||
wait_until_timeout_elapses: false,
|
||||
};
|
||||
|
||||
let name = "recovery-target";
|
||||
log::info!("Ensuring blocks are imported using PoV recovery by {name}");
|
||||
let result = network
|
||||
.get_node(name)?
|
||||
.wait_log_line_count_with_timeout(
|
||||
"Importing blocks retrieved using pov_recovery",
|
||||
false,
|
||||
options,
|
||||
)
|
||||
.await?;
|
||||
|
||||
assert!(result.success(), "Failed importing blocks using PoV recovery by {name}: {result:?}");
|
||||
|
||||
log::info!("Test finished successfully");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn build_network_config() -> Result<NetworkConfig, anyhow::Error> {
|
||||
// images are not relevant for `native`, but we leave it here in case we use `k8s` some day
|
||||
let images = zombienet_sdk::environment::get_images_from_env();
|
||||
log::info!("Using images: {images:?}");
|
||||
|
||||
// Network setup:
|
||||
// - relaychain nodes:
|
||||
// - alice
|
||||
// - validator
|
||||
// - validator[0-3]
|
||||
// - validator
|
||||
// - synchronize only with alice
|
||||
// - teyrchain nodes
|
||||
// - recovery-target
|
||||
// - full node
|
||||
// - collator-elastic
|
||||
// - collator which is the only one producing blocks
|
||||
NetworkConfigBuilder::new()
|
||||
.with_relaychain(|r| {
|
||||
let r = r
|
||||
.with_chain("pezkuwichain-local")
|
||||
.with_default_command("pezkuwi")
|
||||
.with_default_image(images.polkadot.as_str())
|
||||
.with_default_resources(|resources| {
|
||||
// These settings are applicable only for `k8s` provider.
|
||||
// Leaving them in case we switch to `k8s` some day.
|
||||
resources
|
||||
.with_request_cpu(1)
|
||||
.with_request_memory("2G")
|
||||
.with_limit_cpu(2)
|
||||
.with_limit_memory("4G")
|
||||
})
|
||||
.with_genesis_overrides(json!({
|
||||
"configuration": {
|
||||
"config": {
|
||||
"scheduler_params": {
|
||||
"num_cores": 2,
|
||||
"max_validators_per_core": 1
|
||||
},
|
||||
"approval_voting_params": {
|
||||
"max_approval_coalesce_count": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
// Have to set a `with_node` outside of the loop below, so that `r` has the right
|
||||
// type.
|
||||
.with_node(|node| node.with_name("alice").with_args(vec![]));
|
||||
|
||||
(0..4).fold(r, |acc, i| {
|
||||
acc.with_node(|node| {
|
||||
node.with_name(&format!("validator-{i}")).with_args(vec![
|
||||
("-lruntime=debug,teyrchain=trace").into(),
|
||||
("--reserved-only").into(),
|
||||
("--reserved-nodes", "{{ZOMBIE:alice:multiaddr}}").into(),
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
.with_teyrchain(|p| {
|
||||
p.with_id(PARA_ID)
|
||||
.with_chain("elastic-scaling")
|
||||
.with_registration_strategy(RegistrationStrategy::Manual)
|
||||
.with_default_command("test-teyrchain")
|
||||
.with_default_image(images.pezcumulus.as_str())
|
||||
.with_default_resources(|resources| {
|
||||
// These settings are applicable only for `k8s` provider.
|
||||
// Leaving them in case we switch to `k8s` some day.
|
||||
resources
|
||||
.with_request_cpu(1)
|
||||
.with_request_memory("2G")
|
||||
.with_limit_cpu(2)
|
||||
.with_limit_memory("4G")
|
||||
})
|
||||
.with_collator(|n|
|
||||
n.with_name("recovery-target")
|
||||
.validator(false)
|
||||
.with_args(vec![
|
||||
("-lteyrchain::availability=trace,sync=debug,teyrchain=debug,pezcumulus-pov-recovery=debug,pezcumulus-consensus=debug").into(),
|
||||
("--disable-block-announcements").into(),
|
||||
("--in-peers", "0").into(),
|
||||
("--out-peers", "0").into(),
|
||||
("--").into(),
|
||||
("--reserved-only").into(),
|
||||
("--reserved-nodes", "{{ZOMBIE:alice:multiaddr}}").into()
|
||||
]))
|
||||
.with_collator(|n| n.with_name("collator-elastic")
|
||||
.with_args(vec![
|
||||
("-laura=trace,runtime=info,pezcumulus-consensus=trace,consensus::common=trace,teyrchain::collation-generation=trace,teyrchain::collator-protocol=trace,teyrchain=debug").into(),
|
||||
("--disable-block-announcements").into(),
|
||||
("--force-authoring").into(),
|
||||
("--authoring", "slot-based").into()
|
||||
])
|
||||
)
|
||||
})
|
||||
.with_global_settings(|global_settings| match std::env::var("ZOMBIENET_SDK_BASE_DIR") {
|
||||
Ok(val) => global_settings.with_base_dir(val),
|
||||
_ => global_settings,
|
||||
})
|
||||
.build()
|
||||
.map_err(|e| {
|
||||
let errs = e.into_iter().map(|e| e.to_string()).collect::<Vec<_>>().join(" ");
|
||||
anyhow!("config errs: {errs}")
|
||||
})
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use anyhow::anyhow;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::utils::{initialize_network, BEST_BLOCK_METRIC};
|
||||
|
||||
use cumulus_zombienet_sdk_helpers::assign_cores;
|
||||
use serde_json::json;
|
||||
use zombienet_orchestrator::network::node::LogLineCountOptions;
|
||||
use zombienet_sdk::{NetworkConfig, NetworkConfigBuilder};
|
||||
|
||||
const PARA_ID_1: u32 = 2100;
|
||||
const PARA_ID_2: u32 = 2000;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn elastic_scaling_slot_based_authoring() -> Result<(), anyhow::Error> {
|
||||
let _ = env_logger::try_init_from_env(
|
||||
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
||||
);
|
||||
|
||||
log::info!("Spawning network");
|
||||
let config = build_network_config().await?;
|
||||
let network = initialize_network(config).await?;
|
||||
|
||||
let alice = network.get_node("alice")?;
|
||||
let collator_elastic = network.get_node("collator-elastic")?;
|
||||
let collator_single_core = network.get_node("collator-single-core")?;
|
||||
|
||||
log::info!("Checking if alice is up");
|
||||
assert!(alice.wait_until_is_up(60u64).await.is_ok());
|
||||
|
||||
log::info!("Checking if collator-elastic is up");
|
||||
assert!(collator_elastic.wait_until_is_up(60u64).await.is_ok());
|
||||
|
||||
log::info!("Checking if collator-single-core is up");
|
||||
assert!(collator_single_core.wait_until_is_up(60u64).await.is_ok());
|
||||
|
||||
assign_cores(alice, PARA_ID_1, vec![0, 1]).await?;
|
||||
|
||||
for (node, block_cnt) in [(collator_single_core, 20.0), (collator_elastic, 40.0)] {
|
||||
log::info!("Checking block production for {}", node.name());
|
||||
node.wait_metric_with_timeout(BEST_BLOCK_METRIC, |b| b >= block_cnt, 225u64)
|
||||
.await
|
||||
.unwrap_or_else(|e| {
|
||||
panic!("Failed to reach {block_cnt} blocks with node {}: {e}", node.name())
|
||||
});
|
||||
}
|
||||
|
||||
// We want to make sure that none of the consensus hook checks fail, even if the chain makes
|
||||
// progress. If below log line occurred 1 or more times then test failed.
|
||||
for node in [collator_elastic, collator_single_core] {
|
||||
log::info!("Ensuring none of the consensus hook checks fail at {}", node.name());
|
||||
let result = node
|
||||
.wait_log_line_count_with_timeout(
|
||||
"set_validation_data inherent needs to be present in every block",
|
||||
false,
|
||||
LogLineCountOptions::no_occurences_within_timeout(Duration::from_secs(10)),
|
||||
)
|
||||
.await?;
|
||||
assert!(result.success(), "Consensus hook failed at {}: {:?}", node.name(), result);
|
||||
}
|
||||
|
||||
log::info!("Test finished successfully");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn build_network_config() -> Result<NetworkConfig, anyhow::Error> {
|
||||
// images are not relevant for `native`, but we leave it here in case we use `k8s` some day
|
||||
let images = zombienet_sdk::environment::get_images_from_env();
|
||||
log::info!("Using images: {images:?}");
|
||||
|
||||
// Network setup:
|
||||
// - relaychain nodes:
|
||||
// - alice
|
||||
// - validator
|
||||
// - validator[0-4]
|
||||
// - validator
|
||||
// - synchronize only with alice
|
||||
// - teyrchain nodes
|
||||
// - recovery-target
|
||||
// - full node
|
||||
// - collator-elastic
|
||||
// - full node
|
||||
// - collator which is the only one producing blocks
|
||||
NetworkConfigBuilder::new()
|
||||
.with_relaychain(|r| {
|
||||
let r = r
|
||||
.with_chain("pezkuwichain-local")
|
||||
.with_default_command("pezkuwi")
|
||||
.with_default_image(images.polkadot.as_str())
|
||||
.with_genesis_overrides(json!({
|
||||
"configuration": {
|
||||
"config": {
|
||||
"scheduler_params": {
|
||||
"num_cores": 4,
|
||||
"max_validators_per_core": 1
|
||||
},
|
||||
"approval_voting_params": {
|
||||
"max_approval_coalesce_count": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
// Have to set a `with_node` outside of the loop below, so that `r` has the right
|
||||
// type.
|
||||
.with_node(|node| node.with_name("alice").with_args(vec![]));
|
||||
|
||||
(0..5).fold(r, |acc, i| {
|
||||
acc.with_node(|node| {
|
||||
node.with_name(&format!("validator-{i}")).with_args(vec![
|
||||
("-lruntime=debug,teyrchain=trace").into(),
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
.with_teyrchain(|p| {
|
||||
p.with_id(PARA_ID_1)
|
||||
.with_chain("elastic-scaling")
|
||||
.with_default_command("test-teyrchain")
|
||||
.with_default_image(images.pezcumulus.as_str())
|
||||
.with_collator(|n|
|
||||
n.with_name("collator-elastic")
|
||||
.with_args(vec![
|
||||
("-laura=trace,runtime=info,pezcumulus-consensus=trace,consensus::common=trace,teyrchain::collation-generation=trace,teyrchain::collator-protocol=trace,teyrchain=debug").into(),
|
||||
("--force-authoring").into(),
|
||||
("--authoring", "slot-based").into(),
|
||||
]))
|
||||
})
|
||||
.with_teyrchain(|p| {
|
||||
p.with_id(PARA_ID_2)
|
||||
.with_default_command("test-teyrchain")
|
||||
.with_default_image(images.pezcumulus.as_str())
|
||||
.with_collator(|n|
|
||||
n.with_name("collator-single-core")
|
||||
.with_args(vec![
|
||||
("-laura=trace,runtime=info,pezcumulus-consensus=trace,consensus::common=trace,teyrchain::collation-generation=trace,teyrchain::collator-protocol=trace,teyrchain=debug").into(),
|
||||
("--force-authoring").into(),
|
||||
("--authoring", "slot-based").into(),
|
||||
]))
|
||||
})
|
||||
.with_global_settings(|global_settings| match std::env::var("ZOMBIENET_SDK_BASE_DIR") {
|
||||
Ok(val) => global_settings.with_base_dir(val),
|
||||
_ => global_settings,
|
||||
})
|
||||
.build()
|
||||
.map_err(|e| {
|
||||
let errs = e.into_iter().map(|e| e.to_string()).collect::<Vec<_>>().join(" ");
|
||||
anyhow!("config errs: {errs}")
|
||||
})
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Test that teyrchains that use a single slot-based collator with elastic scaling MVP and with
|
||||
// elastic scaling with RFC103 can achieve full throughput of 3 candidates per block.
|
||||
|
||||
use anyhow::anyhow;
|
||||
use cumulus_zombienet_sdk_helpers::{assert_relay_parent_offset, assign_cores};
|
||||
use serde_json::json;
|
||||
use zombienet_sdk::{
|
||||
subxt::{OnlineClient, PolkadotConfig},
|
||||
NetworkConfigBuilder,
|
||||
};
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn elastic_scaling_slot_based_relay_parent_offset_test() -> Result<(), anyhow::Error> {
|
||||
let _ = env_logger::try_init_from_env(
|
||||
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
||||
);
|
||||
|
||||
// images are not relevant for `native`, but we leave it here in case we use `k8s` some day
|
||||
let images = zombienet_sdk::environment::get_images_from_env();
|
||||
|
||||
let config = NetworkConfigBuilder::new()
|
||||
.with_relaychain(|r| {
|
||||
let r = r
|
||||
.with_chain("pezkuwichain-local")
|
||||
.with_default_command("pezkuwi")
|
||||
.with_default_image(images.polkadot.as_str())
|
||||
.with_default_args(vec![("-lteyrchain=debug").into()])
|
||||
.with_genesis_overrides(json!({
|
||||
"configuration": {
|
||||
"config": {
|
||||
"scheduler_params": {
|
||||
// Num cores is 4, because 2 extra will be added automatically when registering the paras.
|
||||
"num_cores": 4,
|
||||
// "lookahead": 8,
|
||||
"max_validators_per_core": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
// Have to set a `with_node` outside of the loop below, so that `r` has the right
|
||||
// type.
|
||||
.with_node(|node| node.with_name("validator-0"));
|
||||
|
||||
(1..6).fold(r, |acc, i| acc.with_node(|node| node.with_name(&format!("validator-{i}"))))
|
||||
})
|
||||
.with_teyrchain(|p| {
|
||||
p.with_id(2400)
|
||||
.with_default_command("test-teyrchain")
|
||||
.with_default_image(images.pezcumulus.as_str())
|
||||
.with_chain("relay-parent-offset")
|
||||
.with_default_args(vec![
|
||||
"--authoring=slot-based".into(),
|
||||
("-lteyrchain=debug,aura=debug,teyrchain::collator-protocol=debug").into(),
|
||||
])
|
||||
.with_collator(|n| n.with_name("collator-rp-offset"))
|
||||
})
|
||||
.with_global_settings(|global_settings| match std::env::var("ZOMBIENET_SDK_BASE_DIR") {
|
||||
Ok(val) => global_settings.with_base_dir(val),
|
||||
_ => global_settings,
|
||||
})
|
||||
.build()
|
||||
.map_err(|e| {
|
||||
let errs = e.into_iter().map(|e| e.to_string()).collect::<Vec<_>>().join(" ");
|
||||
anyhow!("config errs: {errs}")
|
||||
})?;
|
||||
|
||||
let spawn_fn = zombienet_sdk::environment::get_spawn_fn();
|
||||
let network = spawn_fn(config).await?;
|
||||
|
||||
let relay_node = network.get_node("validator-0")?;
|
||||
let relay_client: OnlineClient<PolkadotConfig> = relay_node.wait_client().await?;
|
||||
|
||||
let para_node_rp_offset = network.get_node("collator-rp-offset")?;
|
||||
|
||||
let para_client = para_node_rp_offset.wait_client().await?;
|
||||
|
||||
assign_cores(relay_node, 2400, vec![0, 1]).await?;
|
||||
|
||||
assert_relay_parent_offset(&relay_client, ¶_client, 2, 45).await?;
|
||||
|
||||
log::info!("Test finished successfully");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use anyhow::anyhow;
|
||||
use serde_json::json;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::utils::initialize_network;
|
||||
|
||||
use cumulus_zombienet_sdk_helpers::{
|
||||
assert_para_throughput, assign_cores, runtime_upgrade, wait_for_upgrade,
|
||||
};
|
||||
use pezkuwi_primitives::Id as ParaId;
|
||||
use rstest::rstest;
|
||||
use zombienet_sdk::{
|
||||
subxt::{OnlineClient, PolkadotConfig},
|
||||
NetworkConfig, NetworkConfigBuilder,
|
||||
};
|
||||
|
||||
const PARA_ID: u32 = 2000;
|
||||
const WASM_WITH_ELASTIC_SCALING: &str =
|
||||
"/tmp/wasm_binary_elastic_scaling.rs.compact.compressed.wasm";
|
||||
|
||||
const WASM_WITH_ELASTIC_SCALING_12S_SLOT: &str =
|
||||
"/tmp/wasm_binary_elastic_scaling_12s_slot.rs.compact.compressed.wasm";
|
||||
|
||||
// This test ensures that we can upgrade the teyrchain's runtime to support elastic scaling
|
||||
// and that the teyrchain produces 3 blocks per slot after the upgrade.
|
||||
|
||||
// Covers both sync and async backing teyrchains.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
#[rstest]
|
||||
#[case(true)]
|
||||
#[case(false)]
|
||||
async fn elastic_scaling_upgrade_to_3_cores(
|
||||
#[case] async_backing: bool,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let _ = env_logger::try_init_from_env(
|
||||
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
||||
);
|
||||
|
||||
log::info!("Spawning network");
|
||||
let config = build_network_config(async_backing).await?;
|
||||
let network = initialize_network(config).await?;
|
||||
|
||||
let alice = network.get_node("validator0")?;
|
||||
let alice_client: OnlineClient<PolkadotConfig> = alice.wait_client().await?;
|
||||
|
||||
assign_cores(alice, PARA_ID, vec![0]).await?;
|
||||
|
||||
if async_backing {
|
||||
log::info!("Ensuring teyrchain makes progress making 6s blocks");
|
||||
assert_para_throughput(
|
||||
&alice_client,
|
||||
20,
|
||||
[(ParaId::from(PARA_ID), 15..21)].into_iter().collect(),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
log::info!("Ensuring teyrchain makes progress making 12s blocks");
|
||||
assert_para_throughput(
|
||||
&alice_client,
|
||||
20,
|
||||
[(ParaId::from(PARA_ID), 7..12)].into_iter().collect(),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
assign_cores(alice, PARA_ID, vec![1, 2]).await?;
|
||||
let timeout_secs: u64 = 250;
|
||||
let collator0 = network.get_node("collator0")?;
|
||||
let collator0_client: OnlineClient<PolkadotConfig> = collator0.wait_client().await?;
|
||||
|
||||
let current_spec_version =
|
||||
collator0_client.backend().current_runtime_version().await?.spec_version;
|
||||
log::info!("Current runtime spec version {current_spec_version}");
|
||||
|
||||
let wasm =
|
||||
if async_backing { WASM_WITH_ELASTIC_SCALING } else { WASM_WITH_ELASTIC_SCALING_12S_SLOT };
|
||||
|
||||
runtime_upgrade(&network, collator0, PARA_ID, wasm).await?;
|
||||
|
||||
let collator1 = network.get_node("collator1")?;
|
||||
let collator1_client: OnlineClient<PolkadotConfig> = collator1.wait_client().await?;
|
||||
let expected_spec_version = current_spec_version + 1;
|
||||
|
||||
log::info!(
|
||||
"Waiting (up to {timeout_secs}s) for teyrchain runtime upgrade to version {}",
|
||||
expected_spec_version
|
||||
);
|
||||
tokio::time::timeout(
|
||||
Duration::from_secs(timeout_secs),
|
||||
wait_for_upgrade(collator1_client, expected_spec_version),
|
||||
)
|
||||
.await
|
||||
.expect("Timeout waiting for runtime upgrade")?;
|
||||
|
||||
let spec_version_from_collator0 =
|
||||
collator0_client.backend().current_runtime_version().await?.spec_version;
|
||||
assert_eq!(
|
||||
expected_spec_version, spec_version_from_collator0,
|
||||
"Unexpected runtime spec version"
|
||||
);
|
||||
|
||||
log::info!("Ensure elastic scaling works, 3 blocks should be produced in each 6s slot");
|
||||
assert_para_throughput(
|
||||
&alice_client,
|
||||
20,
|
||||
[(ParaId::from(PARA_ID), 50..61)].into_iter().collect(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn build_network_config(async_backing: bool) -> Result<NetworkConfig, anyhow::Error> {
|
||||
// images are not relevant for `native`, but we leave it here in case we use `k8s` some day
|
||||
let images = zombienet_sdk::environment::get_images_from_env();
|
||||
log::info!("Using images: {images:?}");
|
||||
|
||||
let chain = if async_backing { "async-backing" } else { "sync-backing" };
|
||||
|
||||
// Network setup:
|
||||
// - relaychain nodes:
|
||||
// - alice - validator
|
||||
// - validator1 - validator
|
||||
// - validator2 - validator
|
||||
// - teyrchain nodes
|
||||
// - collator0 - validator
|
||||
// - collator1 - validator
|
||||
// - collator2 - validator
|
||||
let config = NetworkConfigBuilder::new()
|
||||
.with_relaychain(|r| {
|
||||
r.with_chain("pezkuwichain-local")
|
||||
.with_genesis_overrides(json!({
|
||||
"configuration": {
|
||||
"config": {
|
||||
"scheduler_params": {
|
||||
"num_cores": 3,
|
||||
"max_validators_per_core": 1
|
||||
},
|
||||
}
|
||||
}
|
||||
}))
|
||||
.with_default_command("pezkuwi")
|
||||
.with_default_image(images.polkadot.as_str())
|
||||
.with_default_args(vec![("-lteyrchain=debug").into()])
|
||||
.with_node(|node| node.with_name("validator0"))
|
||||
.with_node(|node| node.with_name("validator1"))
|
||||
.with_node(|node| node.with_name("validator2"))
|
||||
})
|
||||
.with_teyrchain(|p| {
|
||||
p.with_id(PARA_ID)
|
||||
.with_default_command("test-teyrchain")
|
||||
.onboard_as_teyrchain(false)
|
||||
.with_chain(chain)
|
||||
.with_default_image(images.pezcumulus.as_str())
|
||||
.with_collator(|n| {
|
||||
n.with_name("collator0").validator(true).with_args(vec![
|
||||
"--authoring=slot-based".into(),
|
||||
("-lteyrchain=debug,aura=debug").into(),
|
||||
])
|
||||
})
|
||||
.with_collator(|n| {
|
||||
n.with_name("collator1").validator(true).with_args(vec![
|
||||
"--authoring=slot-based".into(),
|
||||
("-lteyrchain=debug,aura=debug").into(),
|
||||
])
|
||||
})
|
||||
.with_collator(|n| {
|
||||
n.with_name("collator2").validator(true).with_args(vec![
|
||||
"--authoring=slot-based".into(),
|
||||
("-lteyrchain=debug,aura=debug").into(),
|
||||
])
|
||||
})
|
||||
})
|
||||
.with_global_settings(|global_settings| match std::env::var("ZOMBIENET_SDK_BASE_DIR") {
|
||||
Ok(val) => global_settings.with_base_dir(val),
|
||||
_ => global_settings,
|
||||
})
|
||||
.build()
|
||||
.map_err(|e| {
|
||||
let errs = e.into_iter().map(|e| e.to_string()).collect::<Vec<_>>().join(" ");
|
||||
anyhow!("config errs: {errs}")
|
||||
})?;
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
Reference in New Issue
Block a user