//! Service and ServiceFactory implementation. Specialized wrapper over Substrate service. #![warn(unused_extern_crates)] use std::sync::Arc; use log::info; use transaction_pool::{self, txpool::{Pool as TransactionPool}}; use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi}; use substrate_service::{ FactoryFullConfiguration, LightComponents, FullComponents, FullBackend, FullClient, LightClient, LightBackend, FullExecutor, LightExecutor, TaskExecutor, error::{Error as ServiceError}, }; use basic_authorship::ProposerFactory; use consensus::{import_queue, start_aura, AuraImportQueue, SlotDuration, NothingExtra}; use futures::prelude::*; use substrate_client::{self as client, LongestChain}; use primitives::{ed25519::Pair, Pair as PairT}; use inherents::InherentDataProviders; use network::construct_simple_protocol; use substrate_executor::native_executor_instance; use substrate_service::construct_service_factory; pub use substrate_executor::NativeExecutor; // Our native executor instance. native_executor_instance!( pub Executor, node_template_runtime::api::dispatch, node_template_runtime::native_version, include_bytes!("../runtime/wasm/target/wasm32-unknown-unknown/release/node_template_runtime_wasm.compact.wasm") ); #[derive(Default)] pub struct NodeConfig { inherent_data_providers: InherentDataProviders, } construct_simple_protocol! { /// Demo protocol attachment for substrate. pub struct NodeProtocol where Block = Block { } } construct_service_factory! { struct Factory { Block = Block, RuntimeApi = RuntimeApi, NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) }, RuntimeDispatch = Executor, FullTransactionPoolApi = transaction_pool::ChainApi< client::Client, FullExecutor, Block, RuntimeApi>, Block > { |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) }, LightTransactionPoolApi = transaction_pool::ChainApi< client::Client, LightExecutor, Block, RuntimeApi>, Block > { |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) }, Genesis = GenesisConfig, Configuration = NodeConfig, FullService = FullComponents { |config: FactoryFullConfiguration, executor: TaskExecutor| FullComponents::::new(config, executor) }, AuthoritySetup = { |service: Self::FullService, executor: TaskExecutor, key: Option>| { if let Some(key) = key { info!("Using authority key {}", key.public()); let proposer = Arc::new(ProposerFactory { client: service.client(), transaction_pool: service.transaction_pool(), }); let client = service.client(); let select_chain = service.select_chain() .ok_or_else(|| ServiceError::SelectChainRequired)?; let aura = start_aura( SlotDuration::get_or_compute(&*client)?, key.clone(), client.clone(), select_chain, client, proposer, service.network(), service.config.custom.inherent_data_providers.clone(), service.config.force_authoring, )?; executor.spawn(aura.select(service.on_exit()).then(|_| Ok(()))); } Ok(service) } }, LightService = LightComponents { |config, executor| >::new(config, executor) }, FullImportQueue = AuraImportQueue< Self::Block, > { |config: &mut FactoryFullConfiguration , client: Arc>, _select_chain: Self::SelectChain| { import_queue::<_, _, _, Pair>( SlotDuration::get_or_compute(&*client)?, client.clone(), None, None, None, client, NothingExtra, config.custom.inherent_data_providers.clone(), ).map_err(Into::into) } }, LightImportQueue = AuraImportQueue< Self::Block, > { |config: &mut FactoryFullConfiguration, client: Arc>| { import_queue::<_, _, _, Pair>( SlotDuration::get_or_compute(&*client)?, client.clone(), None, None, None, client, NothingExtra, config.custom.inherent_data_providers.clone(), ).map_err(Into::into) } }, SelectChain = LongestChain, Self::Block> { |config: &FactoryFullConfiguration, client: Arc>| { #[allow(deprecated)] Ok(LongestChain::new(client.backend().clone())) } }, FinalityProofProvider = { |_client: Arc>| { Ok(None) }}, } }