command.rs 8.34 KB
Newer Older
Gavin Wood's avatar
Gavin Wood committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.

use log::info;
Seun Lanlege's avatar
Seun Lanlege committed
18
use service::{IdentifyVariant, self};
Bastian Köcher's avatar
Bastian Köcher committed
19
use sc_cli::{SubstrateCli, Result, RuntimeVersion, Role};
Gavin Wood's avatar
Gavin Wood committed
20
use crate::cli::{Cli, Subcommand};
21

Gavin Wood's avatar
Gavin Wood committed
22
23
24
25
26
27
28
fn get_exec_name() -> Option<String> {
	std::env::current_exe()
		.ok()
		.and_then(|pb| pb.file_name().map(|s| s.to_os_string()))
		.and_then(|s| s.into_string().ok())
}

29
impl SubstrateCli for Cli {
30
	fn impl_name() -> String { "Parity Polkadot".into() }
31

32
	fn impl_version() -> String { env!("SUBSTRATE_CLI_IMPL_VERSION").into() }
33

34
	fn description() -> String { env!("CARGO_PKG_DESCRIPTION").into() }
35

36
	fn author() -> String { env!("CARGO_PKG_AUTHORS").into() }
37

38
	fn support_url() -> String { "https://github.com/paritytech/polkadot/issues/new".into() }
39
40
41

	fn copyright_start_year() -> i32 { 2017 }

42
	fn executable_name() -> String { "polkadot".into() }
43
44

	fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
Gavin Wood's avatar
Gavin Wood committed
45
46
		let id = if id == "" {
			let n = get_exec_name().unwrap_or_default();
47
			["polkadot", "kusama", "westend", "rococo"].iter()
Gavin Wood's avatar
Gavin Wood committed
48
49
50
51
				.cloned()
				.find(|&chain| n.starts_with(chain))
				.unwrap_or("polkadot")
		} else { id };
52
		Ok(match id {
Wei Tang's avatar
Wei Tang committed
53
54
55
56
57
58
			"polkadot-dev" | "dev" => Box::new(service::chain_spec::polkadot_development_config()?),
			"polkadot-local" => Box::new(service::chain_spec::polkadot_local_testnet_config()?),
			"polkadot-staging" => Box::new(service::chain_spec::polkadot_staging_testnet_config()?),
			"kusama-dev" => Box::new(service::chain_spec::kusama_development_config()?),
			"kusama-local" => Box::new(service::chain_spec::kusama_local_testnet_config()?),
			"kusama-staging" => Box::new(service::chain_spec::kusama_staging_testnet_config()?),
Gavin Wood's avatar
Gavin Wood committed
59
			"polkadot" => Box::new(service::chain_spec::polkadot_config()?),
60
			"westend" => Box::new(service::chain_spec::westend_config()?),
Gavin Wood's avatar
Gavin Wood committed
61
			"kusama" => Box::new(service::chain_spec::kusama_config()?),
Wei Tang's avatar
Wei Tang committed
62
63
64
			"westend-dev" => Box::new(service::chain_spec::westend_development_config()?),
			"westend-local" => Box::new(service::chain_spec::westend_local_testnet_config()?),
			"westend-staging" => Box::new(service::chain_spec::westend_staging_testnet_config()?),
65
66
67
			"rococo-staging" => Box::new(service::chain_spec::rococo_staging_testnet_config()?),
			"rococo-local" => Box::new(service::chain_spec::rococo_local_testnet_config()?),
			"rococo" => Box::new(service::chain_spec::rococo_config()?),
68
69
70
71
72
73
74
75
76
			path => {
				let path = std::path::PathBuf::from(path);

				let starts_with = |prefix: &str| {
					path.file_name().map(|f| f.to_str().map(|s| s.starts_with(&prefix))).flatten().unwrap_or(false)
				};

				// When `force_*` is given or the file name starts with the name of one of the known chains,
				// we use the chain spec for the specific chain.
77
78
79
				if self.run.force_rococo || starts_with("rococo") {
					Box::new(service::RococoChainSpec::from_json_file(path)?)
				} else if self.run.force_kusama || starts_with("kusama") {
80
81
82
83
84
85
					Box::new(service::KusamaChainSpec::from_json_file(path)?)
				} else if self.run.force_westend || starts_with("westend") {
					Box::new(service::WestendChainSpec::from_json_file(path)?)
				} else {
					Box::new(service::PolkadotChainSpec::from_json_file(path)?)
				}
86
87
88
			},
		})
	}
89
90
91
92
93
94

	fn native_runtime_version(spec: &Box<dyn service::ChainSpec>) -> &'static RuntimeVersion {
		if spec.is_kusama() {
			&service::kusama_runtime::VERSION
		} else if spec.is_westend() {
			&service::westend_runtime::VERSION
95
96
		} else if spec.is_rococo() {
			&service::rococo_runtime::VERSION
97
98
99
100
		} else {
			&service::polkadot_runtime::VERSION
		}
	}
101
}
Gavin Wood's avatar
Gavin Wood committed
102

103
104
105
106
107
108
109
110
111
112
113
114
115
116
fn set_default_ss58_version(spec: &Box<dyn service::ChainSpec>) {
	use sp_core::crypto::Ss58AddressFormat;

	let ss58_version = if spec.is_kusama() {
		Ss58AddressFormat::KusamaAccount
	} else if spec.is_westend() {
		Ss58AddressFormat::SubstrateAccount
	} else {
		Ss58AddressFormat::PolkadotAccount
	};

	sp_core::crypto::set_default_ss58_version(ss58_version);
}

Gavin Wood's avatar
Gavin Wood committed
117
/// Parses polkadot specific CLI arguments and run the service.
118
119
120
121
pub fn run() -> Result<()> {
	let cli = Cli::from_args();

	match &cli.subcommand {
Gavin Wood's avatar
Gavin Wood committed
122
		None => {
123
124
			let runner = cli.create_runner(&cli.run.base)?;
			let chain_spec = &runner.config().chain_spec;
125
126
127

			set_default_ss58_version(chain_spec);

128
129
130
131
132
			let grandpa_pause = if cli.run.grandpa_pause.is_empty() {
				None
			} else {
				Some((cli.run.grandpa_pause[0], cli.run.grandpa_pause[1]))
			};
Gavin Wood's avatar
Gavin Wood committed
133

134
			if chain_spec.is_kusama() {
Gavin Wood's avatar
Gavin Wood committed
135
136
137
138
139
				info!("----------------------------");
				info!("This chain is not in any way");
				info!("      endorsed by the       ");
				info!("     KUSAMA FOUNDATION      ");
				info!("----------------------------");
140
			}
Gavin Wood's avatar
Gavin Wood committed
141

142
			runner.run_node_until_exit(|config| async move {
143
144
145
				let role = config.role.clone();

				match role {
146
147
148
					Role::Light => service::build_light(config).map(|(task_manager, _)| task_manager),
					_ => service::build_full(
						config,
149
						service::IsCollator::No,
150
						grandpa_pause,
151
					).map(|full| full.task_manager),
152
153
				}
			})
Gavin Wood's avatar
Gavin Wood committed
154
		},
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
		Some(Subcommand::BuildSpec(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.sync_run(|config| cmd.run(config.chain_spec, config.network))
		},
		Some(Subcommand::CheckBlock(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			let chain_spec = &runner.config().chain_spec;

			set_default_ss58_version(chain_spec);

			runner.async_run(|mut config| {
				let (client, _, import_queue, task_manager) = service::new_chain_ops(&mut config)?;
				Ok((cmd.run(client, import_queue), task_manager))
			})
		},
		Some(Subcommand::ExportBlocks(cmd)) => {
			let runner = cli.create_runner(cmd)?;
172
			let chain_spec = &runner.config().chain_spec;
173
174

			set_default_ss58_version(chain_spec);
Gavin Wood's avatar
Gavin Wood committed
175

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
			runner.async_run(|mut config| {
				let (client, _, _, task_manager) = service::new_chain_ops(&mut config)?;
				Ok((cmd.run(client, config.database), task_manager))
			})
		},
		Some(Subcommand::ExportState(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			let chain_spec = &runner.config().chain_spec;

			set_default_ss58_version(chain_spec);

			runner.async_run(|mut config| {
				let (client, _, _, task_manager) = service::new_chain_ops(&mut config)?;
				Ok((cmd.run(client, config.chain_spec), task_manager))
			})
		},
		Some(Subcommand::ImportBlocks(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			let chain_spec = &runner.config().chain_spec;

			set_default_ss58_version(chain_spec);

			runner.async_run(|mut config| {
				let (client, _, import_queue, task_manager) = service::new_chain_ops(&mut config)?;
				Ok((cmd.run(client, import_queue), task_manager))
			})
		},
		Some(Subcommand::PurgeChain(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.sync_run(|config| cmd.run(config.database))
		},
		Some(Subcommand::Revert(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			let chain_spec = &runner.config().chain_spec;

			set_default_ss58_version(chain_spec);

			runner.async_run(|mut config| {
				let (client, backend, _, task_manager) = service::new_chain_ops(&mut config)?;
				Ok((cmd.run(client, backend), task_manager))
			})
Gavin Wood's avatar
Gavin Wood committed
217
		},
218
		Some(Subcommand::ValidationWorker(cmd)) => {
219
			let _ = sc_cli::init_logger("", sc_tracing::TracingReceiver::Log, None, false);
Gavin Wood's avatar
Gavin Wood committed
220

221
			if cfg!(feature = "browser") || cfg!(target_os = "android") {
222
				Err(sc_cli::Error::Input("Cannot run validation worker in browser".into()))
Gavin Wood's avatar
Gavin Wood committed
223
			} else {
224
225
				#[cfg(not(any(target_os = "android", feature = "browser")))]
				polkadot_parachain::wasm_executor::run_worker(&cmd.mem_id)?;
Gavin Wood's avatar
Gavin Wood committed
226
227
228
				Ok(())
			}
		},
229
		Some(Subcommand::Benchmark(cmd)) => {
230
231
			let runner = cli.create_runner(cmd)?;
			let chain_spec = &runner.config().chain_spec;
232
233

			set_default_ss58_version(chain_spec);
234

235
236
237
			runner.sync_run(|config| {
				cmd.run::<service::kusama_runtime::Block, service::KusamaExecutor>(config)
			})
238
		},
Bastian Köcher's avatar
Bastian Köcher committed
239
		Some(Subcommand::Key(cmd)) => cmd.run(),
Gavin Wood's avatar
Gavin Wood committed
240
241
	}
}