git.delta.rocks / unique-network / refs/commits / 20d08c295b0d

difftreelog

source

src/cli.rs3.8 KiBsourcehistory
1use crate::service;2use futures::{future, Future, sync::oneshot};3use std::cell::RefCell;4use tokio::runtime::Runtime;5pub use substrate_cli::{VersionInfo, IntoExit, error};6use substrate_cli::{informant, parse_and_prepare, ParseAndPrepare, NoCustom};7use substrate_service::{AbstractService, Roles as ServiceRoles, Configuration};8use aura_primitives::sr25519::{AuthorityPair as AuraPair};9use crate::chain_spec;10use log::info;1112/// Parse command line arguments into service configuration.13pub fn run<I, T, E>(args: I, exit: E, version: VersionInfo) -> error::Result<()> where14	I: IntoIterator<Item = T>,15	T: Into<std::ffi::OsString> + Clone,16	E: IntoExit,17{18	type Config<T> = Configuration<(), T>;19	match parse_and_prepare::<NoCustom, NoCustom, _>(&version, "substrate-node", args) {20		ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit,21		|exit, _cli_args, _custom_args, config: Config<_>| {22			info!("{}", version.name);23			info!("  version {}", config.full_version());24			info!("  by {}, 2017, 2018", version.author);25			info!("Chain specification: {}", config.chain_spec.name());26			info!("Node name: {}", config.name);27			info!("Roles: {:?}", config.roles);28			let runtime = Runtime::new().map_err(|e| format!("{:?}", e))?;29			match config.roles {30				ServiceRoles::LIGHT => run_until_exit(31					runtime,32				 	service::new_light(config).map_err(|e| format!("{:?}", e))?,33					exit34				),35				_ => run_until_exit(36					runtime,37					service::new_full(config).map_err(|e| format!("{:?}", e))?,38					exit39				),40			}.map_err(|e| format!("{:?}", e))41		}),42		ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec),43		ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>|44			Ok(new_full_start!(config).0), load_spec, exit),45		ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>|46			Ok(new_full_start!(config).0), load_spec, exit),47		ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec),48		ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder(|config: Config<_>|49			Ok(new_full_start!(config).0), load_spec),50		ParseAndPrepare::CustomCommand(_) => Ok(())51	}?;5253	Ok(())54}5556fn load_spec(id: &str) -> Result<Option<chain_spec::ChainSpec>, String> {57	Ok(match chain_spec::Alternative::from(id) {58		Some(spec) => Some(spec.load()?),59		None => None,60	})61}6263fn run_until_exit<T, E>(64	mut runtime: Runtime,65	service: T,66	e: E,67) -> error::Result<()>68where69	T: AbstractService,70	E: IntoExit,71{72	let (exit_send, exit) = exit_future::signal();7374	let informant = informant::build(&service);75	runtime.executor().spawn(exit.until(informant).map(|_| ()));7677	// we eagerly drop the service so that the internal exit future is fired,78	// but we need to keep holding a reference to the global telemetry guard79	let _telemetry = service.telemetry();8081	let service_res = {82		let exit = e.into_exit().map_err(|_| error::Error::Other("Exit future failed.".into()));83		let service = service.map_err(|err| error::Error::Service(err));84		let select = service.select(exit).map(|_| ()).map_err(|(err, _)| err);85		runtime.block_on(select)86	};8788	exit_send.fire();8990	// TODO [andre]: timeout this future #131891	let _ = runtime.shutdown_on_idle().wait();9293	service_res94}9596// handles ctrl-c97pub struct Exit;98impl IntoExit for Exit {99	type Exit = future::MapErr<oneshot::Receiver<()>, fn(oneshot::Canceled) -> ()>;100	fn into_exit(self) -> Self::Exit {101		// can't use signal directly here because CtrlC takes only `Fn`.102		let (exit_send, exit) = oneshot::channel();103104		let exit_send_cell = RefCell::new(Some(exit_send));105		ctrlc::set_handler(move || {106			let exit_send = exit_send_cell.try_borrow_mut().expect("signal handler not reentrant; qed").take();107			if let Some(exit_send) = exit_send {108				exit_send.send(()).expect("Error sending exit notification");109			}110		}).expect("Error setting Ctrl-C handler");111112		exit.map_err(drop)113	}114}