From 1866c3b4673b66a62b1eb9c8c82f2cd827cbd388 Mon Sep 17 00:00:00 2001
From: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com>
Date: Thu, 13 Feb 2025 15:22:42 +0100
Subject: [PATCH] Shorter availability data retention period for testnets
 (#7353)

Closes #3270

---------

Co-authored-by: command-bot <>
---
 .../src/lib.rs                                |  1 +
 polkadot/cli/src/cli.rs                       |  6 +++++
 polkadot/cli/src/command.rs                   |  1 +
 polkadot/node/core/av-store/src/lib.rs        | 23 ++++++++-----------
 polkadot/node/core/av-store/src/tests.rs      |  3 ++-
 polkadot/node/service/src/lib.rs              | 23 ++++++++++++++-----
 .../src/lib/availability/av_store_helpers.rs  |  3 ++-
 polkadot/node/test/service/src/lib.rs         |  2 ++
 .../adder/collator/src/main.rs                |  1 +
 .../undying/collator/src/main.rs              |  1 +
 prdoc/pr_7353.prdoc                           | 13 +++++++++++
 11 files changed, 55 insertions(+), 22 deletions(-)
 create mode 100644 prdoc/pr_7353.prdoc

diff --git a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs
index 4f885525fca..aa4803626d9 100644
--- a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs
+++ b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs
@@ -385,6 +385,7 @@ fn build_polkadot_full_node(
 			prepare_workers_hard_max_num: None,
 			prepare_workers_soft_max_num: None,
 			enable_approval_voting_parallel: false,
+			keep_finalized_for: None,
 		},
 	)?;
 
diff --git a/polkadot/cli/src/cli.rs b/polkadot/cli/src/cli.rs
index 6187eb79a36..721a4714992 100644
--- a/polkadot/cli/src/cli.rs
+++ b/polkadot/cli/src/cli.rs
@@ -152,6 +152,12 @@ pub struct RunCmd {
 	/// should not be used unless explicitly advised to. It will be removed in the future.
 	#[arg(long, default_value = "true", action=ArgAction::Set)]
 	pub enable_approval_voting_parallel: bool,
+
+	/// How long finalized data should be kept in the availability store (in hours).
+	/// Only used for testnets. If not specified, set to 1 hour. Always set to 25 hours for live
+	/// networks.
+	#[arg(long)]
+	pub keep_finalized_for: Option<u32>,
 }
 
 #[allow(missing_docs)]
diff --git a/polkadot/cli/src/command.rs b/polkadot/cli/src/command.rs
index 02c9b97150c..6b716d48783 100644
--- a/polkadot/cli/src/command.rs
+++ b/polkadot/cli/src/command.rs
@@ -235,6 +235,7 @@ where
 				prepare_workers_hard_max_num: cli.run.prepare_workers_hard_max_num,
 				prepare_workers_soft_max_num: cli.run.prepare_workers_soft_max_num,
 				enable_approval_voting_parallel: cli.run.enable_approval_voting_parallel,
+				keep_finalized_for: cli.run.keep_finalized_for,
 			},
 		)
 		.map(|full| full.task_manager)?;
diff --git a/polkadot/node/core/av-store/src/lib.rs b/polkadot/node/core/av-store/src/lib.rs
index 9da2973773a..75a0a4b08ed 100644
--- a/polkadot/node/core/av-store/src/lib.rs
+++ b/polkadot/node/core/av-store/src/lib.rs
@@ -75,9 +75,6 @@ const TOMBSTONE_VALUE: &[u8] = b" ";
 /// Unavailable blocks are kept for 1 hour.
 const KEEP_UNAVAILABLE_FOR: Duration = Duration::from_secs(60 * 60);
 
-/// Finalized data is kept for 25 hours.
-const KEEP_FINALIZED_FOR: Duration = Duration::from_secs(25 * 60 * 60);
-
 /// The pruning interval.
 const PRUNING_INTERVAL: Duration = Duration::from_secs(60 * 5);
 
@@ -423,16 +420,6 @@ struct PruningConfig {
 	pruning_interval: Duration,
 }
 
-impl Default for PruningConfig {
-	fn default() -> Self {
-		Self {
-			keep_unavailable_for: KEEP_UNAVAILABLE_FOR,
-			keep_finalized_for: KEEP_FINALIZED_FOR,
-			pruning_interval: PRUNING_INTERVAL,
-		}
-	}
-}
-
 /// Configuration for the availability store.
 #[derive(Debug, Clone, Copy)]
 pub struct Config {
@@ -440,6 +427,8 @@ pub struct Config {
 	pub col_data: u32,
 	/// The column family for availability store meta information.
 	pub col_meta: u32,
+	/// How long finalized data should be kept (in hours).
+	pub keep_finalized_for: u32,
 }
 
 trait Clock: Send + Sync {
@@ -475,10 +464,16 @@ impl AvailabilityStoreSubsystem {
 		sync_oracle: Box<dyn SyncOracle + Send + Sync>,
 		metrics: Metrics,
 	) -> Self {
+		let pruning_config = PruningConfig {
+			keep_unavailable_for: KEEP_UNAVAILABLE_FOR,
+			keep_finalized_for: Duration::from_secs(config.keep_finalized_for as u64 * 3600),
+			pruning_interval: PRUNING_INTERVAL,
+		};
+
 		Self::with_pruning_config_and_clock(
 			db,
 			config,
-			PruningConfig::default(),
+			pruning_config,
 			Box::new(SystemClock),
 			sync_oracle,
 			metrics,
diff --git a/polkadot/node/core/av-store/src/tests.rs b/polkadot/node/core/av-store/src/tests.rs
index 80043e56976..d1da058f9e4 100644
--- a/polkadot/node/core/av-store/src/tests.rs
+++ b/polkadot/node/core/av-store/src/tests.rs
@@ -43,7 +43,8 @@ mod columns {
 	pub const NUM_COLUMNS: u32 = 2;
 }
 
-const TEST_CONFIG: Config = Config { col_data: columns::DATA, col_meta: columns::META };
+const TEST_CONFIG: Config =
+	Config { col_data: columns::DATA, col_meta: columns::META, keep_finalized_for: 1 };
 
 type VirtualOverseer =
 	polkadot_node_subsystem_test_helpers::TestSubsystemContextHandle<AvailabilityStoreMessage>;
diff --git a/polkadot/node/service/src/lib.rs b/polkadot/node/service/src/lib.rs
index ce17ae5f51b..077fb5c578a 100644
--- a/polkadot/node/service/src/lib.rs
+++ b/polkadot/node/service/src/lib.rs
@@ -128,6 +128,9 @@ pub type FullClient = sc_service::TFullClient<
 /// imported and generated.
 const GRANDPA_JUSTIFICATION_PERIOD: u32 = 512;
 
+/// The number of hours to keep finalized data in the availability store for live networks.
+const KEEP_FINALIZED_FOR_LIVE_NETWORKS: u32 = 25;
+
 /// Provides the header and block number for a hash.
 ///
 /// Decouples `sc_client_api::Backend` and `sp_blockchain::HeaderBackend`.
@@ -628,6 +631,8 @@ pub struct NewFullParams<OverseerGenerator: OverseerGen> {
 	pub prepare_workers_soft_max_num: Option<usize>,
 	/// An optional absolute number of pvf workers that can be spawned in the pvf prepare pool.
 	pub prepare_workers_hard_max_num: Option<usize>,
+	/// How long finalized data should be kept in the availability store (in hours)
+	pub keep_finalized_for: Option<u32>,
 	pub overseer_gen: OverseerGenerator,
 	pub overseer_message_channel_capacity_override: Option<usize>,
 	#[allow(dead_code)]
@@ -691,11 +696,6 @@ impl IsParachainNode {
 	}
 }
 
-pub const AVAILABILITY_CONFIG: AvailabilityConfig = AvailabilityConfig {
-	col_data: parachains_db::REAL_COLUMNS.col_availability_data,
-	col_meta: parachains_db::REAL_COLUMNS.col_availability_meta,
-};
-
 /// Create a new full node of arbitrary runtime and executor.
 ///
 /// This is an advanced feature and not recommended for general use. Generally, `build_full` is
@@ -727,6 +727,7 @@ pub fn new_full<
 		execute_workers_max_num,
 		prepare_workers_soft_max_num,
 		prepare_workers_hard_max_num,
+		keep_finalized_for,
 		enable_approval_voting_parallel,
 	}: NewFullParams<OverseerGenerator>,
 ) -> Result<NewFull, Error> {
@@ -972,11 +973,21 @@ pub fn new_full<
 		let fetch_chunks_threshold =
 			if config.chain_spec.is_polkadot() { None } else { Some(FETCH_CHUNKS_THRESHOLD) };
 
+		let availability_config = AvailabilityConfig {
+			col_data: parachains_db::REAL_COLUMNS.col_availability_data,
+			col_meta: parachains_db::REAL_COLUMNS.col_availability_meta,
+			keep_finalized_for: if matches!(config.chain_spec.identify_chain(), Chain::Rococo) {
+				keep_finalized_for.unwrap_or(1)
+			} else {
+				KEEP_FINALIZED_FOR_LIVE_NETWORKS
+			},
+		};
+
 		Some(ExtendedOverseerGenArgs {
 			keystore,
 			parachains_db,
 			candidate_validation_config,
-			availability_config: AVAILABILITY_CONFIG,
+			availability_config,
 			pov_req_receiver,
 			chunk_req_v1_receiver,
 			chunk_req_v2_receiver,
diff --git a/polkadot/node/subsystem-bench/src/lib/availability/av_store_helpers.rs b/polkadot/node/subsystem-bench/src/lib/availability/av_store_helpers.rs
index 3300def2235..62588454471 100644
--- a/polkadot/node/subsystem-bench/src/lib/availability/av_store_helpers.rs
+++ b/polkadot/node/subsystem-bench/src/lib/availability/av_store_helpers.rs
@@ -26,7 +26,8 @@ mod columns {
 	pub const NUM_COLUMNS: u32 = 2;
 }
 
-const TEST_CONFIG: Config = Config { col_data: columns::DATA, col_meta: columns::META };
+const TEST_CONFIG: Config =
+	Config { col_data: columns::DATA, col_meta: columns::META, keep_finalized_for: 1 };
 
 pub fn new_av_store(dependencies: &TestEnvironmentDependencies) -> AvailabilityStoreSubsystem {
 	let metrics = Metrics::try_register(&dependencies.registry).unwrap();
diff --git a/polkadot/node/test/service/src/lib.rs b/polkadot/node/test/service/src/lib.rs
index 75fd0d9af30..dea2682b61b 100644
--- a/polkadot/node/test/service/src/lib.rs
+++ b/polkadot/node/test/service/src/lib.rs
@@ -101,6 +101,7 @@ pub fn new_full<OverseerGenerator: OverseerGen>(
 					prepare_workers_hard_max_num: None,
 					prepare_workers_soft_max_num: None,
 					enable_approval_voting_parallel: false,
+					keep_finalized_for: None,
 				},
 			),
 		sc_network::config::NetworkBackendType::Litep2p =>
@@ -123,6 +124,7 @@ pub fn new_full<OverseerGenerator: OverseerGen>(
 					prepare_workers_hard_max_num: None,
 					prepare_workers_soft_max_num: None,
 					enable_approval_voting_parallel: false,
+					keep_finalized_for: None,
 				},
 			),
 	}
diff --git a/polkadot/parachain/test-parachains/adder/collator/src/main.rs b/polkadot/parachain/test-parachains/adder/collator/src/main.rs
index 416e58b0a8a..58fa3e841ef 100644
--- a/polkadot/parachain/test-parachains/adder/collator/src/main.rs
+++ b/polkadot/parachain/test-parachains/adder/collator/src/main.rs
@@ -98,6 +98,7 @@ fn main() -> Result<()> {
 						prepare_workers_hard_max_num: None,
 						prepare_workers_soft_max_num: None,
 						enable_approval_voting_parallel: false,
+						keep_finalized_for: None,
 					},
 				)
 				.map_err(|e| e.to_string())?;
diff --git a/polkadot/parachain/test-parachains/undying/collator/src/main.rs b/polkadot/parachain/test-parachains/undying/collator/src/main.rs
index 9d993dd818b..8b18cbb422e 100644
--- a/polkadot/parachain/test-parachains/undying/collator/src/main.rs
+++ b/polkadot/parachain/test-parachains/undying/collator/src/main.rs
@@ -100,6 +100,7 @@ fn main() -> Result<()> {
 						prepare_workers_hard_max_num: None,
 						prepare_workers_soft_max_num: None,
 						enable_approval_voting_parallel: false,
+						keep_finalized_for: None,
 					},
 				)
 				.map_err(|e| e.to_string())?;
diff --git a/prdoc/pr_7353.prdoc b/prdoc/pr_7353.prdoc
new file mode 100644
index 00000000000..8b1f272525d
--- /dev/null
+++ b/prdoc/pr_7353.prdoc
@@ -0,0 +1,13 @@
+# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
+# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
+
+title: Shorter availability data retention period for testnets
+
+doc:
+  - audience: Node Operator
+    description: |
+        Allows specifying a shorter availability data retention period for testnets.
+
+crates:
+- name: polkadot-service
+  bump: patch
-- 
GitLab