Skip to main content

soil_cli/params/
pruning_params.rs

1// This file is part of Soil.
2
3// Copyright (C) Soil contributors.
4// Copyright (C) Parity Technologies (UK) Ltd.
5// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
6
7use crate::error;
8use clap::Args;
9use soil_service::{BlocksPruning, PruningMode};
10
11/// Parameters to define the pruning mode
12#[derive(Debug, Clone, Args)]
13pub struct PruningParams {
14	/// Specify the state pruning mode.
15	///
16	/// This mode specifies when the block's state (ie, storage)
17	/// should be pruned (ie, removed) from the database.
18	/// This setting can only be set on the first creation of the database. Every subsequent run
19	/// will load the pruning mode from the database and will error if the stored mode doesn't
20	/// match this CLI value. It is fine to drop this CLI flag for subsequent runs. The only
21	/// exception is that `NUMBER` can change between subsequent runs (increasing it will not
22	/// lead to restoring pruned state).
23	///
24	/// Possible values:
25	///
26	/// - archive: Keep the data of all blocks.
27	///
28	/// - archive-canonical: Keep only the data of finalized blocks.
29	///
30	/// - NUMBER: Keep the data of the last NUMBER of finalized blocks.
31	///
32	/// [default: 256]
33	#[arg(alias = "pruning", long, value_name = "PRUNING_MODE")]
34	pub state_pruning: Option<DatabasePruningMode>,
35
36	/// Specify the blocks pruning mode.
37	///
38	/// This mode specifies when the block's body (including justifications)
39	/// should be pruned (ie, removed) from the database.
40	///
41	/// Possible values:
42	///
43	/// - archive: Keep the data of all blocks.
44	///
45	/// - archive-canonical: Keep only the data of finalized blocks.
46	///
47	/// - NUMBER: Keep the data of the last NUMBER of finalized blocks.
48	#[arg(
49		alias = "keep-blocks",
50		long,
51		value_name = "PRUNING_MODE",
52		default_value = "archive-canonical"
53	)]
54	pub blocks_pruning: DatabasePruningMode,
55}
56
57impl PruningParams {
58	/// Get the pruning value from the parameters
59	pub fn state_pruning(&self) -> error::Result<Option<PruningMode>> {
60		Ok(self.state_pruning.map(|v| v.into()))
61	}
62
63	/// Get the block pruning value from the parameters
64	pub fn blocks_pruning(&self) -> error::Result<BlocksPruning> {
65		Ok(self.blocks_pruning.into())
66	}
67}
68
69/// Specifies the pruning mode of the database.
70///
71/// This specifies when the block's data (either state via `--state-pruning`
72/// or body via `--blocks-pruning`) should be pruned (ie, removed) from
73/// the database.
74#[derive(Debug, Clone, Copy, PartialEq)]
75pub enum DatabasePruningMode {
76	/// Keep the data of all blocks.
77	Archive,
78	/// Keep only the data of finalized blocks.
79	ArchiveCanonical,
80	/// Keep the data of the last number of finalized blocks.
81	Custom(u32),
82}
83
84impl std::str::FromStr for DatabasePruningMode {
85	type Err = String;
86
87	fn from_str(input: &str) -> Result<Self, Self::Err> {
88		match input {
89			"archive" => Ok(Self::Archive),
90			"archive-canonical" => Ok(Self::ArchiveCanonical),
91			bc => bc
92				.parse()
93				.map_err(|_| "Invalid pruning mode specified".to_string())
94				.map(Self::Custom),
95		}
96	}
97}
98
99impl Into<PruningMode> for DatabasePruningMode {
100	fn into(self) -> PruningMode {
101		match self {
102			DatabasePruningMode::Archive => PruningMode::ArchiveAll,
103			DatabasePruningMode::ArchiveCanonical => PruningMode::ArchiveCanonical,
104			DatabasePruningMode::Custom(n) => PruningMode::blocks_pruning(n),
105		}
106	}
107}
108
109impl Into<BlocksPruning> for DatabasePruningMode {
110	fn into(self) -> BlocksPruning {
111		match self {
112			DatabasePruningMode::Archive => BlocksPruning::KeepAll,
113			DatabasePruningMode::ArchiveCanonical => BlocksPruning::KeepFinalized,
114			DatabasePruningMode::Custom(n) => BlocksPruning::Some(n),
115		}
116	}
117}
118
119#[cfg(test)]
120mod tests {
121	use super::*;
122	use clap::Parser;
123
124	#[derive(Parser)]
125	struct Cli {
126		#[clap(flatten)]
127		pruning: PruningParams,
128	}
129
130	#[test]
131	fn pruning_params_parse_works() {
132		let Cli { pruning } =
133			Cli::parse_from(["", "--state-pruning=1000", "--blocks-pruning=1000"]);
134
135		assert!(matches!(pruning.state_pruning, Some(DatabasePruningMode::Custom(1000))));
136		assert!(matches!(pruning.blocks_pruning, DatabasePruningMode::Custom(1000)));
137
138		let Cli { pruning } =
139			Cli::parse_from(["", "--state-pruning=archive", "--blocks-pruning=archive"]);
140
141		assert!(matches!(dbg!(pruning.state_pruning), Some(DatabasePruningMode::Archive)));
142		assert!(matches!(pruning.blocks_pruning, DatabasePruningMode::Archive));
143
144		let Cli { pruning } = Cli::parse_from([
145			"",
146			"--state-pruning=archive-canonical",
147			"--blocks-pruning=archive-canonical",
148		]);
149
150		assert!(matches!(dbg!(pruning.state_pruning), Some(DatabasePruningMode::ArchiveCanonical)));
151		assert!(matches!(pruning.blocks_pruning, DatabasePruningMode::ArchiveCanonical));
152	}
153}