Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions bin/node-template/node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
let finality_proof_provider =
GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone());

let (network, network_status_sinks, system_rpc_tx) =
let (network, network_status_sinks, system_rpc_tx, network_starter) =
sc_service::build_network(sc_service::BuildNetworkParams {
config: &config,
client: client.clone(),
Expand Down Expand Up @@ -215,6 +215,7 @@ pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
)?;
}

network_starter.start_network();
Ok(task_manager)
}

Expand Down Expand Up @@ -253,7 +254,7 @@ pub fn new_light(config: Configuration) -> Result<TaskManager, ServiceError> {
let finality_proof_provider =
GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone());

let (network, network_status_sinks, system_rpc_tx) =
let (network, network_status_sinks, system_rpc_tx, network_starter) =
sc_service::build_network(sc_service::BuildNetworkParams {
config: &config,
client: client.clone(),
Expand Down Expand Up @@ -288,5 +289,7 @@ pub fn new_light(config: Configuration) -> Result<TaskManager, ServiceError> {
system_rpc_tx,
})?;

network_starter.start_network();

Ok(task_manager)
}
18 changes: 10 additions & 8 deletions bin/node/cli/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ pub fn new_full_base(

let finality_proof_provider =
GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone());
let (network, network_status_sinks, system_rpc_tx) =

let (network, network_status_sinks, system_rpc_tx, network_starter) =
sc_service::build_network(sc_service::BuildNetworkParams {
config: &config,
client: client.clone(),
Expand Down Expand Up @@ -206,7 +206,7 @@ pub fn new_full_base(
network_status_sinks,
system_rpc_tx,
})?;

let (block_import, grandpa_link, babe_link) = import_setup;
let shared_voter_state = rpc_setup;

Expand Down Expand Up @@ -322,6 +322,7 @@ pub fn new_full_base(
)?;
}

network_starter.start_network();
Ok((task_manager, inherent_data_providers, client, network, transaction_pool))
}

Expand Down Expand Up @@ -383,7 +384,7 @@ pub fn new_light_base(config: Configuration) -> Result<(
let finality_proof_provider =
GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone());

let (network, network_status_sinks, system_rpc_tx) =
let (network, network_status_sinks, system_rpc_tx, network_starter) =
sc_service::build_network(sc_service::BuildNetworkParams {
config: &config,
client: client.clone(),
Expand All @@ -395,7 +396,8 @@ pub fn new_light_base(config: Configuration) -> Result<(
finality_proof_request_builder: Some(finality_proof_request_builder),
finality_proof_provider: Some(finality_proof_provider),
})?;

network_starter.start_network();

if config.offchain_worker.enabled {
sc_service::build_offchain_workers(
&config, backend.clone(), task_manager.spawn_handle(), client.clone(), network.clone(),
Expand All @@ -412,7 +414,7 @@ pub fn new_light_base(config: Configuration) -> Result<(
let rpc_extensions = node_rpc::create_light(light_deps);

let rpc_handlers =
sc_service::spawn_tasks(sc_service::SpawnTasksParams {
sc_service::spawn_tasks(sc_service::SpawnTasksParams {
on_demand: Some(on_demand),
remote_blockchain: Some(backend.remote_blockchain()),
rpc_extensions_builder: Box::new(sc_service::NoopRpcExtensionBuilder(rpc_extensions)),
Expand All @@ -423,7 +425,7 @@ pub fn new_light_base(config: Configuration) -> Result<(
telemetry_connection_sinks: sc_service::TelemetryConnectionSinks::default(),
task_manager: &mut task_manager,
})?;

Ok((task_manager, rpc_handlers, client, network, transaction_pool))
}

Expand Down Expand Up @@ -498,7 +500,7 @@ mod tests {
setup_handles = Some((block_import.clone(), babe_link.clone()));
}
)?;

let node = sc_service_test::TestNetComponents::new(
keep_alive, client, network, transaction_pool
);
Expand Down
50 changes: 46 additions & 4 deletions client/service/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use sp_consensus::{
block_validation::{BlockAnnounceValidator, DefaultBlockAnnounceValidator, Chain},
import_queue::ImportQueue,
};
use futures::{FutureExt, StreamExt, future::ready};
use futures::{FutureExt, StreamExt, future::ready, channel::oneshot};
use jsonrpc_pubsub::manager::SubscriptionManager;
use sc_keystore::Store as Keystore;
use log::{info, warn, error};
Expand Down Expand Up @@ -668,7 +668,7 @@ fn build_telemetry<TBl: BlockT>(
let startup_time = SystemTime::UNIX_EPOCH.elapsed()
.map(|dur| dur.as_millis())
.unwrap_or(0);

spawn_handle.spawn(
"telemetry-worker",
telemetry.clone()
Expand Down Expand Up @@ -822,6 +822,7 @@ pub fn build_network<TBl, TExPool, TImpQu, TCl>(
Arc<NetworkService<TBl, <TBl as BlockT>::Hash>>,
NetworkStatusSinks<TBl>,
TracingUnboundedSender<sc_rpc::system::Request<TBl>>,
NetworkStarter,
),
Error
>
Expand Down Expand Up @@ -900,14 +901,55 @@ pub fn build_network<TBl, TExPool, TImpQu, TCl>(
config.announce_block,
);

// TODO: Normally, one is supposed to pass a list of notifications protocols supported by the
// node through the `NetworkConfiguration` struct. But because this function doesn't know in
// advance which components, such as GrandPa or Polkadot, will be plugged on top of the
// service, it is unfortunately not possible to do so without some deep refactoring. To bypass
// this problem, the `NetworkService` provides a `register_notifications_protocol` method that
// can be called even after the network has been initialized. However, we want to avoid the
// situation where `register_notifications_protocol` is called *after* the network actually
// connects to other peers. For this reason, we delay the process of the network future until
// the user calls `NetworkStarter::start_network`.
//
// This entire hack should eventually be removed in favour of passing the list of protocols
// through the configuration.
//
// See also https://github.com/paritytech/substrate/issues/6827
let (network_start_tx, network_start_rx) = oneshot::channel();

// 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", future);
spawn_handle.spawn_blocking("network-worker", async move {
if network_start_rx.await.is_err() {
debug_assert!(false);
log::warn!(
"The NetworkStart returned as part of `build_network` has been silently dropped"
);
// This `return` might seem unnecessary, but we don't want to make it look like
// everything is working as normal even though the user is clearly misusing the API.
return;
}

future.await
});

Ok((network, network_status_sinks, system_rpc_tx, NetworkStarter(network_start_tx)))
}

Ok((network, network_status_sinks, system_rpc_tx))
/// Object used to start the network.
#[must_use]
pub struct NetworkStarter(oneshot::Sender<()>);

impl NetworkStarter {
/// Start the network. Call this after all sub-components have been initialized.
///
/// > **Note**: If you don't call this function, the networking will stay inhert.
Comment thread
tomaka marked this conversation as resolved.
Outdated
pub fn start_network(self) {
let _ = self.0.send(());
}
}
2 changes: 1 addition & 1 deletion client/service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use sp_utils::{status_sinks, mpsc::{tracing_unbounded, TracingUnboundedReceiver,
pub use self::error::Error;
pub use self::builder::{
new_full_client, new_client, new_full_parts, new_light_parts,
spawn_tasks, build_network, BuildNetworkParams, build_offchain_workers,
spawn_tasks, build_network, BuildNetworkParams, NetworkStarter, build_offchain_workers,
SpawnTasksParams, TFullClient, TLightClient, TFullBackend, TLightBackend,
TLightBackendWithHash, TLightClientWithBackend,
TFullCallExecutor, TLightCallExecutor, RpcExtensionBuilder, NoopRpcExtensionBuilder,
Expand Down