123use std::sync::Arc;4use std::time::Duration;5use sc_client::LongestChain;6use sc_client_api::ExecutorProvider;7use node_template_runtime::{self, opaque::Block, RuntimeApi};8use sc_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder};9use sp_inherents::InherentDataProviders;10use sc_executor::native_executor_instance;11pub use sc_executor::NativeExecutor;12use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair};13use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider};141516native_executor_instance!(17 pub Executor,18 node_template_runtime::api::dispatch,19 node_template_runtime::native_version,20);212223242526macro_rules! new_full_start {27 ($config:expr) => {{28 use std::sync::Arc;29 let mut import_setup = None;30 let inherent_data_providers = sp_inherents::InherentDataProviders::new();3132 let builder = sc_service::ServiceBuilder::new_full::<33 node_template_runtime::opaque::Block, node_template_runtime::RuntimeApi, crate::service::Executor34 >($config)?35 .with_select_chain(|_config, backend| {36 Ok(sc_client::LongestChain::new(backend.clone()))37 })?38 .with_transaction_pool(|config, client, _fetcher| {39 let pool_api = sc_transaction_pool::FullChainApi::new(client.clone());40 Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api)))41 })?42 .with_import_queue(|_config, client, mut select_chain, _transaction_pool| {43 let select_chain = select_chain.take()44 .ok_or_else(|| sc_service::Error::SelectChainRequired)?;4546 let (grandpa_block_import, grandpa_link) =47 grandpa::block_import(client.clone(), &(client.clone() as Arc<_>), select_chain)?;4849 let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(50 grandpa_block_import.clone(), client.clone(),51 );5253 let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair>(54 sc_consensus_aura::slot_duration(&*client)?,55 aura_block_import,56 Some(Box::new(grandpa_block_import.clone())),57 None,58 client,59 inherent_data_providers.clone(),60 )?;6162 import_setup = Some((grandpa_block_import, grandpa_link));6364 Ok(import_queue)65 })?;6667 (builder, import_setup, inherent_data_providers)68 }}69}707172pub fn new_full(config: Configuration)73 -> Result<impl AbstractService, ServiceError>74{75 let is_authority = config.roles.is_authority();76 let force_authoring = config.force_authoring;77 let name = config.name.clone();78 let disable_grandpa = config.disable_grandpa;7980 81 82 83 let participates_in_consensus = is_authority && !config.sentry_mode;8485 let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config);8687 let (block_import, grandpa_link) =88 import_setup.take()89 .expect("Link Half and Block Import are present for Full Services or setup failed before. qed");9091 let service = builder92 .with_finality_proof_provider(|client, backend| {93 94 let provider = client as Arc<dyn StorageAndProofProvider<_, _>>;95 Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)96 })?97 .build()?;9899 if participates_in_consensus {100 let proposer = sc_basic_authorship::ProposerFactory::new(101 service.client(),102 service.transaction_pool()103 );104105 let client = service.client();106 let select_chain = service.select_chain()107 .ok_or(ServiceError::SelectChainRequired)?;108109 let can_author_with =110 sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());111112 let aura = sc_consensus_aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _>(113 sc_consensus_aura::slot_duration(&*client)?,114 client,115 select_chain,116 block_import,117 proposer,118 service.network(),119 inherent_data_providers.clone(),120 force_authoring,121 service.keystore(),122 can_author_with,123 )?;124125 126 127 service.spawn_essential_task("aura", aura);128 }129130 131 132 let keystore = if participates_in_consensus {133 Some(service.keystore())134 } else {135 None136 };137138 let grandpa_config = grandpa::Config {139 140 gossip_duration: Duration::from_millis(333),141 justification_period: 512,142 name: Some(name),143 observer_enabled: false,144 keystore,145 is_authority,146 };147148 let enable_grandpa = !disable_grandpa;149 if enable_grandpa {150 151 152 153 154 155 156 let grandpa_config = grandpa::GrandpaParams {157 config: grandpa_config,158 link: grandpa_link,159 network: service.network(),160 inherent_data_providers: inherent_data_providers.clone(),161 telemetry_on_connect: Some(service.telemetry_on_connect_stream()),162 voting_rule: grandpa::VotingRulesBuilder::default().build(),163 prometheus_registry: service.prometheus_registry()164 };165166 167 168 service.spawn_essential_task(169 "grandpa-voter",170 grandpa::run_grandpa_voter(grandpa_config)?171 );172 } else {173 grandpa::setup_disabled_grandpa(174 service.client(),175 &inherent_data_providers,176 service.network(),177 )?;178 }179180 Ok(service)181}182183184pub fn new_light(config: Configuration)185 -> Result<impl AbstractService, ServiceError>186{187 let inherent_data_providers = InherentDataProviders::new();188189 ServiceBuilder::new_light::<Block, RuntimeApi, Executor>(config)?190 .with_select_chain(|_config, backend| {191 Ok(LongestChain::new(backend.clone()))192 })?193 .with_transaction_pool(|config, client, fetcher| {194 let fetcher = fetcher195 .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?;196197 let pool_api = sc_transaction_pool::LightChainApi::new(client.clone(), fetcher.clone());198 let pool = sc_transaction_pool::BasicPool::with_revalidation_type(199 config, Arc::new(pool_api), sc_transaction_pool::RevalidationType::Light,200 );201 Ok(pool)202 })?203 .with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool| {204 let fetch_checker = fetcher205 .map(|fetcher| fetcher.checker().clone())206 .ok_or_else(|| "Trying to start light import queue without active fetch checker")?;207 let grandpa_block_import = grandpa::light_block_import(208 client.clone(),209 backend,210 &(client.clone() as Arc<_>),211 Arc::new(fetch_checker),212 )?;213 let finality_proof_import = grandpa_block_import.clone();214 let finality_proof_request_builder =215 finality_proof_import.create_finality_proof_request_builder();216217 let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair>(218 sc_consensus_aura::slot_duration(&*client)?,219 grandpa_block_import,220 None,221 Some(Box::new(finality_proof_import)),222 client,223 inherent_data_providers.clone(),224 )?;225226 Ok((import_queue, finality_proof_request_builder))227 })?228 .with_finality_proof_provider(|client, backend| {229 230 let provider = client as Arc<dyn StorageAndProofProvider<_, _>>;231 Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)232 })?233 .build()234}