123use std::sync::Arc;4use std::time::Duration;5use sc_client_api::ExecutorProvider;6use sc_consensus::LongestChain;7use nft_runtime::{self, opaque::Block, RuntimeApi};8use sc_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder};9use sp_inherents::InherentDataProviders;10use sc_executor::native_executor_instance;11pub use sc_executor::NativeExecutor;12use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair};13use sc_finality_grandpa::{14 FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider, SharedVoterState,15};161718native_executor_instance!(19 pub Executor,20 nft_runtime::api::dispatch,21 nft_runtime::native_version,22);232425262728macro_rules! new_full_start {29 ($config:expr) => {{30 use std::sync::Arc;31 use sp_consensus_aura::sr25519::AuthorityPair as AuraPair;3233 let mut import_setup = None;34 let inherent_data_providers = sp_inherents::InherentDataProviders::new();3536 let builder = sc_service::ServiceBuilder::new_full::<37 nft_runtime::opaque::Block,38 nft_runtime::RuntimeApi,39 crate::service::Executor40 >($config)?41 .with_select_chain(|_config, backend| {42 Ok(sc_consensus::LongestChain::new(backend.clone()))43 })?44 .with_transaction_pool(|builder| {45 let pool_api = sc_transaction_pool::FullChainApi::new(46 builder.client().clone(),47 );48 Ok(sc_transaction_pool::BasicPool::new(49 builder.config().transaction_pool.clone(),50 std::sync::Arc::new(pool_api),51 builder.prometheus_registry(),52 ))53 })?54 .with_import_queue(|55 _config,56 client,57 mut select_chain,58 _transaction_pool,59 spawn_task_handle,60 registry,61 | {62 let select_chain = select_chain.take()63 .ok_or_else(|| sc_service::Error::SelectChainRequired)?;6465 let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import(66 client.clone(),67 &(client.clone() as Arc<_>),68 select_chain,69 )?;7071 let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(72 grandpa_block_import.clone(), client.clone(),73 );7475 let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _>(76 sc_consensus_aura::slot_duration(&*client)?,77 aura_block_import,78 Some(Box::new(grandpa_block_import.clone())),79 None,80 client,81 inherent_data_providers.clone(),82 spawn_task_handle,83 registry,84 )?;8586 import_setup = Some((grandpa_block_import, grandpa_link));8788 Ok(import_queue)89 })?;9091 (builder, import_setup, inherent_data_providers)92 }}93}949596pub fn new_full(config: Configuration) -> Result<impl AbstractService, ServiceError> {97 let role = config.role.clone();98 let force_authoring = config.force_authoring;99 let name = config.network.node_name.clone();100 let disable_grandpa = config.disable_grandpa;101102 let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config);103104 let (block_import, grandpa_link) =105 import_setup.take()106 .expect("Link Half and Block Import are present for Full Services or setup failed before. qed");107108 let service = builder109 .with_finality_proof_provider(|client, backend| {110 111 let provider = client as Arc<dyn StorageAndProofProvider<_, _>>;112 Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)113 })?114 .build_full()?;115116 if role.is_authority() {117 let proposer = sc_basic_authorship::ProposerFactory::new(118 service.client(),119 service.transaction_pool(),120 service.prometheus_registry().as_ref(),121 );122123 let client = service.client();124 let select_chain = service.select_chain()125 .ok_or(ServiceError::SelectChainRequired)?;126127 let can_author_with =128 sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());129130 let aura = sc_consensus_aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _>(131 sc_consensus_aura::slot_duration(&*client)?,132 client,133 select_chain,134 block_import,135 proposer,136 service.network(),137 inherent_data_providers.clone(),138 force_authoring,139 service.keystore(),140 can_author_with,141 )?;142143 144 145 service.spawn_essential_task_handle().spawn_blocking("aura", aura);146 }147148 149 150 let keystore = if role.is_authority() {151 Some(service.keystore() as sp_core::traits::BareCryptoStorePtr)152 } else {153 None154 };155156 let grandpa_config = sc_finality_grandpa::Config {157 158 gossip_duration: Duration::from_millis(333),159 justification_period: 512,160 name: Some(name),161 observer_enabled: false,162 keystore,163 is_authority: role.is_network_authority(),164 };165166 let enable_grandpa = !disable_grandpa;167 if enable_grandpa {168 169 170 171 172 173 174 let grandpa_config = sc_finality_grandpa::GrandpaParams {175 config: grandpa_config,176 link: grandpa_link,177 network: service.network(),178 inherent_data_providers: inherent_data_providers.clone(),179 telemetry_on_connect: Some(service.telemetry_on_connect_stream()),180 voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(),181 prometheus_registry: service.prometheus_registry(),182 shared_voter_state: SharedVoterState::empty(),183 };184185 186 187 service.spawn_essential_task_handle().spawn_blocking(188 "grandpa-voter",189 sc_finality_grandpa::run_grandpa_voter(grandpa_config)?190 );191 } else {192 sc_finality_grandpa::setup_disabled_grandpa(193 service.client(),194 &inherent_data_providers,195 service.network(),196 )?;197 }198199 Ok(service)200}201202203pub fn new_light(config: Configuration) -> Result<impl AbstractService, ServiceError> {204 let inherent_data_providers = InherentDataProviders::new();205206 ServiceBuilder::new_light::<Block, RuntimeApi, Executor>(config)?207 .with_select_chain(|_config, backend| {208 Ok(LongestChain::new(backend.clone()))209 })?210 .with_transaction_pool(|builder| {211 let fetcher = builder.fetcher()212 .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?;213214 let pool_api = sc_transaction_pool::LightChainApi::new(215 builder.client().clone(),216 fetcher.clone(),217 );218 let pool = sc_transaction_pool::BasicPool::with_revalidation_type(219 builder.config().transaction_pool.clone(),220 Arc::new(pool_api),221 builder.prometheus_registry(),222 sc_transaction_pool::RevalidationType::Light,223 );224 Ok(pool)225 })?226 .with_import_queue_and_fprb(|227 _config,228 client,229 backend,230 fetcher,231 _select_chain,232 _tx_pool,233 spawn_task_handle,234 prometheus_registry,235 | {236 let fetch_checker = fetcher237 .map(|fetcher| fetcher.checker().clone())238 .ok_or_else(|| "Trying to start light import queue without active fetch checker")?;239 let grandpa_block_import = sc_finality_grandpa::light_block_import(240 client.clone(),241 backend,242 &(client.clone() as Arc<_>),243 Arc::new(fetch_checker),244 )?;245 let finality_proof_import = grandpa_block_import.clone();246 let finality_proof_request_builder =247 finality_proof_import.create_finality_proof_request_builder();248249 let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _>(250 sc_consensus_aura::slot_duration(&*client)?,251 grandpa_block_import,252 None,253 Some(Box::new(finality_proof_import)),254 client,255 inherent_data_providers.clone(),256 spawn_task_handle,257 prometheus_registry,258 )?;259260 Ok((import_queue, finality_proof_request_builder))261 })?262 .with_finality_proof_provider(|client, backend| {263 264 let provider = client as Arc<dyn StorageAndProofProvider<_, _>>;265 Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)266 })?267 .build_light()268}