git.delta.rocks / unique-network / refs/commits / 20d08c295b0d

difftreelog

source

src/service.rs7.0 KiBsourcehistory
1//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.23use 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};1617// Our native executor instance.18native_executor_instance!(19	pub Executor,20	node_template_runtime::api::dispatch,21	node_template_runtime::native_version,22);2324construct_simple_protocol! {25	/// Demo protocol attachment for substrate.26	pub struct NodeProtocol where Block = Block { }27}2829/// Starts a `ServiceBuilder` for a full service.30///31/// Use this macro if you don't actually need the full service, but just the builder in order to32/// be able to perform chain operations.33macro_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}7475/// Builds a new service for a full client.76pub 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		// the AURA authoring task is considered essential, i.e. if it121		// fails we take down the service with it.122		service.spawn_essential_task(select);123	}124125	let grandpa_config = grandpa::Config {126		// FIXME #1578 make this available through chainspec127		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			// start the lightweight GRANDPA observer136			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			// start the full GRANDPA voter145			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			// the GRANDPA voter task is considered infallible, i.e.156			// if it fails we take down the service with it.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}170171/// Builds a new service for a light client.172pub 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}