12345678use cumulus_client_consensus_relay_chain::{9 build_relay_chain_consensus, BuildRelayChainConsensusParams,10};11use cumulus_client_network::build_block_announce_validator;12use cumulus_client_service::{13 prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams,14};15use cumulus_primitives_core::ParaId;16use polkadot_primitives::v0::CollatorPair;17use parachain_runtime::{RuntimeApi, opaque::Block};18use sc_executor::native_executor_instance;19pub use sc_executor::NativeExecutor;20use sc_service::{Configuration, PartialComponents, Role, TFullBackend, TFullClient, TaskManager};21use sc_telemetry::{Telemetry, TelemetryWorker, TelemetryWorkerHandle};22use sp_runtime::traits::BlakeTwo256;23use sp_trie::PrefixedMemoryDB;24use std::sync::Arc;252627native_executor_instance!(28 pub Executor,29 parachain_runtime::api::dispatch,30 parachain_runtime::native_version,31);323334353637pub fn new_partial(38 config: &Configuration,39) -> Result<40 PartialComponents<41 TFullClient<Block, RuntimeApi, Executor>,42 TFullBackend<Block>,43 (),44 sp_consensus::import_queue::BasicQueue<Block, PrefixedMemoryDB<BlakeTwo256>>,45 sc_transaction_pool::FullPool<Block, TFullClient<Block, RuntimeApi, Executor>>,46 (Option<Telemetry>, Option<TelemetryWorkerHandle>),47 >,48 sc_service::Error,49> {50 let inherent_data_providers = sp_inherents::InherentDataProviders::new();5152 let telemetry = config53 .telemetry_endpoints54 .clone()55 .filter(|x| !x.is_empty())56 .map(|endpoints| -> Result<_, sc_telemetry::Error> {57 let worker = TelemetryWorker::new(16)?;58 let telemetry = worker.handle().new_telemetry(endpoints);59 Ok((worker, telemetry))60 })61 .transpose()?;6263 let (client, backend, keystore_container, task_manager) =64 sc_service::new_full_parts::<Block, RuntimeApi, Executor>(65 &config,66 telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),67 )?;68 let client = Arc::new(client);6970 let telemetry_worker_handle = telemetry71 .as_ref()72 .map(|(worker, _)| worker.handle());7374 let telemetry = telemetry75 .map(|(worker, telemetry)| {76 task_manager.spawn_handle().spawn("telemetry", worker.run());77 telemetry78 });7980 let registry = config.prometheus_registry();8182 let transaction_pool = sc_transaction_pool::BasicPool::new_full(83 config.transaction_pool.clone(),84 config.role.is_authority().into(),85 config.prometheus_registry(),86 task_manager.spawn_handle(),87 client.clone(),88 );8990 let import_queue = cumulus_client_consensus_relay_chain::import_queue(91 client.clone(),92 client.clone(),93 inherent_data_providers.clone(),94 &task_manager.spawn_essential_handle(),95 registry.clone(),96 )?;9798 let params = PartialComponents {99 backend,100 client,101 import_queue,102 keystore_container,103 task_manager,104 transaction_pool,105 inherent_data_providers,106 select_chain: (),107 other: (telemetry, telemetry_worker_handle),108 };109110 Ok(params)111}112113114115116#[sc_tracing::logging::prefix_logs_with("Parachain")]117async fn start_node_impl<RB>(118 parachain_config: Configuration,119 collator_key: CollatorPair,120 polkadot_config: Configuration,121 id: ParaId,122 validator: bool,123 rpc_ext_builder: RB,124) -> sc_service::error::Result<(TaskManager, Arc<TFullClient<Block, RuntimeApi, Executor>>)>125where126 RB: Fn(127 Arc<TFullClient<Block, RuntimeApi, Executor>>,128 ) -> jsonrpc_core::IoHandler<sc_rpc::Metadata>129 + Send130 + 'static,131{132 if matches!(parachain_config.role, Role::Light) {133 return Err("Light client not supported!".into());134 }135136 let parachain_config = prepare_node_config(parachain_config);137138 let params = new_partial(¶chain_config)?;139 params140 .inherent_data_providers141 .register_provider(sp_timestamp::InherentDataProvider)142 .unwrap();143 let (mut telemetry, telemetry_worker_handle) = params.other;144145 let polkadot_full_node =146 cumulus_client_service::build_polkadot_full_node(147 polkadot_config,148 collator_key.clone(),149 telemetry_worker_handle,150 )151 .map_err(|e| match e {152 polkadot_service::Error::Sub(x) => x,153 s => format!("{}", s).into(),154 })?;155156 let client = params.client.clone();157 let backend = params.backend.clone();158 let block_announce_validator = build_block_announce_validator(159 polkadot_full_node.client.clone(),160 id,161 Box::new(polkadot_full_node.network.clone()),162 polkadot_full_node.backend.clone(),163 );164165 let prometheus_registry = parachain_config.prometheus_registry().cloned();166 let transaction_pool = params.transaction_pool.clone();167 let mut task_manager = params.task_manager;168 let import_queue = params.import_queue;169 let (network, network_status_sinks, system_rpc_tx, start_network) =170 sc_service::build_network(sc_service::BuildNetworkParams {171 config: ¶chain_config,172 client: client.clone(),173 transaction_pool: transaction_pool.clone(),174 spawn_handle: task_manager.spawn_handle(),175 import_queue,176 on_demand: None,177 block_announce_validator_builder: Some(Box::new(|_| block_announce_validator)),178 })?;179180 if parachain_config.offchain_worker.enabled {181 sc_service::build_offchain_workers(182 ¶chain_config,183 task_manager.spawn_handle(),184 client.clone(),185 network.clone(),186 );187 }188189 let rpc_client = client.clone();190 let rpc_extensions_builder = Box::new(move |_, _| rpc_ext_builder(rpc_client.clone()));191192 sc_service::spawn_tasks(sc_service::SpawnTasksParams {193 on_demand: None,194 remote_blockchain: None,195 rpc_extensions_builder,196 client: client.clone(),197 transaction_pool: transaction_pool.clone(),198 task_manager: &mut task_manager,199 config: parachain_config,200 keystore: params.keystore_container.sync_keystore(),201 backend: backend.clone(),202 network: network.clone(),203 network_status_sinks,204 system_rpc_tx,205 telemetry: telemetry.as_mut(),206 })?;207208 let announce_block = {209 let network = network.clone();210 Arc::new(move |hash, data| network.announce_block(hash, data))211 };212213 if validator {214 let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(215 task_manager.spawn_handle(),216 client.clone(),217 transaction_pool,218 prometheus_registry.as_ref(),219 telemetry.as_ref().map(|x| x.handle()),220 );221 let spawner = task_manager.spawn_handle();222223 let parachain_consensus = build_relay_chain_consensus(BuildRelayChainConsensusParams {224 para_id: id,225 proposer_factory,226 inherent_data_providers: params.inherent_data_providers,227 block_import: client.clone(),228 relay_chain_client: polkadot_full_node.client.clone(),229 relay_chain_backend: polkadot_full_node.backend.clone(),230 });231232 let params = StartCollatorParams {233 para_id: id,234 block_status: client.clone(),235 announce_block,236 client: client.clone(),237 task_manager: &mut task_manager,238 collator_key,239 relay_chain_full_node: polkadot_full_node,240 spawner,241 backend,242 parachain_consensus,243 };244245 start_collator(params).await?;246 } else {247 let params = StartFullNodeParams {248 client: client.clone(),249 announce_block,250 task_manager: &mut task_manager,251 para_id: id,252 polkadot_full_node,253 };254255 start_full_node(params)?;256 }257258 start_network.start_network();259260 Ok((task_manager, client))261}262263264pub async fn start_node(265 parachain_config: Configuration,266 collator_key: CollatorPair,267 polkadot_config: Configuration,268 id: ParaId,269 validator: bool,270) -> sc_service::error::Result<(TaskManager, Arc<TFullClient<Block, RuntimeApi, Executor>>)> {271 start_node_impl(272 parachain_config,273 collator_key,274 polkadot_config,275 id,276 validator,277 |_| Default::default(),278 )279 .await280}