diff --git a/Cargo.lock b/Cargo.lock index a79f6134a88d4..cac0087bad2b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3716,6 +3716,7 @@ dependencies = [ "sc-finality-grandpa", "sc-finality-grandpa-rpc", "sc-keystore", + "sc-rpc", "sc-rpc-api", "sp-api", "sp-block-builder", diff --git a/bin/node-template/node/src/command.rs b/bin/node-template/node/src/command.rs index 3391ad2c89289..0e12ca5fa9354 100644 --- a/bin/node-template/node/src/command.rs +++ b/bin/node-template/node/src/command.rs @@ -19,6 +19,8 @@ use crate::chain_spec; use crate::cli::Cli; use crate::service; use sc_cli::{SubstrateCli, RuntimeVersion, Role, ChainSpec}; +use sc_service::ServiceParams; +use crate::service::new_full_params; impl SubstrateCli for Cli { fn impl_name() -> String { @@ -68,8 +70,9 @@ pub fn run() -> sc_cli::Result<()> { Some(subcommand) => { let runner = cli.create_runner(subcommand)?; runner.run_subcommand(subcommand, |config| { - let (builder, _, _) = new_full_start!(config); - Ok(builder.to_chain_ops_parts()) + let (ServiceParams { client, backend, task_manager, import_queue, .. }, ..) + = new_full_params(config)?; + Ok((client, backend, import_queue, task_manager)) }) } None => { diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index 04eb2add2751a..4c41e988d0af4 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -2,13 +2,9 @@ use std::sync::Arc; use std::time::Duration; -use sc_client_api::ExecutorProvider; -use sc_consensus::LongestChain; -use node_template_runtime::{self, opaque::Block, RuntimeApi}; -use sc_service::{ - error::{Error as ServiceError}, Configuration, ServiceBuilder, ServiceComponents, - TaskManager, -}; +use sc_client_api::{ExecutorProvider, RemoteBackend}; +use node_template_runtime::{self, Block, RuntimeApi}; +use sc_service::{error::Error as ServiceError, Configuration, ServiceComponents, TaskManager}; use sp_inherents::InherentDataProviders; use sc_executor::native_executor_instance; pub use sc_executor::NativeExecutor; @@ -24,103 +20,110 @@ native_executor_instance!( node_template_runtime::native_version, ); -/// Starts a `ServiceBuilder` for a full service. -/// -/// Use this macro if you don't actually need the full service, but just the builder in order to -/// be able to perform chain operations. -macro_rules! new_full_start { - ($config:expr) => {{ - use std::sync::Arc; - use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; +type FullClient = sc_service::TFullClient; +type FullBackend = sc_service::TFullBackend; +type FullSelectChain = sc_consensus::LongestChain; + +pub fn new_full_params(config: Configuration) -> Result<( + sc_service::ServiceParams< + Block, FullClient, + sc_consensus_aura::AuraImportQueue, + sc_transaction_pool::FullPool, + (), FullBackend, + >, + FullSelectChain, + sp_inherents::InherentDataProviders, + sc_finality_grandpa::GrandpaBlockImport, + sc_finality_grandpa::LinkHalf +), ServiceError> { + let inherent_data_providers = sp_inherents::InherentDataProviders::new(); - let mut import_setup = None; - let inherent_data_providers = sp_inherents::InherentDataProviders::new(); + let (client, backend, keystore, task_manager) = + sc_service::new_full_parts::(&config)?; + let client = Arc::new(client); - let builder = sc_service::ServiceBuilder::new_full::< - node_template_runtime::opaque::Block, - node_template_runtime::RuntimeApi, - crate::service::Executor - >($config)? - .with_select_chain(|_config, backend| { - Ok(sc_consensus::LongestChain::new(backend.clone())) - })? - .with_transaction_pool(|builder| { - let pool_api = sc_transaction_pool::FullChainApi::new( - builder.client().clone(), - None, - ); - Ok(sc_transaction_pool::BasicPool::new_full( - builder.config().transaction_pool.clone(), - std::sync::Arc::new(pool_api), - builder.prometheus_registry(), - builder.spawn_handle(), - builder.client().clone(), - )) - })? - .with_import_queue(| - _config, - client, - mut select_chain, - _transaction_pool, - spawn_task_handle, - registry, - | { - let select_chain = select_chain.take() - .ok_or_else(|| sc_service::Error::SelectChainRequired)?; + let select_chain = sc_consensus::LongestChain::new(backend.clone()); - let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import( - client.clone(), - &(client.clone() as Arc<_>), - select_chain, - )?; + let pool_api = sc_transaction_pool::FullChainApi::new( + client.clone(), config.prometheus_registry(), + ); + let transaction_pool = sc_transaction_pool::BasicPool::new_full( + config.transaction_pool.clone(), + std::sync::Arc::new(pool_api), + config.prometheus_registry(), + task_manager.spawn_handle(), + client.clone(), + ); - let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new( - grandpa_block_import.clone(), client.clone(), - ); + let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import( + client.clone(), &(client.clone() as Arc<_>), select_chain.clone(), + )?; - let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _>( - sc_consensus_aura::slot_duration(&*client)?, - aura_block_import, - Some(Box::new(grandpa_block_import.clone())), - None, - client, - inherent_data_providers.clone(), - spawn_task_handle, - registry, - )?; + let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new( + grandpa_block_import.clone(), client.clone(), + ); - import_setup = Some((grandpa_block_import, grandpa_link)); + let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _>( + sc_consensus_aura::slot_duration(&*client)?, + aura_block_import, + Some(Box::new(grandpa_block_import.clone())), + None, + client.clone(), + inherent_data_providers.clone(), + &task_manager.spawn_handle(), + config.prometheus_registry(), + )?; - Ok(import_queue) - })?; + let provider = client.clone() as Arc>; + let finality_proof_provider = + Arc::new(GrandpaFinalityProofProvider::new(backend.clone(), provider)); + + let params = sc_service::ServiceParams { + backend, client, import_queue, keystore, task_manager, transaction_pool, + config, + block_announce_validator_builder: None, + finality_proof_request_builder: None, + finality_proof_provider: Some(finality_proof_provider), + on_demand: None, + remote_blockchain: None, + rpc_extensions_builder: Box::new(|_| ()), + }; - (builder, import_setup, inherent_data_providers) - }} + Ok(( + params, select_chain, inherent_data_providers, + grandpa_block_import, grandpa_link, + )) } /// Builds a new service for a full client. -pub fn new_full(config: Configuration) -> Result { - let role = config.role.clone(); - let force_authoring = config.force_authoring; - let name = config.network.node_name.clone(); - let disable_grandpa = config.disable_grandpa; +pub fn new_full(config: Configuration) -> Result { + let ( + params, select_chain, inherent_data_providers, + block_import, grandpa_link, + ) = new_full_params(config)?; + + let ( + role, force_authoring, name, enable_grandpa, prometheus_registry, + client, transaction_pool, keystore, + ) = { + let sc_service::ServiceParams { + config, client, transaction_pool, keystore, .. + } = ¶ms; - let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config); + ( + config.role.clone(), + config.force_authoring, + config.network.node_name.clone(), + !config.disable_grandpa, + config.prometheus_registry().cloned(), - let (block_import, grandpa_link) = - import_setup.take() - .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); + client.clone(), transaction_pool.clone(), keystore.clone(), + ) + }; let ServiceComponents { - client, transaction_pool, task_manager, keystore, network, select_chain, - prometheus_registry, telemetry_on_connect_sinks, .. - } = builder - .with_finality_proof_provider(|client, backend| { - // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider - let provider = client as Arc>; - Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) - })? - .build_full()?; + task_manager, network, telemetry_on_connect_sinks, .. + } = sc_service::build(params)?; if role.is_authority() { let proposer = sc_basic_authorship::ProposerFactory::new( @@ -129,9 +132,6 @@ pub fn new_full(config: Configuration) -> Result { prometheus_registry.as_ref(), ); - let select_chain = select_chain - .ok_or(ServiceError::SelectChainRequired)?; - let can_author_with = sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); @@ -171,7 +171,6 @@ pub fn new_full(config: Configuration) -> Result { is_authority: role.is_network_authority(), }; - let enable_grandpa = !disable_grandpa; if enable_grandpa { // start the full GRANDPA voter // NOTE: non-authorities could run the GRANDPA observer protocol, but at @@ -209,69 +208,49 @@ pub fn new_full(config: Configuration) -> Result { /// Builds a new service for a light client. pub fn new_light(config: Configuration) -> Result { - let inherent_data_providers = InherentDataProviders::new(); + let (client, backend, keystore, task_manager, on_demand) = + sc_service::new_light_parts::(&config)?; + + let transaction_pool_api = Arc::new(sc_transaction_pool::LightChainApi::new( + client.clone(), on_demand.clone(), + )); + let transaction_pool = sc_transaction_pool::BasicPool::new_light( + config.transaction_pool.clone(), + transaction_pool_api, + config.prometheus_registry(), + task_manager.spawn_handle(), + ); - ServiceBuilder::new_light::(config)? - .with_select_chain(|_config, backend| { - Ok(LongestChain::new(backend.clone())) - })? - .with_transaction_pool(|builder| { - let fetcher = builder.fetcher() - .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?; + let grandpa_block_import = sc_finality_grandpa::light_block_import( + client.clone(), backend.clone(), &(client.clone() as Arc<_>), + Arc::new(on_demand.checker().clone()) as Arc<_>, + )?; + let finality_proof_import = grandpa_block_import.clone(); + let finality_proof_request_builder = + finality_proof_import.create_finality_proof_request_builder(); - let pool_api = sc_transaction_pool::LightChainApi::new( - builder.client().clone(), - fetcher, - ); - let pool = Arc::new(sc_transaction_pool::BasicPool::new_light( - builder.config().transaction_pool.clone(), - Arc::new(pool_api), - builder.prometheus_registry(), - builder.spawn_handle(), - )); - Ok(pool) - })? - .with_import_queue_and_fprb(| - _config, - client, - backend, - fetcher, - _select_chain, - _tx_pool, - spawn_task_handle, - prometheus_registry, - | { - let fetch_checker = fetcher - .map(|fetcher| fetcher.checker().clone()) - .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; - let grandpa_block_import = sc_finality_grandpa::light_block_import( - client.clone(), - backend, - &(client.clone() as Arc<_>), - Arc::new(fetch_checker), - )?; - let finality_proof_import = grandpa_block_import.clone(); - let finality_proof_request_builder = - finality_proof_import.create_finality_proof_request_builder(); + let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _>( + sc_consensus_aura::slot_duration(&*client)?, + grandpa_block_import, + None, + Some(Box::new(finality_proof_import)), + client.clone(), + InherentDataProviders::new(), + &task_manager.spawn_handle(), + config.prometheus_registry(), + )?; - let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _>( - sc_consensus_aura::slot_duration(&*client)?, - grandpa_block_import, - None, - Some(Box::new(finality_proof_import)), - client, - inherent_data_providers.clone(), - spawn_task_handle, - prometheus_registry, - )?; + let finality_proof_provider = + Arc::new(GrandpaFinalityProofProvider::new(backend.clone(), client.clone() as Arc<_>)); - Ok((import_queue, finality_proof_request_builder)) - })? - .with_finality_proof_provider(|client, backend| { - // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider - let provider = client as Arc>; - Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) - })? - .build_light() - .map(|ServiceComponents { task_manager, .. }| task_manager) + sc_service::build(sc_service::ServiceParams { + block_announce_validator_builder: None, + finality_proof_request_builder: Some(finality_proof_request_builder), + finality_proof_provider: Some(finality_proof_provider), + on_demand: Some(on_demand), + remote_blockchain: Some(backend.remote_blockchain()), + rpc_extensions_builder: Box::new(|_| ()), + transaction_pool: Arc::new(transaction_pool), + config, client, import_queue, keystore, backend, task_manager + }).map(|ServiceComponents { task_manager, .. }| task_manager) } diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index 91bec64edd63f..7615aef3d261f 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -20,6 +20,8 @@ use crate::{chain_spec, service, Cli, Subcommand}; use node_executor::Executor; use node_runtime::{Block, RuntimeApi}; use sc_cli::{Result, SubstrateCli, RuntimeVersion, Role, ChainSpec}; +use sc_service::ServiceParams; +use crate::service::new_full_params; impl SubstrateCli for Cli { fn impl_name() -> String { @@ -94,8 +96,9 @@ pub fn run() -> Result<()> { Some(Subcommand::Base(subcommand)) => { let runner = cli.create_runner(subcommand)?; runner.run_subcommand(subcommand, |config| { - let (builder, _, _, _) = new_full_start!(config); - Ok(builder.to_chain_ops_parts()) + let (ServiceParams { client, backend, import_queue, task_manager, .. }, ..) + = new_full_params(config)?; + Ok((client, backend, import_queue, task_manager)) }) } } diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index e817bb2a8c72a..46a7318333d4a 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -25,184 +25,183 @@ use sc_consensus_babe; use grandpa::{ self, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider, }; -use node_executor; use node_primitives::Block; use node_runtime::RuntimeApi; use sc_service::{ - ServiceBuilder, config::{Role, Configuration}, error::{Error as ServiceError}, + config::{Role, Configuration}, error::{Error as ServiceError}, RpcHandlers, ServiceComponents, TaskManager, }; use sp_inherents::InherentDataProviders; -use sc_consensus::LongestChain; use sc_network::{Event, NetworkService}; use sp_runtime::traits::Block as BlockT; use futures::prelude::*; -use sc_client_api::ExecutorProvider; +use sc_client_api::{ExecutorProvider, RemoteBackend}; use sp_core::traits::BareCryptoStorePtr; +use node_executor::Executor; -/// Starts a `ServiceBuilder` for a full service. -/// -/// Use this macro if you don't actually need the full service, but just the builder in order to -/// be able to perform chain operations. -macro_rules! new_full_start { - ($config:expr) => {{ - use std::sync::Arc; - - let mut import_setup = None; - let mut rpc_setup = None; - let inherent_data_providers = sp_inherents::InherentDataProviders::new(); - - let builder = sc_service::ServiceBuilder::new_full::< - node_primitives::Block, node_runtime::RuntimeApi, node_executor::Executor - >($config)? - .with_select_chain(|_config, backend| { - Ok(sc_consensus::LongestChain::new(backend.clone())) - })? - .with_transaction_pool(|builder| { - let pool_api = sc_transaction_pool::FullChainApi::new( - builder.client().clone(), - builder.prometheus_registry(), - ); - Ok(sc_transaction_pool::BasicPool::new_full( - builder.config().transaction_pool.clone(), - std::sync::Arc::new(pool_api), - builder.prometheus_registry(), - builder.spawn_handle(), - builder.client().clone(), - )) - })? - .with_import_queue(| - _config, - client, - mut select_chain, - _transaction_pool, - spawn_task_handle, - prometheus_registry, - | { - let select_chain = select_chain.take() - .ok_or_else(|| sc_service::Error::SelectChainRequired)?; - let (grandpa_block_import, grandpa_link) = grandpa::block_import( - client.clone(), - &(client.clone() as Arc<_>), - select_chain.clone(), - )?; - let justification_import = grandpa_block_import.clone(); - - let (block_import, babe_link) = sc_consensus_babe::block_import( - sc_consensus_babe::Config::get_or_compute(&*client)?, - grandpa_block_import, - client.clone(), - )?; - - let import_queue = sc_consensus_babe::import_queue( - babe_link.clone(), - block_import.clone(), - Some(Box::new(justification_import)), - None, - client, - select_chain, - inherent_data_providers.clone(), - spawn_task_handle, - prometheus_registry, - )?; - - import_setup = Some((block_import, grandpa_link, babe_link)); - Ok(import_queue) - })? - .with_rpc_extensions_builder(|builder| { - let grandpa_link = import_setup.as_ref().map(|s| &s.1) - .expect("GRANDPA LinkHalf is present for full services or set up failed; qed."); - - let shared_authority_set = grandpa_link.shared_authority_set().clone(); - let shared_voter_state = grandpa::SharedVoterState::empty(); - - rpc_setup = Some((shared_voter_state.clone())); - - let babe_link = import_setup.as_ref().map(|s| &s.2) - .expect("BabeLink is present for full services or set up failed; qed."); - - let babe_config = babe_link.config().clone(); - let shared_epoch_changes = babe_link.epoch_changes().clone(); - - let client = builder.client().clone(); - let pool = builder.pool().clone(); - let select_chain = builder.select_chain().cloned() - .expect("SelectChain is present for full services or set up failed; qed."); - let keystore = builder.keystore().clone(); - - Ok(move |deny_unsafe| { - let deps = node_rpc::FullDeps { - client: client.clone(), - pool: pool.clone(), - select_chain: select_chain.clone(), - deny_unsafe, - babe: node_rpc::BabeDeps { - babe_config: babe_config.clone(), - shared_epoch_changes: shared_epoch_changes.clone(), - keystore: keystore.clone(), - }, - grandpa: node_rpc::GrandpaDeps { - shared_voter_state: shared_voter_state.clone(), - shared_authority_set: shared_authority_set.clone(), - }, - }; +type FullClient = sc_service::TFullClient; +type FullBackend = sc_service::TFullBackend; +type FullSelectChain = sc_consensus::LongestChain; +type FullGrandpaBlockImport = + grandpa::GrandpaBlockImport; +type LightClient = sc_service::TLightClient; + +pub fn new_full_params(config: Configuration) -> Result<( + sc_service::ServiceParams< + Block, FullClient, + sc_consensus_babe::BabeImportQueue, + sc_transaction_pool::FullPool, node_rpc::IoHandler, + FullBackend + >, + ( + sc_consensus_babe::BabeBlockImport, + grandpa::LinkHalf, + sc_consensus_babe::BabeLink, + ), + grandpa::SharedVoterState, + FullSelectChain, + InherentDataProviders +), ServiceError> { + let (client, backend, keystore, task_manager) = + sc_service::new_full_parts::(&config)?; + let client = Arc::new(client); - node_rpc::create_full(deps) - }) - })?; + let select_chain = sc_consensus::LongestChain::new(backend.clone()); - (builder, import_setup, inherent_data_providers, rpc_setup) - }} -} + let pool_api = sc_transaction_pool::FullChainApi::new( + client.clone(), config.prometheus_registry(), + ); + let transaction_pool = sc_transaction_pool::BasicPool::new_full( + config.transaction_pool.clone(), + std::sync::Arc::new(pool_api), + config.prometheus_registry(), + task_manager.spawn_handle(), + client.clone(), + ); -type FullClient = sc_service::TFullClient; -type FullBackend = sc_service::TFullBackend; -type GrandpaBlockImport = grandpa::GrandpaBlockImport< - FullBackend, Block, FullClient, sc_consensus::LongestChain ->; -type BabeBlockImport = sc_consensus_babe::BabeBlockImport; + let (grandpa_block_import, grandpa_link) = grandpa::block_import( + client.clone(), &(client.clone() as Arc<_>), select_chain.clone(), + )?; + let justification_import = grandpa_block_import.clone(); + + let (block_import, babe_link) = sc_consensus_babe::block_import( + sc_consensus_babe::Config::get_or_compute(&*client)?, + grandpa_block_import, + client.clone(), + )?; + + let inherent_data_providers = sp_inherents::InherentDataProviders::new(); + + let import_queue = sc_consensus_babe::import_queue( + babe_link.clone(), + block_import.clone(), + Some(Box::new(justification_import)), + None, + client.clone(), + select_chain.clone(), + inherent_data_providers.clone(), + &task_manager.spawn_handle(), + config.prometheus_registry(), + )?; + + let import_setup = (block_import, grandpa_link, babe_link); + + let (rpc_extensions_builder, rpc_setup) = { + let (_, grandpa_link, babe_link) = &import_setup; + + let shared_authority_set = grandpa_link.shared_authority_set().clone(); + let shared_voter_state = grandpa::SharedVoterState::empty(); + + let rpc_setup = shared_voter_state.clone(); + + let babe_config = babe_link.config().clone(); + let shared_epoch_changes = babe_link.epoch_changes().clone(); + + let client = client.clone(); + let pool = transaction_pool.clone(); + let select_chain = select_chain.clone(); + let keystore = keystore.clone(); + + let rpc_extensions_builder = Box::new(move |deny_unsafe| { + let deps = node_rpc::FullDeps { + client: client.clone(), + pool: pool.clone(), + select_chain: select_chain.clone(), + deny_unsafe, + babe: node_rpc::BabeDeps { + babe_config: babe_config.clone(), + shared_epoch_changes: shared_epoch_changes.clone(), + keystore: keystore.clone(), + }, + grandpa: node_rpc::GrandpaDeps { + shared_voter_state: shared_voter_state.clone(), + shared_authority_set: shared_authority_set.clone(), + }, + }; + + node_rpc::create_full(deps) + }); + + (rpc_extensions_builder, rpc_setup) + }; + + let provider = client.clone() as Arc>; + let finality_proof_provider = + Arc::new(grandpa::FinalityProofProvider::new(backend.clone(), provider)); + + let params = sc_service::ServiceParams { + config, backend, client, import_queue, keystore, task_manager, rpc_extensions_builder, + transaction_pool, + block_announce_validator_builder: None, + finality_proof_request_builder: None, + finality_proof_provider: Some(finality_proof_provider), + on_demand: None, + remote_blockchain: None, + }; + + Ok((params, import_setup, rpc_setup, select_chain, inherent_data_providers)) +} /// Creates a full service from the configuration. pub fn new_full_base( config: Configuration, - with_startup_data: impl FnOnce(&BabeBlockImport, &sc_consensus_babe::BabeLink) + with_startup_data: impl FnOnce( + &sc_consensus_babe::BabeBlockImport, + &sc_consensus_babe::BabeLink, + ) ) -> Result<( - TaskManager, - InherentDataProviders, - Arc, Arc::Hash>>, - Arc, Block>> + TaskManager, InherentDataProviders, Arc, + Arc::Hash>>, + Arc>, ), ServiceError> { - let ( - role, - force_authoring, - name, - disable_grandpa, - ) = ( - config.role.clone(), - config.force_authoring, - config.network.node_name.clone(), - config.disable_grandpa, - ); + let (params, import_setup, rpc_setup, select_chain, inherent_data_providers) + = new_full_params(config)?; - let (builder, mut import_setup, inherent_data_providers, mut rpc_setup) = - new_full_start!(config); + let ( + role, force_authoring, name, enable_grandpa, prometheus_registry, + client, transaction_pool, keystore, + ) = { + let sc_service::ServiceParams { + config, client, transaction_pool, keystore, .. + } = ¶ms; + + ( + config.role.clone(), + config.force_authoring, + config.network.node_name.clone(), + !config.disable_grandpa, + config.prometheus_registry().cloned(), + + client.clone(), transaction_pool.clone(), keystore.clone(), + ) + }; let ServiceComponents { - client, transaction_pool, task_manager, keystore, network, select_chain, - prometheus_registry, telemetry_on_connect_sinks, .. - } = builder - .with_finality_proof_provider(|client, backend| { - // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider - let provider = client as Arc>; - Ok(Arc::new(grandpa::FinalityProofProvider::new(backend, provider)) as _) - })? - .build_full()?; - - let (block_import, grandpa_link, babe_link) = import_setup.take() - .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); - - let shared_voter_state = rpc_setup.take() - .expect("The SharedVoterState is present for Full Services or setup failed before. qed"); + task_manager, network, telemetry_on_connect_sinks, .. + } = sc_service::build(params)?; + + let (block_import, grandpa_link, babe_link) = import_setup; + let shared_voter_state = rpc_setup; (with_startup_data)(&block_import, &babe_link); @@ -213,9 +212,6 @@ pub fn new_full_base( prometheus_registry.as_ref(), ); - let select_chain = select_chain - .ok_or(sc_service::Error::SelectChainRequired)?; - let can_author_with = sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); @@ -287,7 +283,6 @@ pub fn new_full_base( is_authority: role.is_network_authority(), }; - let enable_grandpa = !disable_grandpa; if enable_grandpa { // start the full GRANDPA voter // NOTE: non-authorities could run the GRANDPA observer protocol, but at @@ -331,108 +326,82 @@ pub fn new_full(config: Configuration) }) } -type LightClient = sc_service::TLightClient; -type LightFetcher = sc_network::config::OnDemand; - pub fn new_light_base(config: Configuration) -> Result<( TaskManager, Arc, Arc, Arc::Hash>>, - Arc, Block - >> + Arc>> ), ServiceError> { - let inherent_data_providers = InherentDataProviders::new(); + let (client, backend, keystore, task_manager, on_demand) = + sc_service::new_light_parts::(&config)?; + + let select_chain = sc_consensus::LongestChain::new(backend.clone()); + + let transaction_pool_api = Arc::new(sc_transaction_pool::LightChainApi::new( + client.clone(), + on_demand.clone(), + )); + let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light( + config.transaction_pool.clone(), + transaction_pool_api, + config.prometheus_registry(), + task_manager.spawn_handle(), + )); + + let grandpa_block_import = grandpa::light_block_import( + client.clone(), backend.clone(), &(client.clone() as Arc<_>), + Arc::new(on_demand.checker().clone()), + )?; + + let finality_proof_import = grandpa_block_import.clone(); + let finality_proof_request_builder = + finality_proof_import.create_finality_proof_request_builder(); + + let (babe_block_import, babe_link) = sc_consensus_babe::block_import( + sc_consensus_babe::Config::get_or_compute(&*client)?, + grandpa_block_import, + client.clone(), + )?; + + let inherent_data_providers = sp_inherents::InherentDataProviders::new(); + + let import_queue = sc_consensus_babe::import_queue( + babe_link, + babe_block_import, + None, + Some(Box::new(finality_proof_import)), + client.clone(), + select_chain.clone(), + inherent_data_providers.clone(), + &task_manager.spawn_handle(), + config.prometheus_registry(), + )?; + + // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider + let provider = client.clone() as Arc>; + let finality_proof_provider = + Arc::new(GrandpaFinalityProofProvider::new(backend.clone(), provider)); + + let light_deps = node_rpc::LightDeps { + remote_blockchain: backend.remote_blockchain(), + fetcher: on_demand.clone(), + client: client.clone(), + pool: transaction_pool.clone(), + }; - let ServiceComponents { - task_manager, rpc_handlers, client, network, transaction_pool, .. - } = ServiceBuilder::new_light::(config)? - .with_select_chain(|_config, backend| { - Ok(LongestChain::new(backend.clone())) - })? - .with_transaction_pool(|builder| { - let fetcher = builder.fetcher() - .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?; - let pool_api = sc_transaction_pool::LightChainApi::new( - builder.client().clone(), - fetcher, - ); - let pool = Arc::new(sc_transaction_pool::BasicPool::new_light( - builder.config().transaction_pool.clone(), - Arc::new(pool_api), - builder.prometheus_registry(), - builder.spawn_handle(), - )); - Ok(pool) - })? - .with_import_queue_and_fprb(| - _config, - client, - backend, - fetcher, - mut select_chain, - _tx_pool, - spawn_task_handle, - registry, - | { - let select_chain = select_chain.take() - .ok_or_else(|| sc_service::Error::SelectChainRequired)?; - - let fetch_checker = fetcher - .map(|fetcher| fetcher.checker().clone()) - .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; - - let grandpa_block_import = grandpa::light_block_import( - client.clone(), - backend, - &(client.clone() as Arc<_>), - Arc::new(fetch_checker), - )?; - - let finality_proof_import = grandpa_block_import.clone(); - let finality_proof_request_builder = - finality_proof_import.create_finality_proof_request_builder(); - - let (babe_block_import, babe_link) = sc_consensus_babe::block_import( - sc_consensus_babe::Config::get_or_compute(&*client)?, - grandpa_block_import, - client.clone(), - )?; - - let import_queue = sc_consensus_babe::import_queue( - babe_link, - babe_block_import, - None, - Some(Box::new(finality_proof_import)), - client, - select_chain, - inherent_data_providers.clone(), - spawn_task_handle, - registry, - )?; - - Ok((import_queue, finality_proof_request_builder)) - })? - .with_finality_proof_provider(|client, backend| { - // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider - let provider = client as Arc>; - Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) - })? - .with_rpc_extensions(|builder| { - let fetcher = builder.fetcher() - .ok_or_else(|| "Trying to start node RPC without active fetcher")?; - let remote_blockchain = builder.remote_backend() - .ok_or_else(|| "Trying to start node RPC without active remote blockchain")?; - - let light_deps = node_rpc::LightDeps { - remote_blockchain, - fetcher, - client: builder.client().clone(), - pool: builder.pool(), - }; + let rpc_extensions = node_rpc::create_light(light_deps); - Ok(node_rpc::create_light(light_deps)) - })? - .build_light()?; + let ServiceComponents { task_manager, rpc_handlers, network, .. } = + sc_service::build(sc_service::ServiceParams { + block_announce_validator_builder: None, + finality_proof_request_builder: Some(finality_proof_request_builder), + finality_proof_provider: Some(finality_proof_provider), + on_demand: Some(on_demand), + remote_blockchain: Some(backend.remote_blockchain()), + rpc_extensions_builder: Box::new(sc_service::NoopRpcExtensionBuilder(rpc_extensions)), + client: client.clone(), + transaction_pool: transaction_pool.clone(), + config, import_queue, keystore, backend, task_manager, + })?; Ok((task_manager, rpc_handlers, client, network, transaction_pool)) } diff --git a/bin/node/rpc/Cargo.toml b/bin/node/rpc/Cargo.toml index d8adc78d80965..d28a4b7b00a24 100644 --- a/bin/node/rpc/Cargo.toml +++ b/bin/node/rpc/Cargo.toml @@ -12,6 +12,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] sc-client-api = { version = "2.0.0-rc5", path = "../../../client/api" } +sc-rpc = { version = "2.0.0-rc5", path = "../../../client/rpc" } jsonrpc-core = "14.2.0" node-primitives = { version = "2.0.0-rc5", path = "../primitives" } node-runtime = { version = "2.0.0-rc5", path = "../runtime" } diff --git a/bin/node/rpc/src/lib.rs b/bin/node/rpc/src/lib.rs index 9b6b5991748f9..142e7fb124b47 100644 --- a/bin/node/rpc/src/lib.rs +++ b/bin/node/rpc/src/lib.rs @@ -94,6 +94,9 @@ pub struct FullDeps { pub grandpa: GrandpaDeps, } +/// A IO handler that uses all Full RPC extensions. +pub type IoHandler = jsonrpc_core::IoHandler; + /// Instantiate all Full RPC extensions. pub fn create_full( deps: FullDeps, diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index 8763239771abb..244b7e929ef95 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -714,7 +714,7 @@ fn authorities(client: &C, at: &BlockId) -> Result, Consensus } /// The Aura import queue type. -pub type AuraImportQueue = BasicQueue; +pub type AuraImportQueue = BasicQueue>; /// Register the aura inherent data provider, if not registered already. fn register_aura_inherent_data_provider( @@ -824,7 +824,7 @@ pub fn import_queue( inherent_data_providers: InherentDataProviders, spawner: &S, registry: Option<&Registry>, -) -> Result>, sp_consensus::Error> where +) -> Result, sp_consensus::Error> where B: BlockT, C::Api: BlockBuilderApi + AuraApi> + ApiExt, C: 'static + ProvideRuntimeApi + BlockOf + ProvideCache + Send + Sync + AuxStore + HeaderBackend, diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index af684499cef8b..f09e9b063c255 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -968,7 +968,7 @@ where } /// The BABE import queue type. -pub type BabeImportQueue = BasicQueue; +pub type BabeImportQueue = BasicQueue>; /// Register the babe inherent data provider, if not registered already. fn register_babe_inherent_data_provider( @@ -1368,7 +1368,7 @@ pub fn import_queue( inherent_data_providers: InherentDataProviders, spawner: &impl sp_core::traits::SpawnNamed, registry: Option<&Registry>, -) -> ClientResult>> where +) -> ClientResult> where Inner: BlockImport> + Send + Sync + 'static, Client: ProvideRuntimeApi + ProvideCache + Send + Sync + AuxStore + 'static, diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index fe8fdcef13cfa..c71746f48a890 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -24,8 +24,8 @@ use crate::{ config::{Configuration, KeystoreConfig, PrometheusConfig, OffchainWorkerConfig}, }; use sc_client_api::{ - self, light::RemoteBlockchain, execution_extensions::ExtensionsFactory, ExecutorProvider, - ForkBlocks, BadBlocks, CloneableSpawn, UsageProvider, backend::RemoteBackend, + light::RemoteBlockchain, ForkBlocks, BadBlocks, CloneableSpawn, UsageProvider, + ExecutorProvider, }; use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; use sc_chain_spec::get_extension; @@ -49,10 +49,10 @@ use sp_runtime::traits::{ }; use sp_api::{ProvideRuntimeApi, CallApiAt}; use sc_executor::{NativeExecutor, NativeExecutionDispatch, RuntimeInfo}; -use std::{collections::HashMap, marker::PhantomData, sync::Arc, pin::Pin}; +use std::{collections::HashMap, sync::Arc, pin::Pin}; use wasm_timer::SystemTime; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; -use sp_transaction_pool::{LocalTransactionPool, MaintainedTransactionPool}; +use sp_transaction_pool::MaintainedTransactionPool; use prometheus_endpoint::Registry; use sc_client_db::{Backend, DatabaseSettings}; use sp_core::traits::CodeExecutor; @@ -66,43 +66,6 @@ use sc_client_api::{ use sp_blockchain::{HeaderMetadata, HeaderBackend}; use crate::{ServiceComponents, TelemetryOnConnectSinks, RpcHandlers, NetworkStatusSinks}; -/// Aggregator for the components required to build a service. -/// -/// # Usage -/// -/// Call [`ServiceBuilder::new_full`] or [`ServiceBuilder::new_light`], then call the various -/// `with_` methods to add the required components that you built yourself: -/// -/// - [`with_select_chain`](ServiceBuilder::with_select_chain) -/// - [`with_import_queue`](ServiceBuilder::with_import_queue) -/// - [`with_finality_proof_provider`](ServiceBuilder::with_finality_proof_provider) -/// - [`with_transaction_pool`](ServiceBuilder::with_transaction_pool) -/// -/// After this is done, call [`build`](ServiceBuilder::build) to construct the service. -/// -/// The order in which the `with_*` methods are called doesn't matter, as the correct binding of -/// generics is done when you call `build`. -/// -pub struct ServiceBuilder -{ - config: Configuration, - pub (crate) client: Arc, - backend: Arc, - task_manager: TaskManager, - keystore: Arc>, - fetcher: Option, - select_chain: Option, - pub (crate) import_queue: TImpQu, - finality_proof_request_builder: Option, - finality_proof_provider: Option, - transaction_pool: Arc, - rpc_extensions_builder: Box + Send>, - remote_backend: Option>>, - marker: PhantomData<(TBl, TRtApi)>, - block_announce_validator_builder: Option) -> Box + Send> + Send>>, -} - /// A utility trait for building an RPC extension given a `DenyUnsafe` instance. /// This is useful since at service definition time we don't know whether the /// specific interface where the RPC extension will be exposed is safe or not. @@ -131,7 +94,7 @@ impl RpcExtensionBuilder for F where /// A utility struct for implementing an `RpcExtensionBuilder` given a cloneable /// `RpcExtension`, the resulting builder will simply ignore the provided /// `DenyUnsafe` instance and return a static `RpcExtension` instance. -struct NoopRpcExtensionBuilder(R); +pub struct NoopRpcExtensionBuilder(pub R); impl RpcExtensionBuilder for NoopRpcExtensionBuilder where R: Clone + sc_rpc::RpcExtension, @@ -170,11 +133,8 @@ pub type TFullCallExecutor = crate::client::LocalCallExecutor< >; /// Light client type. -pub type TLightClient = Client< - TLightBackend, - TLightCallExecutor, - TBl, - TRtApi, +pub type TLightClient = TLightClientWithBackend< + TBl, TRtApi, TExecDisp, TLightBackend >; /// Light client backend type. @@ -205,6 +165,31 @@ type TFullParts = ( TaskManager, ); +type TLightParts = ( + Arc>, + Arc>, + Arc>, + TaskManager, + Arc>, +); + +/// Light client backend type with a specific hash type. +pub type TLightBackendWithHash = sc_light::Backend< + sc_client_db::light::LightStorage, + THash, +>; + +/// Light client type with a specific backend. +pub type TLightClientWithBackend = Client< + TBackend, + sc_light::GenesisCallExecutor< + TBackend, + crate::client::LocalCallExecutor>, + >, + TBl, + TRtApi, +>; + /// Creates a new full client for the given config. pub fn new_full_client( config: &Configuration, @@ -215,7 +200,8 @@ pub fn new_full_client( new_full_parts(config).map(|parts| parts.0) } -fn new_full_parts( +/// Create the initial parts of a full node. +pub fn new_full_parts( config: &Configuration, ) -> Result, Error> where TBl: BlockT, @@ -282,6 +268,63 @@ fn new_full_parts( Ok((client, backend, keystore, task_manager)) } +/// Create the initial parts of a light node. +pub fn new_light_parts( + config: &Configuration +) -> Result, Error> where + TBl: BlockT, + TExecDisp: NativeExecutionDispatch + 'static, +{ + + let task_manager = { + let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); + TaskManager::new(config.task_executor.clone(), registry)? + }; + + let keystore = match &config.keystore { + KeystoreConfig::Path { path, password } => Keystore::open( + path.clone(), + password.clone() + )?, + KeystoreConfig::InMemory => Keystore::new_in_memory(), + }; + + let executor = NativeExecutor::::new( + config.wasm_method, + config.default_heap_pages, + config.max_runtime_instances, + ); + + let db_storage = { + let db_settings = sc_client_db::DatabaseSettings { + state_cache_size: config.state_cache_size, + state_cache_child_ratio: + config.state_cache_child_ratio.map(|v| (v, 100)), + pruning: config.pruning.clone(), + source: config.database.clone(), + }; + sc_client_db::light::LightStorage::new(db_settings)? + }; + let light_blockchain = sc_light::new_light_blockchain(db_storage); + let fetch_checker = Arc::new( + sc_light::new_fetch_checker::<_, TBl, _>( + light_blockchain.clone(), + executor.clone(), + Box::new(task_manager.spawn_handle()), + ), + ); + let on_demand = Arc::new(sc_network::config::OnDemand::new(fetch_checker)); + let backend = sc_light::new_light_backend(light_blockchain); + let client = Arc::new(light::new_light( + backend.clone(), + config.chain_spec.as_storage_builder(), + executor, + Box::new(task_manager.spawn_handle()), + config.prometheus_config.as_ref().map(|config| config.registry.clone()), + )?); + + Ok((client, backend, keystore, task_manager, on_demand)) +} /// Create an instance of db-backed client. pub fn new_client( @@ -328,801 +371,233 @@ pub fn new_client( )) } -impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { - /// Start the service builder with a configuration. - pub fn new_full( - config: Configuration, - ) -> Result, - Arc>, - (), - (), - BoxFinalityProofRequestBuilder, - Arc>, - (), - (), - TFullBackend, - >, Error> { - let (client, backend, keystore, task_manager) = new_full_parts(&config)?; - - let client = Arc::new(client); - - Ok(ServiceBuilder { - config, - client, - backend, - keystore, - task_manager, - fetcher: None, - select_chain: None, - import_queue: (), - finality_proof_request_builder: None, - finality_proof_provider: None, - transaction_pool: Arc::new(()), - rpc_extensions_builder: Box::new(|_| ()), - remote_backend: None, - block_announce_validator_builder: None, - marker: PhantomData, - }) - } - - /// Start the service builder with a configuration. - pub fn new_light( - config: Configuration, - ) -> Result, - Arc>, - (), - (), - BoxFinalityProofRequestBuilder, - Arc>, - (), - (), - TLightBackend, - >, Error> { - let task_manager = { - let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); - TaskManager::new(config.task_executor.clone(), registry)? - }; - - let keystore = match &config.keystore { - KeystoreConfig::Path { path, password } => Keystore::open( - path.clone(), - password.clone() - )?, - KeystoreConfig::InMemory => Keystore::new_in_memory(), - }; - - let executor = NativeExecutor::::new( - config.wasm_method, - config.default_heap_pages, - config.max_runtime_instances, - ); - - let db_storage = { - let db_settings = sc_client_db::DatabaseSettings { - state_cache_size: config.state_cache_size, - state_cache_child_ratio: - config.state_cache_child_ratio.map(|v| (v, 100)), - pruning: config.pruning.clone(), - source: config.database.clone(), - }; - sc_client_db::light::LightStorage::new(db_settings)? - }; - let light_blockchain = sc_light::new_light_blockchain(db_storage); - let fetch_checker = Arc::new( - sc_light::new_fetch_checker::<_, TBl, _>( - light_blockchain.clone(), - executor.clone(), - Box::new(task_manager.spawn_handle()), - ), - ); - let fetcher = Arc::new(sc_network::config::OnDemand::new(fetch_checker)); - let backend = sc_light::new_light_backend(light_blockchain); - let remote_blockchain = backend.remote_blockchain(); - let client = Arc::new(light::new_light( - backend.clone(), - config.chain_spec.as_storage_builder(), - executor, - Box::new(task_manager.spawn_handle()), - config.prometheus_config.as_ref().map(|config| config.registry.clone()), - )?); - - Ok(ServiceBuilder { - config, - client, - backend, - task_manager, - keystore, - fetcher: Some(fetcher), - select_chain: None, - import_queue: (), - finality_proof_request_builder: None, - finality_proof_provider: None, - transaction_pool: Arc::new(()), - rpc_extensions_builder: Box::new(|_| ()), - remote_backend: Some(remote_blockchain), - block_announce_validator_builder: None, - marker: PhantomData, - }) - } +/// Parameters to pass into `build`. +pub struct ServiceParams { + /// The service configuration. + pub config: Configuration, + /// A shared client returned by `new_full_parts`/`new_light_parts`. + pub client: Arc, + /// A shared backend returned by `new_full_parts`/`new_light_parts`. + pub backend: Arc, + /// A task manager returned by `new_full_parts`/`new_light_parts`. + pub task_manager: TaskManager, + /// A shared keystore returned by `new_full_parts`/`new_light_parts`. + pub keystore: Arc>, + /// An optional, shared data fetcher for light clients. + pub on_demand: Option>>, + /// An import queue. + pub import_queue: TImpQu, + /// An optional finality proof request builder. + pub finality_proof_request_builder: Option>, + /// An optional, shared finality proof request provider. + pub finality_proof_provider: Option>>, + /// A shared transaction pool. + pub transaction_pool: Arc, + /// A RPC extension builder. Use `NoopRpcExtensionBuilder` if you just want to pass in the + /// extensions directly. + pub rpc_extensions_builder: Box + Send>, + /// An optional, shared remote blockchain instance. Used for light clients. + pub remote_blockchain: Option>>, + /// A block annouce validator builder. + pub block_announce_validator_builder: + Option) -> Box + Send> + Send>>, } -impl - ServiceBuilder< - TBl, - TRtApi, - TCl, - TFchr, - TSc, - TImpQu, - TFprb, - TFpp, - TExPool, - TRpc, - Backend - > -{ - /// Returns a reference to the configuration that was stored in this builder. - pub fn config(&self) -> &Configuration { - &self.config - } - - /// Returns a reference to the optional prometheus registry that was stored in this builder. - pub fn prometheus_registry(&self) -> Option<&Registry> { - self.config.prometheus_config.as_ref().map(|config| &config.registry) - } - - /// Returns a reference to the client that was stored in this builder. - pub fn client(&self) -> &Arc { - &self.client - } - - /// Returns a reference to the backend that was used in this builder. - pub fn backend(&self) -> &Arc { - &self.backend - } - - /// Returns a reference to the select-chain that was stored in this builder. - pub fn select_chain(&self) -> Option<&TSc> { - self.select_chain.as_ref() - } - - /// Returns a reference to the keystore - pub fn keystore(&self) -> Arc> { - self.keystore.clone() - } - - /// Returns a reference to the transaction pool stored in this builder - pub fn pool(&self) -> Arc { - self.transaction_pool.clone() - } - - /// Returns a reference to the fetcher, only available if builder - /// was created with `new_light`. - pub fn fetcher(&self) -> Option - where TFchr: Clone - { - self.fetcher.clone() - } - - /// Returns a reference to the remote_backend, only available if builder - /// was created with `new_light`. - pub fn remote_backend(&self) -> Option>> { - self.remote_backend.clone() - } - - /// Returns a spawn handle created by the task manager. - pub fn spawn_handle(&self) -> SpawnTaskHandle { - self.task_manager.spawn_handle() - } - - /// Consume the builder and return the parts needed for chain operations. - pub fn to_chain_ops_parts(self) -> (Arc, Arc, TImpQu, TaskManager) { - (self.client, self.backend, self.import_queue, self.task_manager) - } - - /// Defines which head-of-chain strategy to use. - pub fn with_opt_select_chain( - self, - select_chain_builder: impl FnOnce( - &Configuration, &Arc, - ) -> Result, Error> - ) -> Result, Error> { - let select_chain = select_chain_builder(&self.config, &self.backend)?; - - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - task_manager: self.task_manager, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain, - import_queue: self.import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider: self.finality_proof_provider, - transaction_pool: self.transaction_pool, - rpc_extensions_builder: self.rpc_extensions_builder, - remote_backend: self.remote_backend, - block_announce_validator_builder: self.block_announce_validator_builder, - marker: self.marker, - }) - } - - /// Defines which head-of-chain strategy to use. - pub fn with_select_chain( - self, - builder: impl FnOnce(&Configuration, &Arc) -> Result, - ) -> Result, Error> { - self.with_opt_select_chain(|cfg, b| builder(cfg, b).map(Option::Some)) - } - - /// Defines which import queue to use. - pub fn with_import_queue( - self, - builder: impl FnOnce(&Configuration, Arc, Option, Arc, &SpawnTaskHandle, Option<&Registry>) - -> Result - ) -> Result, Error> - where TSc: Clone { - let import_queue = builder( - &self.config, - self.client.clone(), - self.select_chain.clone(), - self.transaction_pool.clone(), - &self.task_manager.spawn_handle(), - self.config.prometheus_config.as_ref().map(|config| &config.registry), - )?; - - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - task_manager: self.task_manager, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider: self.finality_proof_provider, - transaction_pool: self.transaction_pool, - rpc_extensions_builder: self.rpc_extensions_builder, - remote_backend: self.remote_backend, - block_announce_validator_builder: self.block_announce_validator_builder, - marker: self.marker, - }) - } - - /// Defines which strategy to use for providing finality proofs. - pub fn with_opt_finality_proof_provider( - self, - builder: impl FnOnce(Arc, Arc) -> Result>>, Error> - ) -> Result>, - TExPool, - TRpc, - Backend, - >, Error> { - let finality_proof_provider = builder(self.client.clone(), self.backend.clone())?; - - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - task_manager: self.task_manager, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue: self.import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider, - transaction_pool: self.transaction_pool, - rpc_extensions_builder: self.rpc_extensions_builder, - remote_backend: self.remote_backend, - block_announce_validator_builder: self.block_announce_validator_builder, - marker: self.marker, - }) - } - - /// Defines which strategy to use for providing finality proofs. - pub fn with_finality_proof_provider( - self, - build: impl FnOnce(Arc, Arc) -> Result>, Error> - ) -> Result>, - TExPool, - TRpc, - Backend, - >, Error> { - self.with_opt_finality_proof_provider(|client, backend| build(client, backend).map(Option::Some)) - } - - /// Defines which import queue to use. - pub fn with_import_queue_and_opt_fprb( - self, - builder: impl FnOnce( - &Configuration, - Arc, - Arc, - Option, - Option, - Arc, - &SpawnTaskHandle, - Option<&Registry>, - ) -> Result<(UImpQu, Option), Error> - ) -> Result, Error> - where TSc: Clone, TFchr: Clone { - let (import_queue, fprb) = builder( - &self.config, - self.client.clone(), - self.backend.clone(), - self.fetcher.clone(), - self.select_chain.clone(), - self.transaction_pool.clone(), - &self.task_manager.spawn_handle(), - self.config.prometheus_config.as_ref().map(|config| &config.registry), - )?; - - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - task_manager: self.task_manager, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue, - finality_proof_request_builder: fprb, - finality_proof_provider: self.finality_proof_provider, - transaction_pool: self.transaction_pool, - rpc_extensions_builder: self.rpc_extensions_builder, - remote_backend: self.remote_backend, - block_announce_validator_builder: self.block_announce_validator_builder, - marker: self.marker, - }) - } - - /// Defines which import queue to use. - pub fn with_import_queue_and_fprb( - self, - builder: impl FnOnce( - &Configuration, - Arc, - Arc, - Option, - Option, - Arc, - &SpawnTaskHandle, - Option<&Registry>, - ) -> Result<(UImpQu, UFprb), Error> - ) -> Result, Error> - where TSc: Clone, TFchr: Clone { - self.with_import_queue_and_opt_fprb(|cfg, cl, b, f, sc, tx, tb, pr| - builder(cfg, cl, b, f, sc, tx, tb, pr) - .map(|(q, f)| (q, Some(f))) - ) - } - - /// Defines which transaction pool to use. - pub fn with_transaction_pool( - self, - transaction_pool_builder: impl FnOnce( - &Self, - ) -> Result, Error>, - ) -> Result, Error> - where TSc: Clone, TFchr: Clone { - let transaction_pool = transaction_pool_builder(&self)?; - - Ok(ServiceBuilder { - config: self.config, - client: self.client, - task_manager: self.task_manager, - backend: self.backend, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue: self.import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider: self.finality_proof_provider, - transaction_pool: transaction_pool, - rpc_extensions_builder: self.rpc_extensions_builder, - remote_backend: self.remote_backend, - block_announce_validator_builder: self.block_announce_validator_builder, - marker: self.marker, - }) - } - - /// Defines the RPC extension builder to use. Unlike `with_rpc_extensions`, - /// this method is useful in situations where the RPC extensions need to - /// access to a `DenyUnsafe` instance to avoid exposing sensitive methods. - pub fn with_rpc_extensions_builder( - self, - rpc_extensions_builder: impl FnOnce(&Self) -> Result, - ) -> Result< - ServiceBuilder, - Error, - > +/// Put together the components of a service from the parameters. +pub fn build( + builder: ServiceParams, +) -> Result, Error> where - TSc: Clone, - TFchr: Clone, - URpcBuilder: RpcExtensionBuilder + Send + 'static, - URpc: sc_rpc::RpcExtension, - { - let rpc_extensions_builder = rpc_extensions_builder(&self)?; - - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - task_manager: self.task_manager, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue: self.import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider: self.finality_proof_provider, - transaction_pool: self.transaction_pool, - rpc_extensions_builder: Box::new(rpc_extensions_builder), - remote_backend: self.remote_backend, - block_announce_validator_builder: self.block_announce_validator_builder, - marker: self.marker, - }) - } - - /// Defines the RPC extensions to use. - pub fn with_rpc_extensions( - self, - rpc_extensions: impl FnOnce(&Self) -> Result, - ) -> Result< - ServiceBuilder, - Error, - > - where - TSc: Clone, - TFchr: Clone, - URpc: Clone + sc_rpc::RpcExtension + Send + 'static, - { - let rpc_extensions = rpc_extensions(&self)?; - self.with_rpc_extensions_builder(|_| Ok(NoopRpcExtensionBuilder::from(rpc_extensions))) - } - - /// Defines the `BlockAnnounceValidator` to use. `DefaultBlockAnnounceValidator` will be used by - /// default. - pub fn with_block_announce_validator( - self, - block_announce_validator_builder: - impl FnOnce(Arc) -> Box + Send> + Send + 'static, - ) -> Result, Error> - where TSc: Clone, TFchr: Clone { - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - task_manager: self.task_manager, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue: self.import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider: self.finality_proof_provider, - transaction_pool: self.transaction_pool, - rpc_extensions_builder: self.rpc_extensions_builder, - remote_backend: self.remote_backend, - block_announce_validator_builder: Some(Box::new(block_announce_validator_builder)), - marker: self.marker, - }) - } -} - -impl -ServiceBuilder< - TBl, - TRtApi, - TCl, - Arc>, - TSc, - TImpQu, - BoxFinalityProofRequestBuilder, - Arc>, - TExPool, - TRpc, - TBackend, -> where - TCl: ProvideRuntimeApi + HeaderMetadata + Chain + - BlockBackend + BlockIdTo + ProofProvider + - HeaderBackend + BlockchainEvents + ExecutorProvider + UsageProvider + - StorageProvider + CallApiAt + - Send + 'static, - >::Api: - sp_api::Metadata + - sc_offchain::OffchainWorkerApi + - sp_transaction_pool::runtime_api::TaggedTransactionQueue + - sp_session::SessionKeys + - sp_api::ApiErrorExt + - sp_api::ApiExt, - TBl: BlockT, - TRtApi: 'static + Send + Sync, - TBackend: 'static + sc_client_api::backend::Backend + Send, - TSc: Clone, - TImpQu: 'static + ImportQueue, - TExPool: MaintainedTransactionPool::Hash> + MallocSizeOfWasm + 'static, - TRpc: sc_rpc::RpcExtension, + TCl: ProvideRuntimeApi + HeaderMetadata + Chain + + BlockBackend + BlockIdTo + ProofProvider + + HeaderBackend + BlockchainEvents + ExecutorProvider + UsageProvider + + StorageProvider + CallApiAt + + Send + 'static, + >::Api: + sp_api::Metadata + + sc_offchain::OffchainWorkerApi + + sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_session::SessionKeys + + sp_api::ApiErrorExt + + sp_api::ApiExt, + TBl: BlockT, + TBackend: 'static + sc_client_api::backend::Backend + Send, + TImpQu: 'static + ImportQueue, + TExPool: MaintainedTransactionPool::Hash> + + MallocSizeOfWasm + 'static, + TRpc: sc_rpc::RpcExtension { + let ServiceParams { + mut config, + mut task_manager, + client, + on_demand, + backend, + keystore, + import_queue, + finality_proof_request_builder, + finality_proof_provider, + transaction_pool, + rpc_extensions_builder, + remote_blockchain, + block_announce_validator_builder, + } = builder; + + let chain_info = client.usage_info().chain; + + sp_session::generate_initial_session_keys( + client.clone(), + &BlockId::Hash(chain_info.best_hash), + config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default(), + )?; + + info!("📦 Highest known block at #{}", chain_info.best_number); + telemetry!( + SUBSTRATE_INFO; + "node.start"; + "height" => chain_info.best_number.saturated_into::(), + "best" => ?chain_info.best_hash + ); - /// Set an ExecutionExtensionsFactory - pub fn with_execution_extensions_factory(self, execution_extensions_factory: Box) -> Result { - self.client.execution_extensions().set_extensions_factory(execution_extensions_factory); - Ok(self) - } - - fn build_common(self) -> Result, Error> { - let ServiceBuilder { - marker: _, - mut config, - client, - mut task_manager, - fetcher: on_demand, - backend, - keystore, - select_chain, - import_queue, - finality_proof_request_builder, - finality_proof_provider, - transaction_pool, - rpc_extensions_builder, - remote_backend, - block_announce_validator_builder, - } = self; - - let chain_info = client.usage_info().chain; - - sp_session::generate_initial_session_keys( - client.clone(), - &BlockId::Hash(chain_info.best_hash), - config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default(), - )?; - - info!("📦 Highest known block at #{}", chain_info.best_number); - telemetry!( - SUBSTRATE_INFO; - "node.start"; - "height" => chain_info.best_number.saturated_into::(), - "best" => ?chain_info.best_hash - ); - - let (system_rpc_tx, system_rpc_rx) = tracing_unbounded("mpsc_system_rpc"); - - let (network, network_status_sinks, network_future) = build_network( - &config, client.clone(), transaction_pool.clone(), task_manager.spawn_handle(), - on_demand.clone(), block_announce_validator_builder, finality_proof_request_builder, - finality_proof_provider, system_rpc_rx, import_queue - )?; - - let spawn_handle = task_manager.spawn_handle(); - - // The network worker is responsible for gathering all network messages and processing - // them. This is quite a heavy task, and at the time of the writing of this comment it - // frequently happens that this future takes several seconds or in some situations - // even more than a minute until it has processed its entire queue. This is clearly an - // issue, and ideally we would like to fix the network future to take as little time as - // possible, but we also take the extra harm-prevention measure to execute the networking - // future using `spawn_blocking`. - spawn_handle.spawn_blocking( - "network-worker", - network_future - ); + let (system_rpc_tx, system_rpc_rx) = tracing_unbounded("mpsc_system_rpc"); + + let (network, network_status_sinks, network_future) = build_network( + &config, client.clone(), transaction_pool.clone(), task_manager.spawn_handle(), + on_demand.clone(), block_announce_validator_builder, finality_proof_request_builder, + finality_proof_provider, system_rpc_rx, import_queue + )?; + + let spawn_handle = task_manager.spawn_handle(); + + // The network worker is responsible for gathering all network messages and processing + // them. This is quite a heavy task, and at the time of the writing of this comment it + // frequently happens that this future takes several seconds or in some situations + // even more than a minute until it has processed its entire queue. This is clearly an + // issue, and ideally we would like to fix the network future to take as little time as + // possible, but we also take the extra harm-prevention measure to execute the networking + // future using `spawn_blocking`. + spawn_handle.spawn_blocking("network-worker", network_future); + + let offchain_storage = backend.offchain_storage(); + let offchain_workers = match (config.offchain_worker.clone(), offchain_storage.clone()) { + (OffchainWorkerConfig {enabled: true, .. }, Some(db)) => { + Some(Arc::new(sc_offchain::OffchainWorkers::new(client.clone(), db))) + }, + (OffchainWorkerConfig {enabled: true, .. }, None) => { + warn!("Offchain workers disabled, due to lack of offchain storage support in backend."); + None + }, + _ => None, + }; - let offchain_storage = backend.offchain_storage(); - let offchain_workers = match (config.offchain_worker.clone(), offchain_storage.clone()) { - (OffchainWorkerConfig {enabled: true, .. }, Some(db)) => { - Some(Arc::new(sc_offchain::OffchainWorkers::new(client.clone(), db))) - }, - (OffchainWorkerConfig {enabled: true, .. }, None) => { - warn!("Offchain workers disabled, due to lack of offchain storage support in backend."); - None - }, - _ => None, - }; + // Inform the tx pool about imported and finalized blocks. + spawn_handle.spawn( + "txpool-notifications", + sc_transaction_pool::notification_future(client.clone(), transaction_pool.clone()), + ); - // Inform the tx pool about imported and finalized blocks. + // Inform the offchain worker about new imported blocks + if let Some(offchain) = offchain_workers.clone() { spawn_handle.spawn( - "txpool-notifications", - sc_transaction_pool::notification_future(client.clone(), transaction_pool.clone()), + "offchain-notifications", + sc_offchain::notification_future( + config.role.is_authority(), + client.clone(), + offchain, + task_manager.spawn_handle(), + network.clone() + ) ); + } - // Inform the offchain worker about new imported blocks - if let Some(offchain) = offchain_workers.clone() { - spawn_handle.spawn( - "offchain-notifications", - sc_offchain::notification_future( - config.role.is_authority(), - client.clone(), - offchain, - task_manager.spawn_handle(), - network.clone() - ) - ); - } + spawn_handle.spawn( + "on-transaction-imported", + transaction_notifications(transaction_pool.clone(), network.clone()), + ); + // Prometheus metrics. + let metrics_service = if let Some(PrometheusConfig { port, registry }) = + config.prometheus_config.clone() + { + // Set static metrics. + let metrics = MetricsService::with_prometheus(®istry, &config)?; spawn_handle.spawn( - "on-transaction-imported", - transaction_notifications(transaction_pool.clone(), network.clone()), + "prometheus-endpoint", + prometheus_endpoint::init_prometheus(port, registry).map(drop) ); - // Prometheus metrics. - let metrics_service = if let Some(PrometheusConfig { port, registry }) = config.prometheus_config.clone() { - // Set static metrics. - let metrics = MetricsService::with_prometheus(®istry, &config)?; - spawn_handle.spawn( - "prometheus-endpoint", - prometheus_endpoint::init_prometheus(port, registry).map(drop) - ); - - metrics - } else { - MetricsService::new() - }; + metrics + } else { + MetricsService::new() + }; - // Periodically notify the telemetry. - spawn_handle.spawn("telemetry-periodic-send", telemetry_periodic_send( - client.clone(), transaction_pool.clone(), metrics_service, network_status_sinks.clone() - )); + // Periodically notify the telemetry. + spawn_handle.spawn("telemetry-periodic-send", telemetry_periodic_send( + client.clone(), transaction_pool.clone(), metrics_service, network_status_sinks.clone() + )); - // Periodically send the network state to the telemetry. - spawn_handle.spawn( - "telemetry-periodic-network-state", - telemetry_periodic_network_state(network_status_sinks.clone()), - ); - - // RPC - let gen_handler = |deny_unsafe: sc_rpc::DenyUnsafe| gen_handler( - deny_unsafe, &config, &task_manager, client.clone(), transaction_pool.clone(), - keystore.clone(), on_demand.clone(), remote_backend.clone(), &*rpc_extensions_builder, - offchain_storage.clone(), system_rpc_tx.clone() - ); - let rpc = start_rpc_servers(&config, gen_handler)?; - // This is used internally, so don't restrict access to unsafe RPC - let rpc_handlers = Arc::new(RpcHandlers(gen_handler(sc_rpc::DenyUnsafe::No))); + // Periodically send the network state to the telemetry. + spawn_handle.spawn( + "telemetry-periodic-network-state", + telemetry_periodic_network_state(network_status_sinks.clone()), + ); - let telemetry_connection_sinks: Arc>>> = Default::default(); + // RPC + let gen_handler = |deny_unsafe: sc_rpc::DenyUnsafe| gen_handler( + deny_unsafe, &config, task_manager.spawn_handle(), client.clone(), transaction_pool.clone(), + keystore.clone(), on_demand.clone(), remote_blockchain.clone(), &*rpc_extensions_builder, + offchain_storage.clone(), system_rpc_tx.clone() + ); + let rpc = start_rpc_servers(&config, gen_handler)?; + // This is used internally, so don't restrict access to unsafe RPC + let rpc_handlers = Arc::new(RpcHandlers(gen_handler(sc_rpc::DenyUnsafe::No))); - // Telemetry - let telemetry = config.telemetry_endpoints.clone().and_then(|endpoints| { - if endpoints.is_empty() { - // we don't want the telemetry to be initialized if telemetry_endpoints == Some([]) - return None; - } + let telemetry_connection_sinks: Arc>>> = Default::default(); - let genesis_hash = match client.block_hash(Zero::zero()) { - Ok(Some(hash)) => hash, - _ => Default::default(), - }; - - let (telemetry, future) = build_telemetry( - &mut config, - endpoints, - telemetry_connection_sinks.clone(), - network.clone(), - genesis_hash, - ); + // Telemetry + let telemetry = config.telemetry_endpoints.clone().and_then(|endpoints| { + if endpoints.is_empty() { + // we don't want the telemetry to be initialized if telemetry_endpoints == Some([]) + return None; + } - spawn_handle.spawn( - "telemetry-worker", - future, - ); + let genesis_hash = match client.block_hash(Zero::zero()) { + Ok(Some(hash)) => hash, + _ => Default::default(), + }; - Some(telemetry) - }); + Some(build_telemetry( + &mut config, endpoints, telemetry_connection_sinks.clone(), network.clone(), + task_manager.spawn_handle(), genesis_hash, + )) + }); - // Instrumentation - if let Some(tracing_targets) = config.tracing_targets.as_ref() { - let subscriber = sc_tracing::ProfilingSubscriber::new( - config.tracing_receiver, tracing_targets - ); - match tracing::subscriber::set_global_default(subscriber) { - Ok(_) => (), - Err(e) => error!(target: "tracing", "Unable to set global default subscriber {}", e), - } + // Instrumentation + if let Some(tracing_targets) = config.tracing_targets.as_ref() { + let subscriber = sc_tracing::ProfilingSubscriber::new( + config.tracing_receiver, tracing_targets + ); + match tracing::subscriber::set_global_default(subscriber) { + Ok(_) => (), + Err(e) => error!(target: "tracing", "Unable to set global default subscriber {}", e), } - - // Spawn informant task - spawn_handle.spawn("informant", sc_informant::build( - client.clone(), - network_status_sinks.clone(), - transaction_pool.clone(), - config.informant_output_format, - )); - - task_manager.keep_alive((telemetry, config.base_path, rpc, rpc_handlers.clone())); - - Ok(ServiceComponents { - client, - task_manager, - network, - select_chain, - transaction_pool, - rpc_handlers, - keystore, - offchain_workers, - telemetry_on_connect_sinks: TelemetryOnConnectSinks(telemetry_connection_sinks), - network_status_sinks: NetworkStatusSinks::new(network_status_sinks), - prometheus_registry: config.prometheus_config.map(|config| config.registry), - }) } - /// Builds the light service. - pub fn build_light(self) -> Result, Error> { - self.build_common() - } -} + // Spawn informant task + spawn_handle.spawn("informant", sc_informant::build( + client.clone(), + network_status_sinks.clone(), + transaction_pool.clone(), + config.informant_output_format, + )); -impl -ServiceBuilder< - TBl, - TRtApi, - TCl, - Arc>, - TSc, - TImpQu, - BoxFinalityProofRequestBuilder, - Arc>, - TExPool, - TRpc, - TBackend, -> where - TCl: ProvideRuntimeApi + HeaderMetadata + Chain + - BlockBackend + BlockIdTo + ProofProvider + - HeaderBackend + BlockchainEvents + ExecutorProvider + UsageProvider + - StorageProvider + CallApiAt + - Send + 'static, - >::Api: - sp_api::Metadata + - sc_offchain::OffchainWorkerApi + - sp_transaction_pool::runtime_api::TaggedTransactionQueue + - sp_session::SessionKeys + - sp_api::ApiErrorExt + - sp_api::ApiExt, - TBl: BlockT, - TRtApi: 'static + Send + Sync, - TBackend: 'static + sc_client_api::backend::Backend + Send, - TSc: Clone, - TImpQu: 'static + ImportQueue, - TExPool: MaintainedTransactionPool::Hash> + - LocalTransactionPool::Hash> + - MallocSizeOfWasm + - 'static, - TRpc: sc_rpc::RpcExtension, -{ + task_manager.keep_alive((telemetry, config.base_path, rpc, rpc_handlers.clone())); - /// Builds the full service. - pub fn build_full(self) -> Result, Error> { - self.build_common() - } + Ok(ServiceComponents { + task_manager, network, rpc_handlers, offchain_workers, + telemetry_on_connect_sinks: TelemetryOnConnectSinks(telemetry_connection_sinks), + network_status_sinks: NetworkStatusSinks::new(network_status_sinks), + }) } async fn transaction_notifications( @@ -1193,8 +668,9 @@ fn build_telemetry( endpoints: sc_telemetry::TelemetryEndpoints, telemetry_connection_sinks: Arc>>>, network: Arc::Hash>>, + spawn_handle: SpawnTaskHandle, genesis_hash: ::Hash, -) -> (sc_telemetry::Telemetry, Pin + Send>>) { +) -> sc_telemetry::Telemetry { let is_authority = config.role.is_authority(); let network_id = network.local_peer_id().to_base58(); let name = config.network.node_name.clone(); @@ -1208,42 +684,45 @@ fn build_telemetry( let startup_time = SystemTime::UNIX_EPOCH.elapsed() .map(|dur| dur.as_millis()) .unwrap_or(0); - let future = telemetry.clone() - .for_each(move |event| { - // Safe-guard in case we add more events in the future. - let sc_telemetry::TelemetryEvent::Connected = event; - - telemetry!(SUBSTRATE_INFO; "system.connected"; - "name" => name.clone(), - "implementation" => impl_name.clone(), - "version" => impl_version.clone(), - "config" => "", - "chain" => chain_name.clone(), - "genesis_hash" => ?genesis_hash, - "authority" => is_authority, - "startup_time" => startup_time, - "network_id" => network_id.clone() - ); + + spawn_handle.spawn( + "telemetry-worker", + telemetry.clone() + .for_each(move |event| { + // Safe-guard in case we add more events in the future. + let sc_telemetry::TelemetryEvent::Connected = event; + + telemetry!(SUBSTRATE_INFO; "system.connected"; + "name" => name.clone(), + "implementation" => impl_name.clone(), + "version" => impl_version.clone(), + "config" => "", + "chain" => chain_name.clone(), + "genesis_hash" => ?genesis_hash, + "authority" => is_authority, + "startup_time" => startup_time, + "network_id" => network_id.clone() + ); - telemetry_connection_sinks.lock().retain(|sink| { - sink.unbounded_send(()).is_ok() - }); - ready(()) - }) - .boxed(); + telemetry_connection_sinks.lock().retain(|sink| { + sink.unbounded_send(()).is_ok() + }); + ready(()) + }) + ); - (telemetry, future) + telemetry } fn gen_handler( deny_unsafe: sc_rpc::DenyUnsafe, config: &Configuration, - task_manager: &TaskManager, + spawn_handle: SpawnTaskHandle, client: Arc, transaction_pool: Arc, keystore: Arc>, on_demand: Option>>, - remote_backend: Option>>, + remote_blockchain: Option>>, rpc_extensions_builder: &(dyn RpcExtensionBuilder + Send), offchain_storage: Option<>::OffchainStorage>, system_rpc_tx: TracingUnboundedSender> @@ -1271,21 +750,21 @@ fn gen_handler( chain_type: config.chain_spec.chain_type(), }; - let subscriptions = SubscriptionManager::new(Arc::new(task_manager.spawn_handle())); + let subscriptions = SubscriptionManager::new(Arc::new(spawn_handle)); - let (chain, state, child_state) = if let (Some(remote_backend), Some(on_demand)) = - (remote_backend, on_demand) { + let (chain, state, child_state) = if let (Some(remote_blockchain), Some(on_demand)) = + (remote_blockchain, on_demand) { // Light clients let chain = sc_rpc::chain::new_light( client.clone(), subscriptions.clone(), - remote_backend.clone(), - on_demand.clone() + remote_blockchain.clone(), + on_demand.clone(), ); let (state, child_state) = sc_rpc::state::new_light( client.clone(), subscriptions.clone(), - remote_backend.clone(), + remote_blockchain.clone(), on_demand, ); (chain, state, child_state) diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index b8b722503749c..1eef6493e775e 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -52,9 +52,10 @@ use sp_utils::{status_sinks, mpsc::{tracing_unbounded, TracingUnboundedReceiver, pub use self::error::Error; pub use self::builder::{ - new_full_client, new_client, - ServiceBuilder, TFullClient, TLightClient, TFullBackend, TLightBackend, - TFullCallExecutor, TLightCallExecutor, RpcExtensionBuilder, + new_full_client, new_client, new_full_parts, new_light_parts, build, + ServiceParams, TFullClient, TLightClient, TFullBackend, TLightBackend, + TLightBackendWithHash, TLightClientWithBackend, + TFullCallExecutor, TLightCallExecutor, RpcExtensionBuilder, NoopRpcExtensionBuilder, }; pub use config::{ BasePath, Configuration, DatabaseConfig, PruningMode, Role, RpcMethods, TaskExecutor, TaskType, @@ -150,25 +151,15 @@ impl TelemetryOnConnectSinks { /// The individual components of the chain, built by the service builder. You are encouraged to /// deconstruct this into its fields. -pub struct ServiceComponents, TSc, TExPool, TCl> { - /// A blockchain client. - pub client: Arc, - /// A shared transaction pool instance. - pub transaction_pool: Arc, +pub struct ServiceComponents, TCl> { /// The chain task manager. pub task_manager: TaskManager, - /// A keystore that stores keys. - pub keystore: sc_keystore::KeyStorePtr, /// A shared network instance. pub network: Arc::Hash>>, /// RPC handlers that can perform RPC queries. pub rpc_handlers: Arc, - /// A shared instance of the chain selection algorithm. - pub select_chain: Option, /// Sinks to propagate network status updates. pub network_status_sinks: NetworkStatusSinks, - /// A prometheus metrics registry, (if enabled). - pub prometheus_registry: Option, /// Shared Telemetry connection sinks, pub telemetry_on_connect_sinks: TelemetryOnConnectSinks, /// A shared offchain workers instance. diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index fd6d64a340db3..bb9936984f96b 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -64,6 +64,11 @@ type ReadyIteratorFor = BoxedReadyIterator< type PolledIterator = Pin> + Send>>; +/// A transaction pool for a full node. +pub type FullPool = BasicPool, Block>; +/// A transaction pool for a light node. +pub type LightPool = BasicPool, Block>; + /// Basic implementation of transaction pool that can be customized by providing PoolApi. pub struct BasicPool where