From 4fdab499c487c7762425dd7e4e888e7ba71a4990 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bastian=20K=C3=B6cher?= <git@kchr.de>
Date: Mon, 8 Jan 2024 18:41:02 +0000
Subject: [PATCH] Coretime Zombienet test (#2867)

This adds a Zombienet test for Coretime.

Requires: https://github.com/paritytech/polkadot-sdk/pull/2862

---------

Co-authored-by: Javier Viola <javier@parity.io>
Co-authored-by: Javier Viola <363911+pepoviola@users.noreply.github.com>
---
 .gitlab/pipeline/zombienet/polkadot.yml       |  8 +++++
 .../coretime/coretime-rococo/Cargo.toml       |  2 ++
 .../coretime/coretime-rococo/build.rs         | 10 +++++-
 .../coretime/coretime-rococo/src/coretime.rs  | 15 ++++++--
 .../coretime/coretime-rococo/src/lib.rs       |  8 +++++
 .../src/chain_spec/coretime.rs                | 34 ++++++++++++-------
 .../runtime/parachains/src/coretime/mod.rs    | 15 +++++---
 .../smoke/0004-configure-broker.js            | 33 +++++++++---------
 .../smoke/0004-configure-relay.js             | 23 +++++++++++--
 .../smoke/0004-coretime-smoke-test.toml       | 33 +++++-------------
 .../smoke/0004-coretime-smoke-test.zndsl      |  8 ++---
 11 files changed, 118 insertions(+), 71 deletions(-)

diff --git a/.gitlab/pipeline/zombienet/polkadot.yml b/.gitlab/pipeline/zombienet/polkadot.yml
index 6b89648c4e3..c246d98a048 100644
--- a/.gitlab/pipeline/zombienet/polkadot.yml
+++ b/.gitlab/pipeline/zombienet/polkadot.yml
@@ -185,6 +185,14 @@ zombienet-polkadot-smoke-0003-deregister-register-validator:
       --local-dir="${LOCAL_DIR}/smoke"
       --test="0003-deregister-register-validator-smoke.zndsl"
 
+zombienet-polkadot-smoke-0004-coretime-smoke-test:
+  extends:
+    - .zombienet-polkadot-common
+  script:
+    - /home/nonroot/zombie-net/scripts/ci/run-test-local-env-manager.sh
+      --local-dir="${LOCAL_DIR}/smoke"
+      --test="0004-coretime-smoke-test.zndsl"
+
 zombienet-polkadot-misc-0001-parachains-paritydb:
   extends:
     - .zombienet-polkadot-common
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml
index 0af44045da4..c4544f525a2 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml
@@ -194,3 +194,5 @@ try-runtime = [
 ]
 
 experimental = ["pallet-aura/experimental"]
+
+fast-runtime = []
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/build.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/build.rs
index 60f8a125129..28dacd20cf3 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/build.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/build.rs
@@ -19,7 +19,15 @@ fn main() {
 		.with_current_project()
 		.export_heap_base()
 		.import_memory()
-		.build()
+		.build();
+
+	substrate_wasm_builder::WasmBuilder::new()
+		.with_current_project()
+		.set_file_name("fast_runtime_binary.rs")
+		.enable_feature("fast-runtime")
+		.import_memory()
+		.export_heap_base()
+		.build();
 }
 
 #[cfg(not(feature = "std"))]
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs
index a85d67f7b4c..f8a5dc6398a 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs
@@ -17,6 +17,7 @@
 use crate::*;
 use codec::{Decode, Encode};
 use cumulus_pallet_parachain_system::RelaychainDataProvider;
+use cumulus_primitives_core::relay_chain;
 use frame_support::{
 	parameter_types,
 	traits::{
@@ -51,11 +52,16 @@ enum CoretimeProviderCalls {
 	#[codec(index = 1)]
 	RequestCoreCount(CoreIndex),
 	#[codec(index = 2)]
-	RequestRevenueInfoAt(BlockNumber),
+	RequestRevenueInfoAt(relay_chain::BlockNumber),
 	#[codec(index = 3)]
 	CreditAccount(AccountId, Balance),
 	#[codec(index = 4)]
-	AssignCore(CoreIndex, BlockNumber, Vec<(CoreAssignment, PartsOf57600)>, Option<BlockNumber>),
+	AssignCore(
+		CoreIndex,
+		relay_chain::BlockNumber,
+		Vec<(CoreAssignment, PartsOf57600)>,
+		Option<relay_chain::BlockNumber>,
+	),
 }
 
 parameter_types! {
@@ -181,7 +187,7 @@ impl CoretimeInterface for CoretimeAllocator {
 			},
 			Instruction::Transact {
 				origin_kind: OriginKind::Native,
-				require_weight_at_most: Weight::from_parts(1000000000, 200000),
+				require_weight_at_most: Weight::from_parts(1_000_000_000, 200000),
 				call: assign_core_call.encode().into(),
 			},
 		]);
@@ -215,6 +221,9 @@ impl pallet_broker::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type Currency = Balances;
 	type OnRevenue = CreditToCollatorPot;
+	#[cfg(feature = "fast-runtime")]
+	type TimeslicePeriod = ConstU32<10>;
+	#[cfg(not(feature = "fast-runtime"))]
 	type TimeslicePeriod = ConstU32<80>;
 	type MaxLeasedCores = ConstU32<50>;
 	type MaxReservedCores = ConstU32<10>;
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
index 95709117578..0f01c2d7416 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
@@ -21,6 +21,14 @@
 #[cfg(feature = "std")]
 include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
 
+/// Provides the `WASM_BINARY` build with `fast-runtime` feature enabled.
+///
+/// This is for example useful for local test chains.
+#[cfg(feature = "std")]
+pub mod fast_runtime_binary {
+	include!(concat!(env!("OUT_DIR"), "/fast_runtime_binary.rs"));
+}
+
 mod coretime;
 mod weights;
 pub mod xcm_config;
diff --git a/cumulus/polkadot-parachain/src/chain_spec/coretime.rs b/cumulus/polkadot-parachain/src/chain_spec/coretime.rs
index 958336c03b5..fbce4e5bc21 100644
--- a/cumulus/polkadot-parachain/src/chain_spec/coretime.rs
+++ b/cumulus/polkadot-parachain/src/chain_spec/coretime.rs
@@ -20,7 +20,7 @@ use sc_chain_spec::{ChainSpec, ChainType};
 use std::{borrow::Cow, str::FromStr};
 
 /// Collects all supported Coretime configurations.
-#[derive(Debug, PartialEq, Clone)]
+#[derive(Debug, PartialEq, Clone, Copy)]
 pub enum CoretimeRuntimeType {
 	// Live
 	Rococo,
@@ -85,13 +85,13 @@ impl CoretimeRuntimeType {
 				&include_bytes!("../../../parachains/chain-specs/coretime-rococo.json")[..],
 			)?)),
 			CoretimeRuntimeType::RococoLocal =>
-				Ok(Box::new(rococo::local_config(self, "rococo-local"))),
+				Ok(Box::new(rococo::local_config(*self, "rococo-local"))),
 			CoretimeRuntimeType::RococoDevelopment =>
-				Ok(Box::new(rococo::local_config(self, "rococo-dev"))),
+				Ok(Box::new(rococo::local_config(*self, "rococo-dev"))),
 			CoretimeRuntimeType::WestendLocal =>
-				Ok(Box::new(westend::local_config(self, "westend-local"))),
+				Ok(Box::new(westend::local_config(*self, "westend-local"))),
 			CoretimeRuntimeType::WestendDevelopment =>
-				Ok(Box::new(westend::local_config(self, "westend-dev"))),
+				Ok(Box::new(westend::local_config(*self, "westend-dev"))),
 		}
 	}
 }
@@ -114,6 +114,7 @@ pub mod rococo {
 		get_account_id_from_seed, get_collator_keys_from_seed, Extensions, SAFE_XCM_VERSION,
 	};
 	use parachains_common::{AccountId, AuraId, Balance};
+	use sc_chain_spec::ChainType;
 	use sp_core::sr25519;
 
 	pub(crate) const CORETIME_ROCOCO: &str = "coretime-rococo";
@@ -121,24 +122,31 @@ pub mod rococo {
 	pub(crate) const CORETIME_ROCOCO_DEVELOPMENT: &str = "coretime-rococo-dev";
 	const CORETIME_ROCOCO_ED: Balance = parachains_common::rococo::currency::EXISTENTIAL_DEPOSIT;
 
-	pub fn local_config(runtime_type: &CoretimeRuntimeType, relay_chain: &str) -> GenericChainSpec {
+	pub fn local_config(runtime_type: CoretimeRuntimeType, relay_chain: &str) -> GenericChainSpec {
 		// Rococo defaults
 		let mut properties = sc_chain_spec::Properties::new();
 		properties.insert("ss58Format".into(), 42.into());
 		properties.insert("tokenSymbol".into(), "ROC".into());
 		properties.insert("tokenDecimals".into(), 12.into());
 
-		let chain_type = runtime_type.clone().into();
+		let chain_type = runtime_type.into();
 		let chain_name = format!("Coretime Rococo {}", chain_type_name(&chain_type));
 		let para_id = super::CORETIME_PARA_ID;
 
-		GenericChainSpec::builder(
+		let wasm_binary = if matches!(chain_type, ChainType::Local | ChainType::Development) {
+			coretime_rococo_runtime::fast_runtime_binary::WASM_BINARY
+				.expect("WASM binary was not built, please build it!")
+		} else {
 			coretime_rococo_runtime::WASM_BINARY
-				.expect("WASM binary was not built, please build it!"),
+				.expect("WASM binary was not built, please build it!")
+		};
+
+		GenericChainSpec::builder(
+			wasm_binary,
 			Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() },
 		)
 		.with_name(&chain_name)
-		.with_id(runtime_type.clone().into())
+		.with_id(runtime_type.into())
 		.with_chain_type(chain_type)
 		.with_genesis_config_patch(genesis(
 			// initial collators.
@@ -209,14 +217,14 @@ pub mod westend {
 	pub(crate) const CORETIME_WESTEND_DEVELOPMENT: &str = "coretime-westend-dev";
 	const CORETIME_WESTEND_ED: Balance = parachains_common::westend::currency::EXISTENTIAL_DEPOSIT;
 
-	pub fn local_config(runtime_type: &CoretimeRuntimeType, relay_chain: &str) -> GenericChainSpec {
+	pub fn local_config(runtime_type: CoretimeRuntimeType, relay_chain: &str) -> GenericChainSpec {
 		// westend defaults
 		let mut properties = sc_chain_spec::Properties::new();
 		properties.insert("ss58Format".into(), 42.into());
 		properties.insert("tokenSymbol".into(), "WND".into());
 		properties.insert("tokenDecimals".into(), 12.into());
 
-		let chain_type = runtime_type.clone().into();
+		let chain_type = runtime_type.into();
 		let chain_name = format!("Coretime Westend {}", chain_type_name(&chain_type));
 		let para_id = super::CORETIME_PARA_ID;
 
@@ -226,7 +234,7 @@ pub mod westend {
 			Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() },
 		)
 		.with_name(&chain_name)
-		.with_id(runtime_type.clone().into())
+		.with_id(runtime_type.into())
 		.with_chain_type(chain_type)
 		.with_genesis_config_patch(genesis(
 			// initial collators.
diff --git a/polkadot/runtime/parachains/src/coretime/mod.rs b/polkadot/runtime/parachains/src/coretime/mod.rs
index 8da6ccf07ca..60bd8f81193 100644
--- a/polkadot/runtime/parachains/src/coretime/mod.rs
+++ b/polkadot/runtime/parachains/src/coretime/mod.rs
@@ -27,7 +27,8 @@ use pallet_broker::{CoreAssignment, CoreIndex as BrokerCoreIndex};
 use primitives::{CoreIndex, Id as ParaId};
 use sp_arithmetic::traits::SaturatedConversion;
 use xcm::v3::{
-	send_xcm, Instruction, Junction, Junctions, MultiLocation, OriginKind, SendXcm, Xcm,
+	send_xcm, Instruction, Junction, Junctions, MultiLocation, OriginKind, SendXcm, WeightLimit,
+	Xcm,
 };
 
 use crate::{
@@ -220,9 +221,13 @@ impl<T: Config> Pallet<T> {
 		let new_core_count = notification.new_config.coretime_cores;
 		if new_core_count != old_core_count {
 			let core_count: u16 = new_core_count.saturated_into();
-			let message = Xcm(vec![mk_coretime_call(
-				crate::coretime::CoretimeCalls::NotifyCoreCount(core_count),
-			)]);
+			let message = Xcm(vec![
+				Instruction::UnpaidExecution {
+					weight_limit: WeightLimit::Unlimited,
+					check_origin: None,
+				},
+				mk_coretime_call(crate::coretime::CoretimeCalls::NotifyCoreCount(core_count)),
+			]);
 			if let Err(err) = send_xcm::<T::SendXcm>(
 				MultiLocation {
 					parents: 0,
@@ -247,7 +252,7 @@ fn mk_coretime_call(call: crate::coretime::CoretimeCalls) -> Instruction<()> {
 		origin_kind: OriginKind::Superuser,
 		// Largest call is set_lease with 1526 byte:
 		// Longest call is reserve() with 31_000_000
-		require_weight_at_most: Weight::from_parts(100_000_000, 20_000),
+		require_weight_at_most: Weight::from_parts(110_000_000, 20_000),
 		call: BrokerRuntimePallets::Broker(call).encode().into(),
 	}
 }
diff --git a/polkadot/zombienet_tests/smoke/0004-configure-broker.js b/polkadot/zombienet_tests/smoke/0004-configure-broker.js
index a4939ffe1cb..889861f5c52 100644
--- a/polkadot/zombienet_tests/smoke/0004-configure-broker.js
+++ b/polkadot/zombienet_tests/smoke/0004-configure-broker.js
@@ -13,29 +13,30 @@ async function run(nodeName, networkInfo, _jsArgs) {
   const calls = [
     // Default broker configuration
     api.tx.broker.configure({
-      advanceNotice: 2,
+      advanceNotice: 5,
       interludeLength: 1,
       leadinLength: 1,
-      regionLength: 3,
+      regionLength: 1,
       idealBulkProportion: 100,
       limitCoresOffered: null,
       renewalBump: 10,
       contributionTimeout: 5,
     }),
-    // Make reservation for ParaId 100 (adder-a) every other block
-    // and ParaId 101 (adder-b) every other block.
-    api.tx.broker.reserve([
-      {
-        mask: [255, 0, 255, 0, 255, 0, 255, 0, 255, 0],
-        assignment: { Task: 100 },
-      },
-      {
-        mask: [0, 255, 0, 255, 0, 255, 0, 255, 0, 255],
-        assignment: { Task: 101 },
-      },
-    ]),
-    // Start sale with 1 core starting at 1 planck
-    api.tx.broker.startSales(1, 1),
+    // We need MOARE cores.
+    api.tx.broker.requestCoreCount(2),
+    // Set a lease for the broker chain itself.
+    api.tx.broker.setLease(
+      1005,
+      1000,
+    ),
+    // Set a lease for parachain 100
+    api.tx.broker.setLease(
+      100,
+      1000,
+    ),
+    // Start sale to make the broker "work", but we don't offer any cores
+    // as we have fixed leases only anyway.
+    api.tx.broker.startSales(1, 0),
   ];
   const sudo_batch = api.tx.sudo.sudo(api.tx.utility.batch(calls));
 
diff --git a/polkadot/zombienet_tests/smoke/0004-configure-relay.js b/polkadot/zombienet_tests/smoke/0004-configure-relay.js
index 9ca23d86a56..724d1b537a3 100644
--- a/polkadot/zombienet_tests/smoke/0004-configure-relay.js
+++ b/polkadot/zombienet_tests/smoke/0004-configure-relay.js
@@ -1,18 +1,37 @@
 const assert = require("assert");
 
 async function run(nodeName, networkInfo, _jsArgs) {
-  const { wsUri, userDefinedTypes } = networkInfo.nodesByName[nodeName];
+  const init = networkInfo.nodesByName[nodeName];
+  let wsUri = init.wsUri;
+  let userDefinedTypes = init.userDefinedTypes;
   const api = await zombie.connect(wsUri, userDefinedTypes);
 
+  const sec = networkInfo.nodesByName["collator-para-100"];
+  wsUri = sec.wsUri;
+  userDefinedTypes = sec.userDefinedTypes;
+
+  const api_collator = await zombie.connect(wsUri, userDefinedTypes);
+
   await zombie.util.cryptoWaitReady();
 
+  // Get the genesis header and the validation code of parachain 100
+  const genesis_header = await api_collator.rpc.chain.getHeader();
+  const validation_code = await api_collator.rpc.state.getStorage("0x3A636F6465");
+
   // account to submit tx
   const keyring = new zombie.Keyring({ type: "sr25519" });
   const alice = keyring.addFromUri("//Alice");
 
   const calls = [
     api.tx.configuration.setCoretimeCores({ new: 1 }),
-    api.tx.coretime.assignCore(0, 20,[[ { task: 1005 }, 57600 ]], null)
+    api.tx.coretime.assignCore(0, 20,[[ { task: 1005 }, 57600 ]], null),
+    api.tx.registrar.forceRegister(
+      alice.address,
+      0,
+      100,
+      genesis_header.toHex(),
+      validation_code.toHex(),
+    )
   ];
   const sudo_batch = api.tx.sudo.sudo(api.tx.utility.batch(calls));
 
diff --git a/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.toml b/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.toml
index 3bcd0bee3c7..0bdb58fa1ef 100644
--- a/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.toml
+++ b/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.toml
@@ -8,7 +8,7 @@ command = "polkadot"
 
   [[relaychain.nodes]]
   name = "alice"
-  args = ["-lruntime=debug,parachain=trace" ]
+  args = ["-lruntime=debug,xcm=trace" ]
 
   [[relaychain.nodes]]
   name = "bob"
@@ -24,35 +24,18 @@ chain = "coretime-rococo-local"
 
   [parachains.collator]
   name = "coretime-collator"
-  image = "{{COL_IMAGE}}"
+  image = "{{CUMULUS_IMAGE}}"
   command = "polkadot-parachain"
-  args = [ "-lruntime=debug,parachain=trace" ]
+  args = [ "-lruntime=debug,xcm=trace" ]
 
 [[parachains]]
 id = 100
 add_to_genesis = false
-register_para = true
-onboard_as_parachain = false
-
-  [parachains.collator]
-  name = "adder-a"
-  image = "{{COL_IMAGE}}"
-  command = "adder-collator"
-  args = [ "-lruntime=debug,parachain=trace" ]
-
-[[parachains]]
-id = 101
-add_to_genesis = false
-register_para = true
+register_para = false
 onboard_as_parachain = false
 
   [parachains.collator]
-  name = "adder-b"
-  image = "{{COL_IMAGE}}"
-  command = "adder-collator"
-  args = [ "-lruntime=debug,parachain=trace" ]
-
-[types.Header]
-number = "u64"
-parent_hash = "Hash"
-post_state = "Hash"
+  name = "collator-para-100"
+  image = "{{CUMULUS_IMAGE}}"
+  command = "polkadot-parachain"
+  args = ["-lruntime=debug,parachain=trace,aura=trace", "--force-authoring"]
diff --git a/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.zndsl b/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.zndsl
index 45e000e0bf8..cfb1ce7d982 100644
--- a/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.zndsl
+++ b/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.zndsl
@@ -5,15 +5,11 @@ Creds: config
 alice: is up
 coretime-collator: is up
 
-alice: reports block height is at least 3 within 30 seconds
 # configure relay chain
 alice: js-script ./0004-configure-relay.js with "" return is 0 within 600 secs
 
-# Wait 2 sessions. The parachain doesn't start block production immediately.
-alice: log line contains "New session detected session_index=2" within 600 seconds
-
 # configure broker chain
 coretime-collator: js-script ./0004-configure-broker.js with "" return is 0 within 600 secs
 
-# TODO: Fix this
-# alice: parachain 100 block height is at least 10 within 600 seconds
+# Ensure that parachain 100 got onboarded
+alice: parachain 100 block height is at least 5 within 900 seconds
-- 
GitLab