1#![cfg(feature = "full-node")]
20
21mod partial;
22use partial::PolkadotPartialComponents;
23pub(crate) use partial::{new_partial, new_partial_basics};
24
25use crate::{
26 grandpa_support, open_database,
27 overseer::{ExtendedOverseerGenArgs, OverseerGen, OverseerGenArgs},
28 parachains_db,
29 relay_chain_selection::SelectRelayChain,
30 workers, Chain, Error, FullBackend, FullClient, IdentifyVariant, IsParachainNode,
31 GRANDPA_JUSTIFICATION_PERIOD, KEEP_FINALIZED_FOR_LIVE_NETWORKS,
32};
33use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE;
34use gum::info;
35use mmr_gadget::MmrGadget;
36use polkadot_availability_recovery::FETCH_CHUNKS_THRESHOLD;
37use polkadot_collator_protocol::ReputationConfig;
38use polkadot_node_core_approval_voting::Config as ApprovalVotingConfig;
39use polkadot_node_core_av_store::Config as AvailabilityConfig;
40use polkadot_node_core_candidate_validation::Config as CandidateValidationConfig;
41use polkadot_node_core_chain_selection::{
42 self as chain_selection_subsystem, Config as ChainSelectionConfig,
43};
44use polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig;
45use polkadot_node_network_protocol::{
46 peer_set::{CollationVersion, PeerSet, PeerSetProtocolNames},
47 request_response::{IncomingRequest, Protocol, ReqProtocolNames},
48};
49use polkadot_node_subsystem_types::DefaultSubsystemClient;
50use polkadot_overseer::{Handle, OverseerConnector};
51use polkadot_primitives::Block;
52use sc_client_api::Backend;
53use sc_network::config::FullNetworkConfiguration;
54use sc_network_sync::WarpSyncConfig;
55use sc_service::{Configuration, RpcHandlers, TaskManager};
56use sc_sysinfo::Metric;
57use sc_telemetry::TelemetryWorkerHandle;
58use sc_transaction_pool_api::OffchainTransactionPoolFactory;
59use sp_consensus_beefy::ecdsa_crypto;
60use sp_runtime::traits::Block as BlockT;
61use std::{
62 collections::{HashMap, HashSet},
63 sync::Arc,
64 time::Duration,
65};
66
67pub struct NewFullParams<OverseerGenerator: OverseerGen> {
69 pub is_parachain_node: IsParachainNode,
70 pub enable_beefy: bool,
71 pub force_authoring_backoff: bool,
74 pub telemetry_worker_handle: Option<TelemetryWorkerHandle>,
75 pub node_version: Option<String>,
78 pub secure_validator_mode: bool,
80 pub workers_path: Option<std::path::PathBuf>,
82 pub workers_names: Option<(String, String)>,
84 pub execute_workers_max_num: Option<usize>,
86 pub prepare_workers_soft_max_num: Option<usize>,
89 pub prepare_workers_hard_max_num: Option<usize>,
91 pub keep_finalized_for: Option<u32>,
93 pub overseer_gen: OverseerGenerator,
94 pub overseer_message_channel_capacity_override: Option<usize>,
95 #[allow(dead_code)]
96 pub malus_finality_delay: Option<u32>,
97 pub hwbench: Option<sc_sysinfo::HwBench>,
98 pub invulnerable_ah_collators: HashSet<polkadot_node_network_protocol::PeerId>,
100 pub collator_protocol_hold_off: Option<Duration>,
102 pub experimental_collator_protocol: bool,
104 pub collator_reputation_persist_interval: Option<Duration>,
106}
107
108pub struct NewFull {
110 pub task_manager: TaskManager,
111 pub client: Arc<FullClient>,
112 pub overseer_handle: Option<Handle>,
113 pub network: Arc<dyn sc_network::service::traits::NetworkService>,
114 pub sync_service: Arc<sc_network_sync::SyncingService<Block>>,
115 pub rpc_handlers: RpcHandlers,
116 pub backend: Arc<FullBackend>,
117}
118
119pub struct PolkadotServiceBuilder<OverseerGenerator, Network>
120where
121 OverseerGenerator: OverseerGen,
122 Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Hash>,
123{
124 config: Configuration,
125 params: NewFullParams<OverseerGenerator>,
126 overseer_connector: OverseerConnector,
127 partial_components: PolkadotPartialComponents<SelectRelayChain<FullBackend>>,
128 net_config: FullNetworkConfiguration<Block, <Block as BlockT>::Hash, Network>,
129}
130
131impl<OverseerGenerator, Network> PolkadotServiceBuilder<OverseerGenerator, Network>
132where
133 OverseerGenerator: OverseerGen,
134 Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Hash>,
135{
136 pub fn new(
138 mut config: Configuration,
139 params: NewFullParams<OverseerGenerator>,
140 ) -> Result<PolkadotServiceBuilder<OverseerGenerator, Network>, Error> {
141 let basics = new_partial_basics(&mut config, params.telemetry_worker_handle.clone())?;
142
143 let prometheus_registry = config.prometheus_registry().cloned();
144 let overseer_connector = OverseerConnector::default();
145 let overseer_handle = Handle::new(overseer_connector.handle());
146 let auth_or_collator = config.role.is_authority() || params.is_parachain_node.is_collator();
147
148 let select_chain = if auth_or_collator {
149 let metrics = polkadot_node_subsystem_util::metrics::Metrics::register(
150 prometheus_registry.as_ref(),
151 )?;
152
153 SelectRelayChain::new_with_overseer(
154 basics.backend.clone(),
155 overseer_handle.clone(),
156 metrics,
157 Some(basics.task_manager.spawn_handle()),
158 )
159 } else {
160 SelectRelayChain::new_longest_chain(basics.backend.clone())
161 };
162
163 let partial_components =
164 new_partial::<SelectRelayChain<_>>(&mut config, basics, select_chain)?;
165
166 let net_config = sc_network::config::FullNetworkConfiguration::<_, _, Network>::new(
167 &config.network,
168 config.prometheus_config.as_ref().map(|cfg| cfg.registry.clone()),
169 );
170
171 Ok(PolkadotServiceBuilder {
172 config,
173 params,
174 overseer_connector,
175 partial_components,
176 net_config,
177 })
178 }
179
180 pub fn genesis_hash(&self) -> <Block as BlockT>::Hash {
182 self.partial_components.client.chain_info().genesis_hash
183 }
184
185 pub fn add_extra_request_response_protocol(
187 &mut self,
188 config: Network::RequestResponseProtocolConfig,
189 ) {
190 self.net_config.add_request_response_protocol(config);
191 }
192
193 pub fn build(self) -> Result<NewFull, Error> {
195 let Self {
196 config,
197 params:
198 NewFullParams {
199 is_parachain_node,
200 enable_beefy,
201 force_authoring_backoff,
202 telemetry_worker_handle: _,
203 node_version,
204 secure_validator_mode,
205 workers_path,
206 workers_names,
207 overseer_gen,
208 overseer_message_channel_capacity_override,
209 malus_finality_delay: _malus_finality_delay,
210 hwbench,
211 execute_workers_max_num,
212 prepare_workers_soft_max_num,
213 prepare_workers_hard_max_num,
214 keep_finalized_for,
215 invulnerable_ah_collators,
216 collator_protocol_hold_off,
217 experimental_collator_protocol,
218 collator_reputation_persist_interval,
219 },
220 overseer_connector,
221 partial_components:
222 sc_service::PartialComponents::<_, _, SelectRelayChain<_>, _, _, _> {
223 client,
224 backend,
225 mut task_manager,
226 keystore_container,
227 select_chain,
228 import_queue,
229 transaction_pool,
230 other:
231 (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, mut telemetry),
232 },
233 mut net_config,
234 } = self;
235
236 let role = config.role;
237 let auth_or_collator = config.role.is_authority() || is_parachain_node.is_collator();
238 let is_offchain_indexing_enabled = config.offchain_worker.indexing_enabled;
239 let force_authoring = config.force_authoring;
240 let disable_grandpa = config.disable_grandpa;
241 let name = config.network.node_name.clone();
242 let backoff_authoring_blocks = if !force_authoring_backoff &&
243 (config.chain_spec.is_polkadot() || config.chain_spec.is_kusama())
244 {
245 None
247 } else {
248 let mut backoff = sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default();
249
250 if config.chain_spec.is_rococo() ||
251 config.chain_spec.is_versi() ||
252 config.chain_spec.is_dev()
253 {
254 backoff.max_interval = 10;
258 }
259
260 Some(backoff)
261 };
262 let shared_voter_state = rpc_setup;
263 let auth_disc_publish_non_global_ips = config.network.allow_non_globals_in_dht;
264 let auth_disc_public_addresses = config.network.public_addresses.clone();
265
266 let genesis_hash = client.chain_info().genesis_hash;
267 let peer_store_handle = net_config.peer_store_handle();
268
269 let prometheus_registry = config.prometheus_registry().cloned();
270 let metrics = Network::register_notification_metrics(
271 config.prometheus_config.as_ref().map(|cfg| &cfg.registry),
272 );
273
274 let grandpa_protocol_name =
278 sc_consensus_grandpa::protocol_standard_name(&genesis_hash, &config.chain_spec);
279 let (grandpa_protocol_config, grandpa_notification_service) =
280 sc_consensus_grandpa::grandpa_peers_set_config::<_, Network>(
281 grandpa_protocol_name.clone(),
282 metrics.clone(),
283 Arc::clone(&peer_store_handle),
284 );
285 net_config.add_notification_protocol(grandpa_protocol_config);
286
287 let beefy_gossip_proto_name =
288 sc_consensus_beefy::gossip_protocol_name(&genesis_hash, config.chain_spec.fork_id());
289 let (beefy_on_demand_justifications_handler, beefy_req_resp_cfg) =
292 sc_consensus_beefy::communication::request_response::BeefyJustifsRequestHandler::new::<
293 _,
294 Network,
295 >(
296 &genesis_hash,
297 config.chain_spec.fork_id(),
298 client.clone(),
299 prometheus_registry.clone(),
300 );
301 let beefy_notification_service = match enable_beefy {
302 false => None,
303 true => {
304 let (beefy_notification_config, beefy_notification_service) =
305 sc_consensus_beefy::communication::beefy_peers_set_config::<_, Network>(
306 beefy_gossip_proto_name.clone(),
307 metrics.clone(),
308 Arc::clone(&peer_store_handle),
309 );
310
311 net_config.add_notification_protocol(beefy_notification_config);
312 net_config.add_request_response_protocol(beefy_req_resp_cfg);
313 Some(beefy_notification_service)
314 },
315 };
316
317 let main_collation_version = if is_parachain_node.is_running_alongside_parachain_node() ||
319 experimental_collator_protocol
320 {
321 None
322 } else {
323 Some(CollationVersion::V3)
324 };
325 let peerset_protocol_names = PeerSetProtocolNames::new_with_main_collation_version(
326 genesis_hash,
327 config.chain_spec.fork_id(),
328 main_collation_version,
329 );
330
331 let notification_services = if role.is_authority() ||
337 is_parachain_node.is_running_alongside_parachain_node()
338 {
339 use polkadot_network_bridge::{peer_sets_info, IsAuthority};
340 let is_authority = if role.is_authority() { IsAuthority::Yes } else { IsAuthority::No };
341
342 peer_sets_info::<_, Network>(
343 is_authority,
344 &peerset_protocol_names,
345 metrics.clone(),
346 Arc::clone(&peer_store_handle),
347 )
348 .into_iter()
349 .map(|(config, (peerset, service))| {
350 net_config.add_notification_protocol(config);
351 (peerset, service)
352 })
353 .collect::<HashMap<PeerSet, Box<dyn sc_network::NotificationService>>>()
354 } else {
355 std::collections::HashMap::new()
356 };
357
358 let req_protocol_names = ReqProtocolNames::new(&genesis_hash, config.chain_spec.fork_id());
359
360 let cfg = Protocol::CollationFetchingV1
361 .get_outbound_only_config::<_, Network>(&req_protocol_names);
362 net_config.add_request_response_protocol(cfg);
363 let (collation_req_v2_receiver, cfg) =
364 IncomingRequest::get_config_receiver::<_, Network>(&req_protocol_names);
365 net_config.add_request_response_protocol(cfg);
366 let (collation_req_v3_receiver, cfg) =
367 IncomingRequest::get_config_receiver::<_, Network>(&req_protocol_names);
368 net_config.add_request_response_protocol(cfg);
369 let (available_data_req_receiver, cfg) =
370 IncomingRequest::get_config_receiver::<_, Network>(&req_protocol_names);
371 net_config.add_request_response_protocol(cfg);
372 let (pov_req_receiver, cfg) =
373 IncomingRequest::get_config_receiver::<_, Network>(&req_protocol_names);
374 net_config.add_request_response_protocol(cfg);
375 let (chunk_req_v1_receiver, cfg) =
376 IncomingRequest::get_config_receiver::<_, Network>(&req_protocol_names);
377 net_config.add_request_response_protocol(cfg);
378 let (chunk_req_v2_receiver, cfg) =
379 IncomingRequest::get_config_receiver::<_, Network>(&req_protocol_names);
380 net_config.add_request_response_protocol(cfg);
381
382 let grandpa_hard_forks = if config.chain_spec.is_kusama() {
383 grandpa_support::kusama_hard_forks()
384 } else {
385 Vec::new()
386 };
387
388 let warp_sync = Arc::new(sc_consensus_grandpa::warp_proof::NetworkProvider::new(
389 backend.clone(),
390 import_setup.1.shared_authority_set().clone(),
391 grandpa_hard_forks,
392 ));
393
394 let ext_overseer_args = if is_parachain_node.is_running_alongside_parachain_node() {
395 None
396 } else {
397 let parachains_db = open_database(&config.database)?;
398 let candidate_validation_config = if role.is_authority() {
399 let (prep_worker_path, exec_worker_path) = workers::determine_workers_paths(
400 workers_path,
401 workers_names,
402 node_version.clone(),
403 )?;
404 log::info!("๐ Using prepare-worker binary at: {:?}", prep_worker_path);
405 log::info!("๐ Using execute-worker binary at: {:?}", exec_worker_path);
406
407 Some(CandidateValidationConfig {
408 artifacts_cache_path: config
409 .database
410 .path()
411 .ok_or(Error::DatabasePathRequired)?
412 .join("pvf-artifacts"),
413 node_version,
414 secure_validator_mode,
415 prep_worker_path,
416 exec_worker_path,
417 pvf_execute_workers_max_num: execute_workers_max_num.unwrap_or(4),
420 pvf_prepare_workers_soft_max_num: prepare_workers_soft_max_num.unwrap_or(1),
421 pvf_prepare_workers_hard_max_num: prepare_workers_hard_max_num.unwrap_or(2),
422 })
423 } else {
424 None
425 };
426 let (candidate_req_v2_receiver, cfg) =
427 IncomingRequest::get_config_receiver::<_, Network>(&req_protocol_names);
428 net_config.add_request_response_protocol(cfg);
429 let (dispute_req_receiver, cfg) =
430 IncomingRequest::get_config_receiver::<_, Network>(&req_protocol_names);
431 net_config.add_request_response_protocol(cfg);
432 let approval_voting_config = ApprovalVotingConfig {
433 col_approval_data: parachains_db::REAL_COLUMNS.col_approval_data,
434 slot_duration_millis: slot_duration.as_millis() as u64,
435 };
436 let dispute_coordinator_config = DisputeCoordinatorConfig {
437 col_dispute_data: parachains_db::REAL_COLUMNS.col_dispute_coordinator_data,
438 };
439 let chain_selection_config = ChainSelectionConfig {
440 col_data: parachains_db::REAL_COLUMNS.col_chain_selection_data,
441 stagnant_check_interval: Default::default(),
442 stagnant_check_mode: chain_selection_subsystem::StagnantCheckMode::PruneOnly,
443 };
444 let reputation_config = ReputationConfig {
445 col_reputation_data: parachains_db::REAL_COLUMNS.col_collator_reputation_data,
446 persist_interval: collator_reputation_persist_interval,
447 };
448
449 let fetch_chunks_threshold =
451 if config.chain_spec.is_polkadot() { None } else { Some(FETCH_CHUNKS_THRESHOLD) };
452
453 let availability_config = AvailabilityConfig {
454 col_data: parachains_db::REAL_COLUMNS.col_availability_data,
455 col_meta: parachains_db::REAL_COLUMNS.col_availability_meta,
456 keep_finalized_for: if matches!(config.chain_spec.identify_chain(), Chain::Rococo) {
457 keep_finalized_for.unwrap_or(1)
458 } else {
459 KEEP_FINALIZED_FOR_LIVE_NETWORKS
460 },
461 };
462
463 Some(ExtendedOverseerGenArgs {
464 keystore: keystore_container.local_keystore(),
465 parachains_db,
466 candidate_validation_config,
467 availability_config,
468 pov_req_receiver,
469 chunk_req_v1_receiver,
470 chunk_req_v2_receiver,
471 candidate_req_v2_receiver,
472 approval_voting_config,
473 dispute_req_receiver,
474 dispute_coordinator_config,
475 chain_selection_config,
476 fetch_chunks_threshold,
477 invulnerable_ah_collators,
478 collator_protocol_hold_off,
479 experimental_collator_protocol,
480 reputation_config,
481 })
482 };
483
484 let (network, system_rpc_tx, tx_handler_controller, sync_service, _bitswap_handle) =
485 sc_service::build_network(sc_service::BuildNetworkParams {
486 config: &config,
487 net_config,
488 client: client.clone(),
489 transaction_pool: transaction_pool.clone(),
490 spawn_handle: task_manager.spawn_handle(),
491 spawn_essential_handle: task_manager.spawn_essential_handle(),
492 import_queue,
493 block_announce_validator_builder: None,
494 warp_sync_config: Some(WarpSyncConfig::WithProvider(warp_sync)),
495 block_relay: None,
496 metrics,
497 gap_sync_body_policy: None,
498 })?;
499
500 if config.offchain_worker.enabled {
501 use futures::FutureExt;
502
503 task_manager.spawn_handle().spawn(
504 "offchain-workers-runner",
505 "offchain-work",
506 sc_offchain::OffchainWorkers::new(sc_offchain::OffchainWorkerOptions {
507 runtime_api_provider: client.clone(),
508 keystore: Some(keystore_container.keystore()),
509 offchain_db: backend.offchain_storage(),
510 transaction_pool: Some(OffchainTransactionPoolFactory::new(
511 transaction_pool.clone(),
512 )),
513 network_provider: Arc::new(network.clone()),
514 is_validator: role.is_authority(),
515 enable_http_requests: false,
516 custom_extensions: move |_| vec![],
517 })?
518 .run(client.clone(), task_manager.spawn_handle())
519 .boxed(),
520 );
521 }
522
523 let network_config = config.network.clone();
524 let rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams {
525 config,
526 backend: backend.clone(),
527 client: client.clone(),
528 keystore: keystore_container.keystore(),
529 network: network.clone(),
530 sync_service: sync_service.clone(),
531 rpc_builder: Box::new(rpc_extensions_builder),
532 transaction_pool: transaction_pool.clone(),
533 task_manager: &mut task_manager,
534 system_rpc_tx,
535 tx_handler_controller,
536 telemetry: telemetry.as_mut(),
537 tracing_execute_block: None,
538 })?;
539
540 if let Some(hwbench) = hwbench {
541 sc_sysinfo::print_hwbench(&hwbench);
542 match SUBSTRATE_REFERENCE_HARDWARE.check_hardware(&hwbench, role.is_authority()) {
543 Err(err) if role.is_authority() => {
544 if err
545 .0
546 .iter()
547 .any(|failure| matches!(failure.metric, Metric::Blake2256Parallel { .. }))
548 {
549 log::warn!(
550 "โ ๏ธ Starting January 2025 the hardware will fail the minimal physical CPU cores requirements {} for role 'Authority',\n\
551 find out more when this will become mandatory at:\n\
552 https://docs.polkadot.com/infrastructure/running-a-validator/requirements/#minimum-hardware-requirements",
553 err
554 );
555 }
556 if err
557 .0
558 .iter()
559 .any(|failure| !matches!(failure.metric, Metric::Blake2256Parallel { .. }))
560 {
561 log::warn!(
562 "โ ๏ธ The hardware does not meet the minimal requirements {} for role 'Authority' find out more at:\n\
563 https://docs.polkadot.com/infrastructure/running-a-validator/requirements/#minimum-hardware-requirements",
564 err
565 );
566 }
567 },
568 _ => {},
569 }
570
571 if let Some(ref mut telemetry) = telemetry {
572 let telemetry_handle = telemetry.handle();
573 task_manager.spawn_handle().spawn(
574 "telemetry_hwbench",
575 None,
576 sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench),
577 );
578 }
579 }
580
581 let (block_import, link_half, babe_link, beefy_links) = import_setup;
582
583 let overseer_client = client.clone();
584 let spawner = task_manager.spawn_handle();
585
586 let authority_discovery_service =
587 if role.is_authority() || is_parachain_node.is_running_alongside_parachain_node() {
591 use futures::StreamExt;
592 use sc_network::{Event, NetworkEventStream};
593
594 let authority_discovery_role = if role.is_authority() {
595 sc_authority_discovery::Role::PublishAndDiscover(keystore_container.keystore())
596 } else {
597 sc_authority_discovery::Role::Discover
599 };
600 let dht_event_stream =
601 network.event_stream("authority-discovery").filter_map(|e| async move {
602 match e {
603 Event::Dht(e) => Some(e),
604 _ => None,
605 }
606 });
607 let (worker, service) = sc_authority_discovery::new_worker_and_service_with_config(
608 sc_authority_discovery::WorkerConfig {
609 publish_non_global_ips: auth_disc_publish_non_global_ips,
610 public_addresses: auth_disc_public_addresses,
611 strict_record_validation: true,
613 persisted_cache_directory: network_config.net_config_path,
614 ..Default::default()
615 },
616 client.clone(),
617 Arc::new(network.clone()),
618 Box::pin(dht_event_stream),
619 authority_discovery_role,
620 prometheus_registry.clone(),
621 task_manager.spawn_handle(),
622 );
623
624 task_manager.spawn_handle().spawn(
625 "authority-discovery-worker",
626 Some("authority-discovery"),
627 Box::pin(worker.run()),
628 );
629 Some(service)
630 } else {
631 None
632 };
633
634 let runtime_client = Arc::new(DefaultSubsystemClient::new(
635 overseer_client.clone(),
636 OffchainTransactionPoolFactory::new(transaction_pool.clone()),
637 ));
638
639 let overseer_handle = if let Some(authority_discovery_service) = authority_discovery_service
640 {
641 let (overseer, overseer_handle) = overseer_gen
642 .generate::<sc_service::SpawnTaskHandle, DefaultSubsystemClient<FullClient>>(
643 overseer_connector,
644 OverseerGenArgs {
645 runtime_client,
646 network_service: network.clone(),
647 sync_service: sync_service.clone(),
648 authority_discovery_service,
649 collation_req_v2_receiver,
650 collation_req_v3_receiver,
651 available_data_req_receiver,
652 registry: prometheus_registry.as_ref(),
653 spawner,
654 is_parachain_node,
655 overseer_message_channel_capacity_override,
656 req_protocol_names,
657 peerset_protocol_names,
658 notification_services,
659 },
660 ext_overseer_args,
661 )
662 .map_err(|e| {
663 gum::error!("Failed to init overseer: {}", e);
664 e
665 })?;
666 let handle = Handle::new(overseer_handle.clone());
667
668 {
669 let handle = handle.clone();
670 task_manager.spawn_essential_handle().spawn_blocking(
671 "overseer",
672 None,
673 Box::pin(async move {
674 use futures::{pin_mut, select, FutureExt};
675
676 let forward = polkadot_overseer::forward_events(overseer_client, handle);
677
678 let forward = forward.fuse();
679 let overseer_fut = overseer.run().fuse();
680
681 pin_mut!(overseer_fut);
682 pin_mut!(forward);
683
684 select! {
685 () = forward => (),
686 () = overseer_fut => (),
687 complete => (),
688 }
689 }),
690 );
691 }
692 Some(handle)
693 } else {
694 assert!(
695 !auth_or_collator,
696 "Precondition congruence (false) is guaranteed by manual checking. qed"
697 );
698 None
699 };
700
701 if role.is_authority() {
702 let mut proposer = sc_basic_authorship::ProposerFactory::new(
703 task_manager.spawn_handle(),
704 client.clone(),
705 transaction_pool.clone(),
706 prometheus_registry.as_ref(),
707 telemetry.as_ref().map(|x| x.handle()),
708 );
709 proposer.set_default_block_size_limit(15 * 1024 * 1024);
712
713 let client_clone = client.clone();
714 let overseer_handle =
715 overseer_handle.as_ref().ok_or(Error::AuthoritiesRequireRealOverseer)?.clone();
716 let slot_duration = babe_link.config().slot_duration();
717 let babe_config = sc_consensus_babe::BabeParams {
718 keystore: keystore_container.keystore(),
719 client: client.clone(),
720 select_chain,
721 block_import,
722 env: proposer,
723 sync_oracle: sync_service.clone(),
724 justification_sync_link: sync_service.clone(),
725 create_inherent_data_providers: move |parent, ()| {
726 let client_clone = client_clone.clone();
727 let overseer_handle = overseer_handle.clone();
728
729 async move {
730 let parachain =
731 polkadot_node_core_parachains_inherent::ParachainsInherentDataProvider::new(
732 client_clone,
733 overseer_handle,
734 parent,
735 );
736
737 let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
738
739 let slot =
740 sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_slot_duration(
741 *timestamp,
742 slot_duration,
743 );
744
745 Ok((slot, timestamp, parachain))
746 }
747 },
748 force_authoring,
749 backoff_authoring_blocks,
750 babe_link,
751 block_proposal_slot_portion: sc_consensus_babe::SlotProportion::new(2f32 / 3f32),
752 max_block_proposal_slot_portion: None,
753 telemetry: telemetry.as_ref().map(|x| x.handle()),
754 };
755
756 let babe = sc_consensus_babe::start_babe(babe_config)?;
757 task_manager.spawn_essential_handle().spawn_blocking("babe", None, babe);
758 }
759
760 let keystore_opt =
763 if role.is_authority() { Some(keystore_container.keystore()) } else { None };
764
765 if let Some(notification_service) = beefy_notification_service {
767 let justifications_protocol_name =
768 beefy_on_demand_justifications_handler.protocol_name();
769 let network_params = sc_consensus_beefy::BeefyNetworkParams {
770 network: Arc::new(network.clone()),
771 sync: sync_service.clone(),
772 gossip_protocol_name: beefy_gossip_proto_name,
773 justifications_protocol_name,
774 notification_service,
775 _phantom: core::marker::PhantomData::<Block>,
776 };
777 let payload_provider = sp_consensus_beefy::mmr::MmrRootProvider::new(client.clone());
778 let beefy_params = sc_consensus_beefy::BeefyParams {
779 client: client.clone(),
780 backend: backend.clone(),
781 payload_provider,
782 runtime: client.clone(),
783 key_store: keystore_opt.clone(),
784 network_params,
785 min_block_delta: 8,
786 prometheus_registry: prometheus_registry.clone(),
787 links: beefy_links,
788 on_demand_justifications_handler: beefy_on_demand_justifications_handler,
789 is_authority: role.is_authority(),
790 };
791
792 let gadget = sc_consensus_beefy::start_beefy_gadget::<
793 _,
794 _,
795 _,
796 _,
797 _,
798 _,
799 _,
800 ecdsa_crypto::AuthorityId,
801 >(beefy_params);
802
803 task_manager
806 .spawn_essential_handle()
807 .spawn_blocking("beefy-gadget", None, gadget);
808 }
809 if is_offchain_indexing_enabled {
811 task_manager.spawn_essential_handle().spawn_blocking(
812 "mmr-gadget",
813 None,
814 MmrGadget::start(
815 client.clone(),
816 backend.clone(),
817 sp_mmr_primitives::INDEXING_PREFIX.to_vec(),
818 ),
819 );
820 }
821
822 let config = sc_consensus_grandpa::Config {
823 gossip_duration: Duration::from_millis(1000),
827 justification_generation_period: GRANDPA_JUSTIFICATION_PERIOD,
828 name: Some(name),
829 observer_enabled: false,
830 keystore: keystore_opt,
831 local_role: role,
832 telemetry: telemetry.as_ref().map(|x| x.handle()),
833 protocol_name: grandpa_protocol_name,
834 };
835
836 let enable_grandpa = !disable_grandpa;
837 if enable_grandpa {
838 let mut voting_rules_builder = sc_consensus_grandpa::VotingRulesBuilder::default();
846
847 #[cfg(not(feature = "malus"))]
848 let _malus_finality_delay = None;
849
850 if let Some(delay) = _malus_finality_delay {
851 info!(?delay, "Enabling malus finality delay",);
852 voting_rules_builder =
853 voting_rules_builder.add(sc_consensus_grandpa::BeforeBestBlockBy(delay));
854 };
855
856 let grandpa_config = sc_consensus_grandpa::GrandpaParams {
857 config,
858 link: link_half,
859 network: network.clone(),
860 sync: sync_service.clone(),
861 voting_rule: voting_rules_builder.build(),
862 prometheus_registry: prometheus_registry.clone(),
863 shared_voter_state,
864 telemetry: telemetry.as_ref().map(|x| x.handle()),
865 notification_service: grandpa_notification_service,
866 offchain_tx_pool_factory: OffchainTransactionPoolFactory::new(
867 transaction_pool.clone(),
868 ),
869 };
870
871 task_manager.spawn_essential_handle().spawn_blocking(
872 "grandpa-voter",
873 None,
874 sc_consensus_grandpa::run_grandpa_voter(grandpa_config)?,
875 );
876 }
877
878 Ok(NewFull {
879 task_manager,
880 client,
881 overseer_handle,
882 network,
883 sync_service,
884 rpc_handlers,
885 backend,
886 })
887 }
888}
889
890pub fn new_full<
900 OverseerGenerator: OverseerGen,
901 Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Hash>,
902>(
903 config: Configuration,
904 params: NewFullParams<OverseerGenerator>,
905) -> Result<NewFull, Error> {
906 PolkadotServiceBuilder::<OverseerGenerator, Network>::new(config, params)?.build()
907}