diff --git a/substrate/core/cli/src/lib.rs b/substrate/core/cli/src/lib.rs index 297896bf83..9204408eb3 100644 --- a/substrate/core/cli/src/lib.rs +++ b/substrate/core/cli/src/lib.rs @@ -438,11 +438,14 @@ where let is_dev = cli.shared_params.dev; - let role = if cli.light { - service::Roles::LIGHT - } else { - service::Roles::AUTHORITY - }; + let role = + if cli.light { + service::Roles::LIGHT + } else if cli.validator || is_dev { + service::Roles::AUTHORITY + } else { + service::Roles::FULL + }; let exec = cli.execution_strategies; let exec_all_or = |strat: params::ExecutionStrategy| exec.execution.unwrap_or(strat).into(); diff --git a/substrate/core/cli/src/params.rs b/substrate/core/cli/src/params.rs index e3fa04c936..b17fc114c4 100644 --- a/substrate/core/cli/src/params.rs +++ b/substrate/core/cli/src/params.rs @@ -297,7 +297,11 @@ pub struct ExecutionStrategies { /// The `run` command used to run a node. #[derive(Debug, StructOpt, Clone)] pub struct RunCmd { - /// Disable GRANDPA when running in validator mode + /// Enable validator mode + #[structopt(long = "validator")] + pub validator: bool, + + /// Disable GRANDPA voter when running in validator mode, otherwise disables the GRANDPA observer #[structopt(long = "no-grandpa")] pub no_grandpa: bool, diff --git a/substrate/node/cli/src/service.rs b/substrate/node/cli/src/service.rs index 813d23393b..f1fba54829 100644 --- a/substrate/node/cli/src/service.rs +++ b/substrate/node/cli/src/service.rs @@ -113,41 +113,56 @@ construct_service_factory! { } } - let proposer = substrate_basic_authorship::ProposerFactory { - client: service.client(), - transaction_pool: service.transaction_pool(), - }; - - let client = service.client(); - let select_chain = service.select_chain().ok_or(ServiceError::SelectChainRequired)?; - - let babe_config = babe::BabeParams { - config: Config::get_or_compute(&*client)?, - keystore: service.keystore(), - client, - select_chain, - block_import, - env: proposer, - sync_oracle: service.network(), - inherent_data_providers: service.config().custom.inherent_data_providers.clone(), - force_authoring: service.config().force_authoring, - time_source: babe_link, - }; - - let babe = start_babe(babe_config)?; - let select = babe.select(service.on_exit()).then(|_| Ok(())); - service.spawn_task(Box::new(select)); - - if !service.config().disable_grandpa { - let config = grandpa::Config { - // FIXME #1578 make this available through chainspec - gossip_duration: Duration::from_millis(333), - justification_period: 4096, - name: Some(service.config().name.clone()), - keystore: Some(service.keystore()), + if service.config().roles.is_authority() { + let proposer = substrate_basic_authorship::ProposerFactory { + client: service.client(), + transaction_pool: service.transaction_pool(), }; - if service.config().roles.is_authority() { + let client = service.client(); + let select_chain = service.select_chain().ok_or(ServiceError::SelectChainRequired)?; + + let babe_config = babe::BabeParams { + config: Config::get_or_compute(&*client)?, + keystore: service.keystore(), + client, + select_chain, + block_import, + env: proposer, + sync_oracle: service.network(), + inherent_data_providers: service.config().custom.inherent_data_providers.clone(), + force_authoring: service.config().force_authoring, + time_source: babe_link, + }; + + let babe = start_babe(babe_config)?; + let select = babe.select(service.on_exit()).then(|_| Ok(())); + service.spawn_task(Box::new(select)); + } + + let config = grandpa::Config { + // FIXME #1578 make this available through chainspec + gossip_duration: Duration::from_millis(333), + justification_period: 4096, + name: Some(service.config().name.clone()), + keystore: Some(service.keystore()), + }; + + match (service.config().roles.is_authority(), service.config().disable_grandpa) { + (false, false) => { + // start the lightweight GRANDPA observer + service.spawn_task(Box::new(grandpa::run_grandpa_observer( + config, + link_half, + service.network(), + service.on_exit(), + )?)); + }, + (false, true) => { + // nothing to do here + }, + (true, false) => { + // start the full GRANDPA voter let telemetry_on_connect = TelemetryOnConnect { telemetry_connection_sinks: service.telemetry_on_connect_stream(), }; @@ -160,24 +175,20 @@ construct_service_factory! { telemetry_on_connect: Some(telemetry_on_connect), }; service.spawn_task(Box::new(grandpa::run_grandpa_voter(grandpa_config)?)); - } else { - service.spawn_task(Box::new(grandpa::run_grandpa_observer( - config, - link_half, - service.network(), - service.on_exit(), - )?)); - } + }, + (true, true) => { + // since we are an authority, when authoring blocks we + // expect inherent data regarding what our last + // finalized block is, to be available. since we don't + // start the grandpa voter, we need to register the + // inherent data provider ourselves. + grandpa::register_finality_tracker_inherent_data_provider( + service.client(), + &service.config().custom.inherent_data_providers, + )?; + }, } - // regardless of whether grandpa is started or not, when - // authoring blocks we expect inherent data regarding what our - // last finalized block is, to be available. - grandpa::register_finality_tracker_inherent_data_provider( - service.client(), - &service.config().custom.inherent_data_providers, - )?; - Ok(service) } },