123use std::sync::Arc;4use std::time::Duration;5use substrate_client::LongestChain;6use futures::prelude::*;7use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi};8use substrate_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder};9use transaction_pool::{self, txpool::{Pool as TransactionPool}};10use inherents::InherentDataProviders;11use network::{construct_simple_protocol};12use substrate_executor::native_executor_instance;13pub use substrate_executor::NativeExecutor;14use aura_primitives::sr25519::{AuthorityPair as AuraPair};15use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};161718native_executor_instance!(19 pub Executor,20 node_template_runtime::api::dispatch,21 node_template_runtime::native_version,22);2324construct_simple_protocol! {25 26 pub struct NodeProtocol where Block = Block { }27}282930313233macro_rules! new_full_start {34 ($config:expr) => {{35 let mut import_setup = None;36 let inherent_data_providers = inherents::InherentDataProviders::new();3738 let builder = substrate_service::ServiceBuilder::new_full::<39 node_template_runtime::opaque::Block, node_template_runtime::RuntimeApi, crate::service::Executor40 >($config)?41 .with_select_chain(|_config, backend| {42 Ok(substrate_client::LongestChain::new(backend.clone()))43 })?44 .with_transaction_pool(|config, client|45 Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::FullChainApi::new(client)))46 )?47 .with_import_queue(|_config, client, mut select_chain, transaction_pool| {48 let select_chain = select_chain.take()49 .ok_or_else(|| substrate_service::Error::SelectChainRequired)?;5051 let (grandpa_block_import, grandpa_link) =52 grandpa::block_import::<_, _, _, node_template_runtime::RuntimeApi, _, _>(53 client.clone(), &*client, select_chain54 )?;5556 let import_queue = aura::import_queue::<_, _, AuraPair, _>(57 aura::SlotDuration::get_or_compute(&*client)?,58 Box::new(grandpa_block_import.clone()),59 Some(Box::new(grandpa_block_import.clone())),60 None,61 client,62 inherent_data_providers.clone(),63 Some(transaction_pool),64 )?;6566 import_setup = Some((grandpa_block_import, grandpa_link));6768 Ok(import_queue)69 })?;7071 (builder, import_setup, inherent_data_providers)72 }}73}747576pub fn new_full<C: Send + Default + 'static>(config: Configuration<C, GenesisConfig>)77 -> Result<impl AbstractService, ServiceError>78{79 let is_authority = config.roles.is_authority();80 let force_authoring = config.force_authoring;81 let name = config.name.clone();82 let disable_grandpa = config.disable_grandpa;8384 let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config);8586 let (block_import, grandpa_link) =87 import_setup.take()88 .expect("Link Half and Block Import are present for Full Services or setup failed before. qed");8990 let service = builder.with_network_protocol(|_| Ok(NodeProtocol::new()))?91 .with_finality_proof_provider(|client, backend|92 Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _)93 )?94 .build()?;9596 if is_authority {97 let proposer = basic_authorship::ProposerFactory {98 client: service.client(),99 transaction_pool: service.transaction_pool(),100 };101102 let client = service.client();103 let select_chain = service.select_chain()104 .ok_or(ServiceError::SelectChainRequired)?;105106 let aura = aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _>(107 aura::SlotDuration::get_or_compute(&*client)?,108 client,109 select_chain,110 block_import,111 proposer,112 service.network(),113 inherent_data_providers.clone(),114 force_authoring,115 service.keystore(),116 )?;117118 let select = aura.select(service.on_exit()).then(|_| Ok(()));119120 121 122 service.spawn_essential_task(select);123 }124125 let grandpa_config = grandpa::Config {126 127 gossip_duration: Duration::from_millis(333),128 justification_period: 512,129 name: Some(name),130 keystore: Some(service.keystore()),131 };132133 match (is_authority, disable_grandpa) {134 (false, false) => {135 136 service.spawn_task(Box::new(grandpa::run_grandpa_observer(137 grandpa_config,138 grandpa_link,139 service.network(),140 service.on_exit(),141 )?));142 },143 (true, false) => {144 145 let voter_config = grandpa::GrandpaParams {146 config: grandpa_config,147 link: grandpa_link,148 network: service.network(),149 inherent_data_providers: inherent_data_providers.clone(),150 on_exit: service.on_exit(),151 telemetry_on_connect: Some(service.telemetry_on_connect_stream()),152 voting_rule: grandpa::VotingRulesBuilder::default().build(),153 };154155 156 157 service.spawn_essential_task(grandpa::run_grandpa_voter(voter_config)?);158 },159 (_, true) => {160 grandpa::setup_disabled_grandpa(161 service.client(),162 &inherent_data_providers,163 service.network(),164 )?;165 },166 }167168 Ok(service)169}170171172pub fn new_light<C: Send + Default + 'static>(config: Configuration<C, GenesisConfig>)173 -> Result<impl AbstractService, ServiceError>174{175 let inherent_data_providers = InherentDataProviders::new();176177 ServiceBuilder::new_light::<Block, RuntimeApi, Executor>(config)?178 .with_select_chain(|_config, backend| {179 Ok(LongestChain::new(backend.clone()))180 })?181 .with_transaction_pool(|config, client|182 Ok(TransactionPool::new(config, transaction_pool::FullChainApi::new(client)))183 )?184 .with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool| {185 let fetch_checker = fetcher186 .map(|fetcher| fetcher.checker().clone())187 .ok_or_else(|| "Trying to start light import queue without active fetch checker")?;188 let grandpa_block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, _>(189 client.clone(), backend, Arc::new(fetch_checker), client.clone()190 )?;191 let finality_proof_import = grandpa_block_import.clone();192 let finality_proof_request_builder =193 finality_proof_import.create_finality_proof_request_builder();194195 let import_queue = aura::import_queue::<_, _, AuraPair, ()>(196 aura::SlotDuration::get_or_compute(&*client)?,197 Box::new(grandpa_block_import),198 None,199 Some(Box::new(finality_proof_import)),200 client,201 inherent_data_providers.clone(),202 None,203 )?;204205 Ok((import_queue, finality_proof_request_builder))206 })?207 .with_network_protocol(|_| Ok(NodeProtocol::new()))?208 .with_finality_proof_provider(|client, backend|209 Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _)210 )?211 .build()212}