git.delta.rocks / unique-network / refs/commits / 5e8916aa3a6c

difftreelog

source

node/cli/src/command.rs13.1 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// Original license18// This file is part of Substrate.1920// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd.21// SPDX-License-Identifier: Apache-2.02223// Licensed under the Apache License, Version 2.0 (the "License");24// you may not use this file except in compliance with the License.25// You may obtain a copy of the License at26//27// 	http://www.apache.org/licenses/LICENSE-2.028//29// Unless required by applicable law or agreed to in writing, software30// distributed under the License is distributed on an "AS IS" BASIS,31// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.32// See the License for the specific language governing permissions and33// limitations under the License.3435use crate::{36	chain_spec,37	cli::{Cli, RelayChainCli, Subcommand},38	service::{new_partial, ParachainRuntimeExecutor},39};40use codec::Encode;41use cumulus_primitives_core::ParaId;42use cumulus_client_service::genesis::generate_genesis_block;43use log::info;44use unique_runtime::Block;45use polkadot_parachain::primitives::AccountIdConversion;46use sc_cli::{47	ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams,48	NetworkParams, Result, RuntimeVersion, SharedParams, SubstrateCli,49};50use sc_service::{51	config::{BasePath, PrometheusConfig},52};53use sp_core::hexdisplay::HexDisplay;54use sp_runtime::traits::Block as BlockT;55use std::{io::Write, net::SocketAddr};5657fn load_spec(id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {58	Ok(match id {59		"westend-local" => Box::new(chain_spec::local_testnet_westend_config()),60		"rococo-local" => Box::new(chain_spec::local_testnet_rococo_config()),61		"dev" => Box::new(chain_spec::development_config()),62		"" | "local" => Box::new(chain_spec::local_testnet_rococo_config()),63		path => Box::new(chain_spec::ChainSpec::from_json_file(64			std::path::PathBuf::from(path),65		)?),66	})67}6869impl SubstrateCli for Cli {70	// TODO use args71	fn impl_name() -> String {72		"Quartz Node".into()73	}7475	fn impl_version() -> String {76		env!("SUBSTRATE_CLI_IMPL_VERSION").into()77	}78	// TODO use args79	fn description() -> String {80		format!(81			"Quartz Node\n\nThe command-line arguments provided first will be \82		passed to the parachain node, while the arguments provided after -- will be passed \83		to the relaychain node.\n\n\84		{} [parachain-args] -- [relaychain-args]",85			Self::executable_name()86		)87	}8889	fn author() -> String {90		env!("CARGO_PKG_AUTHORS").into()91	}9293	//TODO use args94	fn support_url() -> String {95		"support@unique.network".into()96	}9798	fn copyright_start_year() -> i32 {99		2019100	}101102	fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {103		load_spec(id)104	}105106	fn native_runtime_version(_: &Box<dyn ChainSpec>) -> &'static RuntimeVersion {107		&unique_runtime::VERSION108	}109}110111impl SubstrateCli for RelayChainCli {112	// TODO use args113	fn impl_name() -> String {114		"Quartz Node".into()115	}116117	fn impl_version() -> String {118		env!("SUBSTRATE_CLI_IMPL_VERSION").into()119	}120	// TODO use args121	fn description() -> String {122		"Quartz Node\n\nThe command-line arguments provided first will be \123		passed to the parachain node, while the arguments provided after -- will be passed \124		to the relaychain node.\n\n\125		parachain-collator [parachain-args] -- [relaychain-args]"126			.into()127	}128129	fn author() -> String {130		env!("CARGO_PKG_AUTHORS").into()131	}132	// TODO use args133	fn support_url() -> String {134		"support@unique.network".into()135	}136137	fn copyright_start_year() -> i32 {138		2019139	}140141	fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {142		polkadot_cli::Cli::from_iter([RelayChainCli::executable_name()].iter()).load_spec(id)143	}144145	fn native_runtime_version(chain_spec: &Box<dyn ChainSpec>) -> &'static RuntimeVersion {146		polkadot_cli::Cli::native_runtime_version(chain_spec)147	}148}149150#[allow(clippy::borrowed_box)]151fn extract_genesis_wasm(chain_spec: &Box<dyn sc_service::ChainSpec>) -> Result<Vec<u8>> {152	let mut storage = chain_spec.build_storage()?;153154	storage155		.top156		.remove(sp_core::storage::well_known_keys::CODE)157		.ok_or_else(|| "Could not find wasm file in genesis state!".into())158}159160macro_rules! construct_async_run {161	(|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{162		let runner = $cli.create_runner($cmd)?;163		runner.async_run(|$config| {164			let $components = new_partial::<165				_166			>(167				&$config,168				crate::service::parachain_build_import_queue,169			)?;170			let task_manager = $components.task_manager;171			{ $( $code )* }.map(|v| (v, task_manager))172		})173	}}174}175176/// Parse command line arguments into service configuration.177pub fn run() -> Result<()> {178	let cli = Cli::from_args();179180	match &cli.subcommand {181		Some(Subcommand::BuildSpec(cmd)) => {182			let runner = cli.create_runner(cmd)?;183			runner.sync_run(|config| cmd.run(config.chain_spec, config.network))184		}185		Some(Subcommand::CheckBlock(cmd)) => {186			construct_async_run!(|components, cli, cmd, config| {187				Ok(cmd.run(components.client, components.import_queue))188			})189		}190		Some(Subcommand::ExportBlocks(cmd)) => {191			construct_async_run!(|components, cli, cmd, config| {192				Ok(cmd.run(components.client, config.database))193			})194		}195		Some(Subcommand::ExportState(cmd)) => {196			construct_async_run!(|components, cli, cmd, config| {197				Ok(cmd.run(components.client, config.chain_spec))198			})199		}200		Some(Subcommand::ImportBlocks(cmd)) => {201			construct_async_run!(|components, cli, cmd, config| {202				Ok(cmd.run(components.client, components.import_queue))203			})204		}205		Some(Subcommand::PurgeChain(cmd)) => {206			let runner = cli.create_runner(cmd)?;207208			runner.sync_run(|config| {209				let polkadot_cli = RelayChainCli::new(210					&config,211					[RelayChainCli::executable_name()]212						.iter()213						.chain(cli.relaychain_args.iter()),214				);215216				let polkadot_config = SubstrateCli::create_configuration(217					&polkadot_cli,218					&polkadot_cli,219					config.tokio_handle.clone(),220				)221				.map_err(|err| format!("Relay chain argument error: {}", err))?;222223				cmd.run(config, polkadot_config)224			})225		}226		Some(Subcommand::Revert(cmd)) => construct_async_run!(|components, cli, cmd, config| {227			Ok(cmd.run(components.client, components.backend))228		}),229		Some(Subcommand::ExportGenesisState(params)) => {230			let mut builder = sc_cli::LoggerBuilder::new("");231			builder.with_profiling(sc_tracing::TracingReceiver::Log, "");232			let _ = builder.init();233234			let spec = load_spec(&params.chain.clone().unwrap_or_default())?;235			let state_version = Cli::native_runtime_version(&spec).state_version();236			let block: Block = generate_genesis_block(&spec, state_version)?;237			let raw_header = block.header().encode();238			let output_buf = if params.raw {239				raw_header240			} else {241				format!("0x{:?}", HexDisplay::from(&block.header().encode())).into_bytes()242			};243244			if let Some(output) = &params.output {245				std::fs::write(output, output_buf)?;246			} else {247				std::io::stdout().write_all(&output_buf)?;248			}249250			Ok(())251		}252		Some(Subcommand::ExportGenesisWasm(params)) => {253			let mut builder = sc_cli::LoggerBuilder::new("");254			builder.with_profiling(sc_tracing::TracingReceiver::Log, "");255			let _ = builder.init();256257			let raw_wasm_blob =258				extract_genesis_wasm(&cli.load_spec(&params.chain.clone().unwrap_or_default())?)?;259			let output_buf = if params.raw {260				raw_wasm_blob261			} else {262				format!("0x{:?}", HexDisplay::from(&raw_wasm_blob)).into_bytes()263			};264265			if let Some(output) = &params.output {266				std::fs::write(output, output_buf)?;267			} else {268				std::io::stdout().write_all(&output_buf)?;269			}270271			Ok(())272		}273		Some(Subcommand::Benchmark(cmd)) => {274			if cfg!(feature = "runtime-benchmarks") {275				let runner = cli.create_runner(cmd)?;276277				runner.sync_run(|config| cmd.run::<Block, ParachainRuntimeExecutor>(config))278			} else {279				Err("Benchmarking wasn't enabled when building the node. \280				You can enable it with `--features runtime-benchmarks`."281					.into())282			}283		}284		None => {285			let runner = cli.create_runner(&cli.run.normalize())?;286287			runner.run_node_until_exit(|config| async move {288				let para_id = chain_spec::Extensions::try_get(&*config.chain_spec)289					.map(|e| e.para_id)290					.ok_or("Could not find parachain ID in chain-spec.")?;291292				let polkadot_cli = RelayChainCli::new(293					&config,294					[RelayChainCli::executable_name()]295						.iter()296						.chain(cli.relaychain_args.iter()),297				);298299				let id = ParaId::from(para_id);300301				let parachain_account =302					AccountIdConversion::<polkadot_primitives::v0::AccountId>::into_account(&id);303304				let state_version =305					RelayChainCli::native_runtime_version(&config.chain_spec).state_version();306				let block: Block = generate_genesis_block(&config.chain_spec, state_version)307					.map_err(|e| format!("{:?}", e))?;308				let genesis_state = format!("0x{:?}", HexDisplay::from(&block.header().encode()));309				let genesis_hash = format!("0x{:?}", HexDisplay::from(&block.header().hash().0));310311				let polkadot_config = SubstrateCli::create_configuration(312					&polkadot_cli,313					&polkadot_cli,314					config.tokio_handle.clone(),315				)316				.map_err(|err| format!("Relay chain argument error: {}", err))?;317318				info!("Parachain id: {:?}", id);319				info!("Parachain Account: {}", parachain_account);320				info!("Parachain genesis state: {}", genesis_state);321				info!("Parachain genesis hash: {}", genesis_hash);322				info!(323					"Is collating: {}",324					if config.role.is_authority() {325						"yes"326					} else {327						"no"328					}329				);330331				crate::service::start_node(config, polkadot_config, id)332					.await333					.map(|r| r.0)334					.map_err(Into::into)335			})336		}337	}338}339340impl DefaultConfigurationValues for RelayChainCli {341	fn p2p_listen_port() -> u16 {342		30334343	}344345	fn rpc_ws_listen_port() -> u16 {346		9945347	}348349	fn rpc_http_listen_port() -> u16 {350		9934351	}352353	fn prometheus_listen_port() -> u16 {354		9616355	}356}357358impl CliConfiguration<Self> for RelayChainCli {359	fn shared_params(&self) -> &SharedParams {360		self.base.base.shared_params()361	}362363	fn import_params(&self) -> Option<&ImportParams> {364		self.base.base.import_params()365	}366367	fn network_params(&self) -> Option<&NetworkParams> {368		self.base.base.network_params()369	}370371	fn keystore_params(&self) -> Option<&KeystoreParams> {372		self.base.base.keystore_params()373	}374375	fn base_path(&self) -> Result<Option<BasePath>> {376		Ok(self377			.shared_params()378			.base_path()379			.or_else(|| self.base_path.clone().map(Into::into)))380	}381382	fn rpc_http(&self, default_listen_port: u16) -> Result<Option<SocketAddr>> {383		self.base.base.rpc_http(default_listen_port)384	}385386	fn rpc_ipc(&self) -> Result<Option<String>> {387		self.base.base.rpc_ipc()388	}389390	fn rpc_ws(&self, default_listen_port: u16) -> Result<Option<SocketAddr>> {391		self.base.base.rpc_ws(default_listen_port)392	}393394	fn prometheus_config(395		&self,396		default_listen_port: u16,397		chain_spec: &Box<dyn ChainSpec>,398	) -> Result<Option<PrometheusConfig>> {399		self.base400			.base401			.prometheus_config(default_listen_port, chain_spec)402	}403404	fn init<F>(405		&self,406		_support_url: &String,407		_impl_version: &String,408		_logger_hook: F,409		_config: &sc_service::Configuration,410	) -> Result<()> {411		unreachable!("PolkadotCli is never initialized; qed");412	}413414	fn chain_id(&self, is_dev: bool) -> Result<String> {415		let chain_id = self.base.base.chain_id(is_dev)?;416417		Ok(if chain_id.is_empty() {418			self.chain_id.clone().unwrap_or_default()419		} else {420			chain_id421		})422	}423424	fn role(&self, is_dev: bool) -> Result<sc_service::Role> {425		self.base.base.role(is_dev)426	}427428	fn transaction_pool(&self) -> Result<sc_service::config::TransactionPoolOptions> {429		self.base.base.transaction_pool()430	}431432	fn state_cache_child_ratio(&self) -> Result<Option<usize>> {433		self.base.base.state_cache_child_ratio()434	}435436	fn rpc_methods(&self) -> Result<sc_service::config::RpcMethods> {437		self.base.base.rpc_methods()438	}439440	fn rpc_ws_max_connections(&self) -> Result<Option<usize>> {441		self.base.base.rpc_ws_max_connections()442	}443444	fn rpc_cors(&self, is_dev: bool) -> Result<Option<Vec<String>>> {445		self.base.base.rpc_cors(is_dev)446	}447448	fn default_heap_pages(&self) -> Result<Option<u64>> {449		self.base.base.default_heap_pages()450	}451452	fn force_authoring(&self) -> Result<bool> {453		self.base.base.force_authoring()454	}455456	fn disable_grandpa(&self) -> Result<bool> {457		self.base.base.disable_grandpa()458	}459460	fn max_runtime_instances(&self) -> Result<Option<usize>> {461		self.base.base.max_runtime_instances()462	}463464	fn announce_block(&self) -> Result<bool> {465		self.base.base.announce_block()466	}467468	fn telemetry_endpoints(469		&self,470		chain_spec: &Box<dyn ChainSpec>,471	) -> Result<Option<sc_telemetry::TelemetryEndpoints>> {472		self.base.base.telemetry_endpoints(chain_spec)473	}474}