git.delta.rocks / unique-network / refs/commits / 333b2b4b7046

difftreelog

source

node/src/service.rs7.6 KiBsourcehistory
1//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.23use std::sync::Arc;4use std::time::Duration;5use sc_client::LongestChain;6use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi};7use sc_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder};8use sp_inherents::InherentDataProviders;9use sc_executor::native_executor_instance;10pub use sc_executor::NativeExecutor;11use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair};12use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};1314// Our native executor instance.15native_executor_instance!(16	pub Executor,17	node_template_runtime::api::dispatch,18	node_template_runtime::native_version,19);2021/// Starts a `ServiceBuilder` for a full service.22///23/// Use this macro if you don't actually need the full service, but just the builder in order to24/// be able to perform chain operations.25macro_rules! new_full_start {26	($config:expr) => {{27		let mut import_setup = None;28		let inherent_data_providers = sp_inherents::InherentDataProviders::new();2930		let builder = sc_service::ServiceBuilder::new_full::<31			node_template_runtime::opaque::Block, node_template_runtime::RuntimeApi, crate::service::Executor32		>($config)?33			.with_select_chain(|_config, backend| {34				Ok(sc_client::LongestChain::new(backend.clone()))35			})?36			.with_transaction_pool(|config, client, _fetcher| {37				let pool_api = sc_transaction_pool::FullChainApi::new(client.clone());38				Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api)))39			})?40			.with_import_queue(|_config, client, mut select_chain, _transaction_pool| {41				let select_chain = select_chain.take()42					.ok_or_else(|| sc_service::Error::SelectChainRequired)?;4344				let (grandpa_block_import, grandpa_link) =45					grandpa::block_import(client.clone(), &*client, select_chain)?;4647				let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(48					grandpa_block_import.clone(), client.clone(),49				);5051				let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair>(52					sc_consensus_aura::slot_duration(&*client)?,53					aura_block_import,54					Some(Box::new(grandpa_block_import.clone())),55					None,56					client,57					inherent_data_providers.clone(),58				)?;5960				import_setup = Some((grandpa_block_import, grandpa_link));6162				Ok(import_queue)63			})?;6465		(builder, import_setup, inherent_data_providers)66	}}67}6869/// Builds a new service for a full client.70pub fn new_full(config: Configuration<GenesisConfig>)71	-> Result<impl AbstractService, ServiceError>72{73	let is_authority = config.roles.is_authority();74	let force_authoring = config.force_authoring;75	let name = config.name.clone();76	let disable_grandpa = config.disable_grandpa;7778	// sentry nodes announce themselves as authorities to the network79	// and should run the same protocols authorities do, but it should80	// never actively participate in any consensus process.81	let participates_in_consensus = is_authority && !config.sentry_mode;8283	let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config);8485	let (block_import, grandpa_link) =86		import_setup.take()87			.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");8889	let service = builder90		.with_finality_proof_provider(|client, backend|91			Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _)92		)?93		.build()?;9495	if participates_in_consensus {96		let proposer = sc_basic_authorship::ProposerFactory::new(97			service.client(),98			service.transaction_pool()99		);100101		let client = service.client();102		let select_chain = service.select_chain()103			.ok_or(ServiceError::SelectChainRequired)?;104105		let can_author_with =106			sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());107108		let aura = sc_consensus_aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _>(109			sc_consensus_aura::slot_duration(&*client)?,110			client,111			select_chain,112			block_import,113			proposer,114			service.network(),115			inherent_data_providers.clone(),116			force_authoring,117			service.keystore(),118			can_author_with,119		)?;120121		// the AURA authoring task is considered essential, i.e. if it122		// fails we take down the service with it.123		service.spawn_essential_task("aura", aura);124	}125126	// if the node isn't actively participating in consensus then it doesn't127	// need a keystore, regardless of which protocol we use below.128	let keystore = if participates_in_consensus {129		Some(service.keystore())130	} else {131		None132	};133134	let grandpa_config = grandpa::Config {135		// FIXME #1578 make this available through chainspec136		gossip_duration: Duration::from_millis(333),137		justification_period: 512,138		name: Some(name),139		observer_enabled: false,140		keystore,141		is_authority,142	};143144	let enable_grandpa = !disable_grandpa;145	if enable_grandpa {146		// start the full GRANDPA voter147		// NOTE: non-authorities could run the GRANDPA observer protocol, but at148		// this point the full voter should provide better guarantees of block149		// and vote data availability than the observer. The observer has not150		// been tested extensively yet and having most nodes in a network run it151		// could lead to finality stalls.152		let grandpa_config = grandpa::GrandpaParams {153			config: grandpa_config,154			link: grandpa_link,155			network: service.network(),156			inherent_data_providers: inherent_data_providers.clone(),157			on_exit: service.on_exit(),158			telemetry_on_connect: Some(service.telemetry_on_connect_stream()),159			voting_rule: grandpa::VotingRulesBuilder::default().build(),160		};161162		// the GRANDPA voter task is considered infallible, i.e.163		// if it fails we take down the service with it.164		service.spawn_essential_task(165			"grandpa-voter",166			grandpa::run_grandpa_voter(grandpa_config)?167		);168	} else {169		grandpa::setup_disabled_grandpa(170			service.client(),171			&inherent_data_providers,172			service.network(),173		)?;174	}175176	Ok(service)177}178179/// Builds a new service for a light client.180pub fn new_light(config: Configuration<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, fetcher| {190			let fetcher = fetcher191				.ok_or_else(|| "Trying to start light transaction pool without active fetcher")?;192193			let pool_api = sc_transaction_pool::LightChainApi::new(client.clone(), fetcher.clone());194			let pool = sc_transaction_pool::BasicPool::with_revalidation_type(195				config, Arc::new(pool_api), sc_transaction_pool::RevalidationType::Light,196			);197			Ok(pool)198		})?199		.with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool| {200			let fetch_checker = fetcher201				.map(|fetcher| fetcher.checker().clone())202				.ok_or_else(|| "Trying to start light import queue without active fetch checker")?;203			let grandpa_block_import = grandpa::light_block_import(204				client.clone(), backend, &*client.clone(), Arc::new(fetch_checker),205			)?;206			let finality_proof_import = grandpa_block_import.clone();207			let finality_proof_request_builder =208				finality_proof_import.create_finality_proof_request_builder();209210			let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair>(211				sc_consensus_aura::slot_duration(&*client)?,212				grandpa_block_import,213				None,214				Some(Box::new(finality_proof_import)),215				client,216				inherent_data_providers.clone(),217			)?;218219			Ok((import_queue, finality_proof_request_builder))220		})?221		.with_finality_proof_provider(|client, backend|222			Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _)223		)?224		.build()225}