diff --git a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs index d384c9d9bd22..866214fe2c52 100644 --- a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs +++ b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs @@ -295,7 +295,7 @@ fn build_polkadot_full_node( workers_path: None, workers_names: None, - overseer_gen: polkadot_service::RealOverseerGen, + overseer_gen: polkadot_service::CollatorOverseerGen, overseer_message_channel_capacity_override: None, malus_finality_delay: None, hwbench, diff --git a/cumulus/test/service/src/lib.rs b/cumulus/test/service/src/lib.rs index 2bd6fa43f76c..aa2c4af97dfd 100644 --- a/cumulus/test/service/src/lib.rs +++ b/cumulus/test/service/src/lib.rs @@ -271,6 +271,7 @@ async fn build_relay_chain_interface( polkadot_service::IsParachainNode::Collator(CollatorPair::generate().0) }, None, + polkadot_service::CollatorOverseerGen, ) .map_err(|e| RelayChainError::Application(Box::new(e) as Box<_>))?, cumulus_client_cli::RelayChainMode::ExternalRpc(rpc_target_urls) => diff --git a/polkadot/cli/src/command.rs b/polkadot/cli/src/command.rs index 1e25f6533f04..97710bc4237b 100644 --- a/polkadot/cli/src/command.rs +++ b/polkadot/cli/src/command.rs @@ -299,7 +299,7 @@ pub fn run() -> Result<()> { match &cli.subcommand { None => run_node_inner( cli, - service::RealOverseerGen, + service::ValidatorOverseerGen, None, polkadot_node_metrics::logger_hook(), ), diff --git a/polkadot/cli/src/lib.rs b/polkadot/cli/src/lib.rs index 35a467146b42..4bb0dfb75835 100644 --- a/polkadot/cli/src/lib.rs +++ b/polkadot/cli/src/lib.rs @@ -29,7 +29,7 @@ mod error; pub use service::{self, Block, CoreApi, IdentifyVariant, ProvideRuntimeApi, TFullClient}; #[cfg(feature = "malus")] -pub use service::overseer::prepared_overseer_builder; +pub use service::overseer::validator_overseer_builder; #[cfg(feature = "cli")] pub use cli::*; diff --git a/polkadot/node/core/pvf-checker/src/lib.rs b/polkadot/node/core/pvf-checker/src/lib.rs index 043da00eba15..ae0fae6b4f9f 100644 --- a/polkadot/node/core/pvf-checker/src/lib.rs +++ b/polkadot/node/core/pvf-checker/src/lib.rs @@ -49,29 +49,24 @@ use self::{ /// PVF pre-checking subsystem. pub struct PvfCheckerSubsystem { - enabled: bool, keystore: KeystorePtr, metrics: Metrics, } impl PvfCheckerSubsystem { - pub fn new(enabled: bool, keystore: KeystorePtr, metrics: Metrics) -> Self { - PvfCheckerSubsystem { enabled, keystore, metrics } + pub fn new(keystore: KeystorePtr, metrics: Metrics) -> Self { + PvfCheckerSubsystem { keystore, metrics } } } #[overseer::subsystem(PvfChecker, error=SubsystemError, prefix = self::overseer)] impl PvfCheckerSubsystem { fn start(self, ctx: Context) -> SpawnedSubsystem { - if self.enabled { - let future = run(ctx, self.keystore, self.metrics) - .map_err(|e| SubsystemError::with_origin("pvf-checker", e)) - .boxed(); - - SpawnedSubsystem { name: "pvf-checker-subsystem", future } - } else { - polkadot_overseer::DummySubsystem.start(ctx) - } + let future = run(ctx, self.keystore, self.metrics) + .map_err(|e| SubsystemError::with_origin("pvf-checker", e)) + .boxed(); + + SpawnedSubsystem { name: "pvf-checker-subsystem", future } } } diff --git a/polkadot/node/malus/src/variants/back_garbage_candidate.rs b/polkadot/node/malus/src/variants/back_garbage_candidate.rs index aa904c37b80a..82475d291422 100644 --- a/polkadot/node/malus/src/variants/back_garbage_candidate.rs +++ b/polkadot/node/malus/src/variants/back_garbage_candidate.rs @@ -19,13 +19,12 @@ //! candidates. use polkadot_cli::{ - prepared_overseer_builder, service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, HeaderBackend, Overseer, - OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, ParachainHost, - ProvideRuntimeApi, + AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, + HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, + ParachainHost, ProvideRuntimeApi, }, - Cli, + validator_overseer_builder, Cli, }; use polkadot_node_subsystem::SpawnGlue; use polkadot_node_subsystem_types::DefaultSubsystemClient; @@ -63,6 +62,7 @@ impl OverseerGen for BackGarbageCandidates { &self, connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, + ext_args: Option, ) -> Result< (Overseer, Arc>>, OverseerHandle), Error, @@ -80,11 +80,14 @@ impl OverseerGen for BackGarbageCandidates { SpawnGlue(spawner), ); - prepared_overseer_builder(args)? - .replace_candidate_validation(move |cv_subsystem| { - InterceptedSubsystem::new(cv_subsystem, validation_filter) - }) - .build_with_connector(connector) - .map_err(|e| e.into()) + validator_overseer_builder( + args, + ext_args.expect("Extended arguments required to build validator overseer are provided"), + )? + .replace_candidate_validation(move |cv_subsystem| { + InterceptedSubsystem::new(cv_subsystem, validation_filter) + }) + .build_with_connector(connector) + .map_err(|e| e.into()) } } diff --git a/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs b/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs index 7f83c386090e..b3555ba2f5be 100644 --- a/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs +++ b/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs @@ -33,13 +33,12 @@ use futures::channel::oneshot; use polkadot_cli::{ - prepared_overseer_builder, service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, HeaderBackend, Overseer, - OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, ParachainHost, - ProvideRuntimeApi, + AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, + HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, + ParachainHost, ProvideRuntimeApi, }, - Cli, + validator_overseer_builder, Cli, }; use polkadot_node_subsystem::{messages::ApprovalVotingMessage, SpawnGlue}; use polkadot_node_subsystem_types::{DefaultSubsystemClient, OverseerSignal}; @@ -237,6 +236,7 @@ impl OverseerGen for DisputeFinalizedCandidates { &self, connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, + ext_args: Option, ) -> Result< (Overseer, Arc>>, OverseerHandle), Error, @@ -257,9 +257,12 @@ impl OverseerGen for DisputeFinalizedCandidates { dispute_offset: self.dispute_offset, }; - prepared_overseer_builder(args)? - .replace_approval_voting(move |cb| InterceptedSubsystem::new(cb, ancestor_disputer)) - .build_with_connector(connector) - .map_err(|e| e.into()) + validator_overseer_builder( + args, + ext_args.expect("Extended arguments required to build validator overseer are provided"), + )? + .replace_approval_voting(move |cb| InterceptedSubsystem::new(cb, ancestor_disputer)) + .build_with_connector(connector) + .map_err(|e| e.into()) } } diff --git a/polkadot/node/malus/src/variants/dispute_valid_candidates.rs b/polkadot/node/malus/src/variants/dispute_valid_candidates.rs index fa3b0c38bc2f..b9812cbb5012 100644 --- a/polkadot/node/malus/src/variants/dispute_valid_candidates.rs +++ b/polkadot/node/malus/src/variants/dispute_valid_candidates.rs @@ -23,13 +23,12 @@ #![allow(missing_docs)] use polkadot_cli::{ - prepared_overseer_builder, service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, HeaderBackend, Overseer, - OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, ParachainHost, - ProvideRuntimeApi, + AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, + HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, + ParachainHost, ProvideRuntimeApi, }, - Cli, + validator_overseer_builder, Cli, }; use polkadot_node_subsystem::SpawnGlue; use polkadot_node_subsystem_types::DefaultSubsystemClient; @@ -80,6 +79,7 @@ impl OverseerGen for DisputeValidCandidates { &self, connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, + ext_args: Option, ) -> Result< (Overseer, Arc>>, OverseerHandle), Error, @@ -97,11 +97,14 @@ impl OverseerGen for DisputeValidCandidates { SpawnGlue(spawner.clone()), ); - prepared_overseer_builder(args)? - .replace_candidate_validation(move |cv_subsystem| { - InterceptedSubsystem::new(cv_subsystem, validation_filter) - }) - .build_with_connector(connector) - .map_err(|e| e.into()) + validator_overseer_builder( + args, + ext_args.expect("Extended arguments required to build validator overseer are provided"), + )? + .replace_candidate_validation(move |cv_subsystem| { + InterceptedSubsystem::new(cv_subsystem, validation_filter) + }) + .build_with_connector(connector) + .map_err(|e| e.into()) } } diff --git a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs index cf0ff5f809d8..5e460f18903b 100644 --- a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs +++ b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs @@ -23,13 +23,12 @@ #![allow(missing_docs)] use polkadot_cli::{ - prepared_overseer_builder, service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, HeaderBackend, Overseer, - OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, ParachainHost, - ProvideRuntimeApi, + AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, + HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, + ParachainHost, ProvideRuntimeApi, }, - Cli, + validator_overseer_builder, Cli, }; use polkadot_node_core_candidate_validation::find_validation_data; use polkadot_node_primitives::{AvailableData, BlockData, PoV}; @@ -266,6 +265,7 @@ impl OverseerGen for SuggestGarbageCandidates { &self, connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, + ext_args: Option, ) -> Result< (Overseer, Arc>>, OverseerHandle), Error, @@ -293,12 +293,13 @@ impl OverseerGen for SuggestGarbageCandidates { SpawnGlue(args.spawner.clone()), ); - prepared_overseer_builder(args)? - .replace_candidate_backing(move |cb| InterceptedSubsystem::new(cb, note_candidate)) - .replace_candidate_validation(move |cb| { - InterceptedSubsystem::new(cb, validation_filter) - }) - .build_with_connector(connector) - .map_err(|e| e.into()) + validator_overseer_builder( + args, + ext_args.expect("Extended arguments required to build validator overseer are provided"), + )? + .replace_candidate_backing(move |cb| InterceptedSubsystem::new(cb, note_candidate)) + .replace_candidate_validation(move |cb| InterceptedSubsystem::new(cb, validation_filter)) + .build_with_connector(connector) + .map_err(|e| e.into()) } } diff --git a/polkadot/node/malus/src/variants/support_disabled.rs b/polkadot/node/malus/src/variants/support_disabled.rs index 5fb53be7774b..e25df56fd643 100644 --- a/polkadot/node/malus/src/variants/support_disabled.rs +++ b/polkadot/node/malus/src/variants/support_disabled.rs @@ -18,13 +18,12 @@ //! to always return an empty set of disabled validators. use polkadot_cli::{ - prepared_overseer_builder, service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, HeaderBackend, Overseer, - OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, ParachainHost, - ProvideRuntimeApi, + AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, + HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, + ParachainHost, ProvideRuntimeApi, }, - Cli, + validator_overseer_builder, Cli, }; use polkadot_node_subsystem::SpawnGlue; use polkadot_node_subsystem_types::DefaultSubsystemClient; @@ -50,6 +49,7 @@ impl OverseerGen for SupportDisabled { &self, connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, + ext_args: Option, ) -> Result< (Overseer, Arc>>, OverseerHandle), Error, @@ -59,12 +59,15 @@ impl OverseerGen for SupportDisabled { RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, Spawner: 'static + SpawnNamed + Clone + Unpin, { - prepared_overseer_builder(args)? - .replace_runtime_api(move |ra_subsystem| { - InterceptedSubsystem::new(ra_subsystem, IgnoreDisabled) - }) - .build_with_connector(connector) - .map_err(|e| e.into()) + validator_overseer_builder( + args, + ext_args.expect("Extended arguments required to build validator overseer are provided"), + )? + .replace_runtime_api(move |ra_subsystem| { + InterceptedSubsystem::new(ra_subsystem, IgnoreDisabled) + }) + .build_with_connector(connector) + .map_err(|e| e.into()) } } diff --git a/polkadot/node/service/src/lib.rs b/polkadot/node/service/src/lib.rs index 1aadef03ce79..6dcdec07ca84 100644 --- a/polkadot/node/service/src/lib.rs +++ b/polkadot/node/service/src/lib.rs @@ -31,7 +31,10 @@ pub mod overseer; pub mod workers; #[cfg(feature = "full-node")] -pub use self::overseer::{OverseerGen, OverseerGenArgs, RealOverseerGen}; +pub use self::overseer::{ + CollatorOverseerGen, ExtendedOverseerGenArgs, OverseerGen, OverseerGenArgs, + ValidatorOverseerGen, +}; #[cfg(test)] mod tests; @@ -775,8 +778,6 @@ pub fn new_full( let keystore = basics.keystore_container.local_keystore(); let auth_or_collator = role.is_authority() || is_parachain_node.is_collator(); - // We only need to enable the pvf checker when this is a validator. - let pvf_checker_enabled = role.is_authority(); let select_chain = if auth_or_collator { let metrics = @@ -867,10 +868,6 @@ pub fn new_full( let req_protocol_names = ReqProtocolNames::new(&genesis_hash, config.chain_spec.fork_id()); - let (pov_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); - net_config.add_request_response_protocol(cfg); - let (chunk_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); - net_config.add_request_response_protocol(cfg); let (collation_req_v1_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); net_config.add_request_response_protocol(cfg); @@ -880,12 +877,9 @@ pub fn new_full( let (available_data_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); net_config.add_request_response_protocol(cfg); - let (statement_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); - net_config.add_request_response_protocol(cfg); - let (candidate_req_v2_receiver, cfg) = - IncomingRequest::get_config_receiver(&req_protocol_names); + let (pov_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); net_config.add_request_response_protocol(cfg); - let (dispute_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); + let (chunk_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); net_config.add_request_response_protocol(cfg); let grandpa_hard_forks = if config.chain_spec.is_kusama() { @@ -900,6 +894,69 @@ pub fn new_full( grandpa_hard_forks, )); + let ext_overseer_args = if is_parachain_node.is_running_alongside_parachain_node() { + None + } else { + let parachains_db = open_database(&config.database)?; + let candidate_validation_config = if role.is_authority() { + let (prep_worker_path, exec_worker_path) = workers::determine_workers_paths( + workers_path, + workers_names, + node_version.clone(), + )?; + log::info!("🚀 Using prepare-worker binary at: {:?}", prep_worker_path); + log::info!("🚀 Using execute-worker binary at: {:?}", exec_worker_path); + + Some(CandidateValidationConfig { + artifacts_cache_path: config + .database + .path() + .ok_or(Error::DatabasePathRequired)? + .join("pvf-artifacts"), + node_version, + secure_validator_mode, + prep_worker_path, + exec_worker_path, + }) + } else { + None + }; + let (statement_req_receiver, cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + net_config.add_request_response_protocol(cfg); + let (candidate_req_v2_receiver, cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + net_config.add_request_response_protocol(cfg); + let (dispute_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); + net_config.add_request_response_protocol(cfg); + let approval_voting_config = ApprovalVotingConfig { + col_approval_data: parachains_db::REAL_COLUMNS.col_approval_data, + slot_duration_millis: slot_duration.as_millis() as u64, + }; + let dispute_coordinator_config = DisputeCoordinatorConfig { + col_dispute_data: parachains_db::REAL_COLUMNS.col_dispute_coordinator_data, + }; + let chain_selection_config = ChainSelectionConfig { + col_data: parachains_db::REAL_COLUMNS.col_chain_selection_data, + stagnant_check_interval: Default::default(), + stagnant_check_mode: chain_selection_subsystem::StagnantCheckMode::PruneOnly, + }; + Some(ExtendedOverseerGenArgs { + keystore, + parachains_db, + candidate_validation_config, + availability_config: AVAILABILITY_CONFIG, + pov_req_receiver, + chunk_req_receiver, + statement_req_receiver, + candidate_req_v2_receiver, + approval_voting_config, + dispute_req_receiver, + dispute_coordinator_config, + chain_selection_config, + }) + }; + let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) = service::build_network(service::BuildNetworkParams { config: &config, @@ -936,44 +993,6 @@ pub fn new_full( ); } - let parachains_db = open_database(&config.database)?; - - let approval_voting_config = ApprovalVotingConfig { - col_approval_data: parachains_db::REAL_COLUMNS.col_approval_data, - slot_duration_millis: slot_duration.as_millis() as u64, - }; - - let candidate_validation_config = if role.is_authority() { - let (prep_worker_path, exec_worker_path) = - workers::determine_workers_paths(workers_path, workers_names, node_version.clone())?; - log::info!("🚀 Using prepare-worker binary at: {:?}", prep_worker_path); - log::info!("🚀 Using execute-worker binary at: {:?}", exec_worker_path); - - Some(CandidateValidationConfig { - artifacts_cache_path: config - .database - .path() - .ok_or(Error::DatabasePathRequired)? - .join("pvf-artifacts"), - node_version, - secure_validator_mode, - prep_worker_path, - exec_worker_path, - }) - } else { - None - }; - - let chain_selection_config = ChainSelectionConfig { - col_data: parachains_db::REAL_COLUMNS.col_chain_selection_data, - stagnant_check_interval: Default::default(), - stagnant_check_mode: chain_selection_subsystem::StagnantCheckMode::PruneOnly, - }; - - let dispute_coordinator_config = DisputeCoordinatorConfig { - col_dispute_data: parachains_db::REAL_COLUMNS.col_dispute_coordinator_data, - }; - let rpc_handlers = service::spawn_tasks(service::SpawnTasksParams { config, backend: backend.clone(), @@ -1067,29 +1086,16 @@ pub fn new_full( .generate::( overseer_connector, OverseerGenArgs { - keystore, runtime_client: overseer_client.clone(), - parachains_db, network_service: network.clone(), sync_service: sync_service.clone(), authority_discovery_service, - pov_req_receiver, - chunk_req_receiver, collation_req_v1_receiver, collation_req_v2_receiver, available_data_req_receiver, - statement_req_receiver, - candidate_req_v2_receiver, - dispute_req_receiver, registry: prometheus_registry.as_ref(), spawner, is_parachain_node, - approval_voting_config, - availability_config: AVAILABILITY_CONFIG, - candidate_validation_config, - chain_selection_config, - dispute_coordinator_config, - pvf_checker_enabled, overseer_message_channel_capacity_override, req_protocol_names, peerset_protocol_names, @@ -1098,6 +1104,7 @@ pub fn new_full( ), notification_services, }, + ext_overseer_args, ) .map_err(|e| { gum::error!("Failed to init overseer: {}", e); diff --git a/polkadot/node/service/src/overseer.rs b/polkadot/node/service/src/overseer.rs index 599563d64549..b2b0786bfc24 100644 --- a/polkadot/node/service/src/overseer.rs +++ b/polkadot/node/service/src/overseer.rs @@ -16,6 +16,7 @@ use super::{AuthorityDiscoveryApi, Block, Error, Hash, IsParachainNode, Registry}; use polkadot_node_subsystem_types::DefaultSubsystemClient; +use polkadot_overseer::{DummySubsystem, InitializedOverseerBuilder, SubsystemError}; use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sp_core::traits::SpawnNamed; @@ -32,13 +33,10 @@ use polkadot_node_network_protocol::{ }, }; #[cfg(any(feature = "malus", test))] -pub use polkadot_overseer::{ - dummy::{dummy_overseer_builder, DummySubsystem}, - HeadSupportsParachains, -}; +pub use polkadot_overseer::{dummy::dummy_overseer_builder, HeadSupportsParachains}; use polkadot_overseer::{ - metrics::Metrics as OverseerMetrics, InitializedOverseerBuilder, MetricsTrait, Overseer, - OverseerConnector, OverseerHandle, SpawnGlue, + metrics::Metrics as OverseerMetrics, MetricsTrait, Overseer, OverseerConnector, OverseerHandle, + SpawnGlue, }; use parking_lot::Mutex; @@ -86,22 +84,14 @@ where RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, Spawner: 'static + SpawnNamed + Clone + Unpin, { - /// The keystore to use for i.e. validator keys. - pub keystore: Arc, /// Runtime client generic, providing the `ProvieRuntimeApi` trait besides others. pub runtime_client: Arc, - /// The underlying key value store for the parachains. - pub parachains_db: Arc, /// Underlying network service implementation. pub network_service: Arc>, /// Underlying syncing service implementation. pub sync_service: Arc>, /// Underlying authority discovery service. pub authority_discovery_service: AuthorityDiscoveryService, - /// POV request receiver. - pub pov_req_receiver: IncomingRequestReceiver, - /// Erasure chunks request receiver. - pub chunk_req_receiver: IncomingRequestReceiver, /// Collations request receiver for network protocol v1. pub collation_req_v1_receiver: IncomingRequestReceiver, /// Collations request receiver for network protocol v2. @@ -109,30 +99,12 @@ where /// Receiver for available data requests. pub available_data_req_receiver: IncomingRequestReceiver, - /// Receiver for incoming large statement requests. - pub statement_req_receiver: IncomingRequestReceiver, - /// Receiver for incoming candidate requests. - pub candidate_req_v2_receiver: IncomingRequestReceiver, - /// Receiver for incoming disputes. - pub dispute_req_receiver: IncomingRequestReceiver, /// Prometheus registry, commonly used for production systems, less so for test. pub registry: Option<&'a Registry>, /// Task spawner to be used throughout the overseer and the APIs it provides. pub spawner: Spawner, /// Determines the behavior of the collator. pub is_parachain_node: IsParachainNode, - /// Configuration for the approval voting subsystem. - pub approval_voting_config: ApprovalVotingConfig, - /// Configuration for the availability store subsystem. - pub availability_config: AvailabilityConfig, - /// Configuration for the candidate validation subsystem. - pub candidate_validation_config: Option, - /// Configuration for the chain selection subsystem. - pub chain_selection_config: ChainSelectionConfig, - /// Configuration for the dispute coordinator subsystem. - pub dispute_coordinator_config: DisputeCoordinatorConfig, - /// Enable PVF pre-checking - pub pvf_checker_enabled: bool, /// Overseer channel capacity override. pub overseer_message_channel_capacity_override: Option, /// Request-response protocol names source. @@ -145,39 +117,66 @@ where pub notification_services: HashMap>, } -/// Obtain a prepared `OverseerBuilder`, that is initialized -/// with all default values. -pub fn prepared_overseer_builder( +pub struct ExtendedOverseerGenArgs { + /// The keystore to use for i.e. validator keys. + pub keystore: Arc, + /// The underlying key value store for the parachains. + pub parachains_db: Arc, + /// Configuration for the candidate validation subsystem. + pub candidate_validation_config: Option, + /// Configuration for the availability store subsystem. + pub availability_config: AvailabilityConfig, + /// POV request receiver. + pub pov_req_receiver: IncomingRequestReceiver, + /// Erasure chunks request receiver. + pub chunk_req_receiver: IncomingRequestReceiver, + /// Receiver for incoming large statement requests. + pub statement_req_receiver: IncomingRequestReceiver, + /// Receiver for incoming candidate requests. + pub candidate_req_v2_receiver: IncomingRequestReceiver, + /// Configuration for the approval voting subsystem. + pub approval_voting_config: ApprovalVotingConfig, + /// Receiver for incoming disputes. + pub dispute_req_receiver: IncomingRequestReceiver, + /// Configuration for the dispute coordinator subsystem. + pub dispute_coordinator_config: DisputeCoordinatorConfig, + /// Configuration for the chain selection subsystem. + pub chain_selection_config: ChainSelectionConfig, +} + +/// Obtain a prepared validator `Overseer`, that is initialized with all default values. +pub fn validator_overseer_builder( OverseerGenArgs { - keystore, runtime_client, - parachains_db, network_service, sync_service, authority_discovery_service, - pov_req_receiver, - chunk_req_receiver, - collation_req_v1_receiver, - collation_req_v2_receiver, + collation_req_v1_receiver: _, + collation_req_v2_receiver: _, available_data_req_receiver, - statement_req_receiver, - candidate_req_v2_receiver, - dispute_req_receiver, registry, spawner, is_parachain_node, - approval_voting_config, - availability_config, - candidate_validation_config, - chain_selection_config, - dispute_coordinator_config, - pvf_checker_enabled, overseer_message_channel_capacity_override, req_protocol_names, peerset_protocol_names, offchain_transaction_pool_factory, notification_services, }: OverseerGenArgs, + ExtendedOverseerGenArgs { + keystore, + parachains_db, + candidate_validation_config, + availability_config, + pov_req_receiver, + chunk_req_receiver, + statement_req_receiver, + candidate_req_v2_receiver, + approval_voting_config, + dispute_req_receiver, + dispute_coordinator_config, + chain_selection_config, + }: ExtendedOverseerGenArgs, ) -> Result< InitializedOverseerBuilder< SpawnGlue, @@ -280,23 +279,15 @@ where Metrics::register(registry)?, // candidate-validation metrics Metrics::register(registry)?, // validation host metrics )) - .pvf_checker(PvfCheckerSubsystem::new( - pvf_checker_enabled, - keystore.clone(), - Metrics::register(registry)?, - )) + .pvf_checker(PvfCheckerSubsystem::new(keystore.clone(), Metrics::register(registry)?)) .chain_api(ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?)) .collation_generation(CollationGenerationSubsystem::new(Metrics::register(registry)?)) .collator_protocol({ let side = match is_parachain_node { - IsParachainNode::Collator(collator_pair) => ProtocolSide::Collator { - peer_id: network_service.local_peer_id(), - collator_pair, - request_receiver_v1: collation_req_v1_receiver, - request_receiver_v2: collation_req_v2_receiver, - metrics: Metrics::register(registry)?, - }, - IsParachainNode::FullNode => ProtocolSide::None, + IsParachainNode::Collator(_) | IsParachainNode::FullNode => + return Err(Error::Overseer(SubsystemError::Context( + "build validator overseer for parachain node".to_owned(), + ))), IsParachainNode::No => ProtocolSide::Validator { keystore: keystore.clone(), eviction_policy: Default::default(), @@ -352,23 +343,173 @@ where .metrics(metrics) .spawner(spawner); - if let Some(capacity) = overseer_message_channel_capacity_override { - Ok(builder.message_channel_capacity(capacity)) + let builder = if let Some(capacity) = overseer_message_channel_capacity_override { + builder.message_channel_capacity(capacity) } else { - Ok(builder) - } + builder + }; + Ok(builder) +} + +/// Obtain a prepared collator `Overseer`, that is initialized with all default values. +pub fn collator_overseer_builder( + OverseerGenArgs { + runtime_client, + network_service, + sync_service, + authority_discovery_service, + collation_req_v1_receiver, + collation_req_v2_receiver, + available_data_req_receiver, + registry, + spawner, + is_parachain_node, + overseer_message_channel_capacity_override, + req_protocol_names, + peerset_protocol_names, + offchain_transaction_pool_factory, + notification_services, + }: OverseerGenArgs, +) -> Result< + InitializedOverseerBuilder< + SpawnGlue, + Arc>, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + AvailabilityRecoverySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + RuntimeApiSubsystem>, + DummySubsystem, + NetworkBridgeRxSubsystem< + Arc>, + AuthorityDiscoveryService, + >, + NetworkBridgeTxSubsystem< + Arc>, + AuthorityDiscoveryService, + >, + ChainApiSubsystem, + CollationGenerationSubsystem, + CollatorProtocolSubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + DummySubsystem, + ProspectiveParachainsSubsystem, + >, + Error, +> +where + RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, + RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + Spawner: 'static + SpawnNamed + Clone + Unpin, +{ + use polkadot_node_subsystem_util::metrics::Metrics; + + let metrics = ::register(registry)?; + let notification_sinks = Arc::new(Mutex::new(HashMap::new())); + + let spawner = SpawnGlue(spawner); + + let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?; + + let runtime_api_client = Arc::new(DefaultSubsystemClient::new( + runtime_client.clone(), + offchain_transaction_pool_factory, + )); + + let builder = Overseer::builder() + .network_bridge_tx(NetworkBridgeTxSubsystem::new( + network_service.clone(), + authority_discovery_service.clone(), + network_bridge_metrics.clone(), + req_protocol_names, + peerset_protocol_names.clone(), + notification_sinks.clone(), + )) + .network_bridge_rx(NetworkBridgeRxSubsystem::new( + network_service.clone(), + authority_discovery_service.clone(), + Box::new(sync_service.clone()), + network_bridge_metrics, + peerset_protocol_names, + notification_services, + notification_sinks, + )) + .availability_distribution(DummySubsystem) + .availability_recovery(AvailabilityRecoverySubsystem::for_collator( + available_data_req_receiver, + Metrics::register(registry)?, + )) + .availability_store(DummySubsystem) + .bitfield_distribution(DummySubsystem) + .bitfield_signing(DummySubsystem) + .candidate_backing(DummySubsystem) + .candidate_validation(DummySubsystem) + .pvf_checker(DummySubsystem) + .chain_api(ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?)) + .collation_generation(CollationGenerationSubsystem::new(Metrics::register(registry)?)) + .collator_protocol({ + let side = match is_parachain_node { + IsParachainNode::No => + return Err(Error::Overseer(SubsystemError::Context( + "build parachain node overseer for validator".to_owned(), + ))), + IsParachainNode::Collator(collator_pair) => ProtocolSide::Collator { + peer_id: network_service.local_peer_id(), + collator_pair, + request_receiver_v1: collation_req_v1_receiver, + request_receiver_v2: collation_req_v2_receiver, + metrics: Metrics::register(registry)?, + }, + IsParachainNode::FullNode => ProtocolSide::None, + }; + CollatorProtocolSubsystem::new(side) + }) + .provisioner(DummySubsystem) + .runtime_api(RuntimeApiSubsystem::new( + runtime_api_client.clone(), + Metrics::register(registry)?, + spawner.clone(), + )) + .statement_distribution(DummySubsystem) + .approval_distribution(DummySubsystem) + .approval_voting(DummySubsystem) + .gossip_support(DummySubsystem) + .dispute_coordinator(DummySubsystem) + .dispute_distribution(DummySubsystem) + .chain_selection(DummySubsystem) + .prospective_parachains(ProspectiveParachainsSubsystem::new(Metrics::register(registry)?)) + .activation_external_listeners(Default::default()) + .span_per_active_leaf(Default::default()) + .active_leaves(Default::default()) + .supports_parachains(runtime_api_client) + .metrics(metrics) + .spawner(spawner); + + let builder = if let Some(capacity) = overseer_message_channel_capacity_override { + builder.message_channel_capacity(capacity) + } else { + builder + }; + Ok(builder) } /// Trait for the `fn` generating the overseer. -/// -/// Default behavior is to create an unmodified overseer, as `RealOverseerGen` -/// would do. pub trait OverseerGen { /// Overwrite the full generation of the overseer, including the subsystems. fn generate( &self, connector: OverseerConnector, args: OverseerGenArgs, + ext_args: Option, ) -> Result< (Overseer, Arc>>, OverseerHandle), Error, @@ -376,24 +517,50 @@ pub trait OverseerGen { where RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, - Spawner: 'static + SpawnNamed + Clone + Unpin, - { - let gen = RealOverseerGen; - RealOverseerGen::generate::(&gen, connector, args) - } + Spawner: 'static + SpawnNamed + Clone + Unpin; + // It would be nice to make `create_subsystems` part of this trait, // but the amount of generic arguments that would be required as // as consequence make this rather annoying to implement and use. } /// The regular set of subsystems. -pub struct RealOverseerGen; +pub struct ValidatorOverseerGen; + +impl OverseerGen for ValidatorOverseerGen { + fn generate( + &self, + connector: OverseerConnector, + args: OverseerGenArgs, + ext_args: Option, + ) -> Result< + (Overseer, Arc>>, OverseerHandle), + Error, + > + where + RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, + RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + Spawner: 'static + SpawnNamed + Clone + Unpin, + { + let ext_args = ext_args.ok_or(Error::Overseer(SubsystemError::Context( + "create validator overseer as mandatory extended arguments were not provided" + .to_owned(), + )))?; + validator_overseer_builder(args, ext_args)? + .build_with_connector(connector) + .map_err(|e| e.into()) + } +} + +/// Reduced set of subsystems, to use in collator and collator's full node. +pub struct CollatorOverseerGen; -impl OverseerGen for RealOverseerGen { +impl OverseerGen for CollatorOverseerGen { fn generate( &self, connector: OverseerConnector, args: OverseerGenArgs, + _ext_args: Option, ) -> Result< (Overseer, Arc>>, OverseerHandle), Error, @@ -403,7 +570,7 @@ impl OverseerGen for RealOverseerGen { RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, Spawner: 'static + SpawnNamed + Clone + Unpin, { - prepared_overseer_builder(args)? + collator_overseer_builder(args)? .build_with_connector(connector) .map_err(|e| e.into()) } diff --git a/polkadot/node/test/service/src/lib.rs b/polkadot/node/test/service/src/lib.rs index 3ef969566b2d..e4eec32baf2a 100644 --- a/polkadot/node/test/service/src/lib.rs +++ b/polkadot/node/test/service/src/lib.rs @@ -28,7 +28,9 @@ use polkadot_overseer::Handle; use polkadot_primitives::{Balance, CollatorPair, HeadData, Id as ParaId, ValidationCode}; use polkadot_runtime_common::BlockHashCount; use polkadot_runtime_parachains::paras::{ParaGenesisArgs, ParaKind}; -use polkadot_service::{Error, FullClient, IsParachainNode, NewFull, PrometheusConfig}; +use polkadot_service::{ + Error, FullClient, IsParachainNode, NewFull, OverseerGen, PrometheusConfig, +}; use polkadot_test_runtime::{ ParasCall, ParasSudoWrapperCall, Runtime, SignedExtra, SignedPayload, SudoCall, UncheckedExtrinsic, VERSION, @@ -69,10 +71,11 @@ pub use polkadot_service::{FullBackend, GetLastTimestamp}; /// Create a new full node. #[sc_tracing::logging::prefix_logs_with(config.network.node_name.as_str())] -pub fn new_full( +pub fn new_full( config: Configuration, is_parachain_node: IsParachainNode, workers_path: Option, + overseer_gen: OverseerGenerator, ) -> Result { let workers_path = Some(workers_path.unwrap_or_else(get_relative_workers_path_for_test)); @@ -88,7 +91,7 @@ pub fn new_full( secure_validator_mode: false, workers_path, workers_names: None, - overseer_gen: polkadot_service::RealOverseerGen, + overseer_gen, overseer_message_channel_capacity_override: None, malus_finality_delay: None, hwbench: None, @@ -207,9 +210,13 @@ pub fn run_validator_node( worker_program_path: Option, ) -> PolkadotTestNode { let multiaddr = config.network.listen_addresses[0].clone(); - let NewFull { task_manager, client, network, rpc_handlers, overseer_handle, .. } = - new_full(config, IsParachainNode::No, worker_program_path) - .expect("could not create Polkadot test service"); + let NewFull { task_manager, client, network, rpc_handlers, overseer_handle, .. } = new_full( + config, + IsParachainNode::No, + worker_program_path, + polkadot_service::ValidatorOverseerGen, + ) + .expect("could not create Polkadot test service"); let overseer_handle = overseer_handle.expect("test node must have an overseer handle"); let peer_id = network.local_peer_id(); @@ -239,9 +246,13 @@ pub fn run_collator_node( ) -> PolkadotTestNode { let config = node_config(storage_update_func, tokio_handle, key, boot_nodes, false); let multiaddr = config.network.listen_addresses[0].clone(); - let NewFull { task_manager, client, network, rpc_handlers, overseer_handle, .. } = - new_full(config, IsParachainNode::Collator(collator_pair), None) - .expect("could not create Polkadot test service"); + let NewFull { task_manager, client, network, rpc_handlers, overseer_handle, .. } = new_full( + config, + IsParachainNode::Collator(collator_pair), + None, + polkadot_service::CollatorOverseerGen, + ) + .expect("could not create Polkadot test service"); let overseer_handle = overseer_handle.expect("test node must have an overseer handle"); let peer_id = network.local_peer_id(); diff --git a/polkadot/parachain/test-parachains/adder/collator/src/main.rs b/polkadot/parachain/test-parachains/adder/collator/src/main.rs index 5d9384d49561..fec90fc41cdb 100644 --- a/polkadot/parachain/test-parachains/adder/collator/src/main.rs +++ b/polkadot/parachain/test-parachains/adder/collator/src/main.rs @@ -91,7 +91,7 @@ fn main() -> Result<()> { workers_path: None, workers_names: None, - overseer_gen: polkadot_service::RealOverseerGen, + overseer_gen: polkadot_service::CollatorOverseerGen, overseer_message_channel_capacity_override: None, malus_finality_delay: None, hwbench: None, diff --git a/polkadot/parachain/test-parachains/undying/collator/src/main.rs b/polkadot/parachain/test-parachains/undying/collator/src/main.rs index d6fb9a04ab30..45f21e7b8596 100644 --- a/polkadot/parachain/test-parachains/undying/collator/src/main.rs +++ b/polkadot/parachain/test-parachains/undying/collator/src/main.rs @@ -93,7 +93,7 @@ fn main() -> Result<()> { workers_path: None, workers_names: None, - overseer_gen: polkadot_service::RealOverseerGen, + overseer_gen: polkadot_service::CollatorOverseerGen, overseer_message_channel_capacity_override: None, malus_finality_delay: None, hwbench: None, diff --git a/prdoc/pr_3061.prdoc b/prdoc/pr_3061.prdoc new file mode 100644 index 000000000000..977a9b6fd799 --- /dev/null +++ b/prdoc/pr_3061.prdoc @@ -0,0 +1,15 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Do not run unneeded subsystems on collator and its alongside node + +doc: + - audience: Node Dev + description: | + Optimizes overseer building strategy to only include subsystems needed to run the given + type of node. Reduces overseer overhead and also solves the problem with unused subsystems + getting stalled from time to time. + +crates: + - name: polkadot-overseer + - name: polkadot-service