referrerpolicy=no-referrer-when-downgrade

test_parachain/
cli.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Cumulus.
3
4// Cumulus is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Cumulus is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
16
17use clap::ValueEnum;
18use cumulus_client_cli::{ExportGenesisHeadCommand, ExportGenesisWasmCommand};
19use polkadot_service::{ChainSpec, ParaId, PrometheusConfig};
20use sc_cli::{
21	CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams, NetworkParams,
22	Result as CliResult, RpcEndpoint, SharedParams, SubstrateCli,
23};
24use sc_service::BasePath;
25use std::{
26	fmt::{Display, Formatter},
27	path::PathBuf,
28};
29
30#[derive(Debug, clap::Parser)]
31#[command(
32	version,
33	propagate_version = true,
34	args_conflicts_with_subcommands = true,
35	subcommand_negates_reqs = true
36)]
37pub struct TestCollatorCli {
38	#[command(subcommand)]
39	pub subcommand: Option<Subcommand>,
40
41	#[command(flatten)]
42	pub run: cumulus_client_cli::RunCmd,
43
44	/// Relay chain arguments
45	#[arg(raw = true)]
46	pub relaychain_args: Vec<String>,
47
48	#[arg(long)]
49	pub disable_block_announcements: bool,
50
51	#[arg(long)]
52	pub fail_pov_recovery: bool,
53
54	/// Authoring style to use.
55	#[arg(long, default_value_t = AuthoringPolicy::Lookahead)]
56	pub authoring: AuthoringPolicy,
57
58	/// Upper bound on collator reserved-peer mesh slots. `0` disables the mesh.
59	#[arg(long, value_name = "N", default_value_t = 32)]
60	pub collator_reserved_slots: usize,
61}
62
63/// Collator implementation to use.
64#[derive(PartialEq, Debug, ValueEnum, Clone, Copy)]
65pub enum AuthoringPolicy {
66	/// Use the lookahead collator. Builds blocks once per relay chain block,
67	/// builds on relay chain forks.
68	Lookahead,
69	/// Use the slot-based collator which can handle elastic-scaling. Builds blocks based on time
70	/// and can utilize multiple cores, always builds on the best relay chain block available.
71	SlotBased,
72}
73
74impl Display for AuthoringPolicy {
75	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
76		match self {
77			AuthoringPolicy::Lookahead => write!(f, "lookahead"),
78			AuthoringPolicy::SlotBased => write!(f, "slot-based"),
79		}
80	}
81}
82
83#[derive(Debug, clap::Subcommand)]
84pub enum Subcommand {
85	/// Export the chain specification.
86	ExportChainSpec(sc_cli::ExportChainSpecCmd),
87
88	/// Export the genesis state of the parachain.
89	#[command(alias = "export-genesis-state")]
90	ExportGenesisHead(ExportGenesisHeadCommand),
91
92	/// Export the genesis wasm of the parachain.
93	ExportGenesisWasm(ExportGenesisWasmCommand),
94}
95
96#[derive(Debug)]
97pub struct RelayChainCli {
98	/// The actual relay chain cli object.
99	pub base: polkadot_cli::RunCmd,
100
101	/// Optional chain id that should be passed to the relay chain.
102	pub chain_id: Option<String>,
103
104	/// The base path that should be used by the relay chain.
105	pub base_path: Option<PathBuf>,
106}
107
108impl RelayChainCli {
109	/// Parse the relay chain CLI parameters using the para chain `Configuration`.
110	pub fn new<'a>(
111		para_config: &sc_service::Configuration,
112		relay_chain_args: impl Iterator<Item = &'a String>,
113	) -> Self {
114		let base_path = para_config.base_path.path().join("polkadot");
115		Self {
116			base_path: Some(base_path),
117			chain_id: None,
118			base: clap::Parser::parse_from(relay_chain_args),
119		}
120	}
121}
122
123impl CliConfiguration<Self> for RelayChainCli {
124	fn shared_params(&self) -> &SharedParams {
125		self.base.base.shared_params()
126	}
127
128	fn import_params(&self) -> Option<&ImportParams> {
129		self.base.base.import_params()
130	}
131
132	fn network_params(&self) -> Option<&NetworkParams> {
133		self.base.base.network_params()
134	}
135
136	fn keystore_params(&self) -> Option<&KeystoreParams> {
137		self.base.base.keystore_params()
138	}
139
140	fn base_path(&self) -> CliResult<Option<BasePath>> {
141		Ok(self
142			.shared_params()
143			.base_path()?
144			.or_else(|| self.base_path.clone().map(Into::into)))
145	}
146
147	fn rpc_addr(&self, default_listen_port: u16) -> CliResult<Option<Vec<RpcEndpoint>>> {
148		self.base.base.rpc_addr(default_listen_port)
149	}
150
151	fn prometheus_config(
152		&self,
153		default_listen_port: u16,
154		chain_spec: &Box<dyn ChainSpec>,
155	) -> CliResult<Option<PrometheusConfig>> {
156		self.base.base.prometheus_config(default_listen_port, chain_spec)
157	}
158
159	fn init<F>(
160		&self,
161		_support_url: &String,
162		_impl_version: &String,
163		_logger_hook: F,
164	) -> CliResult<()>
165	where
166		F: FnOnce(&mut sc_cli::LoggerBuilder),
167	{
168		unreachable!("PolkadotCli is never initialized; qed");
169	}
170
171	fn chain_id(&self, is_dev: bool) -> CliResult<String> {
172		let chain_id = self.base.base.chain_id(is_dev)?;
173
174		Ok(if chain_id.is_empty() { self.chain_id.clone().unwrap_or_default() } else { chain_id })
175	}
176
177	fn role(&self, is_dev: bool) -> CliResult<sc_service::Role> {
178		self.base.base.role(is_dev)
179	}
180
181	fn transaction_pool(
182		&self,
183		is_dev: bool,
184	) -> CliResult<sc_service::config::TransactionPoolOptions> {
185		self.base.base.transaction_pool(is_dev)
186	}
187
188	fn trie_cache_maximum_size(&self) -> CliResult<Option<usize>> {
189		self.base.base.trie_cache_maximum_size()
190	}
191
192	fn rpc_methods(&self) -> CliResult<sc_service::config::RpcMethods> {
193		self.base.base.rpc_methods()
194	}
195
196	fn rpc_max_connections(&self) -> CliResult<u32> {
197		self.base.base.rpc_max_connections()
198	}
199
200	fn rpc_cors(&self, is_dev: bool) -> CliResult<Option<Vec<String>>> {
201		self.base.base.rpc_cors(is_dev)
202	}
203
204	fn default_heap_pages(&self) -> CliResult<Option<u64>> {
205		self.base.base.default_heap_pages()
206	}
207
208	fn force_authoring(&self) -> CliResult<bool> {
209		self.base.base.force_authoring()
210	}
211
212	fn disable_grandpa(&self) -> CliResult<bool> {
213		self.base.base.disable_grandpa()
214	}
215
216	fn max_runtime_instances(&self) -> CliResult<Option<usize>> {
217		self.base.base.max_runtime_instances()
218	}
219
220	fn announce_block(&self) -> CliResult<bool> {
221		self.base.base.announce_block()
222	}
223
224	fn telemetry_endpoints(
225		&self,
226		chain_spec: &Box<dyn ChainSpec>,
227	) -> CliResult<Option<sc_telemetry::TelemetryEndpoints>> {
228		self.base.base.telemetry_endpoints(chain_spec)
229	}
230
231	fn node_name(&self) -> CliResult<String> {
232		self.base.base.node_name()
233	}
234}
235
236impl DefaultConfigurationValues for RelayChainCli {
237	fn p2p_listen_port() -> u16 {
238		30334
239	}
240
241	fn rpc_listen_port() -> u16 {
242		9945
243	}
244
245	fn prometheus_listen_port() -> u16 {
246		9616
247	}
248}
249
250impl SubstrateCli for TestCollatorCli {
251	fn impl_name() -> String {
252		"Cumulus zombienet test parachain".into()
253	}
254
255	fn impl_version() -> String {
256		String::new()
257	}
258
259	fn description() -> String {
260		format!(
261			"Cumulus zombienet test parachain\n\nThe command-line arguments provided first will be \
262		passed to the parachain node, while the arguments provided after -- will be passed \
263		to the relaychain node.\n\n\
264		{} [parachain-args] -- [relaychain-args]",
265			Self::executable_name()
266		)
267	}
268
269	fn author() -> String {
270		env!("CARGO_PKG_AUTHORS").into()
271	}
272
273	fn support_url() -> String {
274		"https://github.com/paritytech/polkadot-sdk/issues/new".into()
275	}
276
277	fn copyright_start_year() -> i32 {
278		2017
279	}
280
281	fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
282		Ok(Box::new(match id {
283			"" => {
284				tracing::info!("Using default test service chain spec.");
285				cumulus_test_service::get_chain_spec(
286					cumulus_test_runtime::WASM_BINARY,
287					Some(ParaId::from(2000)),
288				)
289			},
290			"elastic-scaling-mvp" => {
291				tracing::info!("Using elastic-scaling mvp chain spec.");
292				cumulus_test_service::get_chain_spec(
293					cumulus_test_runtime::elastic_scaling::WASM_BINARY,
294					Some(ParaId::from(2100)),
295				)
296			},
297			"elastic-scaling" => {
298				tracing::info!("Using elastic-scaling chain spec.");
299				cumulus_test_service::get_chain_spec(
300					cumulus_test_runtime::elastic_scaling::WASM_BINARY,
301					Some(ParaId::from(2200)),
302				)
303			},
304			"elastic-scaling-500ms" => {
305				tracing::info!("Using elastic-scaling 500ms chain spec.");
306				cumulus_test_service::get_chain_spec(
307					cumulus_test_runtime::elastic_scaling_500ms::WASM_BINARY,
308					Some(ParaId::from(2300)),
309				)
310			},
311			"block-bundling" => {
312				tracing::info!("Using block-bundling chain spec.");
313				cumulus_test_service::get_chain_spec(
314					cumulus_test_runtime::block_bundling::WASM_BINARY,
315					Some(ParaId::from(2400)),
316				)
317			},
318			"sync-backing" => {
319				tracing::info!("Using sync backing chain spec.");
320				cumulus_test_service::get_chain_spec(
321					cumulus_test_runtime::sync_backing::WASM_BINARY,
322					Some(ParaId::from(2500)),
323				)
324			},
325			"async-backing" => {
326				tracing::info!("Using async backing chain spec.");
327				cumulus_test_service::get_chain_spec(
328					cumulus_test_runtime::WASM_BINARY,
329					Some(ParaId::from(2500)),
330				)
331			},
332			"relay-parent-offset-2" => cumulus_test_service::get_chain_spec(
333				cumulus_test_runtime::relay_parent_offset_2::WASM_BINARY,
334				Some(ParaId::from(2600)),
335			),
336			"with-authority-discovery" => {
337				tracing::info!("Using with-authority-discovery chain spec.");
338				cumulus_test_service::get_chain_spec(
339					cumulus_test_runtime::with_authority_discovery::WASM_BINARY,
340					Some(ParaId::from(1000)),
341				)
342			},
343			"v3" => {
344				tracing::info!("Using async backing V3 chain spec.");
345				cumulus_test_service::get_chain_spec(
346					cumulus_test_runtime::v3::WASM_BINARY,
347					Some(ParaId::from(2700)),
348				)
349			},
350			"v3-rpo-2" => {
351				tracing::info!("Using async backing V3 with relay parent offset 2 chain spec.");
352				cumulus_test_service::get_chain_spec(
353					cumulus_test_runtime::v3_rpo_2::WASM_BINARY,
354					Some(ParaId::from(2700)),
355				)
356			},
357			"v3-rpo-4" => {
358				tracing::info!("Using async backing V3 with relay parent offset 4 chain spec.");
359				cumulus_test_service::get_chain_spec(
360					cumulus_test_runtime::v3_rpo_4::WASM_BINARY,
361					Some(ParaId::from(2700)),
362				)
363			},
364			"v3-rpo-6" => {
365				tracing::info!("Using async backing V3 with relay parent offset 6 chain spec.");
366				cumulus_test_service::get_chain_spec(
367					cumulus_test_runtime::v3_rpo_6::WASM_BINARY,
368					Some(ParaId::from(2700)),
369				)
370			},
371			"v3-rpo-15" => {
372				tracing::info!("Using async backing V3 with relay parent offset 15 chain spec.");
373				cumulus_test_service::get_chain_spec(
374					cumulus_test_runtime::v3_rpo_15::WASM_BINARY,
375					Some(ParaId::from(2700)),
376				)
377			},
378			"elastic-scaling-v3" => {
379				tracing::info!("Using elastic scaling V3 chain spec.");
380				cumulus_test_service::get_chain_spec(
381					cumulus_test_runtime::elastic_scaling_v3::WASM_BINARY,
382					Some(ParaId::from(2800)),
383				)
384			},
385			path => {
386				let chain_spec: sc_chain_spec::GenericChainSpec =
387					sc_chain_spec::GenericChainSpec::from_json_file(path.into())?;
388				chain_spec
389			},
390		}))
391	}
392}
393
394impl SubstrateCli for RelayChainCli {
395	fn impl_name() -> String {
396		"Polkadot collator".into()
397	}
398
399	fn impl_version() -> String {
400		String::new()
401	}
402
403	fn description() -> String {
404		format!(
405			"Polkadot collator\n\nThe command-line arguments provided first will be \
406		passed to the parachain node, while the arguments provided after -- will be passed \
407		to the relay chain node.\n\n\
408		{} [parachain-args] -- [relay_chain-args]",
409			Self::executable_name()
410		)
411	}
412
413	fn author() -> String {
414		env!("CARGO_PKG_AUTHORS").into()
415	}
416
417	fn support_url() -> String {
418		"https://github.com/paritytech/polkadot-sdk/issues/new".into()
419	}
420
421	fn copyright_start_year() -> i32 {
422		2017
423	}
424
425	fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
426		<polkadot_cli::Cli as SubstrateCli>::from_iter([RelayChainCli::executable_name()].iter())
427			.load_spec(id)
428	}
429}