// 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 . use log::info; use sp_runtime::traits::BlakeTwo256; use service::{IsKusama, Block, self, RuntimeApiCollection, TFullClient}; use sp_api::ConstructRuntimeApi; use sc_executor::NativeExecutionDispatch; use crate::chain_spec::load_spec; use crate::cli::{Cli, Subcommand}; use sc_cli::VersionInfo; /// Parses polkadot specific CLI arguments and run the service. pub fn run(version: VersionInfo) -> sc_cli::Result<()> { let opt = sc_cli::from_args::(&version); let mut config = service::Configuration::from_version(&version); config.impl_name = "parity-polkadot"; match opt.subcommand { None => { opt.run.init(&version)?; opt.run.update_config(&mut config, load_spec, &version)?; let is_kusama = config.chain_spec.as_ref().map_or(false, |s| s.is_kusama()); info!("{}", version.name); info!(" version {}", config.full_version()); info!(" by {}, 2017-2020", version.author); info!("Chain specification: {}", config.expect_chain_spec().name()); info!("Node name: {}", config.name); info!("Roles: {}", config.display_role()); if is_kusama { info!("Native runtime: {}", service::KusamaExecutor::native_version().runtime_version); info!("----------------------------"); info!("This chain is not in any way"); info!(" endorsed by the "); info!(" KUSAMA FOUNDATION "); info!("----------------------------"); run_service_until_exit::< service::kusama_runtime::RuntimeApi, service::KusamaExecutor, service::kusama_runtime::UncheckedExtrinsic, >(config, opt.authority_discovery_enabled) } else { info!("Native runtime: {}", service::PolkadotExecutor::native_version().runtime_version); run_service_until_exit::< service::polkadot_runtime::RuntimeApi, service::PolkadotExecutor, service::polkadot_runtime::UncheckedExtrinsic, >(config, opt.authority_discovery_enabled) } }, Some(Subcommand::Base(cmd)) => { cmd.init(&version)?; cmd.update_config(&mut config, load_spec, &version)?; let is_kusama = config.chain_spec.as_ref().map_or(false, |s| s.is_kusama()); if is_kusama { cmd.run(config, service::new_chain_ops::< service::kusama_runtime::RuntimeApi, service::KusamaExecutor, service::kusama_runtime::UncheckedExtrinsic, >) } else { cmd.run(config, service::new_chain_ops::< service::polkadot_runtime::RuntimeApi, service::PolkadotExecutor, service::polkadot_runtime::UncheckedExtrinsic, >) } }, Some(Subcommand::ValidationWorker(args)) => { sc_cli::init_logger(""); if cfg!(feature = "browser") { Err(sc_cli::Error::Input("Cannot run validation worker in browser".into())) } else { #[cfg(not(feature = "browser"))] service::run_validation_worker(&args.mem_id)?; Ok(()) } }, } } fn run_service_until_exit( config: service::Configuration, authority_discovery_enabled: bool, ) -> sc_cli::Result<()> where R: ConstructRuntimeApi> + Send + Sync + 'static, >>::RuntimeApi: RuntimeApiCollection, Block>>, >>::RuntimeApi: RuntimeApiCollection, Block>>, E: service::Codec + Send + Sync + 'static, D: service::NativeExecutionDispatch + 'static, // Rust bug: https://github.com/rust-lang/rust/issues/24159 <>>::RuntimeApi as sp_api::ApiExt>::StateBackend: sp_api::StateBackend, // Rust bug: https://github.com/rust-lang/rust/issues/43580 R: ConstructRuntimeApi< Block, TLightClient >, { match config.roles { service::Roles::LIGHT => sc_cli::run_service_until_exit( config, |config| service::new_light::(config), ), _ => sc_cli::run_service_until_exit( config, |config| service::new_full::(config, None, None, authority_discovery_enabled, 6000) .map(|(s, _)| s), ), } } // We can't simply use `service::TLightClient` due to a // Rust bug: https://github.com/rust-lang/rust/issues/43580 type TLightClient = sc_client::Client< sc_client::light::backend::Backend, BlakeTwo256>, sc_client::light::call_executor::GenesisCallExecutor< sc_client::light::backend::Backend, BlakeTwo256>, sc_client::LocalCallExecutor< sc_client::light::backend::Backend, BlakeTwo256>, sc_executor::NativeExecutor > >, Block, Runtime >;