123use std::sync::Arc;4use std::time::Duration;5use substrate_client::LongestChain;6use babe;7use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};8use futures::prelude::*;9use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi};10use substrate_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder};11use transaction_pool::{self, txpool::{Pool as TransactionPool}};12use inherents::InherentDataProviders;13use network::construct_simple_protocol;14use substrate_executor::native_executor_instance;15pub use substrate_executor::NativeExecutor;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::ChainApi::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)?;50 let (grandpa_block_import, grandpa_link) =51 grandpa::block_import::<_, _, _, node_template_runtime::RuntimeApi, _, _>(52 client.clone(), &*client, select_chain53 )?;54 let justification_import = grandpa_block_import.clone();5556 let (babe_block_import, babe_link) = babe::block_import(57 babe::Config::get_or_compute(&*client)?,58 grandpa_block_import,59 client.clone(),60 client.clone(),61 )?;6263 let import_queue = babe::import_queue(64 babe_link.clone(),65 babe_block_import.clone(),66 Some(Box::new(justification_import)),67 None,68 client.clone(),69 client,70 inherent_data_providers.clone(),71 )?;7273 import_setup = Some((babe_block_import, grandpa_link, babe_link));7475 Ok(import_queue)76 })?;7778 (builder, import_setup, inherent_data_providers)79 }}80}818283pub fn new_full<C: Send + Default + 'static>(config: Configuration<C, GenesisConfig>)84 -> Result<impl AbstractService, ServiceError>85{8687 let is_authority = config.roles.is_authority();88 let name = config.name.clone();89 let disable_grandpa = config.disable_grandpa;90 let force_authoring = config.force_authoring;9192 let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config);9394 let service = builder.with_network_protocol(|_| Ok(NodeProtocol::new()))?95 .with_finality_proof_provider(|client, backend|96 Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _)97 )?98 .build()?;99100 let (block_import, grandpa_link, babe_link) =101 import_setup.take()102 .expect("Link Half and Block Import are present for Full Services or setup failed before. qed");103104 if is_authority {105 let proposer = basic_authorship::ProposerFactory {106 client: service.client(),107 transaction_pool: service.transaction_pool(),108 };109110 let client = service.client();111 let select_chain = service.select_chain()112 .ok_or(ServiceError::SelectChainRequired)?;113114 let babe_config = babe::BabeParams {115 keystore: service.keystore(),116 client,117 select_chain,118 env: proposer,119 block_import,120 sync_oracle: service.network(),121 inherent_data_providers: inherent_data_providers.clone(),122 force_authoring,123 babe_link,124 };125126 let babe = babe::start_babe(babe_config)?;127 let select = babe.select(service.on_exit()).then(|_| Ok(()));128129 130 131 service.spawn_essential_task(select);132 }133134 let grandpa_config = grandpa::Config {135 136 gossip_duration: Duration::from_millis(333),137 justification_period: 512,138 name: Some(name),139 keystore: Some(service.keystore()),140 };141142 match (is_authority, disable_grandpa) {143 (false, false) => {144 145 service.spawn_task(Box::new(grandpa::run_grandpa_observer(146 grandpa_config,147 grandpa_link,148 service.network(),149 service.on_exit(),150 )?));151 },152 (true, false) => {153 154 let voter_config = grandpa::GrandpaParams {155 config: grandpa_config,156 link: grandpa_link,157 network: service.network(),158 inherent_data_providers: inherent_data_providers.clone(),159 on_exit: service.on_exit(),160 telemetry_on_connect: Some(service.telemetry_on_connect_stream()),161 };162163 164 165 service.spawn_essential_task(grandpa::run_grandpa_voter(voter_config)?);166 },167 (_, true) => {168 grandpa::setup_disabled_grandpa(169 service.client(),170 &inherent_data_providers,171 service.network(),172 )?;173 },174 }175176 Ok(service)177}178179180pub fn new_light<C: Send + Default + 'static>(config: Configuration<C, GenesisConfig>)181 -> Result<impl AbstractService, ServiceError>182{183 let inherent_data_providers = InherentDataProviders::new();184185 ServiceBuilder::new_light::<Block, RuntimeApi, Executor>(config)?186 .with_select_chain(|_config, backend| {187 Ok(LongestChain::new(backend.clone()))188 })?189 .with_transaction_pool(|config, client|190 Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client)))191 )?192 .with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool| {193 let fetch_checker = fetcher194 .map(|fetcher| fetcher.checker().clone())195 .ok_or_else(|| "Trying to start light import queue without active fetch checker")?;196 let grandpa_block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, _>(197 client.clone(), backend, Arc::new(fetch_checker), client.clone()198 )?;199200 let finality_proof_import = grandpa_block_import.clone();201 let finality_proof_request_builder =202 finality_proof_import.create_finality_proof_request_builder();203204 let (babe_block_import, babe_link) = babe::block_import(205 babe::Config::get_or_compute(&*client)?,206 grandpa_block_import,207 client.clone(),208 client.clone(),209 )?;210211 let import_queue = babe::import_queue(212 babe_link.clone(),213 babe_block_import,214 None,215 Some(Box::new(finality_proof_import)),216 client.clone(),217 client,218 inherent_data_providers.clone(),219 )?;220221 Ok((import_queue, finality_proof_request_builder))222 })?223 .with_network_protocol(|_| Ok(NodeProtocol::new()))?224 .with_finality_proof_provider(|client, backend|225 Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _)226 )?227 .build()228}