referrerpolicy=no-referrer-when-downgrade

polkadot_service/
overseer.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17use super::{Error, IsParachainNode, Registry};
18use polkadot_collator_protocol::ReputationConfig;
19use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient};
20use polkadot_overseer::{DummySubsystem, InitializedOverseerBuilder, SubsystemError};
21use sp_core::traits::SpawnNamed;
22
23use polkadot_availability_distribution::IncomingRequestReceivers;
24use polkadot_node_core_approval_voting::Config as ApprovalVotingConfig;
25use polkadot_node_core_av_store::Config as AvailabilityConfig;
26use polkadot_node_core_candidate_validation::Config as CandidateValidationConfig;
27use polkadot_node_core_chain_selection::Config as ChainSelectionConfig;
28use polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig;
29use polkadot_node_network_protocol::{
30	peer_set::{PeerSet, PeerSetProtocolNames},
31	request_response::{
32		v1 as request_v1, v2 as request_v2, v3 as request_v3, IncomingRequestReceiver,
33		ReqProtocolNames,
34	},
35};
36#[cfg(any(feature = "malus", test))]
37pub use polkadot_overseer::{dummy::dummy_overseer_builder, HeadSupportsParachains};
38use polkadot_overseer::{
39	metrics::Metrics as OverseerMetrics, MetricsTrait, Overseer, OverseerConnector, OverseerHandle,
40	SpawnGlue,
41};
42
43use parking_lot::Mutex;
44use sc_authority_discovery::Service as AuthorityDiscoveryService;
45use sc_client_api::AuxStore;
46use sc_keystore::LocalKeystore;
47use sc_network::{NetworkStateInfo, NotificationService};
48use std::{
49	collections::{HashMap, HashSet},
50	sync::Arc,
51	time::Duration,
52};
53
54pub use polkadot_approval_distribution::ApprovalDistribution as ApprovalDistributionSubsystem;
55pub use polkadot_availability_bitfield_distribution::BitfieldDistribution as BitfieldDistributionSubsystem;
56pub use polkadot_availability_distribution::AvailabilityDistributionSubsystem;
57pub use polkadot_availability_recovery::AvailabilityRecoverySubsystem;
58pub use polkadot_collator_protocol::{CollatorProtocolSubsystem, ProtocolSide};
59pub use polkadot_dispute_distribution::DisputeDistributionSubsystem;
60pub use polkadot_gossip_support::GossipSupport as GossipSupportSubsystem;
61pub use polkadot_network_bridge::{
62	Metrics as NetworkBridgeMetrics, NetworkBridgeRx as NetworkBridgeRxSubsystem,
63	NetworkBridgeTx as NetworkBridgeTxSubsystem,
64};
65pub use polkadot_node_collation_generation::CollationGenerationSubsystem;
66pub use polkadot_node_core_approval_voting::ApprovalVotingSubsystem;
67pub use polkadot_node_core_approval_voting_parallel::{
68	ApprovalVotingParallelSubsystem, Metrics as ApprovalVotingParallelMetrics,
69};
70pub use polkadot_node_core_av_store::AvailabilityStoreSubsystem;
71pub use polkadot_node_core_backing::CandidateBackingSubsystem;
72pub use polkadot_node_core_bitfield_signing::BitfieldSigningSubsystem;
73pub use polkadot_node_core_candidate_validation::CandidateValidationSubsystem;
74pub use polkadot_node_core_chain_api::ChainApiSubsystem;
75pub use polkadot_node_core_chain_selection::ChainSelectionSubsystem;
76pub use polkadot_node_core_dispute_coordinator::DisputeCoordinatorSubsystem;
77pub use polkadot_node_core_prospective_parachains::ProspectiveParachainsSubsystem;
78pub use polkadot_node_core_provisioner::ProvisionerSubsystem;
79pub use polkadot_node_core_pvf_checker::PvfCheckerSubsystem;
80pub use polkadot_node_core_runtime_api::RuntimeApiSubsystem;
81pub use polkadot_statement_distribution::StatementDistributionSubsystem;
82
83/// Arguments passed for overseer construction.
84pub struct OverseerGenArgs<'a, Spawner, RuntimeClient>
85where
86	Spawner: 'static + SpawnNamed + Clone + Unpin,
87{
88	/// Runtime client generic, providing the `ProvideRuntimeApi` trait besides others.
89	pub runtime_client: Arc<RuntimeClient>,
90	/// Underlying network service implementation.
91	pub network_service: Arc<dyn sc_network::service::traits::NetworkService>,
92	/// Underlying syncing service implementation.
93	pub sync_service: Arc<dyn sp_consensus::SyncOracle + Send + Sync>,
94	/// Underlying authority discovery service.
95	pub authority_discovery_service: AuthorityDiscoveryService,
96	/// Collations request receiver for network protocol v2.
97	pub collation_req_v2_receiver: IncomingRequestReceiver<request_v2::CollationFetchingRequest>,
98	/// Collations request receiver for network protocol v3.
99	pub collation_req_v3_receiver: IncomingRequestReceiver<request_v3::CollationFetchingRequest>,
100	/// Receiver for available data requests.
101	pub available_data_req_receiver:
102		IncomingRequestReceiver<request_v1::AvailableDataFetchingRequest>,
103	/// Prometheus registry, commonly used for production systems, less so for test.
104	pub registry: Option<&'a Registry>,
105	/// Task spawner to be used throughout the overseer and the APIs it provides.
106	pub spawner: Spawner,
107	/// Determines the behavior of the collator.
108	pub is_parachain_node: IsParachainNode,
109	/// Overseer channel capacity override.
110	pub overseer_message_channel_capacity_override: Option<usize>,
111	/// Request-response protocol names source.
112	pub req_protocol_names: ReqProtocolNames,
113	/// `PeerSet` protocol names to protocols mapping.
114	pub peerset_protocol_names: PeerSetProtocolNames,
115	/// Notification services for validation/collation protocols.
116	pub notification_services: HashMap<PeerSet, Box<dyn NotificationService>>,
117}
118
119pub struct ExtendedOverseerGenArgs {
120	/// The keystore to use for i.e. validator keys.
121	pub keystore: Arc<LocalKeystore>,
122	/// The underlying key value store for the parachains.
123	pub parachains_db: Arc<dyn polkadot_node_subsystem_util::database::Database>,
124	/// Configuration for the candidate validation subsystem.
125	pub candidate_validation_config: Option<CandidateValidationConfig>,
126	/// Configuration for the availability store subsystem.
127	pub availability_config: AvailabilityConfig,
128	/// POV request receiver.
129	pub pov_req_receiver: IncomingRequestReceiver<request_v1::PoVFetchingRequest>,
130	/// Erasure chunk request v1 receiver.
131	pub chunk_req_v1_receiver: IncomingRequestReceiver<request_v1::ChunkFetchingRequest>,
132	/// Erasure chunk request v2 receiver.
133	pub chunk_req_v2_receiver: IncomingRequestReceiver<request_v2::ChunkFetchingRequest>,
134	/// Receiver for incoming candidate requests.
135	pub candidate_req_v2_receiver: IncomingRequestReceiver<request_v2::AttestedCandidateRequest>,
136	/// Configuration for the approval voting subsystem.
137	pub approval_voting_config: ApprovalVotingConfig,
138	/// Receiver for incoming disputes.
139	pub dispute_req_receiver: IncomingRequestReceiver<request_v1::DisputeRequest>,
140	/// Configuration for the dispute coordinator subsystem.
141	pub dispute_coordinator_config: DisputeCoordinatorConfig,
142	/// Configuration for the chain selection subsystem.
143	pub chain_selection_config: ChainSelectionConfig,
144	/// Optional availability recovery fetch chunks threshold. If PoV size size is lower
145	/// than the value put in here we always try to recovery availability from backers.
146	/// The presence of this parameter here is needed to have different values per chain.
147	pub fetch_chunks_threshold: Option<usize>,
148	/// Set of invulnerable AH collator `PeerId`s
149	pub invulnerable_ah_collators: HashSet<polkadot_node_network_protocol::PeerId>,
150	/// Override for `HOLD_OFF_DURATION` constant .
151	pub collator_protocol_hold_off: Option<Duration>,
152	/// Use experimental collator protocol
153	pub experimental_collator_protocol: bool,
154	/// Reputation DB config used by experimental collator protocol,
155	pub reputation_config: ReputationConfig,
156}
157
158/// Obtain a prepared validator `Overseer`, that is initialized with all default values.
159pub fn validator_overseer_builder<Spawner, RuntimeClient>(
160	OverseerGenArgs {
161		runtime_client,
162		network_service,
163		sync_service,
164		authority_discovery_service,
165		collation_req_v2_receiver: _,
166		collation_req_v3_receiver: _,
167		available_data_req_receiver,
168		registry,
169		spawner,
170		is_parachain_node,
171		overseer_message_channel_capacity_override,
172		req_protocol_names,
173		peerset_protocol_names,
174		notification_services,
175	}: OverseerGenArgs<Spawner, RuntimeClient>,
176	ExtendedOverseerGenArgs {
177		keystore,
178		parachains_db,
179		candidate_validation_config,
180		availability_config,
181		pov_req_receiver,
182		chunk_req_v1_receiver,
183		chunk_req_v2_receiver,
184		candidate_req_v2_receiver,
185		approval_voting_config,
186		dispute_req_receiver,
187		dispute_coordinator_config,
188		chain_selection_config,
189		fetch_chunks_threshold,
190		invulnerable_ah_collators,
191		collator_protocol_hold_off,
192		experimental_collator_protocol,
193		reputation_config,
194	}: ExtendedOverseerGenArgs,
195) -> Result<
196	InitializedOverseerBuilder<
197		SpawnGlue<Spawner>,
198		Arc<RuntimeClient>,
199		CandidateValidationSubsystem,
200		PvfCheckerSubsystem,
201		CandidateBackingSubsystem,
202		StatementDistributionSubsystem,
203		AvailabilityDistributionSubsystem,
204		AvailabilityRecoverySubsystem,
205		BitfieldSigningSubsystem,
206		BitfieldDistributionSubsystem,
207		ProvisionerSubsystem,
208		RuntimeApiSubsystem<RuntimeClient>,
209		AvailabilityStoreSubsystem,
210		NetworkBridgeRxSubsystem<
211			Arc<dyn sc_network::service::traits::NetworkService>,
212			AuthorityDiscoveryService,
213		>,
214		NetworkBridgeTxSubsystem<
215			Arc<dyn sc_network::service::traits::NetworkService>,
216			AuthorityDiscoveryService,
217		>,
218		ChainApiSubsystem<RuntimeClient>,
219		DummySubsystem,
220		CollatorProtocolSubsystem,
221		DummySubsystem,
222		DummySubsystem,
223		ApprovalVotingParallelSubsystem,
224		GossipSupportSubsystem<AuthorityDiscoveryService>,
225		DisputeCoordinatorSubsystem,
226		DisputeDistributionSubsystem<AuthorityDiscoveryService>,
227		ChainSelectionSubsystem,
228		ProspectiveParachainsSubsystem,
229	>,
230	Error,
231>
232where
233	RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static,
234	Spawner: 'static + SpawnNamed + Clone + Unpin,
235{
236	use polkadot_node_subsystem_util::metrics::Metrics;
237
238	let metrics = <OverseerMetrics as MetricsTrait>::register(registry)?;
239	let notification_sinks = Arc::new(Mutex::new(HashMap::new()));
240
241	let spawner = SpawnGlue(spawner);
242
243	let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?;
244	let approval_voting_parallel_metrics: ApprovalVotingParallelMetrics =
245		Metrics::register(registry)?;
246	let builder = Overseer::builder()
247		.network_bridge_tx(NetworkBridgeTxSubsystem::new(
248			network_service.clone(),
249			authority_discovery_service.clone(),
250			network_bridge_metrics.clone(),
251			req_protocol_names.clone(),
252			peerset_protocol_names.clone(),
253			notification_sinks.clone(),
254		))
255		.network_bridge_rx(NetworkBridgeRxSubsystem::new(
256			network_service.clone(),
257			authority_discovery_service.clone(),
258			Box::new(sync_service.clone()),
259			network_bridge_metrics,
260			peerset_protocol_names,
261			notification_services,
262			notification_sinks,
263		))
264		.availability_distribution(AvailabilityDistributionSubsystem::new(
265			keystore.clone(),
266			IncomingRequestReceivers {
267				pov_req_receiver,
268				chunk_req_v1_receiver,
269				chunk_req_v2_receiver,
270			},
271			req_protocol_names.clone(),
272			Metrics::register(registry)?,
273		))
274		.availability_recovery(AvailabilityRecoverySubsystem::for_validator(
275			fetch_chunks_threshold,
276			available_data_req_receiver,
277			&req_protocol_names,
278			Metrics::register(registry)?,
279		))
280		.availability_store(AvailabilityStoreSubsystem::new(
281			parachains_db.clone(),
282			availability_config,
283			Box::new(sync_service.clone()),
284			Metrics::register(registry)?,
285		))
286		.bitfield_distribution(BitfieldDistributionSubsystem::new(Metrics::register(registry)?))
287		.bitfield_signing(BitfieldSigningSubsystem::new(
288			keystore.clone(),
289			Metrics::register(registry)?,
290		))
291		.candidate_backing(CandidateBackingSubsystem::new(
292			keystore.clone(),
293			Metrics::register(registry)?,
294		))
295		.candidate_validation(CandidateValidationSubsystem::with_config(
296			candidate_validation_config,
297			keystore.clone(),
298			Metrics::register(registry)?, // candidate-validation metrics
299			Metrics::register(registry)?, // validation host metrics
300		))
301		.pvf_checker(PvfCheckerSubsystem::new(keystore.clone(), Metrics::register(registry)?))
302		.chain_api(ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?))
303		.collation_generation(DummySubsystem)
304		.collator_protocol({
305			let side = match is_parachain_node {
306				IsParachainNode::Collator(_) | IsParachainNode::FullNode => {
307					return Err(Error::Overseer(SubsystemError::Context(
308						"build validator overseer for parachain node".to_owned(),
309					)))
310				},
311				IsParachainNode::No => {
312					if experimental_collator_protocol {
313						ProtocolSide::ValidatorExperimental {
314							keystore: keystore.clone(),
315							metrics: Metrics::register(registry)?,
316							db: parachains_db.clone(),
317							reputation_config,
318							clock: polkadot_node_clock::system_clock(),
319						}
320					} else {
321						ProtocolSide::Validator {
322							keystore: keystore.clone(),
323							eviction_policy: Default::default(),
324							metrics: Metrics::register(registry)?,
325							invulnerables: invulnerable_ah_collators,
326							collator_protocol_hold_off,
327							clock: polkadot_node_clock::system_clock(),
328						}
329					}
330				},
331			};
332			CollatorProtocolSubsystem::new(side)
333		})
334		.provisioner(ProvisionerSubsystem::new(Metrics::register(registry)?))
335		.runtime_api(RuntimeApiSubsystem::new(
336			runtime_client.clone(),
337			Metrics::register(registry)?,
338			spawner.clone(),
339		))
340		.statement_distribution(StatementDistributionSubsystem::new(
341			keystore.clone(),
342			candidate_req_v2_receiver,
343			Metrics::register(registry)?,
344		))
345		.approval_distribution(DummySubsystem)
346		.approval_voting(DummySubsystem)
347		.approval_voting_parallel(ApprovalVotingParallelSubsystem::with_config(
348			approval_voting_config,
349			parachains_db.clone(),
350			keystore.clone(),
351			Box::new(sync_service.clone()),
352			approval_voting_parallel_metrics,
353			spawner.clone(),
354			overseer_message_channel_capacity_override,
355		))
356		.gossip_support(GossipSupportSubsystem::new(
357			keystore.clone(),
358			authority_discovery_service.clone(),
359			Metrics::register(registry)?,
360		))
361		.dispute_coordinator(DisputeCoordinatorSubsystem::new(
362			parachains_db.clone(),
363			dispute_coordinator_config,
364			keystore.clone(),
365			Metrics::register(registry)?,
366		))
367		.dispute_distribution(DisputeDistributionSubsystem::new(
368			keystore.clone(),
369			dispute_req_receiver,
370			authority_discovery_service.clone(),
371			Metrics::register(registry)?,
372		))
373		.chain_selection(ChainSelectionSubsystem::new(chain_selection_config, parachains_db))
374		.prospective_parachains(ProspectiveParachainsSubsystem::new(Metrics::register(registry)?))
375		.activation_external_listeners(Default::default())
376		.active_leaves(Default::default())
377		.supports_parachains(runtime_client)
378		.metrics(metrics)
379		.spawner(spawner);
380
381	let builder = if let Some(capacity) = overseer_message_channel_capacity_override {
382		builder.message_channel_capacity(capacity)
383	} else {
384		builder
385	};
386	Ok(builder)
387}
388
389/// Obtain a prepared collator `Overseer`, that is initialized with all default values.
390pub fn collator_overseer_builder<Spawner, RuntimeClient>(
391	OverseerGenArgs {
392		runtime_client,
393		network_service,
394		sync_service,
395		authority_discovery_service,
396		collation_req_v2_receiver,
397		collation_req_v3_receiver,
398		available_data_req_receiver,
399		registry,
400		spawner,
401		is_parachain_node,
402		overseer_message_channel_capacity_override,
403		req_protocol_names,
404		peerset_protocol_names,
405		notification_services,
406	}: OverseerGenArgs<Spawner, RuntimeClient>,
407) -> Result<
408	InitializedOverseerBuilder<
409		SpawnGlue<Spawner>,
410		Arc<RuntimeClient>,
411		DummySubsystem,
412		DummySubsystem,
413		DummySubsystem,
414		DummySubsystem,
415		DummySubsystem,
416		AvailabilityRecoverySubsystem,
417		DummySubsystem,
418		DummySubsystem,
419		DummySubsystem,
420		RuntimeApiSubsystem<RuntimeClient>,
421		DummySubsystem,
422		NetworkBridgeRxSubsystem<
423			Arc<dyn sc_network::service::traits::NetworkService>,
424			AuthorityDiscoveryService,
425		>,
426		NetworkBridgeTxSubsystem<
427			Arc<dyn sc_network::service::traits::NetworkService>,
428			AuthorityDiscoveryService,
429		>,
430		ChainApiSubsystem<RuntimeClient>,
431		CollationGenerationSubsystem,
432		CollatorProtocolSubsystem,
433		DummySubsystem,
434		DummySubsystem,
435		DummySubsystem,
436		DummySubsystem,
437		DummySubsystem,
438		DummySubsystem,
439		DummySubsystem,
440		DummySubsystem,
441	>,
442	Error,
443>
444where
445	Spawner: 'static + SpawnNamed + Clone + Unpin,
446	RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static,
447{
448	use polkadot_node_subsystem_util::metrics::Metrics;
449
450	let notification_sinks = Arc::new(Mutex::new(HashMap::new()));
451
452	let spawner = SpawnGlue(spawner);
453
454	let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?;
455
456	let builder = Overseer::builder()
457		.network_bridge_tx(NetworkBridgeTxSubsystem::new(
458			network_service.clone(),
459			authority_discovery_service.clone(),
460			network_bridge_metrics.clone(),
461			req_protocol_names.clone(),
462			peerset_protocol_names.clone(),
463			notification_sinks.clone(),
464		))
465		.network_bridge_rx(NetworkBridgeRxSubsystem::new(
466			network_service.clone(),
467			authority_discovery_service.clone(),
468			Box::new(sync_service.clone()),
469			network_bridge_metrics,
470			peerset_protocol_names,
471			notification_services,
472			notification_sinks,
473		))
474		.availability_distribution(DummySubsystem)
475		.availability_recovery(AvailabilityRecoverySubsystem::for_collator(
476			None,
477			available_data_req_receiver,
478			&req_protocol_names,
479			Metrics::register(registry)?,
480		))
481		.availability_store(DummySubsystem)
482		.bitfield_distribution(DummySubsystem)
483		.bitfield_signing(DummySubsystem)
484		.candidate_backing(DummySubsystem)
485		.candidate_validation(DummySubsystem)
486		.pvf_checker(DummySubsystem)
487		.chain_api(ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?))
488		.collation_generation(CollationGenerationSubsystem::new(Metrics::register(registry)?))
489		.collator_protocol({
490			let side = match is_parachain_node {
491				IsParachainNode::No => {
492					return Err(Error::Overseer(SubsystemError::Context(
493						"build parachain node overseer for validator".to_owned(),
494					)))
495				},
496				IsParachainNode::Collator(collator_pair) => ProtocolSide::Collator {
497					peer_id: network_service.local_peer_id(),
498					collator_pair,
499					request_receiver_v2: collation_req_v2_receiver,
500					request_receiver_v3: collation_req_v3_receiver,
501					metrics: Metrics::register(registry)?,
502					clock: polkadot_node_clock::system_clock(),
503				},
504				IsParachainNode::FullNode => ProtocolSide::None,
505			};
506			CollatorProtocolSubsystem::new(side)
507		})
508		.provisioner(DummySubsystem)
509		.runtime_api(RuntimeApiSubsystem::new(
510			runtime_client.clone(),
511			Metrics::register(registry)?,
512			spawner.clone(),
513		))
514		.statement_distribution(DummySubsystem)
515		.approval_distribution(DummySubsystem)
516		.approval_voting(DummySubsystem)
517		.approval_voting_parallel(DummySubsystem)
518		.gossip_support(DummySubsystem)
519		.dispute_coordinator(DummySubsystem)
520		.dispute_distribution(DummySubsystem)
521		.chain_selection(DummySubsystem)
522		.prospective_parachains(DummySubsystem)
523		.activation_external_listeners(Default::default())
524		.active_leaves(Default::default())
525		.supports_parachains(runtime_client)
526		.metrics(Metrics::register(registry)?)
527		.spawner(spawner);
528
529	let builder = if let Some(capacity) = overseer_message_channel_capacity_override {
530		builder.message_channel_capacity(capacity)
531	} else {
532		builder
533	};
534	Ok(builder)
535}
536
537/// Trait for the `fn` generating the overseer.
538pub trait OverseerGen {
539	/// Overwrite the full generation of the overseer, including the subsystems.
540	fn generate<Spawner, RuntimeClient>(
541		&self,
542		connector: OverseerConnector,
543		args: OverseerGenArgs<Spawner, RuntimeClient>,
544		ext_args: Option<ExtendedOverseerGenArgs>,
545	) -> Result<(Overseer<SpawnGlue<Spawner>, Arc<RuntimeClient>>, OverseerHandle), Error>
546	where
547		RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static,
548		Spawner: 'static + SpawnNamed + Clone + Unpin;
549
550	// It would be nice to make `create_subsystems` part of this trait,
551	// but the amount of generic arguments that would be required as
552	// as consequence make this rather annoying to implement and use.
553}
554
555/// The regular set of subsystems.
556pub struct ValidatorOverseerGen;
557
558impl OverseerGen for ValidatorOverseerGen {
559	fn generate<Spawner, RuntimeClient>(
560		&self,
561		connector: OverseerConnector,
562		args: OverseerGenArgs<Spawner, RuntimeClient>,
563		ext_args: Option<ExtendedOverseerGenArgs>,
564	) -> Result<(Overseer<SpawnGlue<Spawner>, Arc<RuntimeClient>>, OverseerHandle), Error>
565	where
566		RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static,
567		Spawner: 'static + SpawnNamed + Clone + Unpin,
568	{
569		let ext_args = ext_args.ok_or(Error::Overseer(SubsystemError::Context(
570			"create validator overseer as mandatory extended arguments were not provided"
571				.to_owned(),
572		)))?;
573		validator_overseer_builder(args, ext_args)?
574			.build_with_connector(connector)
575			.map_err(|e| e.into())
576	}
577}
578
579/// Reduced set of subsystems, to use in collator and collator's full node.
580pub struct CollatorOverseerGen;
581
582impl OverseerGen for CollatorOverseerGen {
583	fn generate<Spawner, RuntimeClient>(
584		&self,
585		connector: OverseerConnector,
586		args: OverseerGenArgs<Spawner, RuntimeClient>,
587		_ext_args: Option<ExtendedOverseerGenArgs>,
588	) -> Result<(Overseer<SpawnGlue<Spawner>, Arc<RuntimeClient>>, OverseerHandle), Error>
589	where
590		RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static,
591		Spawner: 'static + SpawnNamed + Clone + Unpin,
592	{
593		collator_overseer_builder(args)?
594			.build_with_connector(connector)
595			.map_err(|e| e.into())
596	}
597}