123use std::sync::Arc;4use std::time::Duration;5use substrate_client::LongestChain;6use babe::{import_queue, start_babe, Config};7use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};8use futures::prelude::*;9use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi, WASM_BINARY};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_version22);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();37 let mut tasks_to_spawn = None;3839 let builder = substrate_service::ServiceBuilder::new_full::<40 node_template_runtime::opaque::Block, node_template_runtime::RuntimeApi, crate::service::Executor41 >($config)?42 .with_select_chain(|_config, client| {43 #[allow(deprecated)]44 Ok(substrate_client::LongestChain::new(client.backend().clone()))45 })?46 .with_transaction_pool(|config, client|47 Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::ChainApi::new(client)))48 )?49 .with_import_queue(|_config, client, mut select_chain, transaction_pool| {50 let select_chain = select_chain.take()51 .ok_or_else(|| substrate_service::Error::SelectChainRequired)?;52 let (block_import, link_half) =53 grandpa::block_import::<_, _, _, node_template_runtime::RuntimeApi, _, _>(54 client.clone(), client.clone(), select_chain55 )?;56 let justification_import = block_import.clone();5758 let (import_queue, babe_link, babe_block_import, pruning_task) = babe::import_queue(59 babe::Config::get_or_compute(&*client)?,60 block_import,61 Some(Box::new(justification_import)),62 None,63 client.clone(),64 client,65 inherent_data_providers.clone(),66 Some(transaction_pool)67 )?;6869 import_setup = Some((babe_block_import.clone(), link_half, babe_link));70 tasks_to_spawn = Some(vec![Box::new(pruning_task)]);7172 Ok(import_queue)73 })?;7475 (builder, import_setup, inherent_data_providers, tasks_to_spawn)76 }}77}787980pub fn new_full<C: Send + Default + 'static>(config: Configuration<C, GenesisConfig>)81 -> Result<impl AbstractService, ServiceError>82{8384 let (builder, mut import_setup, inherent_data_providers, mut tasks_to_spawn) = new_full_start!(config);8586 let service = builder.with_network_protocol(|_| Ok(NodeProtocol::new()))?87 .with_finality_proof_provider(|client|88 Ok(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _)89 )?90 .build()?;9192 let (block_import, link_half, babe_link) =93 import_setup.take()94 .expect("Link Half and Block Import are present for Full Services or setup failed before. qed");9596 97 if let Some(tasks) = tasks_to_spawn.take() {98 for task in tasks {99 service.spawn_task(100 task.select(service.on_exit())101 .map(|_| ())102 .map_err(|_| ())103 );104 }105 }106107 if service.config().roles.is_authority() {108 let proposer = basic_authorship::ProposerFactory {109 client: service.client(),110 transaction_pool: service.transaction_pool(),111 };112113 let client = service.client();114 let select_chain = service.select_chain()115 .ok_or(ServiceError::SelectChainRequired)?;116117 let babe_config = babe::BabeParams {118 config: Config::get_or_compute(&*client)?,119 keystore: service.keystore(),120 client,121 select_chain,122 block_import,123 env: proposer,124 sync_oracle: service.network(),125 inherent_data_providers: inherent_data_providers.clone(),126 force_authoring: service.config().force_authoring,127 time_source: babe_link,128 };129130 let babe = start_babe(babe_config)?;131 let select = babe.select(service.on_exit()).then(|_| Ok(()));132133 134 135 service.spawn_essential_task(select);136 }137138 let config = grandpa::Config {139 140 gossip_duration: Duration::from_millis(333),141 justification_period: 4096,142 name: Some(service.config().name.clone()),143 keystore: Some(service.keystore()),144 };145146 match (service.config().roles.is_authority(), service.config().disable_grandpa) {147 (false, false) => {148 149 service.spawn_task(Box::new(grandpa::run_grandpa_observer(150 config,151 link_half,152 service.network(),153 service.on_exit(),154 )?));155 },156 (true, false) => {157 158 let grandpa_config = grandpa::GrandpaParams {159 config: config,160 link: link_half,161 network: service.network(),162 inherent_data_providers: inherent_data_providers.clone(),163 on_exit: service.on_exit(),164 telemetry_on_connect: Some(service.telemetry_on_connect_stream()),165 };166167 168 169 service.spawn_essential_task(grandpa::run_grandpa_voter(grandpa_config)?);170 },171 (_, true) => {172 grandpa::setup_disabled_grandpa(173 service.client(),174 &inherent_data_providers,175 service.network(),176 )?;177 },178 }179180 Ok(service)181}182183184pub fn new_light<C: Send + Default + 'static>(config: Configuration<C, GenesisConfig>)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, client| {191 #[allow(deprecated)]192 Ok(LongestChain::new(client.backend().clone()))193 })?194 .with_transaction_pool(|config, client|195 Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client)))196 )?197 .with_import_queue_and_fprb(|_config, client, _select_chain, transaction_pool| {198 #[allow(deprecated)]199 let fetch_checker = client.backend().blockchain().fetcher()200 .upgrade()201 .map(|fetcher| fetcher.checker().clone())202 .ok_or_else(|| "Trying to start light import queue without active fetch checker")?;203 let block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, _>(204 client.clone(), Arc::new(fetch_checker), client.clone()205 )?;206207 let finality_proof_import = block_import.clone();208 let finality_proof_request_builder =209 finality_proof_import.create_finality_proof_request_builder();210211 212 let (import_queue, ..) = import_queue(213 Config::get_or_compute(&*client)?,214 block_import,215 None,216 Some(Box::new(finality_proof_import)),217 client.clone(),218 client,219 inherent_data_providers.clone(),220 Some(transaction_pool)221 )?;222223 Ok((import_queue, finality_proof_request_builder))224 })?225 .with_network_protocol(|_| Ok(NodeProtocol::new()))?226 .with_finality_proof_provider(|client|227 Ok(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _)228 )?229 .build()230}