diff --git a/Cargo.lock b/Cargo.lock
index 358f22463a4b2..f640e41c8bd7b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5809,7 +5809,6 @@ dependencies = [
"atty",
"chrono",
"derive_more",
- "directories",
"env_logger 0.7.1",
"fdlimit",
"futures 0.3.4",
@@ -6567,6 +6566,7 @@ name = "sc-service"
version = "0.8.0-rc2"
dependencies = [
"derive_more",
+ "directories",
"exit-future",
"futures 0.1.29",
"futures 0.3.4",
@@ -6619,6 +6619,7 @@ dependencies = [
"substrate-prometheus-endpoint",
"substrate-test-runtime-client",
"sysinfo",
+ "tempfile",
"tracing",
"wasm-timer",
]
diff --git a/bin/node/cli/src/cli.rs b/bin/node/cli/src/cli.rs
index 0156faf47ee4a..29e916fe0180e 100644
--- a/bin/node/cli/src/cli.rs
+++ b/bin/node/cli/src/cli.rs
@@ -20,7 +20,7 @@ use sc_cli::RunCmd;
use structopt::StructOpt;
/// An overarching CLI command definition.
-#[derive(Clone, Debug, StructOpt)]
+#[derive(Debug, StructOpt)]
pub struct Cli {
/// Possible subcommand with parameters.
#[structopt(subcommand)]
@@ -31,7 +31,7 @@ pub struct Cli {
}
/// Possible subcommands of the main binary.
-#[derive(Clone, Debug, StructOpt)]
+#[derive(Debug, StructOpt)]
pub enum Subcommand {
/// A set of base subcommands handled by `sc_cli`.
#[structopt(flatten)]
diff --git a/bin/node/cli/tests/temp_base_path_works.rs b/bin/node/cli/tests/temp_base_path_works.rs
new file mode 100644
index 0000000000000..9351568d87955
--- /dev/null
+++ b/bin/node/cli/tests/temp_base_path_works.rs
@@ -0,0 +1,72 @@
+// This file is part of Substrate.
+
+// Copyright (C) 2020 Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
+
+// This program 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.
+
+// This program 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 this program. If not, see .
+
+#![cfg(unix)]
+
+use assert_cmd::cargo::cargo_bin;
+use nix::sys::signal::{kill, Signal::SIGINT};
+use nix::unistd::Pid;
+use regex::Regex;
+use std::convert::TryInto;
+use std::io::Read;
+use std::path::PathBuf;
+use std::process::{Command, Stdio};
+use std::thread;
+use std::time::Duration;
+
+pub mod common;
+
+#[test]
+fn temp_base_path_works() {
+ let mut cmd = Command::new(cargo_bin("substrate"));
+
+ let mut cmd = cmd
+ .args(&["--dev", "--tmp"])
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped())
+ .spawn()
+ .unwrap();
+
+ // Let it produce some blocks.
+ thread::sleep(Duration::from_secs(30));
+ assert!(
+ cmd.try_wait().unwrap().is_none(),
+ "the process should still be running"
+ );
+
+ // Stop the process
+ kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap();
+ assert!(common::wait_for(&mut cmd, 40)
+ .map(|x| x.success())
+ .unwrap_or_default());
+
+ // Ensure the database has been deleted
+ let mut stderr = String::new();
+ cmd.stderr.unwrap().read_to_string(&mut stderr).unwrap();
+ let re = Regex::new(r"Database: .+ at (\S+)").unwrap();
+ let db_path = PathBuf::from(
+ re.captures(stderr.as_str())
+ .unwrap()
+ .get(1)
+ .unwrap()
+ .as_str()
+ .to_string(),
+ );
+
+ assert!(!db_path.exists());
+}
diff --git a/bin/node/inspect/src/cli.rs b/bin/node/inspect/src/cli.rs
index 4475d31755fdc..d66644bab52fa 100644
--- a/bin/node/inspect/src/cli.rs
+++ b/bin/node/inspect/src/cli.rs
@@ -23,7 +23,7 @@ use sc_cli::{ImportParams, SharedParams};
use structopt::StructOpt;
/// The `inspect` command used to print decoded chain data.
-#[derive(Debug, StructOpt, Clone)]
+#[derive(Debug, StructOpt)]
pub struct InspectCmd {
#[allow(missing_docs)]
#[structopt(flatten)]
@@ -39,7 +39,7 @@ pub struct InspectCmd {
}
/// A possible inspect sub-commands.
-#[derive(Debug, StructOpt, Clone)]
+#[derive(Debug, StructOpt)]
pub enum InspectSubCmd {
/// Decode block with native version of runtime and print out the details.
Block {
diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml
index 8c19da95c493b..f7e94f36d7473 100644
--- a/client/cli/Cargo.toml
+++ b/client/cli/Cargo.toml
@@ -20,7 +20,6 @@ regex = "1.3.1"
time = "0.1.42"
ansi_term = "0.12.1"
lazy_static = "1.4.0"
-directories = "2.0.2"
tokio = { version = "0.2.9", features = [ "signal", "rt-core", "rt-threaded" ] }
futures = "0.3.4"
fdlimit = "0.1.4"
diff --git a/client/cli/src/commands/build_spec_cmd.rs b/client/cli/src/commands/build_spec_cmd.rs
index d2e2ef3a5467c..23626359ff131 100644
--- a/client/cli/src/commands/build_spec_cmd.rs
+++ b/client/cli/src/commands/build_spec_cmd.rs
@@ -27,7 +27,7 @@ use structopt::StructOpt;
use std::io::Write;
/// The `build-spec` command used to build a specification.
-#[derive(Debug, StructOpt, Clone)]
+#[derive(Debug, StructOpt)]
pub struct BuildSpecCmd {
/// Force raw genesis storage output.
#[structopt(long = "raw")]
diff --git a/client/cli/src/commands/check_block_cmd.rs b/client/cli/src/commands/check_block_cmd.rs
index d1241f010d597..c000ea7fb11ee 100644
--- a/client/cli/src/commands/check_block_cmd.rs
+++ b/client/cli/src/commands/check_block_cmd.rs
@@ -25,7 +25,7 @@ use std::{fmt::Debug, str::FromStr};
use structopt::StructOpt;
/// The `check-block` command used to validate blocks.
-#[derive(Debug, StructOpt, Clone)]
+#[derive(Debug, StructOpt)]
pub struct CheckBlockCmd {
/// Block hash or number
#[structopt(value_name = "HASH or NUMBER")]
diff --git a/client/cli/src/commands/export_blocks_cmd.rs b/client/cli/src/commands/export_blocks_cmd.rs
index 2fdc408250bce..7c523c0555d55 100644
--- a/client/cli/src/commands/export_blocks_cmd.rs
+++ b/client/cli/src/commands/export_blocks_cmd.rs
@@ -31,7 +31,7 @@ use std::path::PathBuf;
use structopt::StructOpt;
/// The `export-blocks` command used to export blocks.
-#[derive(Debug, StructOpt, Clone)]
+#[derive(Debug, StructOpt)]
pub struct ExportBlocksCmd {
/// Output file name or stdout if unspecified.
#[structopt(parse(from_os_str))]
diff --git a/client/cli/src/commands/export_state_cmd.rs b/client/cli/src/commands/export_state_cmd.rs
index 33111e7737b1c..23a43a178abe5 100644
--- a/client/cli/src/commands/export_state_cmd.rs
+++ b/client/cli/src/commands/export_state_cmd.rs
@@ -27,7 +27,7 @@ use structopt::StructOpt;
/// The `export-state` command used to export the state of a given block into
/// a chain spec.
-#[derive(Debug, StructOpt, Clone)]
+#[derive(Debug, StructOpt)]
pub struct ExportStateCmd {
/// Block hash or number.
#[structopt(value_name = "HASH or NUMBER")]
@@ -59,7 +59,7 @@ impl ExportStateCmd {
{
info!("Exporting raw state...");
let mut input_spec = config.chain_spec.cloned_box();
- let block_id = self.input.clone().map(|b| b.parse()).transpose()?;
+ let block_id = self.input.as_ref().map(|b| b.parse()).transpose()?;
let raw_state = builder(config)?.export_raw_state(block_id)?;
input_spec.set_storage(raw_state);
diff --git a/client/cli/src/commands/import_blocks_cmd.rs b/client/cli/src/commands/import_blocks_cmd.rs
index a74f4d524c95b..8e178c4b97964 100644
--- a/client/cli/src/commands/import_blocks_cmd.rs
+++ b/client/cli/src/commands/import_blocks_cmd.rs
@@ -29,7 +29,7 @@ use std::path::PathBuf;
use structopt::StructOpt;
/// The `import-blocks` command used to import blocks.
-#[derive(Debug, StructOpt, Clone)]
+#[derive(Debug, StructOpt)]
pub struct ImportBlocksCmd {
/// Input file or stdin if unspecified.
#[structopt(parse(from_os_str))]
diff --git a/client/cli/src/commands/mod.rs b/client/cli/src/commands/mod.rs
index 62757890ef01d..a4d5c8ca7f20b 100644
--- a/client/cli/src/commands/mod.rs
+++ b/client/cli/src/commands/mod.rs
@@ -27,11 +27,11 @@ mod run_cmd;
pub use self::build_spec_cmd::BuildSpecCmd;
pub use self::check_block_cmd::CheckBlockCmd;
pub use self::export_blocks_cmd::ExportBlocksCmd;
+pub use self::export_state_cmd::ExportStateCmd;
pub use self::import_blocks_cmd::ImportBlocksCmd;
pub use self::purge_chain_cmd::PurgeChainCmd;
pub use self::revert_cmd::RevertCmd;
pub use self::run_cmd::RunCmd;
-pub use self::export_state_cmd::ExportStateCmd;
use std::fmt::Debug;
use structopt::StructOpt;
@@ -40,7 +40,7 @@ use structopt::StructOpt;
/// The core commands are split into multiple subcommands and `Run` is the default subcommand. From
/// the CLI user perspective, it is not visible that `Run` is a subcommand. So, all parameters of
/// `Run` are exported as main executable parameters.
-#[derive(Debug, Clone, StructOpt)]
+#[derive(Debug, StructOpt)]
pub enum Subcommand {
/// Build a spec.json file, outputs to stdout.
BuildSpec(BuildSpecCmd),
@@ -162,7 +162,7 @@ macro_rules! substrate_cli_subcommands {
}
}
- fn base_path(&self) -> $crate::Result<::std::option::Option<::std::path::PathBuf>> {
+ fn base_path(&self) -> $crate::Result<::std::option::Option> {
match self {
$($enum::$variant(cmd) => cmd.base_path()),*
}
@@ -409,4 +409,3 @@ macro_rules! substrate_cli_subcommands {
substrate_cli_subcommands!(
Subcommand => BuildSpec, ExportBlocks, ImportBlocks, CheckBlock, Revert, PurgeChain, ExportState
);
-
diff --git a/client/cli/src/commands/purge_chain_cmd.rs b/client/cli/src/commands/purge_chain_cmd.rs
index 9d364a45f7d09..053f427309828 100644
--- a/client/cli/src/commands/purge_chain_cmd.rs
+++ b/client/cli/src/commands/purge_chain_cmd.rs
@@ -26,7 +26,7 @@ use std::io::{self, Write};
use structopt::StructOpt;
/// The `purge-chain` command used to remove the whole chain.
-#[derive(Debug, StructOpt, Clone)]
+#[derive(Debug, StructOpt)]
pub struct PurgeChainCmd {
/// Skip interactive prompt by answering yes automatically.
#[structopt(short = "y")]
diff --git a/client/cli/src/commands/revert_cmd.rs b/client/cli/src/commands/revert_cmd.rs
index 6117eaf4880bf..1b5489df708a7 100644
--- a/client/cli/src/commands/revert_cmd.rs
+++ b/client/cli/src/commands/revert_cmd.rs
@@ -25,7 +25,7 @@ use std::fmt::Debug;
use structopt::StructOpt;
/// The `revert` command used revert the chain to a previous state.
-#[derive(Debug, StructOpt, Clone)]
+#[derive(Debug, StructOpt)]
pub struct RevertCmd {
/// Number of blocks to revert.
#[structopt(default_value = "256")]
diff --git a/client/cli/src/commands/run_cmd.rs b/client/cli/src/commands/run_cmd.rs
index 23a410d679b8f..82d40e6a73f07 100644
--- a/client/cli/src/commands/run_cmd.rs
+++ b/client/cli/src/commands/run_cmd.rs
@@ -21,13 +21,13 @@ use crate::error::{Error, Result};
use crate::params::ImportParams;
use crate::params::KeystoreParams;
use crate::params::NetworkParams;
+use crate::params::OffchainWorkerParams;
use crate::params::SharedParams;
use crate::params::TransactionPoolParams;
-use crate::params::OffchainWorkerParams;
use crate::CliConfiguration;
use regex::Regex;
use sc_service::{
- config::{MultiaddrWithPeerId, PrometheusConfig, TransactionPoolOptions},
+ config::{BasePath, MultiaddrWithPeerId, PrometheusConfig, TransactionPoolOptions},
ChainSpec, Role,
};
use sc_telemetry::TelemetryEndpoints;
@@ -35,7 +35,7 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use structopt::StructOpt;
/// The `run` command used to run a node.
-#[derive(Debug, StructOpt, Clone)]
+#[derive(Debug, StructOpt)]
pub struct RunCmd {
/// Enable validator mode.
///
@@ -250,6 +250,16 @@ pub struct RunCmd {
conflicts_with_all = &[ "sentry", "public-addr" ]
)]
pub sentry_nodes: Vec,
+
+ /// Run a temporary node.
+ ///
+ /// A temporary directory will be created to store the configuration and will be deleted
+ /// at the end of the process.
+ ///
+ /// Note: the directory is random per process execution. This directory is used as base path
+ /// which includes: database, node key and keystore.
+ #[structopt(long, conflicts_with = "base-path")]
+ pub tmp: bool,
}
impl RunCmd {
@@ -446,6 +456,14 @@ impl CliConfiguration for RunCmd {
fn max_runtime_instances(&self) -> Result