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

cumulus: bump PARENT_SEARCH_DEPTH and add test for 12-core elastic scaling #6983

Open
wants to merge 6 commits into
base: alindima/zombienet-sdk-rewrite
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions .gitlab/pipeline/zombienet/polkadot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,22 @@ zombienet-polkadot-elastic-scaling-slot-based-3cores:
- unset NEXTEST_SUCCESS_OUTPUT
- cargo nextest run --archive-file ./artifacts/polkadot-zombienet-tests.tar.zst --no-capture -- elastic_scaling::slot_based_3cores::slot_based_3cores_test

zombienet-polkadot-elastic-scaling-slot-based-12cores:
extends:
- .zombienet-polkadot-common
needs:
- job: build-polkadot-zombienet-tests
artifacts: true
before_script:
- !reference [ ".zombienet-polkadot-common", "before_script" ]
- export POLKADOT_IMAGE="${ZOMBIENET_INTEGRATION_TEST_IMAGE}"
- export CUMULUS_IMAGE="docker.io/paritypr/test-parachain:${PIPELINE_IMAGE_TAG}"
script:
# we want to use `--no-capture` in zombienet tests.
- unset NEXTEST_FAILURE_OUTPUT
- unset NEXTEST_SUCCESS_OUTPUT
- cargo nextest run --archive-file ./artifacts/polkadot-zombienet-tests.tar.zst --no-capture -- elastic_scaling::slot_based_12cores::slot_based_12cores_test

zombienet-polkadot-elastic-scaling-doesnt-break-parachains:
extends:
- .zombienet-polkadot-common
Expand Down
7 changes: 4 additions & 3 deletions cumulus/client/consensus/aura/src/collators/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ pub mod lookahead;
pub mod slot_based;

// This is an arbitrary value which is likely guaranteed to exceed any reasonable
// limit, as it would correspond to 10 non-included blocks.
// limit, as it would correspond to 30 non-included blocks.
//
// Since we only search for parent blocks which have already been imported,
// we can guarantee that all imported blocks respect the unincluded segment
// rules specified by the parachain's runtime and thus will never be too deep.
const PARENT_SEARCH_DEPTH: usize = 10;
// rules specified by the parachain's runtime and thus will never be too deep. This is just an extra
// sanity check.
const PARENT_SEARCH_DEPTH: usize = 30;

/// Check the `local_validation_code_hash` against the validation code hash in the relay chain
/// state.
Expand Down
1 change: 1 addition & 0 deletions cumulus/test/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,5 @@ std = [
]
increment-spec-version = []
elastic-scaling = []
elastic-scaling-500ms = []
experimental-ump-signals = ["cumulus-pallet-parachain-system/experimental-ump-signals"]
8 changes: 8 additions & 0 deletions cumulus/test/runtime/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ fn main() {
.import_memory()
.set_file_name("wasm_binary_elastic_scaling.rs")
.build();

WasmBuilder::new()
.with_current_project()
.enable_feature("elastic-scaling-500ms")
.enable_feature("experimental-ump-signals")
.import_memory()
.set_file_name("wasm_binary_elastic_scaling_500ms.rs")
.build();
}

#[cfg(not(feature = "std"))]
Expand Down
26 changes: 18 additions & 8 deletions cumulus/test/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ pub mod wasm_spec_version_incremented {
include!(concat!(env!("OUT_DIR"), "/wasm_binary_spec_version_incremented.rs"));
}

pub mod elastic_scaling_500ms {
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary_elastic_scaling_500ms.rs"));
}
pub mod elastic_scaling_mvp {
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary_elastic_scaling_mvp.rs"));
Expand Down Expand Up @@ -98,21 +102,27 @@ impl_opaque_keys! {
/// The para-id used in this runtime.
pub const PARACHAIN_ID: u32 = 100;

#[cfg(not(feature = "elastic-scaling"))]
#[cfg(not(any(feature = "elastic-scaling", feature = "elastic-scaling-500ms")))]
const UNINCLUDED_SEGMENT_CAPACITY: u32 = 4;
#[cfg(not(feature = "elastic-scaling"))]
#[cfg(not(any(feature = "elastic-scaling", feature = "elastic-scaling-500ms")))]
const BLOCK_PROCESSING_VELOCITY: u32 = 1;
#[cfg(not(any(feature = "elastic-scaling", feature = "elastic-scaling-500ms")))]
pub const MILLISECS_PER_BLOCK: u64 = 6000;

#[cfg(feature = "elastic-scaling")]
#[cfg(all(feature = "elastic-scaling", not(feature = "elastic-scaling-500ms")))]
const UNINCLUDED_SEGMENT_CAPACITY: u32 = 7;
#[cfg(feature = "elastic-scaling")]
#[cfg(all(feature = "elastic-scaling", not(feature = "elastic-scaling-500ms")))]
const BLOCK_PROCESSING_VELOCITY: u32 = 4;

#[cfg(not(feature = "elastic-scaling"))]
pub const MILLISECS_PER_BLOCK: u64 = 6000;
#[cfg(feature = "elastic-scaling")]
#[cfg(all(feature = "elastic-scaling", not(feature = "elastic-scaling-500ms")))]
pub const MILLISECS_PER_BLOCK: u64 = 2000;

#[cfg(feature = "elastic-scaling-500ms")]
const UNINCLUDED_SEGMENT_CAPACITY: u32 = 30;
#[cfg(feature = "elastic-scaling-500ms")]
const BLOCK_PROCESSING_VELOCITY: u32 = 12;
#[cfg(feature = "elastic-scaling-500ms")]
pub const MILLISECS_PER_BLOCK: u64 = 500;

pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;

const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
Expand Down
10 changes: 10 additions & 0 deletions cumulus/test/service/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,16 @@ pub fn get_elastic_scaling_chain_spec(id: Option<ParaId>) -> ChainSpec {
)
}

/// Get the chain spec for a specific parachain ID.
pub fn get_elastic_scaling_500ms_chain_spec(id: Option<ParaId>) -> ChainSpec {
get_chain_spec_with_extra_endowed(
id,
Default::default(),
cumulus_test_runtime::elastic_scaling_500ms::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
)
}

/// Get the chain spec for a specific parachain ID.
pub fn get_elastic_scaling_mvp_chain_spec(id: Option<ParaId>) -> ChainSpec {
get_chain_spec_with_extra_endowed(
Expand Down
6 changes: 6 additions & 0 deletions cumulus/test/service/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,12 @@ impl SubstrateCli for TestCollatorCli {
2200,
)))) as Box<_>
},
"elastic-scaling-500ms" => {
tracing::info!("Using elastic-scaling 500ms chain spec.");
Box::new(cumulus_test_service::get_elastic_scaling_500ms_chain_spec(Some(
ParaId::from(2300),
))) as Box<_>
},
path => {
let chain_spec =
cumulus_test_service::chain_spec::ChainSpec::from_json_file(path.into())?;
Expand Down
1 change: 1 addition & 0 deletions polkadot/zombienet-sdk-tests/tests/elastic_scaling/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@

mod basic_3cores;
mod doesnt_break_parachains;
mod slot_based_12cores;
mod slot_based_3cores;
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Test that a parachain that uses a single slot-based collator with elastic scaling can use 12
// cores in order to achieve 500ms blocks.

use anyhow::anyhow;

use crate::helpers::{
assert_finalized_block_height, assert_para_throughput, rococo,
rococo::runtime_types::{
pallet_broker::coretime_interface::CoreAssignment,
polkadot_runtime_parachains::assigner_coretime::PartsOf57600,
},
};
use polkadot_primitives::Id as ParaId;
use serde_json::json;
use subxt::{OnlineClient, PolkadotConfig};
use subxt_signer::sr25519::dev;
use zombienet_sdk::NetworkConfigBuilder;

#[tokio::test(flavor = "multi_thread")]
async fn slot_based_12cores_test() -> Result<(), anyhow::Error> {
let _ = env_logger::try_init_from_env(
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
);

let images = zombienet_sdk::environment::get_images_from_env();

let config = NetworkConfigBuilder::new()
.with_relaychain(|r| {
let r = r
.with_chain("rococo-local")
.with_default_command("polkadot")
.with_default_image(images.polkadot.as_str())
.with_default_args(vec![("-lparachain=debug").into()])
.with_genesis_overrides(json!({
"configuration": {
"config": {
"scheduler_params": {
"num_cores": 11,
"max_validators_per_core": 1
},
"async_backing_params": {
"max_candidate_depth": 24,
"allowed_ancestry_len": 2
}
}
}
}))
// 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..12)
.fold(r, |acc, i| acc.with_node(|node| node.with_name(&format!("validator-{i}"))))
})
.with_parachain(|p| {
p.with_id(2300)
.with_default_command("test-parachain")
.with_default_image(images.cumulus.as_str())
.with_chain("elastic-scaling-500ms")
.with_default_args(vec![
("--experimental-use-slot-based").into(),
("-lparachain=debug,aura=debug").into(),
])
.with_collator(|n| n.with_name("collator-elastic"))
})
.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 para_node = network.get_node("collator-elastic")?;

let relay_client: OnlineClient<PolkadotConfig> = relay_node.wait_client().await?;
let alice = dev::alice();

// Assign 11 extra cores to the parachain.

relay_client
.tx()
.sign_and_submit_then_watch_default(
&rococo::tx()
.sudo()
.sudo(rococo::runtime_types::rococo_runtime::RuntimeCall::Utility(
rococo::runtime_types::pallet_utility::pallet::Call::batch {
calls: (0..11).map(|idx| rococo::runtime_types::rococo_runtime::RuntimeCall::Coretime(
rococo::runtime_types::polkadot_runtime_parachains::coretime::pallet::Call::assign_core {
core: idx,
begin: 0,
assignment: vec![(CoreAssignment::Task(2300), PartsOf57600(57600))],
end_hint: None
}
)).collect()
},
)),
&alice,
)
.await?
.wait_for_finalized_success()
.await?;

log::info!("11 more cores assigned to the parachain");

// Expect a backed candidate count of at least 170 in 15 relay chain blocks
// (11.33 candidates per para per relay chain block).
// Note that only blocks after the first session change and blocks that don't contain a session
// change will be counted.
assert_para_throughput(
&relay_client,
15,
[(ParaId::from(2300), 170..181)].into_iter().collect(),
)
.await?;

// Assert the parachain finalized block height is also on par with the number of backed
// candidates.
assert_finalized_block_height(&para_node.wait_client().await?, 158..181).await?;

log::info!("Test finished successfully");

Ok(())
}
Loading