Skip to main content

soil_cli/
arg_enums.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
7//! Definitions of [`ValueEnum`] types.
8
9use clap::ValueEnum;
10use std::str::FromStr;
11
12/// The instantiation strategy to use in compiled mode.
13#[derive(Debug, Clone, Copy, ValueEnum)]
14#[value(rename_all = "kebab-case")]
15pub enum WasmtimeInstantiationStrategy {
16	/// Pool the instances to avoid initializing everything from scratch
17	/// on each instantiation. Use copy-on-write memory when possible.
18	PoolingCopyOnWrite,
19
20	/// Recreate the instance from scratch on every instantiation.
21	/// Use copy-on-write memory when possible.
22	RecreateInstanceCopyOnWrite,
23
24	/// Pool the instances to avoid initializing everything from scratch
25	/// on each instantiation.
26	Pooling,
27
28	/// Recreate the instance from scratch on every instantiation. Very slow.
29	RecreateInstance,
30}
31
32/// The default [`WasmtimeInstantiationStrategy`].
33pub const DEFAULT_WASMTIME_INSTANTIATION_STRATEGY: WasmtimeInstantiationStrategy =
34	WasmtimeInstantiationStrategy::PoolingCopyOnWrite;
35
36/// How to execute Wasm runtime code.
37#[derive(Debug, Clone, Copy, ValueEnum)]
38#[value(rename_all = "kebab-case")]
39pub enum WasmExecutionMethod {
40	/// Uses an interpreter which now is deprecated.
41	#[clap(name = "interpreted-i-know-what-i-do")]
42	Interpreted,
43	/// Uses a compiled runtime.
44	Compiled,
45}
46
47impl std::fmt::Display for WasmExecutionMethod {
48	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49		match self {
50			Self::Interpreted => write!(f, "Interpreted"),
51			Self::Compiled => write!(f, "Compiled"),
52		}
53	}
54}
55
56/// Converts the execution method and instantiation strategy command line arguments
57/// into an execution method which can be used internally.
58pub fn execution_method_from_cli(
59	execution_method: WasmExecutionMethod,
60	instantiation_strategy: WasmtimeInstantiationStrategy,
61) -> soil_service::config::WasmExecutionMethod {
62	if let WasmExecutionMethod::Interpreted = execution_method {
63		log::warn!(
64			"`interpreted-i-know-what-i-do` is deprecated and will be removed in the future. Defaults to `compiled` execution mode."
65		);
66	}
67
68	soil_service::config::WasmExecutionMethod::Compiled {
69		instantiation_strategy: match instantiation_strategy {
70			WasmtimeInstantiationStrategy::PoolingCopyOnWrite => {
71				soil_service::config::WasmtimeInstantiationStrategy::PoolingCopyOnWrite
72			},
73			WasmtimeInstantiationStrategy::RecreateInstanceCopyOnWrite => {
74				soil_service::config::WasmtimeInstantiationStrategy::RecreateInstanceCopyOnWrite
75			},
76			WasmtimeInstantiationStrategy::Pooling => {
77				soil_service::config::WasmtimeInstantiationStrategy::Pooling
78			},
79			WasmtimeInstantiationStrategy::RecreateInstance => {
80				soil_service::config::WasmtimeInstantiationStrategy::RecreateInstance
81			},
82		},
83	}
84}
85
86/// The default [`WasmExecutionMethod`].
87pub const DEFAULT_WASM_EXECUTION_METHOD: WasmExecutionMethod = WasmExecutionMethod::Compiled;
88
89#[allow(missing_docs)]
90#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
91#[value(rename_all = "kebab-case")]
92pub enum TracingReceiver {
93	/// Output the tracing records using the log.
94	Log,
95}
96
97impl Into<soil_client::tracing::TracingReceiver> for TracingReceiver {
98	fn into(self) -> soil_client::tracing::TracingReceiver {
99		match self {
100			TracingReceiver::Log => soil_client::tracing::TracingReceiver::Log,
101		}
102	}
103}
104
105/// The type of the node key.
106#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
107#[value(rename_all = "kebab-case")]
108pub enum NodeKeyType {
109	/// Use ed25519.
110	Ed25519,
111}
112
113/// The crypto scheme to use.
114#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
115#[value(rename_all = "kebab-case")]
116pub enum CryptoScheme {
117	/// Use ed25519.
118	Ed25519,
119	/// Use sr25519.
120	Sr25519,
121	/// Use ecdsa.
122	Ecdsa,
123}
124
125/// The type of the output format.
126#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
127#[value(rename_all = "kebab-case")]
128pub enum OutputType {
129	/// Output as json.
130	Json,
131	/// Output as text.
132	Text,
133}
134
135/// How to execute blocks
136#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
137#[value(rename_all = "kebab-case")]
138pub enum ExecutionStrategy {
139	/// Execute with native build (if available, WebAssembly otherwise).
140	Native,
141	/// Only execute with the WebAssembly build.
142	Wasm,
143	/// Execute with both native (where available) and WebAssembly builds.
144	Both,
145	/// Execute with the native build if possible; if it fails, then execute with WebAssembly.
146	NativeElseWasm,
147}
148
149/// Available RPC methods.
150#[allow(missing_docs)]
151#[derive(Debug, Copy, Clone, PartialEq, ValueEnum)]
152#[value(rename_all = "kebab-case")]
153pub enum RpcMethods {
154	/// Expose every RPC method only when RPC is listening on `localhost`,
155	/// otherwise serve only safe RPC methods.
156	Auto,
157	/// Allow only a safe subset of RPC methods.
158	Safe,
159	/// Expose every RPC method (even potentially unsafe ones).
160	Unsafe,
161}
162
163impl FromStr for RpcMethods {
164	type Err = String;
165
166	fn from_str(s: &str) -> Result<Self, Self::Err> {
167		match s {
168			"safe" => Ok(RpcMethods::Safe),
169			"unsafe" => Ok(RpcMethods::Unsafe),
170			"auto" => Ok(RpcMethods::Auto),
171			invalid => Err(format!("Invalid rpc methods {invalid}")),
172		}
173	}
174}
175
176impl Into<soil_service::config::RpcMethods> for RpcMethods {
177	fn into(self) -> soil_service::config::RpcMethods {
178		match self {
179			RpcMethods::Auto => soil_service::config::RpcMethods::Auto,
180			RpcMethods::Safe => soil_service::config::RpcMethods::Safe,
181			RpcMethods::Unsafe => soil_service::config::RpcMethods::Unsafe,
182		}
183	}
184}
185
186/// CORS setting
187///
188/// The type is introduced to overcome `Option<Option<T>>` handling of `clap`.
189#[derive(Clone, Debug)]
190pub enum Cors {
191	/// All hosts allowed.
192	All,
193	/// Only hosts on the list are allowed.
194	List(Vec<String>),
195}
196
197impl From<Cors> for Option<Vec<String>> {
198	fn from(cors: Cors) -> Self {
199		match cors {
200			Cors::All => None,
201			Cors::List(list) => Some(list),
202		}
203	}
204}
205
206impl FromStr for Cors {
207	type Err = crate::Error;
208
209	fn from_str(s: &str) -> Result<Self, Self::Err> {
210		let mut is_all = false;
211		let mut origins = Vec::new();
212		for part in s.split(',') {
213			match part {
214				"all" | "*" => {
215					is_all = true;
216					break;
217				},
218				other => origins.push(other.to_owned()),
219			}
220		}
221
222		if is_all {
223			Ok(Cors::All)
224		} else {
225			Ok(Cors::List(origins))
226		}
227	}
228}
229
230/// Database backend
231#[derive(Debug, Clone, PartialEq, Copy, clap::ValueEnum)]
232#[value(rename_all = "lower")]
233pub enum Database {
234	/// Facebooks RocksDB
235	#[cfg(feature = "rocksdb")]
236	RocksDb,
237	/// ParityDb. <https://github.com/paritytech/parity-db/>
238	ParityDb,
239	/// Detect whether there is an existing database. Use it, if there is, if not, create new
240	/// instance of ParityDb
241	Auto,
242	/// ParityDb. <https://github.com/paritytech/parity-db/>
243	#[value(name = "paritydb-experimental")]
244	ParityDbDeprecated,
245}
246
247impl Database {
248	/// Returns all the variants of this enum to be shown in the cli.
249	pub const fn variants() -> &'static [&'static str] {
250		&[
251			#[cfg(feature = "rocksdb")]
252			"rocksdb",
253			"paritydb",
254			"paritydb-experimental",
255			"auto",
256		]
257	}
258}
259
260/// Whether off-chain workers are enabled.
261#[allow(missing_docs)]
262#[derive(Debug, Clone, ValueEnum)]
263#[value(rename_all = "kebab-case")]
264pub enum OffchainWorkerEnabled {
265	/// Always have offchain worker enabled.
266	Always,
267	/// Never enable the offchain worker.
268	Never,
269	/// Only enable the offchain worker when running as a validator (or collator, if this is a
270	/// parachain node).
271	WhenAuthority,
272}
273
274/// Syncing mode.
275#[derive(Debug, Clone, Copy, ValueEnum, PartialEq)]
276#[value(rename_all = "kebab-case")]
277pub enum SyncMode {
278	/// Full sync. Download and verify all blocks.
279	Full,
280	/// Download blocks without executing them. Download latest state with proofs.
281	Fast,
282	/// Download blocks without executing them. Download latest state without proofs.
283	FastUnsafe,
284	/// Prove finality and download the latest state.
285	/// After warp sync completes, the node will have block headers but not bodies for historical
286	/// blocks (unless `blocks-pruning` is set to archive mode). This saves bandwidth while still
287	/// allowing the node to serve as a warp sync source for other nodes.
288	Warp,
289}
290
291impl Into<soil_network::config::SyncMode> for SyncMode {
292	fn into(self) -> soil_network::config::SyncMode {
293		match self {
294			SyncMode::Full => soil_network::config::SyncMode::Full,
295			SyncMode::Fast => soil_network::config::SyncMode::LightState {
296				skip_proofs: false,
297				storage_chain_mode: false,
298			},
299			SyncMode::FastUnsafe => soil_network::config::SyncMode::LightState {
300				skip_proofs: true,
301				storage_chain_mode: false,
302			},
303			SyncMode::Warp => soil_network::config::SyncMode::Warp,
304		}
305	}
306}
307
308/// Network backend type.
309#[derive(Debug, Clone, Copy, ValueEnum, PartialEq)]
310#[value(rename_all = "lower")]
311pub enum NetworkBackendType {
312	/// Use libp2p for P2P networking.
313	Libp2p,
314
315	/// Use litep2p for P2P networking.
316	Litep2p,
317}
318
319impl Into<soil_network::config::NetworkBackendType> for NetworkBackendType {
320	fn into(self) -> soil_network::config::NetworkBackendType {
321		match self {
322			Self::Libp2p => soil_network::config::NetworkBackendType::Libp2p,
323			Self::Litep2p => soil_network::config::NetworkBackendType::Litep2p,
324		}
325	}
326}