From 16e46614468915707b4a4b3ea37d6c7e50e07311 Mon Sep 17 00:00:00 2001
From: Chris Sosnin <48099298+slumber@users.noreply.github.com>
Date: Tue, 28 Mar 2023 17:55:24 +0300
Subject: [PATCH] configuration: backport async backing parameters from the
 feature branch (#6961)

* Backport async backing params primitive

* migration follow-up

* link pr

* parameters -> params

* rustfmt::skip block ident
---
 polkadot/primitives/src/vstaging/mod.rs       | 23 ++++++++++++++++
 .../runtime/parachains/src/configuration.rs   | 27 ++++++++++++++++++-
 .../parachains/src/configuration/migration.rs | 10 ++++++-
 .../parachains/src/configuration/tests.rs     |  4 +++
 4 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs
index 64671bd48a6..9f5a99852e3 100644
--- a/polkadot/primitives/src/vstaging/mod.rs
+++ b/polkadot/primitives/src/vstaging/mod.rs
@@ -17,3 +17,26 @@
 //! Staging Primitives.
 
 // Put any primitives used by staging APIs functions here
+pub use crate::v4::*;
+use sp_std::prelude::*;
+
+use parity_scale_codec::{Decode, Encode};
+use primitives::RuntimeDebug;
+use scale_info::TypeInfo;
+
+/// Candidate's acceptance limitations for asynchronous backing per relay parent.
+#[derive(RuntimeDebug, Copy, Clone, PartialEq, Encode, Decode, TypeInfo)]
+#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
+pub struct AsyncBackingParams {
+	/// The maximum number of para blocks between the para head in a relay parent
+	/// and a new candidate. Restricts nodes from building arbitrary long chains
+	/// and spamming other validators.
+	///
+	/// When async backing is disabled, the only valid value is 0.
+	pub max_candidate_depth: u32,
+	/// How many ancestors of a relay parent are allowed to build candidates on top
+	/// of.
+	///
+	/// When async backing is disabled, the only valid value is 0.
+	pub allowed_ancestry_len: u32,
+}
diff --git a/polkadot/runtime/parachains/src/configuration.rs b/polkadot/runtime/parachains/src/configuration.rs
index 0e8420f5137..b314e47202e 100644
--- a/polkadot/runtime/parachains/src/configuration.rs
+++ b/polkadot/runtime/parachains/src/configuration.rs
@@ -23,7 +23,10 @@ use frame_support::{pallet_prelude::*, weights::constants::WEIGHT_REF_TIME_PER_M
 use frame_system::pallet_prelude::*;
 use parity_scale_codec::{Decode, Encode};
 use polkadot_parachain::primitives::{MAX_HORIZONTAL_MESSAGE_NUM, MAX_UPWARD_MESSAGE_NUM};
-use primitives::{Balance, SessionIndex, MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, MAX_POV_SIZE};
+use primitives::{
+	vstaging::AsyncBackingParams, Balance, SessionIndex, MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE,
+	MAX_POV_SIZE,
+};
 use sp_runtime::traits::Zero;
 use sp_std::prelude::*;
 
@@ -118,6 +121,8 @@ pub struct HostConfiguration<BlockNumber> {
 	 * The parameters that are not essential, but still may be of interest for parachains.
 	 */
 
+	/// Asynchronous backing parameters.
+	pub async_backing_params: AsyncBackingParams,
 	/// The maximum POV block size, in bytes.
 	pub max_pov_size: u32,
 	/// The maximum size of a message that can be put in a downward message queue.
@@ -243,6 +248,10 @@ pub struct HostConfiguration<BlockNumber> {
 impl<BlockNumber: Default + From<u32>> Default for HostConfiguration<BlockNumber> {
 	fn default() -> Self {
 		Self {
+			async_backing_params: AsyncBackingParams {
+				max_candidate_depth: 0,
+				allowed_ancestry_len: 0,
+			},
 			group_rotation_frequency: 1u32.into(),
 			chain_availability_period: 1u32.into(),
 			thread_availability_period: 1u32.into(),
@@ -1138,6 +1147,22 @@ pub mod pallet {
 			BypassConsistencyCheck::<T>::put(new);
 			Ok(())
 		}
+
+		/// Set the asynchronous backing parameters.
+		#[pallet::call_index(45)]
+		#[pallet::weight((
+			T::WeightInfo::set_config_with_option_u32(), // The same size in bytes.
+			DispatchClass::Operational,
+		))]
+		pub fn set_async_backing_params(
+			origin: OriginFor<T>,
+			new: AsyncBackingParams,
+		) -> DispatchResult {
+			ensure_root(origin)?;
+			Self::schedule_config_update(|config| {
+				config.async_backing_params = new;
+			})
+		}
 	}
 
 	#[pallet::hooks]
diff --git a/polkadot/runtime/parachains/src/configuration/migration.rs b/polkadot/runtime/parachains/src/configuration/migration.rs
index be91521db24..8606c15b766 100644
--- a/polkadot/runtime/parachains/src/configuration/migration.rs
+++ b/polkadot/runtime/parachains/src/configuration/migration.rs
@@ -19,6 +19,7 @@
 use crate::configuration::{self, ActiveConfig, Config, Pallet, PendingConfigs, MAX_POV_SIZE};
 use frame_support::{pallet_prelude::*, traits::StorageVersion, weights::Weight};
 use frame_system::pallet_prelude::BlockNumberFor;
+use primitives::vstaging::AsyncBackingParams;
 use sp_std::vec::Vec;
 
 /// The current storage version.
@@ -27,7 +28,7 @@ use sp_std::vec::Vec;
 /// v1-v2: <https://github.com/paritytech/polkadot/pull/4420>
 /// v2-v3: <https://github.com/paritytech/polkadot/pull/6091>
 /// v3-v4: <https://github.com/paritytech/polkadot/pull/6345>
-/// v4-v5: <https://github.com/paritytech/polkadot/pull/6937>
+/// v4-v5: <https://github.com/paritytech/polkadot/pull/6937> + <https://github.com/paritytech/polkadot/pull/6961>
 pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(5);
 
 pub mod v5 {
@@ -226,6 +227,9 @@ ump_max_individual_weight                : pre.ump_max_individual_weight,
 pvf_checking_enabled                     : pre.pvf_checking_enabled,
 pvf_voting_ttl                           : pre.pvf_voting_ttl,
 minimum_validation_upgrade_delay         : pre.minimum_validation_upgrade_delay,
+
+// Default values are zeroes, thus it's ensured allowed ancestry never crosses the upgrade block.
+async_backing_params                     : AsyncBackingParams { max_candidate_depth: 0, allowed_ancestry_len: 0 },
 		}
 	};
 
@@ -383,6 +387,10 @@ mod tests {
 					assert_eq!(v4.pvf_voting_ttl                           , v5.pvf_voting_ttl);
 					assert_eq!(v4.minimum_validation_upgrade_delay         , v5.minimum_validation_upgrade_delay);
 				}; // ; makes this a statement. `rustfmt::skip` cannot be put on an expression.
+
+				// additional checks for async backing.
+				assert_eq!(v5.async_backing_params.allowed_ancestry_len, 0);
+				assert_eq!(v5.async_backing_params.max_candidate_depth, 0);
 			}
 		});
 	}
diff --git a/polkadot/runtime/parachains/src/configuration/tests.rs b/polkadot/runtime/parachains/src/configuration/tests.rs
index eb29200a12c..76c46e1f704 100644
--- a/polkadot/runtime/parachains/src/configuration/tests.rs
+++ b/polkadot/runtime/parachains/src/configuration/tests.rs
@@ -281,6 +281,10 @@ fn consistency_bypass_works() {
 fn setting_pending_config_members() {
 	new_test_ext(Default::default()).execute_with(|| {
 		let new_config = HostConfiguration {
+			async_backing_params: primitives::vstaging::AsyncBackingParams {
+				allowed_ancestry_len: 0,
+				max_candidate_depth: 0,
+			},
 			validation_upgrade_cooldown: 100,
 			validation_upgrade_delay: 10,
 			code_retention_period: 5,
-- 
GitLab