123456789101112131415161718use std::sync::Arc;19use std::sync::Mutex;20use std::collections::BTreeMap;21use std::time::Duration;22use std::pin::Pin;23use fc_rpc_core::types::FeeHistoryCache;24use futures::{25 Stream, StreamExt,26 stream::select,27 task::{Context, Poll},28};29use tokio::time::Interval;3031use unique_rpc::overrides_handle;3233use serde::{Serialize, Deserialize};343536use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion};37use cumulus_client_consensus_common::ParachainConsensus;38use cumulus_client_service::{39 prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams,40};41use cumulus_client_cli::CollatorOptions;42use cumulus_client_network::BlockAnnounceValidator;43use cumulus_primitives_core::ParaId;44use cumulus_relay_chain_inprocess_interface::build_inprocess_relay_chain;45use cumulus_relay_chain_interface::{RelayChainError, RelayChainInterface, RelayChainResult};46use cumulus_relay_chain_rpc_interface::{RelayChainRpcInterface, create_client_and_start_worker};474849use sc_executor::NativeElseWasmExecutor;50use sc_executor::NativeExecutionDispatch;51use sc_network::{NetworkService, NetworkBlock};52use sc_service::{BasePath, Configuration, PartialComponents, TaskManager};53use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};54use sp_keystore::SyncCryptoStorePtr;55use sp_runtime::traits::BlakeTwo256;56use substrate_prometheus_endpoint::Registry;57use sc_client_api::BlockchainEvents;5859use polkadot_service::CollatorPair;606162use fc_rpc_core::types::FilterPool;63use fc_mapping_sync::{MappingSyncWorker, SyncStrategy};6465use up_common::types::opaque::{66 AuraId, RuntimeInstance, AccountId, Balance, Index, Hash, Block, BlockNumber,67};686970use up_data_structs::{71 RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo,72 RmrkPartType, RmrkTheme,73};747576#[cfg(feature = "unique-runtime")]77pub struct UniqueRuntimeExecutor;7879#[cfg(feature = "quartz-runtime")]8081pub struct QuartzRuntimeExecutor;828384pub struct OpalRuntimeExecutor;8586#[cfg(all(feature = "unique-runtime", feature = "runtime-benchmarks"))]87pub type DefaultRuntimeExecutor = UniqueRuntimeExecutor;8889#[cfg(all(90 not(feature = "unique-runtime"),91 feature = "quartz-runtime",92 feature = "runtime-benchmarks"93))]94pub type DefaultRuntimeExecutor = QuartzRuntimeExecutor;9596#[cfg(all(97 not(feature = "unique-runtime"),98 not(feature = "quartz-runtime"),99 feature = "runtime-benchmarks"100))]101pub type DefaultRuntimeExecutor = OpalRuntimeExecutor;102103#[cfg(feature = "unique-runtime")]104impl NativeExecutionDispatch for UniqueRuntimeExecutor {105 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;106107 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {108 unique_runtime::api::dispatch(method, data)109 }110111 fn native_version() -> sc_executor::NativeVersion {112 unique_runtime::native_version()113 }114}115116#[cfg(feature = "quartz-runtime")]117impl NativeExecutionDispatch for QuartzRuntimeExecutor {118 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;119120 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {121 quartz_runtime::api::dispatch(method, data)122 }123124 fn native_version() -> sc_executor::NativeVersion {125 quartz_runtime::native_version()126 }127}128129impl NativeExecutionDispatch for OpalRuntimeExecutor {130 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;131132 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {133 opal_runtime::api::dispatch(method, data)134 }135136 fn native_version() -> sc_executor::NativeVersion {137 opal_runtime::native_version()138 }139}140141pub struct AutosealInterval {142 interval: Interval,143}144145impl AutosealInterval {146 pub fn new(config: &Configuration, interval: Duration) -> Self {147 let _tokio_runtime = config.tokio_handle.enter();148 let interval = tokio::time::interval(interval);149150 Self { interval }151 }152}153154impl Stream for AutosealInterval {155 type Item = tokio::time::Instant;156157 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {158 self.interval.poll_tick(cx).map(Some)159 }160}161162pub fn open_frontier_backend(config: &Configuration) -> Result<Arc<fc_db::Backend<Block>>, String> {163 let config_dir = config164 .base_path165 .as_ref()166 .map(|base_path| base_path.config_dir(config.chain_spec.id()))167 .unwrap_or_else(|| {168 BasePath::from_project("", "", "unique").config_dir(config.chain_spec.id())169 });170 let database_dir = config_dir.join("frontier").join("db");171172 Ok(Arc::new(fc_db::Backend::<Block>::new(173 &fc_db::DatabaseSettings {174 source: fc_db::DatabaseSource::RocksDb {175 path: database_dir,176 cache_size: 0,177 },178 },179 )?))180}181182type FullClient<RuntimeApi, ExecutorDispatch> =183 sc_service::TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<ExecutorDispatch>>;184type FullBackend = sc_service::TFullBackend<Block>;185type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;186187188189190191#[allow(clippy::type_complexity)]192pub fn new_partial<RuntimeApi, ExecutorDispatch, BIQ>(193 config: &Configuration,194 build_import_queue: BIQ,195) -> Result<196 PartialComponents<197 FullClient<RuntimeApi, ExecutorDispatch>,198 FullBackend,199 FullSelectChain,200 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,201 sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,202 (203 Option<Telemetry>,204 Option<FilterPool>,205 Arc<fc_db::Backend<Block>>,206 Option<TelemetryWorkerHandle>,207 FeeHistoryCache,208 ),209 >,210 sc_service::Error,211>212where213 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,214 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>215 + Send216 + Sync217 + 'static,218 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>,219 ExecutorDispatch: NativeExecutionDispatch + 'static,220 BIQ: FnOnce(221 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,222 &Configuration,223 Option<TelemetryHandle>,224 &TaskManager,225 ) -> Result<226 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,227 sc_service::Error,228 >,229{230 let _telemetry = config231 .telemetry_endpoints232 .clone()233 .filter(|x| !x.is_empty())234 .map(|endpoints| -> Result<_, sc_telemetry::Error> {235 let worker = TelemetryWorker::new(16)?;236 let telemetry = worker.handle().new_telemetry(endpoints);237 Ok((worker, telemetry))238 })239 .transpose()?;240241 let telemetry = config242 .telemetry_endpoints243 .clone()244 .filter(|x| !x.is_empty())245 .map(|endpoints| -> Result<_, sc_telemetry::Error> {246 let worker = TelemetryWorker::new(16)?;247 let telemetry = worker.handle().new_telemetry(endpoints);248 Ok((worker, telemetry))249 })250 .transpose()?;251252 let executor = NativeElseWasmExecutor::<ExecutorDispatch>::new(253 config.wasm_method,254 config.default_heap_pages,255 config.max_runtime_instances,256 config.runtime_cache_size,257 );258259 let (client, backend, keystore_container, task_manager) =260 sc_service::new_full_parts::<Block, RuntimeApi, _>(261 config,262 telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),263 executor,264 )?;265 let client = Arc::new(client);266267 let telemetry_worker_handle = telemetry.as_ref().map(|(worker, _)| worker.handle());268269 let telemetry = telemetry.map(|(worker, telemetry)| {270 task_manager271 .spawn_handle()272 .spawn("telemetry", None, worker.run());273 telemetry274 });275276 let select_chain = sc_consensus::LongestChain::new(backend.clone());277278 let transaction_pool = sc_transaction_pool::BasicPool::new_full(279 config.transaction_pool.clone(),280 config.role.is_authority().into(),281 config.prometheus_registry(),282 task_manager.spawn_essential_handle(),283 client.clone(),284 );285286 let filter_pool: Option<FilterPool> = Some(Arc::new(Mutex::new(BTreeMap::new())));287288 let frontier_backend = open_frontier_backend(config)?;289290 let import_queue = build_import_queue(291 client.clone(),292 config,293 telemetry.as_ref().map(|telemetry| telemetry.handle()),294 &task_manager,295 )?;296 let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new()));297298 let params = PartialComponents {299 backend,300 client,301 import_queue,302 keystore_container,303 task_manager,304 transaction_pool,305 select_chain,306 other: (307 telemetry,308 filter_pool,309 frontier_backend,310 telemetry_worker_handle,311 fee_history_cache,312 ),313 };314315 Ok(params)316}317318async fn build_relay_chain_interface(319 polkadot_config: Configuration,320 parachain_config: &Configuration,321 telemetry_worker_handle: Option<TelemetryWorkerHandle>,322 task_manager: &mut TaskManager,323 collator_options: CollatorOptions,324 hwbench: Option<sc_sysinfo::HwBench>,325) -> RelayChainResult<(326 Arc<(dyn RelayChainInterface + 'static)>,327 Option<CollatorPair>,328)> {329 match collator_options.relay_chain_rpc_url {330 Some(relay_chain_url) => {331 let rpc_client = create_client_and_start_worker(relay_chain_url, task_manager).await?;332333 Ok((334 Arc::new(RelayChainRpcInterface::new(rpc_client)) as Arc<_>,335 None,336 ))337 }338 None => build_inprocess_relay_chain(339 polkadot_config,340 parachain_config,341 telemetry_worker_handle,342 task_manager,343 hwbench,344 ),345 }346}347348349350351#[sc_tracing::logging::prefix_logs_with("Parachain")]352async fn start_node_impl<Runtime, RuntimeApi, ExecutorDispatch, BIQ, BIC>(353 parachain_config: Configuration,354 polkadot_config: Configuration,355 collator_options: CollatorOptions,356 id: ParaId,357 build_import_queue: BIQ,358 build_consensus: BIC,359 hwbench: Option<sc_sysinfo::HwBench>,360) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>361where362 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,363 Runtime: RuntimeInstance + Send + Sync + 'static,364 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,365 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,366 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>367 + Send368 + Sync369 + 'static,370 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>371 + fp_rpc::EthereumRuntimeRPCApi<Block>372 + fp_rpc::ConvertTransactionRuntimeApi<Block>373 + sp_session::SessionKeys<Block>374 + sp_block_builder::BlockBuilder<Block>375 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>376 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>377 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>378 + app_promotion_rpc::AppPromotionApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>379 + rmrk_rpc::RmrkApi<380 Block,381 AccountId,382 RmrkCollectionInfo<AccountId>,383 RmrkInstanceInfo<AccountId>,384 RmrkResourceInfo,385 RmrkPropertyInfo,386 RmrkBaseInfo<AccountId>,387 RmrkPartType,388 RmrkTheme,389 > + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>390 + sp_api::Metadata<Block>391 + sp_offchain::OffchainWorkerApi<Block>392 + cumulus_primitives_core::CollectCollationInfo<Block>,393 ExecutorDispatch: NativeExecutionDispatch + 'static,394 BIQ: FnOnce(395 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,396 &Configuration,397 Option<TelemetryHandle>,398 &TaskManager,399 ) -> Result<400 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,401 sc_service::Error,402 >,403 BIC: FnOnce(404 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,405 Option<&Registry>,406 Option<TelemetryHandle>,407 &TaskManager,408 Arc<dyn RelayChainInterface>,409 Arc<sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>>,410 Arc<NetworkService<Block, Hash>>,411 SyncCryptoStorePtr,412 bool,413 ) -> Result<Box<dyn ParachainConsensus<Block>>, sc_service::Error>,414{415 let parachain_config = prepare_node_config(parachain_config);416417 let params =418 new_partial::<RuntimeApi, ExecutorDispatch, BIQ>(¶chain_config, build_import_queue)?;419 let (mut telemetry, filter_pool, frontier_backend, telemetry_worker_handle, fee_history_cache) =420 params.other;421422 let client = params.client.clone();423 let backend = params.backend.clone();424 let mut task_manager = params.task_manager;425426 let (relay_chain_interface, collator_key) = build_relay_chain_interface(427 polkadot_config,428 ¶chain_config,429 telemetry_worker_handle,430 &mut task_manager,431 collator_options.clone(),432 hwbench.clone(),433 )434 .await435 .map_err(|e| match e {436 RelayChainError::ServiceError(polkadot_service::Error::Sub(x)) => x,437 s => s.to_string().into(),438 })?;439440 let block_announce_validator = BlockAnnounceValidator::new(relay_chain_interface.clone(), id);441442 let force_authoring = parachain_config.force_authoring;443 let validator = parachain_config.role.is_authority();444 let prometheus_registry = parachain_config.prometheus_registry().cloned();445 let transaction_pool = params.transaction_pool.clone();446 let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue);447448 let (network, system_rpc_tx, tx_handler_controller, start_network) =449 sc_service::build_network(sc_service::BuildNetworkParams {450 config: ¶chain_config,451 client: client.clone(),452 transaction_pool: transaction_pool.clone(),453 spawn_handle: task_manager.spawn_handle(),454 import_queue: import_queue.clone(),455 block_announce_validator_builder: Some(Box::new(|_| {456 Box::new(block_announce_validator)457 })),458 warp_sync: None,459 })?;460461 let rpc_client = client.clone();462 let rpc_pool = transaction_pool.clone();463 let select_chain = params.select_chain.clone();464 let rpc_network = network.clone();465466 let rpc_frontier_backend = frontier_backend.clone();467468 let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new(469 task_manager.spawn_handle(),470 overrides_handle::<_, _, Runtime>(client.clone()),471 50,472 50,473 prometheus_registry.clone(),474 ));475476 task_manager.spawn_essential_handle().spawn(477 "frontier-mapping-sync-worker",478 None,479 MappingSyncWorker::new(480 client.import_notification_stream(),481 Duration::new(6, 0),482 client.clone(),483 backend.clone(),484 frontier_backend.clone(),485 3,486 0,487 SyncStrategy::Normal,488 )489 .for_each(|()| futures::future::ready(())),490 );491492 let rpc_builder = Box::new(move |deny_unsafe, subscription_task_executor| {493 let full_deps = unique_rpc::FullDeps {494 backend: rpc_frontier_backend.clone(),495 deny_unsafe,496 client: rpc_client.clone(),497 pool: rpc_pool.clone(),498 graph: rpc_pool.pool().clone(),499 500 enable_dev_signer: false,501 filter_pool: filter_pool.clone(),502 network: rpc_network.clone(),503 select_chain: select_chain.clone(),504 is_authority: validator,505 506 max_past_logs: 10000,507 block_data_cache: block_data_cache.clone(),508 fee_history_cache: fee_history_cache.clone(),509 510 fee_history_limit: 2048,511 };512513 unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(514 full_deps,515 subscription_task_executor,516 )517 .map_err(Into::into)518 });519520 sc_service::spawn_tasks(sc_service::SpawnTasksParams {521 rpc_builder,522 client: client.clone(),523 transaction_pool: transaction_pool.clone(),524 task_manager: &mut task_manager,525 config: parachain_config,526 keystore: params.keystore_container.sync_keystore(),527 backend: backend.clone(),528 network: network.clone(),529 system_rpc_tx,530 telemetry: telemetry.as_mut(),531 tx_handler_controller,532 })?;533534 if let Some(hwbench) = hwbench {535 sc_sysinfo::print_hwbench(&hwbench);536537 if let Some(ref mut telemetry) = telemetry {538 let telemetry_handle = telemetry.handle();539 task_manager.spawn_handle().spawn(540 "telemetry_hwbench",541 None,542 sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench),543 );544 }545 }546547 let announce_block = {548 let network = network.clone();549 Arc::new(Box::new(move |hash, data| {550 network.announce_block(hash, data)551 }))552 };553554 let relay_chain_slot_duration = Duration::from_secs(6);555556 if validator {557 let parachain_consensus = build_consensus(558 client.clone(),559 prometheus_registry.as_ref(),560 telemetry.as_ref().map(|t| t.handle()),561 &task_manager,562 relay_chain_interface.clone(),563 transaction_pool,564 network,565 params.keystore_container.sync_keystore(),566 force_authoring,567 )?;568569 let spawner = task_manager.spawn_handle();570571 let params = StartCollatorParams {572 para_id: id,573 block_status: client.clone(),574 announce_block,575 client: client.clone(),576 task_manager: &mut task_manager,577 spawner,578 parachain_consensus,579 import_queue,580 collator_key: collator_key.expect("Command line arguments do not allow this. qed"),581 relay_chain_interface,582 relay_chain_slot_duration,583 };584585 start_collator(params).await?;586 } else {587 let params = StartFullNodeParams {588 client: client.clone(),589 announce_block,590 task_manager: &mut task_manager,591 para_id: id,592 import_queue,593 relay_chain_interface,594 relay_chain_slot_duration,595 collator_options,596 };597598 start_full_node(params)?;599 }600601 start_network.start_network();602603 Ok((task_manager, client))604}605606607pub fn parachain_build_import_queue<RuntimeApi, ExecutorDispatch>(608 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,609 config: &Configuration,610 telemetry: Option<TelemetryHandle>,611 task_manager: &TaskManager,612) -> Result<613 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,614 sc_service::Error,615>616where617 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>618 + Send619 + Sync620 + 'static,621 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>622 + sp_block_builder::BlockBuilder<Block>623 + sp_consensus_aura::AuraApi<Block, AuraId>624 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,625 ExecutorDispatch: NativeExecutionDispatch + 'static,626{627 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;628629 cumulus_client_consensus_aura::import_queue::<630 sp_consensus_aura::sr25519::AuthorityPair,631 _,632 _,633 _,634 _,635 _,636 >(cumulus_client_consensus_aura::ImportQueueParams {637 block_import: client.clone(),638 client: client.clone(),639 create_inherent_data_providers: move |_, _| async move {640 let time = sp_timestamp::InherentDataProvider::from_system_time();641642 let slot =643 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(644 *time,645 slot_duration,646 );647648 Ok((slot, time))649 },650 registry: config.prometheus_registry(),651 spawner: &task_manager.spawn_essential_handle(),652 telemetry,653 })654 .map_err(Into::into)655}656657658pub async fn start_node<Runtime, RuntimeApi, ExecutorDispatch>(659 parachain_config: Configuration,660 polkadot_config: Configuration,661 collator_options: CollatorOptions,662 id: ParaId,663 hwbench: Option<sc_sysinfo::HwBench>,664) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>665where666 Runtime: RuntimeInstance + Send + Sync + 'static,667 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,668 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,669 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>670 + Send671 + Sync672 + 'static,673 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>674 + fp_rpc::EthereumRuntimeRPCApi<Block>675 + fp_rpc::ConvertTransactionRuntimeApi<Block>676 + sp_session::SessionKeys<Block>677 + sp_block_builder::BlockBuilder<Block>678 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>679 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>680 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>681 + app_promotion_rpc::AppPromotionApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>682 + rmrk_rpc::RmrkApi<683 Block,684 AccountId,685 RmrkCollectionInfo<AccountId>,686 RmrkInstanceInfo<AccountId>,687 RmrkResourceInfo,688 RmrkPropertyInfo,689 RmrkBaseInfo<AccountId>,690 RmrkPartType,691 RmrkTheme,692 > + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>693 + sp_api::Metadata<Block>694 + sp_offchain::OffchainWorkerApi<Block>695 + cumulus_primitives_core::CollectCollationInfo<Block>696 + sp_consensus_aura::AuraApi<Block, AuraId>,697 ExecutorDispatch: NativeExecutionDispatch + 'static,698{699 start_node_impl::<Runtime, RuntimeApi, ExecutorDispatch, _, _>(700 parachain_config,701 polkadot_config,702 collator_options,703 id,704 parachain_build_import_queue,705 |client,706 prometheus_registry,707 telemetry,708 task_manager,709 relay_chain_interface,710 transaction_pool,711 sync_oracle,712 keystore,713 force_authoring| {714 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;715716 let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(717 task_manager.spawn_handle(),718 client.clone(),719 transaction_pool,720 prometheus_registry,721 telemetry.clone(),722 );723724 Ok(AuraConsensus::build::<725 sp_consensus_aura::sr25519::AuthorityPair,726 _,727 _,728 _,729 _,730 _,731 _,732 >(BuildAuraConsensusParams {733 proposer_factory,734 create_inherent_data_providers: move |_, (relay_parent, validation_data)| {735 let relay_chain_interface = relay_chain_interface.clone();736 async move {737 let parachain_inherent =738 cumulus_primitives_parachain_inherent::ParachainInherentData::create_at(739 relay_parent,740 &relay_chain_interface,741 &validation_data,742 id,743 ).await;744745 let time = sp_timestamp::InherentDataProvider::from_system_time();746747 let slot =748 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(749 *time,750 slot_duration,751 );752753 let parachain_inherent = parachain_inherent.ok_or_else(|| {754 Box::<dyn std::error::Error + Send + Sync>::from(755 "Failed to create parachain inherent",756 )757 })?;758 Ok((slot, time, parachain_inherent))759 }760 },761 block_import: client.clone(),762 para_client: client,763 backoff_authoring_blocks: Option::<()>::None,764 sync_oracle,765 keystore,766 force_authoring,767 slot_duration,768 769 block_proposal_slot_portion: SlotProportion::new(1f32 / 24f32),770 telemetry,771 max_block_proposal_slot_portion: None,772 }))773 },774 hwbench,775 )776 .await777}778779fn dev_build_import_queue<RuntimeApi, ExecutorDispatch>(780 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,781 config: &Configuration,782 _: Option<TelemetryHandle>,783 task_manager: &TaskManager,784) -> Result<785 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,786 sc_service::Error,787>788where789 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>790 + Send791 + Sync792 + 'static,793 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>794 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,795 ExecutorDispatch: NativeExecutionDispatch + 'static,796{797 Ok(sc_consensus_manual_seal::import_queue(798 Box::new(client.clone()),799 &task_manager.spawn_essential_handle(),800 config.prometheus_registry(),801 ))802}803804805806pub fn start_dev_node<Runtime, RuntimeApi, ExecutorDispatch>(807 config: Configuration,808 autoseal_interval: Duration,809) -> sc_service::error::Result<TaskManager>810where811 Runtime: RuntimeInstance + Send + Sync + 'static,812 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,813 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,814 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>815 + Send816 + Sync817 + 'static,818 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>819 + fp_rpc::EthereumRuntimeRPCApi<Block>820 + fp_rpc::ConvertTransactionRuntimeApi<Block>821 + sp_session::SessionKeys<Block>822 + sp_block_builder::BlockBuilder<Block>823 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>824 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>825 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>826 + app_promotion_rpc::AppPromotionApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>827 + rmrk_rpc::RmrkApi<828 Block,829 AccountId,830 RmrkCollectionInfo<AccountId>,831 RmrkInstanceInfo<AccountId>,832 RmrkResourceInfo,833 RmrkPropertyInfo,834 RmrkBaseInfo<AccountId>,835 RmrkPartType,836 RmrkTheme,837 > + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>838 + sp_api::Metadata<Block>839 + sp_offchain::OffchainWorkerApi<Block>840 + cumulus_primitives_core::CollectCollationInfo<Block>841 + sp_consensus_aura::AuraApi<Block, AuraId>,842 ExecutorDispatch: NativeExecutionDispatch + 'static,843{844 use sc_consensus_manual_seal::{run_manual_seal, EngineCommand, ManualSealParams};845 use fc_consensus::FrontierBlockImport;846 use sc_client_api::HeaderBackend;847848 let sc_service::PartialComponents {849 client,850 backend,851 mut task_manager,852 import_queue,853 keystore_container,854 select_chain: maybe_select_chain,855 transaction_pool,856 other:857 (telemetry, filter_pool, frontier_backend, _telemetry_worker_handle, fee_history_cache),858 } = new_partial::<RuntimeApi, ExecutorDispatch, _>(859 &config,860 dev_build_import_queue::<RuntimeApi, ExecutorDispatch>,861 )?;862 let prometheus_registry = config.prometheus_registry().cloned();863864 let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new(865 task_manager.spawn_handle(),866 overrides_handle::<_, _, Runtime>(client.clone()),867 50,868 50,869 prometheus_registry.clone(),870 ));871872 let (network, system_rpc_tx, tx_handler_controller, network_starter) =873 sc_service::build_network(sc_service::BuildNetworkParams {874 config: &config,875 client: client.clone(),876 transaction_pool: transaction_pool.clone(),877 spawn_handle: task_manager.spawn_handle(),878 import_queue,879 block_announce_validator_builder: None,880 warp_sync: None,881 })?;882883 if config.offchain_worker.enabled {884 sc_service::build_offchain_workers(885 &config,886 task_manager.spawn_handle(),887 client.clone(),888 network.clone(),889 );890 }891892 let collator = config.role.is_authority();893894 let select_chain = maybe_select_chain.clone();895896 if collator {897 let block_import =898 FrontierBlockImport::new(client.clone(), client.clone(), frontier_backend.clone());899900 let env = sc_basic_authorship::ProposerFactory::new(901 task_manager.spawn_handle(),902 client.clone(),903 transaction_pool.clone(),904 prometheus_registry.as_ref(),905 telemetry.as_ref().map(|x| x.handle()),906 );907908 let transactions_commands_stream: Box<909 dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin,910 > = Box::new(911 transaction_pool912 .pool()913 .validated_pool()914 .import_notification_stream()915 .map(|_| EngineCommand::SealNewBlock {916 create_empty: true,917 finalize: false,918 parent_hash: None,919 sender: None,920 }),921 );922923 let autoseal_interval = Box::pin(AutosealInterval::new(&config, autoseal_interval));924 let idle_commands_stream: Box<925 dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin,926 > = Box::new(autoseal_interval.map(|_| EngineCommand::SealNewBlock {927 create_empty: true,928 finalize: false,929 parent_hash: None,930 sender: None,931 }));932933 let commands_stream = select(transactions_commands_stream, idle_commands_stream);934935 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;936 let client_set_aside_for_cidp = client.clone();937938 task_manager.spawn_essential_handle().spawn_blocking(939 "authorship_task",940 Some("block-authoring"),941 run_manual_seal(ManualSealParams {942 block_import,943 env,944 client: client.clone(),945 pool: transaction_pool.clone(),946 commands_stream,947 select_chain: select_chain.clone(),948 consensus_data_provider: None,949 create_inherent_data_providers: move |block: Hash, ()| {950 let current_para_block = client_set_aside_for_cidp951 .number(block)952 .expect("Header lookup should succeed")953 .expect("Header passed in as parent should be present in backend.");954955 let client_for_xcm = client_set_aside_for_cidp.clone();956 async move {957 let time = sp_timestamp::InherentDataProvider::from_system_time();958959 let mocked_parachain = cumulus_primitives_parachain_inherent::MockValidationDataInherentDataProvider {960 current_para_block,961 relay_offset: 1000,962 relay_blocks_per_para_block: 2,963 para_blocks_per_relay_epoch: 0,964 xcm_config: cumulus_primitives_parachain_inherent::MockXcmConfig::new(965 &*client_for_xcm,966 block,967 Default::default(),968 Default::default(),969 ),970 relay_randomness_config: (),971 raw_downward_messages: vec![],972 raw_horizontal_messages: vec![],973 };974975 let slot =976 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(977 *time,978 slot_duration,979 );980981 Ok((time, slot, mocked_parachain))982 }983 },984 }),985 );986 }987988 task_manager.spawn_essential_handle().spawn(989 "frontier-mapping-sync-worker",990 Some("block-authoring"),991 MappingSyncWorker::new(992 client.import_notification_stream(),993 Duration::new(6, 0),994 client.clone(),995 backend.clone(),996 frontier_backend.clone(),997 3,998 0,999 SyncStrategy::Normal,1000 )1001 .for_each(|()| futures::future::ready(())),1002 );10031004 let rpc_client = client.clone();1005 let rpc_pool = transaction_pool.clone();1006 let rpc_network = network.clone();1007 let rpc_frontier_backend = frontier_backend.clone();1008 let rpc_builder = Box::new(move |deny_unsafe, subscription_executor| {1009 let full_deps = unique_rpc::FullDeps {1010 backend: rpc_frontier_backend.clone(),1011 deny_unsafe,1012 client: rpc_client.clone(),1013 pool: rpc_pool.clone(),1014 graph: rpc_pool.pool().clone(),1015 1016 enable_dev_signer: false,1017 filter_pool: filter_pool.clone(),1018 network: rpc_network.clone(),1019 select_chain: select_chain.clone(),1020 is_authority: collator,1021 1022 max_past_logs: 10000,1023 block_data_cache: block_data_cache.clone(),1024 fee_history_cache: fee_history_cache.clone(),1025 1026 fee_history_limit: 2048,1027 };10281029 unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(1030 full_deps,1031 subscription_executor,1032 )1033 .map_err(Into::into)1034 });10351036 sc_service::spawn_tasks(sc_service::SpawnTasksParams {1037 network,1038 client,1039 keystore: keystore_container.sync_keystore(),1040 task_manager: &mut task_manager,1041 transaction_pool,1042 rpc_builder,1043 backend,1044 system_rpc_tx,1045 config,1046 telemetry: None,1047 tx_handler_controller,1048 })?;10491050 network_starter.start_network();1051 Ok(task_manager)1052}