mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 03:27:58 +00:00
Check block CLI command (#4240)
* Check block operation * Update client/cli/src/lib.rs * Update client/cli/src/params.rs
This commit is contained in:
committed by
Gavin Wood
parent
f78b83e363
commit
504e2f8bd5
+125
-74
@@ -29,7 +29,7 @@ pub mod informant;
|
||||
use client_api::execution_extensions::ExecutionStrategies;
|
||||
use service::{
|
||||
config::{Configuration, DatabaseConfig},
|
||||
ServiceBuilderExport, ServiceBuilderImport, ServiceBuilderRevert,
|
||||
ServiceBuilderCommand,
|
||||
RuntimeGenesis, ChainSpecExtension, PruningMode, ChainSpec,
|
||||
};
|
||||
use network::{
|
||||
@@ -54,7 +54,7 @@ pub use structopt::clap::App;
|
||||
use params::{
|
||||
RunCmd, PurgeChainCmd, RevertCmd, ImportBlocksCmd, ExportBlocksCmd, BuildSpecCmd,
|
||||
NetworkConfigurationParams, MergeParameters, TransactionPoolParams,
|
||||
NodeKeyParams, NodeKeyType, Cors,
|
||||
NodeKeyParams, NodeKeyType, Cors, CheckBlockCmd,
|
||||
};
|
||||
pub use params::{NoCustom, CoreParams, SharedParams, ExecutionStrategy as ExecutionStrategyParam};
|
||||
pub use traits::{GetLogFilter, AugmentClap};
|
||||
@@ -64,6 +64,8 @@ use lazy_static::lazy_static;
|
||||
use futures::{Future, FutureExt, TryFutureExt};
|
||||
use futures01::{Async, Future as _};
|
||||
use substrate_telemetry::TelemetryEndpoints;
|
||||
use sr_primitives::generic::BlockId;
|
||||
use sr_primitives::traits::Block as BlockT;
|
||||
|
||||
/// default sub directory to store network config
|
||||
const DEFAULT_NETWORK_CONFIG_PATH : &'static str = "network";
|
||||
@@ -231,6 +233,9 @@ where
|
||||
params::CoreParams::ImportBlocks(params) => ParseAndPrepare::ImportBlocks(
|
||||
ParseAndPrepareImport { params, version }
|
||||
),
|
||||
params::CoreParams::CheckBlock(params) => ParseAndPrepare::CheckBlock(
|
||||
CheckBlock { params, version }
|
||||
),
|
||||
params::CoreParams::PurgeChain(params) => ParseAndPrepare::PurgeChain(
|
||||
ParseAndPreparePurge { params, version }
|
||||
),
|
||||
@@ -263,6 +268,8 @@ pub enum ParseAndPrepare<'a, CC, RP> {
|
||||
ExportBlocks(ParseAndPrepareExport<'a>),
|
||||
/// Command ready to import the chain.
|
||||
ImportBlocks(ParseAndPrepareImport<'a>),
|
||||
/// Command to check a block.
|
||||
CheckBlock(CheckBlock<'a>),
|
||||
/// Command ready to purge the chain.
|
||||
PurgeChain(ParseAndPreparePurge<'a>),
|
||||
/// Command ready to revert the chain.
|
||||
@@ -366,7 +373,7 @@ impl<'a> ParseAndPrepareExport<'a> {
|
||||
) -> error::Result<()>
|
||||
where S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
|
||||
F: FnOnce(Configuration<C, G, E>) -> Result<B, error::Error>,
|
||||
B: ServiceBuilderExport,
|
||||
B: ServiceBuilderCommand,
|
||||
C: Default,
|
||||
G: RuntimeGenesis,
|
||||
E: ChainSpecExtension,
|
||||
@@ -427,19 +434,13 @@ impl<'a> ParseAndPrepareImport<'a> {
|
||||
) -> error::Result<()>
|
||||
where S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
|
||||
F: FnOnce(Configuration<C, G, E>) -> Result<B, error::Error>,
|
||||
B: ServiceBuilderImport,
|
||||
B: ServiceBuilderCommand,
|
||||
C: Default,
|
||||
G: RuntimeGenesis,
|
||||
E: ChainSpecExtension,
|
||||
Exit: IntoExit
|
||||
{
|
||||
let mut config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?;
|
||||
config.wasm_method = self.params.wasm_method.into();
|
||||
config.execution_strategies = ExecutionStrategies {
|
||||
importing: self.params.execution.into(),
|
||||
other: self.params.execution.into(),
|
||||
..Default::default()
|
||||
};
|
||||
let config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?;
|
||||
|
||||
let file: Box<dyn ReadPlusSeek + Send> = match self.params.input {
|
||||
Some(filename) => Box::new(File::open(filename)?),
|
||||
@@ -461,7 +462,7 @@ impl<'a> ParseAndPrepareImport<'a> {
|
||||
let _ = exit_send.send(());
|
||||
});
|
||||
|
||||
let mut import_fut = builder(config)?.import_blocks(file);
|
||||
let mut import_fut = builder(config)?.import_blocks(file, false);
|
||||
let fut = futures01::future::poll_fn(|| {
|
||||
if exit_recv.try_recv().is_ok() {
|
||||
return Ok(Async::Ready(()));
|
||||
@@ -475,6 +476,49 @@ impl<'a> ParseAndPrepareImport<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Command to check a block.
|
||||
pub struct CheckBlock<'a> {
|
||||
params: CheckBlockCmd,
|
||||
version: &'a VersionInfo,
|
||||
}
|
||||
|
||||
impl<'a> CheckBlock<'a> {
|
||||
/// Runs the command and imports to the chain.
|
||||
pub fn run_with_builder<C, G, E, F, B, S, Exit>(
|
||||
self,
|
||||
builder: F,
|
||||
spec_factory: S,
|
||||
_exit: Exit,
|
||||
) -> error::Result<()>
|
||||
where S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
|
||||
F: FnOnce(Configuration<C, G, E>) -> Result<B, error::Error>,
|
||||
B: ServiceBuilderCommand,
|
||||
<<B as ServiceBuilderCommand>::Block as BlockT>::Hash: FromStr,
|
||||
C: Default,
|
||||
G: RuntimeGenesis,
|
||||
E: ChainSpecExtension,
|
||||
Exit: IntoExit
|
||||
{
|
||||
let config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?;
|
||||
|
||||
let input = if self.params.input.starts_with("0x") { &self.params.input[2..] } else { &self.params.input[..] };
|
||||
let block_id = match FromStr::from_str(input) {
|
||||
Ok(hash) => BlockId::hash(hash),
|
||||
Err(_) => match self.params.input.parse::<u32>() {
|
||||
Ok(n) => BlockId::number((n as u32).into()),
|
||||
Err(_) => return Err(error::Error::Input("Invalid hash or number specified".into())),
|
||||
}
|
||||
};
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let check = builder(config)?.check_block(block_id);
|
||||
let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap();
|
||||
runtime.block_on(check)?;
|
||||
println!("Completed in {} ms.", start.elapsed().as_millis());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Command ready to purge the chain.
|
||||
pub struct ParseAndPreparePurge<'a> {
|
||||
params: PurgeChainCmd,
|
||||
@@ -548,7 +592,7 @@ impl<'a> ParseAndPrepareRevert<'a> {
|
||||
) -> error::Result<()> where
|
||||
S: FnOnce(&str) -> Result<Option<ChainSpec<G, E>>, String>,
|
||||
F: FnOnce(Configuration<C, G, E>) -> Result<B, error::Error>,
|
||||
B: ServiceBuilderRevert,
|
||||
B: ServiceBuilderCommand,
|
||||
C: Default,
|
||||
G: RuntimeGenesis,
|
||||
E: ChainSpecExtension,
|
||||
@@ -694,6 +738,55 @@ fn fill_config_keystore_password<C, G, E>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fill_shared_config<C, G, E>(config: &mut Configuration<C, G, E>, cli: &SharedParams, role: service::Roles)
|
||||
-> error::Result<()>
|
||||
where
|
||||
C: Default,
|
||||
G: RuntimeGenesis,
|
||||
E: ChainSpecExtension,
|
||||
{
|
||||
config.database = DatabaseConfig::Path {
|
||||
path: config.in_chain_config_dir(DEFAULT_DB_CONFIG_PATH).expect("We provided a base_path."),
|
||||
cache_size: Some(cli.database_cache_size),
|
||||
};
|
||||
config.state_cache_size = cli.state_cache_size;
|
||||
|
||||
// by default we disable pruning if the node is an authority (i.e.
|
||||
// `ArchiveAll`), otherwise we keep state for the last 256 blocks. if the
|
||||
// node is an authority and pruning is enabled explicitly, then we error
|
||||
// unless `unsafe_pruning` is set.
|
||||
config.pruning = match &cli.pruning {
|
||||
Some(ref s) if s == "archive" => PruningMode::ArchiveAll,
|
||||
None if role == service::Roles::AUTHORITY => PruningMode::ArchiveAll,
|
||||
None => PruningMode::default(),
|
||||
Some(s) => {
|
||||
if role == service::Roles::AUTHORITY && !cli.unsafe_pruning {
|
||||
return Err(error::Error::Input(
|
||||
"Validators should run with state pruning disabled (i.e. archive). \
|
||||
You can ignore this check with `--unsafe-pruning`.".to_string()
|
||||
));
|
||||
}
|
||||
|
||||
PruningMode::keep_blocks(s.parse()
|
||||
.map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))?
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
config.wasm_method = cli.wasm_method.into();
|
||||
|
||||
let exec = &cli.execution_strategies;
|
||||
let exec_all_or = |strat: params::ExecutionStrategy| exec.execution.unwrap_or(strat).into();
|
||||
config.execution_strategies = ExecutionStrategies {
|
||||
syncing: exec_all_or(exec.execution_syncing),
|
||||
importing: exec_all_or(exec.execution_import_block),
|
||||
block_construction: exec_all_or(exec.execution_block_construction),
|
||||
offchain_worker: exec_all_or(exec.execution_offchain_worker),
|
||||
other: exec_all_or(exec.execution_other),
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_run_node_config<C, G, E, S>(
|
||||
cli: RunCmd, spec_factory: S, impl_name: &'static str, version: &VersionInfo,
|
||||
) -> error::Result<Configuration<C, G, E>>
|
||||
@@ -709,6 +802,19 @@ where
|
||||
|
||||
fill_config_keystore_password(&mut config, &cli)?;
|
||||
|
||||
let is_dev = cli.shared_params.dev;
|
||||
let is_authority = cli.validator || cli.sentry || is_dev || cli.keyring.account.is_some();
|
||||
let role =
|
||||
if cli.light {
|
||||
service::Roles::LIGHT
|
||||
} else if is_authority {
|
||||
service::Roles::AUTHORITY
|
||||
} else {
|
||||
service::Roles::FULL
|
||||
};
|
||||
|
||||
fill_shared_config(&mut config, &cli.shared_params, role)?;
|
||||
|
||||
config.impl_name = impl_name;
|
||||
config.impl_commit = version.commit;
|
||||
config.impl_version = version.version;
|
||||
@@ -731,61 +837,9 @@ where
|
||||
|
||||
config.keystore_path = cli.keystore_path.or_else(|| config.in_chain_config_dir(DEFAULT_KEYSTORE_CONFIG_PATH));
|
||||
|
||||
config.database = DatabaseConfig::Path {
|
||||
path: config.in_chain_config_dir(DEFAULT_DB_CONFIG_PATH).expect("We provided a base_path."),
|
||||
cache_size: Some(cli.database_cache_size),
|
||||
};
|
||||
config.state_cache_size = cli.state_cache_size;
|
||||
|
||||
let is_dev = cli.shared_params.dev;
|
||||
let is_authority = cli.validator || cli.sentry || is_dev || cli.keyring.account.is_some();
|
||||
|
||||
let role =
|
||||
if cli.light {
|
||||
service::Roles::LIGHT
|
||||
} else if is_authority {
|
||||
service::Roles::AUTHORITY
|
||||
} else {
|
||||
service::Roles::FULL
|
||||
};
|
||||
|
||||
// set sentry mode (i.e. act as an authority but **never** actively participate)
|
||||
config.sentry_mode = cli.sentry;
|
||||
|
||||
// by default we disable pruning if the node is an authority (i.e.
|
||||
// `ArchiveAll`), otherwise we keep state for the last 256 blocks. if the
|
||||
// node is an authority and pruning is enabled explicitly, then we error
|
||||
// unless `unsafe_pruning` is set.
|
||||
config.pruning = match cli.pruning {
|
||||
Some(ref s) if s == "archive" => PruningMode::ArchiveAll,
|
||||
None if role == service::Roles::AUTHORITY => PruningMode::ArchiveAll,
|
||||
None => PruningMode::default(),
|
||||
Some(s) => {
|
||||
if role == service::Roles::AUTHORITY && !cli.unsafe_pruning {
|
||||
return Err(error::Error::Input(
|
||||
"Validators should run with state pruning disabled (i.e. archive). \
|
||||
You can ignore this check with `--unsafe-pruning`.".to_string()
|
||||
));
|
||||
}
|
||||
|
||||
PruningMode::keep_blocks(s.parse()
|
||||
.map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))?
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
config.wasm_method = cli.wasm_method.into();
|
||||
|
||||
let exec = cli.execution_strategies;
|
||||
let exec_all_or = |strat: params::ExecutionStrategy| exec.execution.unwrap_or(strat).into();
|
||||
config.execution_strategies = ExecutionStrategies {
|
||||
syncing: exec_all_or(exec.execution_syncing),
|
||||
importing: exec_all_or(exec.execution_import_block),
|
||||
block_construction: exec_all_or(exec.execution_block_construction),
|
||||
offchain_worker: exec_all_or(exec.execution_offchain_worker),
|
||||
other: exec_all_or(exec.execution_other),
|
||||
};
|
||||
|
||||
config.offchain_worker = match (cli.offchain_worker, role) {
|
||||
(params::OffchainWorkerEnabled::WhenValidating, service::Roles::AUTHORITY) => true,
|
||||
(params::OffchainWorkerEnabled::Always, _) => true,
|
||||
@@ -871,11 +925,7 @@ where
|
||||
let base_path = base_path(cli, version);
|
||||
|
||||
let mut config = service::Configuration::default_with_spec_and_base_path(spec.clone(), Some(base_path));
|
||||
config.database = DatabaseConfig::Path {
|
||||
path: config.in_chain_config_dir(DEFAULT_DB_CONFIG_PATH).expect("We provided a base_path."),
|
||||
cache_size: None,
|
||||
};
|
||||
|
||||
fill_shared_config(&mut config, &cli, service::Roles::FULL)?;
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
@@ -943,14 +993,15 @@ fn init_logger(pattern: &str) {
|
||||
)
|
||||
};
|
||||
|
||||
if !enable_color {
|
||||
output = kill_color(output.as_ref());
|
||||
}
|
||||
|
||||
if !isatty && record.level() <= log::Level::Info && atty::is(atty::Stream::Stdout) {
|
||||
// duplicate INFO/WARN output to console
|
||||
println!("{}", output);
|
||||
}
|
||||
|
||||
if !enable_color {
|
||||
output = kill_color(output.as_ref());
|
||||
}
|
||||
|
||||
writeln!(buf, "{}", output)
|
||||
});
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ impl Into<client_api::ExecutionStrategy> for ExecutionStrategy {
|
||||
arg_enum! {
|
||||
/// How to execute Wasm runtime code
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum WasmExecutionMethod {
|
||||
// Uses an interpreter.
|
||||
Interpreted,
|
||||
@@ -109,6 +109,44 @@ pub struct SharedParams {
|
||||
/// Sets a custom logging filter.
|
||||
#[structopt(short = "l", long = "log", value_name = "LOG_PATTERN")]
|
||||
pub log: Option<String>,
|
||||
|
||||
/// Specify the state pruning mode, a number of blocks to keep or 'archive'.
|
||||
///
|
||||
/// Default is to keep all block states if the node is running as a
|
||||
/// validator (i.e. 'archive'), otherwise state is only kept for the last
|
||||
/// 256 blocks.
|
||||
#[structopt(long = "pruning", value_name = "PRUNING_MODE")]
|
||||
pub pruning: Option<String>,
|
||||
|
||||
/// Force start with unsafe pruning settings.
|
||||
///
|
||||
/// When running as a validator it is highly recommended to disable state
|
||||
/// pruning (i.e. 'archive') which is the default. The node will refuse to
|
||||
/// start as a validator if pruning is enabled unless this option is set.
|
||||
#[structopt(long = "unsafe-pruning")]
|
||||
pub unsafe_pruning: bool,
|
||||
|
||||
/// Method for executing Wasm runtime code.
|
||||
#[structopt(
|
||||
long = "wasm-execution",
|
||||
value_name = "METHOD",
|
||||
possible_values = &WasmExecutionMethod::enabled_variants(),
|
||||
case_insensitive = true,
|
||||
default_value = "Interpreted"
|
||||
)]
|
||||
pub wasm_method: WasmExecutionMethod,
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[structopt(flatten)]
|
||||
pub execution_strategies: ExecutionStrategies,
|
||||
|
||||
/// Limit the memory the database cache can use.
|
||||
#[structopt(long = "db-cache", value_name = "MiB", default_value = "1024")]
|
||||
pub database_cache_size: u32,
|
||||
|
||||
/// Specify the state cache size.
|
||||
#[structopt(long = "state-cache-size", value_name = "Bytes", default_value = "67108864")]
|
||||
pub state_cache_size: usize,
|
||||
}
|
||||
|
||||
impl GetLogFilter for SharedParams {
|
||||
@@ -386,14 +424,6 @@ pub struct RunCmd {
|
||||
#[structopt(long = "light")]
|
||||
pub light: bool,
|
||||
|
||||
/// Limit the memory the database cache can use.
|
||||
#[structopt(long = "db-cache", value_name = "MiB", default_value = "1024")]
|
||||
pub database_cache_size: u32,
|
||||
|
||||
/// Specify the state cache size.
|
||||
#[structopt(long = "state-cache-size", value_name = "Bytes", default_value = "67108864")]
|
||||
pub state_cache_size: usize,
|
||||
|
||||
/// Listen to all RPC interfaces.
|
||||
///
|
||||
/// Default is local.
|
||||
@@ -438,22 +468,6 @@ pub struct RunCmd {
|
||||
#[structopt(long = "grafana-port", value_name = "PORT")]
|
||||
pub grafana_port: Option<u16>,
|
||||
|
||||
/// Specify the state pruning mode, a number of blocks to keep or 'archive'.
|
||||
///
|
||||
/// Default is to keep all block states if the node is running as a
|
||||
/// validator (i.e. 'archive'), otherwise state is only kept for the last
|
||||
/// 256 blocks.
|
||||
#[structopt(long = "pruning", value_name = "PRUNING_MODE")]
|
||||
pub pruning: Option<String>,
|
||||
|
||||
/// Force start with unsafe pruning settings.
|
||||
///
|
||||
/// When running as a validator it is highly recommended to disable state
|
||||
/// pruning (i.e. 'archive') which is the default. The node will refuse to
|
||||
/// start as a validator if pruning is enabled unless this option is set.
|
||||
#[structopt(long = "unsafe-pruning")]
|
||||
pub unsafe_pruning: bool,
|
||||
|
||||
/// The human-readable name for this node.
|
||||
///
|
||||
/// The node name will be reported to the telemetry server, if enabled.
|
||||
@@ -487,20 +501,6 @@ pub struct RunCmd {
|
||||
)]
|
||||
pub offchain_worker: OffchainWorkerEnabled,
|
||||
|
||||
/// Method for executing Wasm runtime code.
|
||||
#[structopt(
|
||||
long = "wasm-execution",
|
||||
value_name = "METHOD",
|
||||
possible_values = &WasmExecutionMethod::enabled_variants(),
|
||||
case_insensitive = true,
|
||||
default_value = "Interpreted"
|
||||
)]
|
||||
pub wasm_method: WasmExecutionMethod,
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[structopt(flatten)]
|
||||
pub execution_strategies: ExecutionStrategies,
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[structopt(flatten)]
|
||||
pub shared_params: SharedParams,
|
||||
@@ -764,30 +764,30 @@ pub struct ImportBlocksCmd {
|
||||
#[allow(missing_docs)]
|
||||
#[structopt(flatten)]
|
||||
pub shared_params: SharedParams,
|
||||
|
||||
/// Method for executing Wasm runtime code.
|
||||
#[structopt(
|
||||
long = "wasm-execution",
|
||||
value_name = "METHOD",
|
||||
possible_values = &WasmExecutionMethod::variants(),
|
||||
case_insensitive = true,
|
||||
default_value = "Interpreted"
|
||||
)]
|
||||
pub wasm_method: WasmExecutionMethod,
|
||||
|
||||
/// The means of execution used when calling into the runtime while importing blocks.
|
||||
#[structopt(
|
||||
long = "execution",
|
||||
value_name = "STRATEGY",
|
||||
possible_values = &ExecutionStrategy::variants(),
|
||||
case_insensitive = true,
|
||||
default_value = "NativeElseWasm"
|
||||
)]
|
||||
pub execution: ExecutionStrategy,
|
||||
}
|
||||
|
||||
impl_get_log_filter!(ImportBlocksCmd);
|
||||
|
||||
/// The `check-block` command used to validate blocks.
|
||||
#[derive(Debug, StructOpt, Clone)]
|
||||
pub struct CheckBlockCmd {
|
||||
/// Block hash or number
|
||||
#[structopt(value_name = "HASH or NUMBER")]
|
||||
pub input: String,
|
||||
|
||||
/// The default number of 64KB pages to ever allocate for Wasm execution.
|
||||
///
|
||||
/// Don't alter this unless you know what you're doing.
|
||||
#[structopt(long = "default-heap-pages", value_name = "COUNT")]
|
||||
pub default_heap_pages: Option<u32>,
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[structopt(flatten)]
|
||||
pub shared_params: SharedParams,
|
||||
}
|
||||
|
||||
impl_get_log_filter!(CheckBlockCmd);
|
||||
|
||||
/// The `revert` command used revert the chain to a previous state.
|
||||
#[derive(Debug, StructOpt, Clone)]
|
||||
pub struct RevertCmd {
|
||||
@@ -835,6 +835,9 @@ pub enum CoreParams<CC, RP> {
|
||||
/// Import blocks from file.
|
||||
ImportBlocks(ImportBlocksCmd),
|
||||
|
||||
/// Validte a single block.
|
||||
CheckBlock(CheckBlockCmd),
|
||||
|
||||
/// Revert chain to the previous state.
|
||||
Revert(RevertCmd),
|
||||
|
||||
@@ -868,6 +871,10 @@ impl<CC, RP> StructOpt for CoreParams<CC, RP> where
|
||||
ImportBlocksCmd::augment_clap(SubCommand::with_name("import-blocks"))
|
||||
.about("Import blocks from file.")
|
||||
)
|
||||
.subcommand(
|
||||
CheckBlockCmd::augment_clap(SubCommand::with_name("check-block"))
|
||||
.about("Re-validate a known block.")
|
||||
)
|
||||
.subcommand(
|
||||
RevertCmd::augment_clap(SubCommand::with_name("revert"))
|
||||
.about("Revert chain to the previous state.")
|
||||
@@ -886,6 +893,8 @@ impl<CC, RP> StructOpt for CoreParams<CC, RP> where
|
||||
CoreParams::ExportBlocks(ExportBlocksCmd::from_clap(matches)),
|
||||
("import-blocks", Some(matches)) =>
|
||||
CoreParams::ImportBlocks(ImportBlocksCmd::from_clap(matches)),
|
||||
("check-block", Some(matches)) =>
|
||||
CoreParams::CheckBlock(CheckBlockCmd::from_clap(matches)),
|
||||
("revert", Some(matches)) => CoreParams::Revert(RevertCmd::from_clap(matches)),
|
||||
("purge-chain", Some(matches)) =>
|
||||
CoreParams::PurgeChain(PurgeChainCmd::from_clap(matches)),
|
||||
@@ -902,6 +911,7 @@ impl<CC, RP> GetLogFilter for CoreParams<CC, RP> where CC: GetLogFilter {
|
||||
CoreParams::BuildSpec(c) => c.get_log_filter(),
|
||||
CoreParams::ExportBlocks(c) => c.get_log_filter(),
|
||||
CoreParams::ImportBlocks(c) => c.get_log_filter(),
|
||||
CoreParams::CheckBlock(c) => c.get_log_filter(),
|
||||
CoreParams::PurgeChain(c) => c.get_log_filter(),
|
||||
CoreParams::Revert(c) => c.get_log_filter(),
|
||||
CoreParams::Custom(c) => c.get_log_filter(),
|
||||
|
||||
Reference in New Issue
Block a user