//! 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, }; use basic_authorship::ProposerFactory; use consensus::{import_queue, start_aura, AuraImportQueue, SlotDuration, NothingExtra}; 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, FullExecutor, Block, RuntimeApi>, Block> { |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) }, LightTransactionPoolApi = transaction_pool::ChainApi, 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(), inherents_pool: service.inherents_pool(), }); let client = service.client(); executor.spawn(start_aura( SlotDuration::get_or_compute(&*client)?, key.clone(), client.clone(), service.select_chain(), client, proposer, service.network(), service.on_exit(), service.config.custom.inherent_data_providers.clone(), service.config.force_authoring, )?); } 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, 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, client, NothingExtra, config.custom.inherent_data_providers.clone(), ).map_err(Into::into) } }, SelectChain = LongestChain, Self::Block> { |config: &FactoryFullConfiguration, client: Arc>| { Ok(LongestChain::new( client.backend().clone(), client.import_lock() )) } }, } }