use crate::{ chain_spec, cli::{Cli, Subcommand}, command_helper::{inherent_benchmark_data, BenchmarkExtrinsicBuilder}, service, }; use frame_benchmarking_cli::{BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE}; use node_template_runtime::Block; use sc_cli::{ChainSpec, RuntimeVersion, SubstrateCli}; use sc_service::PartialComponents; use std::sync::Arc; impl SubstrateCli for Cli { fn impl_name() -> String { "Substrate Node".into() } fn impl_version() -> String { env!("SUBSTRATE_CLI_IMPL_VERSION").into() } fn description() -> String { env!("CARGO_PKG_DESCRIPTION").into() } fn author() -> String { env!("CARGO_PKG_AUTHORS").into() } fn support_url() -> String { "support.anonymous.an".into() } fn copyright_start_year() -> i32 { 2017 } fn load_spec(&self, id: &str) -> Result, String> { Ok(match id { "dev" => Box::new(chain_spec::development_config()?), "" | "local" => Box::new(chain_spec::local_testnet_config()?), path => Box::new(chain_spec::ChainSpec::from_json_file(std::path::PathBuf::from(path))?), }) } fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { &node_template_runtime::VERSION } } /// Parse and run command line arguments pub fn run() -> sc_cli::Result<()> { let cli = Cli::from_args(); match &cli.subcommand { Some(Subcommand::Key(cmd)) => cmd.run(&cli), 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)?; runner.async_run(|config| { let PartialComponents { client, task_manager, import_queue, .. } = service::new_partial(&config)?; Ok((cmd.run(client, import_queue), task_manager)) }) }, Some(Subcommand::ExportBlocks(cmd)) => { let runner = cli.create_runner(cmd)?; runner.async_run(|config| { let PartialComponents { client, task_manager, .. } = service::new_partial(&config)?; Ok((cmd.run(client, config.database), task_manager)) }) }, Some(Subcommand::ExportState(cmd)) => { let runner = cli.create_runner(cmd)?; runner.async_run(|config| { let PartialComponents { client, task_manager, .. } = service::new_partial(&config)?; Ok((cmd.run(client, config.chain_spec), task_manager)) }) }, Some(Subcommand::ImportBlocks(cmd)) => { let runner = cli.create_runner(cmd)?; runner.async_run(|config| { let PartialComponents { client, task_manager, import_queue, .. } = service::new_partial(&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)?; runner.async_run(|config| { let PartialComponents { client, task_manager, backend, .. } = service::new_partial(&config)?; let aux_revert = Box::new(|client, _, blocks| { sc_finality_grandpa::revert(client, blocks)?; Ok(()) }); Ok((cmd.run(client, backend, Some(aux_revert)), task_manager)) }) }, Some(Subcommand::Benchmark(cmd)) => { let runner = cli.create_runner(cmd)?; runner.sync_run(|config| { // This switch needs to be in the client, since the client decides // which sub-commands it wants to support. match cmd { BenchmarkCmd::Pallet(cmd) => { if !cfg!(feature = "runtime-benchmarks") { return Err( "Runtime benchmarking wasn't enabled when building the node. \ You can enable it with `--features runtime-benchmarks`." .into(), ) } cmd.run::(config) }, BenchmarkCmd::Block(cmd) => { let PartialComponents { client, .. } = service::new_partial(&config)?; cmd.run(client) }, BenchmarkCmd::Storage(cmd) => { let PartialComponents { client, backend, .. } = service::new_partial(&config)?; let db = backend.expose_db(); let storage = backend.expose_storage(); cmd.run(config, client, db, storage) }, BenchmarkCmd::Overhead(cmd) => { let PartialComponents { client, .. } = service::new_partial(&config)?; let ext_builder = BenchmarkExtrinsicBuilder::new(client.clone()); cmd.run(config, client, inherent_benchmark_data()?, Arc::new(ext_builder)) }, BenchmarkCmd::Machine(cmd) => cmd.run(&config, SUBSTRATE_REFERENCE_HARDWARE.clone()), } }) }, #[cfg(feature = "try-runtime")] Some(Subcommand::TryRuntime(cmd)) => { let runner = cli.create_runner(cmd)?; runner.async_run(|config| { // we don't need any of the components of new_partial, just a runtime, or a task // manager to do `async_run`. let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); let task_manager = sc_service::TaskManager::new(config.tokio_handle.clone(), registry) .map_err(|e| sc_cli::Error::Service(sc_service::Error::Prometheus(e)))?; Ok((cmd.run::(config), task_manager)) }) }, #[cfg(not(feature = "try-runtime"))] Some(Subcommand::TryRuntime) => Err("TryRuntime wasn't enabled when building the node. \ You can enable it with `--features try-runtime`." .into()), Some(Subcommand::ChainInfo(cmd)) => { let runner = cli.create_runner(cmd)?; runner.sync_run(|config| cmd.run::(&config)) }, None => { let runner = cli.create_runner(&cli.run)?; runner.run_node_until_exit(|config| async move { service::new_full(config).map_err(sc_cli::Error::Service) }) }, } }