difftreelog
feat upgrade code to v1.2.0
in: master
2 files changed
node/cli/src/service.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// std18use std::{19 collections::BTreeMap,20 marker::PhantomData,21 pin::Pin,22 sync::{Arc, Mutex},23 time::Duration,24};2526use cumulus_client_cli::CollatorOptions;27use cumulus_client_collator::service::CollatorService;28#[cfg(not(feature = "lookahead"))]29use cumulus_client_consensus_aura::collators::basic::{30 run as run_aura, Params as BuildAuraConsensusParams,31};32#[cfg(feature = "lookahead")]33use cumulus_client_consensus_aura::collators::lookahead::{34 run as run_aura, Params as BuildAuraConsensusParams,35};36use cumulus_client_consensus_common::ParachainBlockImport as TParachainBlockImport;37use cumulus_client_consensus_proposer::Proposer;38use cumulus_client_service::{39 build_relay_chain_interface, prepare_node_config, start_relay_chain_tasks, DARecoveryProfile,40 StartRelayChainTasksParams,41};42use cumulus_primitives_core::ParaId;43use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface};44use fc_mapping_sync::{kv::MappingSyncWorker, EthereumBlockNotificationSinks, SyncStrategy};45use fc_rpc::{46 frontier_backend_client::SystemAccountId32StorageOverride, EthBlockDataCacheTask, EthConfig,47 EthTask, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override, SchemaV2Override,48 SchemaV3Override, StorageOverride,49};50use fc_rpc_core::types::{FeeHistoryCache, FilterPool};51use fp_rpc::EthereumRuntimeRPCApi;52use fp_storage::EthereumStorageSchema;53use futures::{54 stream::select,55 task::{Context, Poll},56 Stream, StreamExt,57};58use jsonrpsee::RpcModule;59use polkadot_service::CollatorPair;60use sc_client_api::{AuxStore, Backend, BlockOf, BlockchainEvents, StorageProvider};61use sc_consensus::ImportQueue;62use sc_executor::{NativeElseWasmExecutor, NativeExecutionDispatch};63use sc_network::NetworkBlock;64use sc_network_sync::SyncingService;65use sc_rpc::SubscriptionTaskExecutor;66use sc_service::{Configuration, PartialComponents, TaskManager};67use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};68use serde::{Deserialize, Serialize};69use sp_api::{ProvideRuntimeApi, StateBackend};70use sp_block_builder::BlockBuilder;71use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};72use sp_consensus_aura::sr25519::AuthorityPair as AuraAuthorityPair;73use sp_keystore::KeystorePtr;74use sp_runtime::traits::BlakeTwo256;75use substrate_prometheus_endpoint::Registry;76use tokio::time::Interval;77use up_common::types::{opaque::*, Nonce};7879use crate::{80 chain_spec::RuntimeIdentification,81 rpc::{create_eth, create_full, EthDeps, FullDeps},82};8384/// Unique native executor instance.85#[cfg(feature = "unique-runtime")]86pub struct UniqueRuntimeExecutor;8788#[cfg(feature = "quartz-runtime")]89/// Quartz native executor instance.90pub struct QuartzRuntimeExecutor;9192/// Opal native executor instance.93pub struct OpalRuntimeExecutor;9495#[cfg(feature = "unique-runtime")]96impl NativeExecutionDispatch for UniqueRuntimeExecutor {97 /// Only enable the benchmarking host functions when we actually want to benchmark.98 #[cfg(feature = "runtime-benchmarks")]99 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;100 /// Otherwise we only use the default Substrate host functions.101 #[cfg(not(feature = "runtime-benchmarks"))]102 type ExtendHostFunctions = ();103104 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {105 unique_runtime::api::dispatch(method, data)106 }107108 fn native_version() -> sc_executor::NativeVersion {109 unique_runtime::native_version()110 }111}112113#[cfg(feature = "quartz-runtime")]114impl NativeExecutionDispatch for QuartzRuntimeExecutor {115 /// Only enable the benchmarking host functions when we actually want to benchmark.116 #[cfg(feature = "runtime-benchmarks")]117 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;118 /// Otherwise we only use the default Substrate host functions.119 #[cfg(not(feature = "runtime-benchmarks"))]120 type ExtendHostFunctions = ();121122 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {123 quartz_runtime::api::dispatch(method, data)124 }125126 fn native_version() -> sc_executor::NativeVersion {127 quartz_runtime::native_version()128 }129}130131impl NativeExecutionDispatch for OpalRuntimeExecutor {132 /// Only enable the benchmarking host functions when we actually want to benchmark.133 #[cfg(feature = "runtime-benchmarks")]134 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;135 /// Otherwise we only use the default Substrate host functions.136 #[cfg(not(feature = "runtime-benchmarks"))]137 type ExtendHostFunctions = ();138139 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {140 opal_runtime::api::dispatch(method, data)141 }142143 fn native_version() -> sc_executor::NativeVersion {144 opal_runtime::native_version()145 }146}147148pub struct AutosealInterval {149 interval: Interval,150}151152impl AutosealInterval {153 pub fn new(config: &Configuration, interval: u64) -> Self {154 let _tokio_runtime = config.tokio_handle.enter();155 let interval = tokio::time::interval(Duration::from_millis(interval));156157 Self { interval }158 }159}160161impl Stream for AutosealInterval {162 type Item = tokio::time::Instant;163164 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {165 self.interval.poll_tick(cx).map(Some)166 }167}168169pub fn open_frontier_backend<C: HeaderBackend<Block>>(170 client: Arc<C>,171 config: &Configuration,172) -> Result<Arc<fc_db::kv::Backend<Block>>, String> {173 let config_dir = config.base_path.config_dir(config.chain_spec.id());174 let database_dir = config_dir.join("frontier").join("db");175176 Ok(Arc::new(fc_db::kv::Backend::<Block>::new(177 client,178 &fc_db::kv::DatabaseSettings {179 source: fc_db::DatabaseSource::RocksDb {180 path: database_dir,181 cache_size: 0,182 },183 },184 )?))185}186187type FullClient<RuntimeApi, ExecutorDispatch> =188 sc_service::TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<ExecutorDispatch>>;189type FullBackend = sc_service::TFullBackend<Block>;190type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;191type ParachainBlockImport<RuntimeApi, ExecutorDispatch> =192 TParachainBlockImport<Block, Arc<FullClient<RuntimeApi, ExecutorDispatch>>, FullBackend>;193194/// Generate a supertrait based on bounds, and blanket impl for it.195macro_rules! ez_bounds {196 ($vis:vis trait $name:ident$(<$($gen:ident $(: $($(+)? $bound:path)*)?),* $(,)?>)? $(:)? $($(+)? $super:path)* {}) => {197 $vis trait $name $(<$($gen $(: $($bound+)*)?,)*>)?: $($super +)* {}198 impl<T, $($($gen $(: $($bound+)*)?,)*)?> $name$(<$($gen,)*>)? for T199 where T: $($super +)* {}200 }201}202ez_bounds!(203 pub trait RuntimeApiDep<Runtime: RuntimeInstance>:204 sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>205 + sp_consensus_aura::AuraApi<Block, AuraId>206 + fp_rpc::EthereumRuntimeRPCApi<Block>207 + sp_session::SessionKeys<Block>208 + sp_block_builder::BlockBuilder<Block>209 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>210 + sp_api::ApiExt<Block>211 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>212 + app_promotion_rpc::AppPromotionApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>213 + up_pov_estimate_rpc::PovEstimateApi<Block>214 + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>215 + sp_api::Metadata<Block>216 + sp_offchain::OffchainWorkerApi<Block>217 + cumulus_primitives_core::CollectCollationInfo<Block>218 // Deprecated, not used.219 + fp_rpc::ConvertTransactionRuntimeApi<Block>220 {221 }222);223#[cfg(not(feature = "lookahead"))]224ez_bounds!(225 pub trait LookaheadApiDep {}226);227#[cfg(feature = "lookahead")]228ez_bounds!(229 pub trait LookaheadApiDep: cumulus_primitives_aura::AuraUnincludedSegmentApi<Block> {}230);231232/// Starts a `ServiceBuilder` for a full service.233///234/// Use this macro if you don't actually need the full service, but just the builder in order to235/// be able to perform chain operations.236#[allow(clippy::type_complexity)]237pub fn new_partial<Runtime, RuntimeApi, ExecutorDispatch, BIQ>(238 config: &Configuration,239 build_import_queue: BIQ,240) -> Result<241 PartialComponents<242 FullClient<RuntimeApi, ExecutorDispatch>,243 FullBackend,244 FullSelectChain,245 sc_consensus::DefaultImportQueue<Block>,246 sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,247 OtherPartial,248 >,249 sc_service::Error,250>251where252 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,253 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>254 + Send255 + Sync256 + 'static,257 RuntimeApi::RuntimeApi: RuntimeApiDep<Runtime> + 'static,258 Runtime: RuntimeInstance,259 ExecutorDispatch: NativeExecutionDispatch + 'static,260 BIQ: FnOnce(261 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,262 Arc<FullBackend>,263 &Configuration,264 Option<TelemetryHandle>,265 &TaskManager,266 ) -> Result<sc_consensus::DefaultImportQueue<Block>, sc_service::Error>,267{268 let telemetry = config269 .telemetry_endpoints270 .clone()271 .filter(|x| !x.is_empty())272 .map(|endpoints| -> Result<_, sc_telemetry::Error> {273 let worker = TelemetryWorker::new(16)?;274 let telemetry = worker.handle().new_telemetry(endpoints);275 Ok((worker, telemetry))276 })277 .transpose()?;278279 let executor = sc_service::new_native_or_wasm_executor(config);280281 let (client, backend, keystore_container, task_manager) =282 sc_service::new_full_parts::<Block, RuntimeApi, _>(283 config,284 telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),285 executor,286 )?;287 let client = Arc::new(client);288289 let telemetry_worker_handle = telemetry.as_ref().map(|(worker, _)| worker.handle());290291 let telemetry = telemetry.map(|(worker, telemetry)| {292 task_manager293 .spawn_handle()294 .spawn("telemetry", None, worker.run());295 telemetry296 });297298 let select_chain = sc_consensus::LongestChain::new(backend.clone());299300 let transaction_pool = sc_transaction_pool::BasicPool::new_full(301 config.transaction_pool.clone(),302 config.role.is_authority().into(),303 config.prometheus_registry(),304 task_manager.spawn_essential_handle(),305 client.clone(),306 );307308 let eth_filter_pool: Option<FilterPool> = Some(Arc::new(Mutex::new(BTreeMap::new())));309310 let eth_backend = open_frontier_backend(client.clone(), config)?;311312 let import_queue = build_import_queue(313 client.clone(),314 backend.clone(),315 config,316 telemetry.as_ref().map(|telemetry| telemetry.handle()),317 &task_manager,318 )?;319320 let params = PartialComponents {321 backend,322 client,323 import_queue,324 keystore_container,325 task_manager,326 transaction_pool,327 select_chain,328 other: OtherPartial {329 telemetry,330 eth_filter_pool,331 eth_backend,332 telemetry_worker_handle,333 },334 };335336 Ok(params)337}338339macro_rules! clone {340 ($($i:ident),* $(,)?) => {341 $(342 let $i = $i.clone();343 )*344 };345}346347/// Start a node with the given parachain `Configuration` and relay chain `Configuration`.348///349/// This is the actual implementation that is abstract over the executor and the runtime api.350#[sc_tracing::logging::prefix_logs_with("Parachain")]351pub async fn start_node<Runtime, RuntimeApi, ExecutorDispatch>(352 parachain_config: Configuration,353 polkadot_config: Configuration,354 collator_options: CollatorOptions,355 para_id: ParaId,356 hwbench: Option<sc_sysinfo::HwBench>,357) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>358where359 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,360 Runtime: RuntimeInstance + Send + Sync + 'static,361 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,362 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,363 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>364 + Send365 + Sync366 + 'static,367 RuntimeApi::RuntimeApi: RuntimeApiDep<Runtime> + 'static,368 RuntimeApi::RuntimeApi: LookaheadApiDep,369 Runtime: RuntimeInstance,370 ExecutorDispatch: NativeExecutionDispatch + 'static,371{372 let parachain_config = prepare_node_config(parachain_config);373374 let params = new_partial::<Runtime, RuntimeApi, ExecutorDispatch, _>(375 ¶chain_config,376 parachain_build_import_queue,377 )?;378 let OtherPartial {379 mut telemetry,380 telemetry_worker_handle,381 eth_filter_pool,382 eth_backend,383 } = params.other;384 let net_config = sc_network::config::FullNetworkConfiguration::new(¶chain_config.network);385386 let client = params.client.clone();387 let backend = params.backend.clone();388 let mut task_manager = params.task_manager;389390 let (relay_chain_interface, collator_key) = build_relay_chain_interface(391 polkadot_config,392 ¶chain_config,393 telemetry_worker_handle,394 &mut task_manager,395 collator_options.clone(),396 hwbench.clone(),397 )398 .await399 .map_err(|e| sc_service::Error::Application(Box::new(e) as Box<_>))?;400401 // Aura is sybil-resistant, collator-selection is generally too.402 let block_announce_validator =403 cumulus_client_network::AssumeSybilResistance::allow_seconded_messages();404405 let validator = parachain_config.role.is_authority();406 let prometheus_registry = parachain_config.prometheus_registry().cloned();407 let transaction_pool = params.transaction_pool.clone();408 let import_queue_service = params.import_queue.service();409410 let (network, system_rpc_tx, tx_handler_controller, start_network, sync_service) =411 sc_service::build_network(sc_service::BuildNetworkParams {412 config: ¶chain_config,413 net_config,414 client: client.clone(),415 transaction_pool: transaction_pool.clone(),416 spawn_handle: task_manager.spawn_handle(),417 import_queue: params.import_queue,418 block_announce_validator_builder: Some(Box::new(|_| {419 Box::new(block_announce_validator)420 })),421 warp_sync_params: None,422 })?;423424 let select_chain = params.select_chain.clone();425426 let runtime_id = parachain_config.chain_spec.runtime_id();427428 // Frontier429 let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new()));430 let fee_history_limit = 2048;431432 let eth_pubsub_notification_sinks: Arc<433 EthereumBlockNotificationSinks<fc_mapping_sync::EthereumBlockNotification<Block>>,434 > = Default::default();435436 let overrides = overrides_handle(client.clone());437 let eth_block_data_cache = spawn_frontier_tasks(438 FrontierTaskParams {439 client: client.clone(),440 substrate_backend: backend.clone(),441 eth_filter_pool: eth_filter_pool.clone(),442 eth_backend: eth_backend.clone(),443 fee_history_limit,444 fee_history_cache: fee_history_cache.clone(),445 task_manager: &task_manager,446 prometheus_registry: prometheus_registry.clone(),447 overrides: overrides.clone(),448 sync_strategy: SyncStrategy::Parachain,449 },450 sync_service.clone(),451 eth_pubsub_notification_sinks.clone(),452 );453454 // Rpc455 let rpc_builder = Box::new({456 clone!(457 client,458 backend,459 eth_backend,460 eth_pubsub_notification_sinks,461 fee_history_cache,462 eth_block_data_cache,463 overrides,464 transaction_pool,465 network,466 sync_service,467 );468 move |deny_unsafe, subscription_task_executor: SubscriptionTaskExecutor| {469 clone!(470 backend,471 eth_block_data_cache,472 client,473 eth_backend,474 eth_filter_pool,475 eth_pubsub_notification_sinks,476 fee_history_cache,477 eth_block_data_cache,478 network,479 runtime_id,480 transaction_pool,481 select_chain,482 overrides,483 );484485 #[cfg(not(feature = "pov-estimate"))]486 let _ = backend;487488 let mut rpc_handle = RpcModule::new(());489490 let full_deps = FullDeps {491 client: client.clone(),492 runtime_id,493494 #[cfg(feature = "pov-estimate")]495 exec_params: uc_rpc::pov_estimate::ExecutorParams {496 wasm_method: parachain_config.wasm_method,497 default_heap_pages: parachain_config.default_heap_pages,498 max_runtime_instances: parachain_config.max_runtime_instances,499 runtime_cache_size: parachain_config.runtime_cache_size,500 },501502 #[cfg(feature = "pov-estimate")]503 backend,504505 deny_unsafe,506 pool: transaction_pool.clone(),507 select_chain,508 };509510 create_full::<_, _, _, Runtime, _>(&mut rpc_handle, full_deps)?;511512 let eth_deps = EthDeps {513 client,514 graph: transaction_pool.pool().clone(),515 pool: transaction_pool,516 is_authority: validator,517 network,518 eth_backend,519 // TODO: Unhardcode520 max_past_logs: 10000,521 fee_history_limit,522 fee_history_cache,523 eth_block_data_cache,524 // TODO: Unhardcode525 enable_dev_signer: false,526 eth_filter_pool,527 eth_pubsub_notification_sinks,528 overrides,529 sync: sync_service.clone(),530 pending_create_inherent_data_providers: |_, ()| async move { Ok(()) },531 };532533 create_eth::<534 _,535 _,536 _,537 _,538 _,539 _,540 DefaultEthConfig<FullClient<RuntimeApi, ExecutorDispatch>>,541 >(542 &mut rpc_handle,543 eth_deps,544 subscription_task_executor.clone(),545 )?;546547 Ok(rpc_handle)548 }549 });550551 sc_service::spawn_tasks(sc_service::SpawnTasksParams {552 rpc_builder,553 client: client.clone(),554 transaction_pool: transaction_pool.clone(),555 task_manager: &mut task_manager,556 config: parachain_config,557 keystore: params.keystore_container.keystore(),558 backend: backend.clone(),559 network,560 sync_service: sync_service.clone(),561 system_rpc_tx,562 telemetry: telemetry.as_mut(),563 tx_handler_controller,564 })?;565566 if let Some(hwbench) = hwbench {567 sc_sysinfo::print_hwbench(&hwbench);568569 if let Some(ref mut telemetry) = telemetry {570 let telemetry_handle = telemetry.handle();571 task_manager.spawn_handle().spawn(572 "telemetry_hwbench",573 None,574 sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench),575 );576 }577 }578579 let announce_block = {580 let sync_service = sync_service.clone();581 Arc::new(Box::new(move |hash, data| {582 sync_service.announce_block(hash, data)583 }))584 };585586 let relay_chain_slot_duration = Duration::from_secs(6);587588 let overseer_handle = relay_chain_interface589 .overseer_handle()590 .map_err(|e| sc_service::Error::Application(Box::new(e)))?;591592 start_relay_chain_tasks(StartRelayChainTasksParams {593 client: client.clone(),594 announce_block: announce_block.clone(),595 para_id,596 relay_chain_interface: relay_chain_interface.clone(),597 task_manager: &mut task_manager,598 da_recovery_profile: if validator {599 DARecoveryProfile::Collator600 } else {601 DARecoveryProfile::FullNode602 },603 import_queue: import_queue_service,604 relay_chain_slot_duration,605 recovery_handle: Box::new(overseer_handle.clone()),606 sync_service: sync_service.clone(),607 })?;608609 if validator {610 start_consensus(611 client.clone(),612 transaction_pool,613 StartConsensusParameters {614 backend: backend.clone(),615 prometheus_registry: prometheus_registry.as_ref(),616 telemetry: telemetry.as_ref().map(|t| t.handle()),617 task_manager: &task_manager,618 relay_chain_interface: relay_chain_interface.clone(),619 sync_oracle: sync_service,620 keystore: params.keystore_container.keystore(),621 overseer_handle,622 relay_chain_slot_duration,623 para_id,624 collator_key: collator_key.expect("cli args do not allow this"),625 announce_block,626 },627 )?;628 }629630 start_network.start_network();631632 Ok((task_manager, client))633}634635/// Build the import queue for the the parachain runtime.636pub fn parachain_build_import_queue<Runtime, RuntimeApi, ExecutorDispatch>(637 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,638 backend: Arc<FullBackend>,639 config: &Configuration,640 telemetry: Option<TelemetryHandle>,641 task_manager: &TaskManager,642) -> Result<sc_consensus::DefaultImportQueue<Block>, sc_service::Error>643where644 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>645 + Send646 + Sync647 + 'static,648 RuntimeApi::RuntimeApi: RuntimeApiDep<Runtime> + 'static,649 Runtime: RuntimeInstance,650 ExecutorDispatch: NativeExecutionDispatch + 'static,651{652 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;653654 let block_import = ParachainBlockImport::new(client.clone(), backend);655656 cumulus_client_consensus_aura::import_queue::<657 sp_consensus_aura::sr25519::AuthorityPair,658 _,659 _,660 _,661 _,662 _,663 >(cumulus_client_consensus_aura::ImportQueueParams {664 block_import,665 client,666 create_inherent_data_providers: move |_, _| async move {667 let time = sp_timestamp::InherentDataProvider::from_system_time();668669 let slot =670 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(671 *time,672 slot_duration,673 );674675 Ok((slot, time))676 },677 registry: config.prometheus_registry(),678 spawner: &task_manager.spawn_essential_handle(),679 telemetry,680 })681 .map_err(Into::into)682}683684pub struct StartConsensusParameters<'a> {685 backend: Arc<FullBackend>,686 prometheus_registry: Option<&'a Registry>,687 telemetry: Option<TelemetryHandle>,688 task_manager: &'a TaskManager,689 relay_chain_interface: Arc<dyn RelayChainInterface>,690 sync_oracle: Arc<SyncingService<Block>>,691 keystore: KeystorePtr,692 overseer_handle: OverseerHandle,693 relay_chain_slot_duration: Duration,694 para_id: ParaId,695 collator_key: CollatorPair,696 announce_block: Arc<dyn Fn(Hash, Option<Vec<u8>>) + Send + Sync>,697}698699// Clones ignored for optional lookahead collator700#[allow(clippy::redundant_clone)]701pub fn start_consensus<ExecutorDispatch, RuntimeApi, Runtime>(702 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,703 transaction_pool: Arc<704 sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,705 >,706 parameters: StartConsensusParameters<'_>,707) -> Result<(), sc_service::Error>708where709 ExecutorDispatch: NativeExecutionDispatch + 'static,710 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>711 + Send712 + Sync713 + 'static,714 RuntimeApi::RuntimeApi: RuntimeApiDep<Runtime> + 'static,715 RuntimeApi::RuntimeApi: LookaheadApiDep,716 Runtime: RuntimeInstance,717{718 let StartConsensusParameters {719 backend,720 prometheus_registry,721 telemetry,722 task_manager,723 relay_chain_interface,724 sync_oracle,725 keystore,726 overseer_handle,727 relay_chain_slot_duration,728 para_id,729 collator_key,730 announce_block,731 } = parameters;732 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;733734 let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(735 task_manager.spawn_handle(),736 client.clone(),737 transaction_pool,738 prometheus_registry,739 telemetry,740 );741 let proposer = Proposer::new(proposer_factory);742743 let collator_service = CollatorService::new(744 client.clone(),745 Arc::new(task_manager.spawn_handle()),746 announce_block,747 client.clone(),748 );749750 let block_import = ParachainBlockImport::new(client.clone(), backend.clone());751752 let params = BuildAuraConsensusParams {753 create_inherent_data_providers: move |_, ()| async move { Ok(()) },754 block_import,755 para_client: client.clone(),756 #[cfg(feature = "lookahead")]757 para_backend: backend,758 para_id,759 relay_client: relay_chain_interface,760 sync_oracle,761 keystore,762 slot_duration,763 proposer,764 collator_service,765 // With async-baking, we allowed to be both slower (longer authoring) and faster (multiple para blocks per relay block)766 #[cfg(not(feature = "lookahead"))]767 authoring_duration: Duration::from_millis(500),768 #[cfg(feature = "lookahead")]769 authoring_duration: Duration::from_millis(1500),770 overseer_handle,771 #[cfg(feature = "lookahead")]772 code_hash_provider: move |block_hash| {773 client774 .code_at(block_hash)775 .ok()776 .map(cumulus_primitives_core::relay_chain::ValidationCode)777 .map(|c| c.hash())778 },779 collator_key,780 relay_chain_slot_duration,781 };782783 task_manager.spawn_essential_handle().spawn(784 "aura",785 None,786 #[cfg(not(feature = "lookahead"))]787 run_aura::<_, AuraAuthorityPair, _, _, _, _, _, _, _>(params),788 #[cfg(feature = "lookahead")]789 run_aura::<_, AuraAuthorityPair, _, _, _, _, _, _, _, _, _>(params),790 );791 Ok(())792}793794fn dev_build_import_queue<RuntimeApi, ExecutorDispatch>(795 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,796 _: Arc<FullBackend>,797 config: &Configuration,798 _: Option<TelemetryHandle>,799 task_manager: &TaskManager,800) -> Result<sc_consensus::DefaultImportQueue<Block>, sc_service::Error>801where802 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>803 + Send804 + Sync805 + 'static,806 RuntimeApi::RuntimeApi:807 sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> + sp_api::ApiExt<Block>,808 ExecutorDispatch: NativeExecutionDispatch + 'static,809{810 Ok(sc_consensus_manual_seal::import_queue(811 Box::new(client),812 &task_manager.spawn_essential_handle(),813 config.prometheus_registry(),814 ))815}816817pub struct OtherPartial {818 pub telemetry: Option<Telemetry>,819 pub telemetry_worker_handle: Option<TelemetryWorkerHandle>,820 pub eth_filter_pool: Option<FilterPool>,821 pub eth_backend: Arc<fc_db::kv::Backend<Block>>,822}823824struct DefaultEthConfig<C>(PhantomData<C>);825impl<C> EthConfig<Block, C> for DefaultEthConfig<C>826where827 C: StorageProvider<Block, FullBackend> + Sync + Send + 'static,828{829 type EstimateGasAdapter = ();830 type RuntimeStorageOverride = SystemAccountId32StorageOverride<Block, C, FullBackend>;831}832833/// Builds a new development service. This service uses instant seal, and mocks834/// the parachain inherent835pub fn start_dev_node<Runtime, RuntimeApi, ExecutorDispatch>(836 config: Configuration,837 autoseal_interval: u64,838 autoseal_finalize_delay: Option<u64>,839 disable_autoseal_on_tx: bool,840) -> sc_service::error::Result<TaskManager>841where842 Runtime: RuntimeInstance + Send + Sync + 'static,843 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,844 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,845 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>846 + Send847 + Sync848 + 'static,849 RuntimeApi::RuntimeApi: RuntimeApiDep<Runtime> + 'static,850 ExecutorDispatch: NativeExecutionDispatch + 'static,851{852 use fc_consensus::FrontierBlockImport;853 use sc_consensus_manual_seal::{854 run_delayed_finalize, run_manual_seal, DelayedFinalizeParams, EngineCommand,855 ManualSealParams,856 };857858 let sc_service::PartialComponents {859 client,860 backend,861 mut task_manager,862 import_queue,863 keystore_container,864 select_chain: maybe_select_chain,865 transaction_pool,866 other:867 OtherPartial {868 telemetry,869 eth_filter_pool,870 eth_backend,871 telemetry_worker_handle: _,872 },873 } = new_partial::<Runtime, RuntimeApi, ExecutorDispatch, _>(874 &config,875 dev_build_import_queue::<RuntimeApi, ExecutorDispatch>,876 )?;877 let net_config = sc_network::config::FullNetworkConfiguration::new(&config.network);878 let prometheus_registry = config.prometheus_registry().cloned();879880 let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) =881 sc_service::build_network(sc_service::BuildNetworkParams {882 config: &config,883 net_config,884 client: client.clone(),885 transaction_pool: transaction_pool.clone(),886 spawn_handle: task_manager.spawn_handle(),887 import_queue,888 block_announce_validator_builder: None,889 warp_sync_params: None,890 })?;891892 let collator = config.role.is_authority();893894 let select_chain = maybe_select_chain;895896 if collator {897 let block_import = FrontierBlockImport::new(client.clone(), client.clone());898899 let env = sc_basic_authorship::ProposerFactory::new(900 task_manager.spawn_handle(),901 client.clone(),902 transaction_pool.clone(),903 prometheus_registry.as_ref(),904 telemetry.as_ref().map(|x| x.handle()),905 );906907 let transactions_commands_stream: Box<908 dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin,909 > = Box::new(910 transaction_pool911 .pool()912 .validated_pool()913 .import_notification_stream()914 .filter(move |_| futures::future::ready(!disable_autoseal_on_tx))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));924925 let idle_commands_stream: Box<926 dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin,927 > = Box::new(autoseal_interval.map(|_| EngineCommand::SealNewBlock {928 create_empty: true,929 finalize: false,930 parent_hash: None,931 sender: None,932 }));933934 let commands_stream = select(transactions_commands_stream, idle_commands_stream);935936 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;937 let client_set_aside_for_cidp = client.clone();938939 if let Some(delay_sec) = autoseal_finalize_delay {940 let spawn_handle = task_manager.spawn_handle();941942 task_manager.spawn_essential_handle().spawn_blocking(943 "finalization_task",944 Some("block-authoring"),945 run_delayed_finalize(DelayedFinalizeParams {946 client: client.clone(),947 delay_sec,948 spawn_handle,949 }),950 );951 }952953 task_manager.spawn_essential_handle().spawn_blocking(954 "authorship_task",955 Some("block-authoring"),956 run_manual_seal(ManualSealParams {957 block_import,958 env,959 client: client.clone(),960 pool: transaction_pool.clone(),961 commands_stream,962 select_chain: select_chain.clone(),963 consensus_data_provider: None,964 create_inherent_data_providers: move |block: Hash, ()| {965 let current_para_block = client_set_aside_for_cidp966 .number(block)967 .expect("Header lookup should succeed")968 .expect("Header passed in as parent should be present in backend.");969970 let client_for_xcm = client_set_aside_for_cidp.clone();971 async move {972 let time = sp_timestamp::InherentDataProvider::from_system_time();973974 let mocked_parachain = cumulus_primitives_parachain_inherent::MockValidationDataInherentDataProvider {975 current_para_block,976 relay_offset: 1000,977 relay_blocks_per_para_block: 2,978 para_blocks_per_relay_epoch: 0,979 xcm_config: cumulus_primitives_parachain_inherent::MockXcmConfig::new(980 &*client_for_xcm,981 block,982 Default::default(),983 Default::default(),984 ),985 relay_randomness_config: (),986 raw_downward_messages: vec![],987 raw_horizontal_messages: vec![],988 };989990 let slot =991 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(992 *time,993 slot_duration,994 );995996 Ok((time, slot, mocked_parachain))997 }998 },999 }),1000 );1001 }10021003 #[cfg(feature = "pov-estimate")]1004 let rpc_backend = backend.clone();10051006 let runtime_id = config.chain_spec.runtime_id();10071008 // Frontier1009 let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new()));1010 let fee_history_limit = 2048;10111012 let eth_pubsub_notification_sinks: Arc<1013 EthereumBlockNotificationSinks<fc_mapping_sync::EthereumBlockNotification<Block>>,1014 > = Default::default();10151016 let overrides = overrides_handle(client.clone());1017 let eth_block_data_cache = spawn_frontier_tasks(1018 FrontierTaskParams {1019 client: client.clone(),1020 substrate_backend: backend.clone(),1021 eth_filter_pool: eth_filter_pool.clone(),1022 eth_backend: eth_backend.clone(),1023 fee_history_limit,1024 fee_history_cache: fee_history_cache.clone(),1025 task_manager: &task_manager,1026 prometheus_registry,1027 overrides: overrides.clone(),1028 sync_strategy: SyncStrategy::Normal,1029 },1030 sync_service.clone(),1031 eth_pubsub_notification_sinks.clone(),1032 );10331034 // Rpc1035 let rpc_builder = Box::new({1036 clone!(1037 client,1038 backend,1039 eth_backend,1040 eth_pubsub_notification_sinks,1041 fee_history_cache,1042 eth_block_data_cache,1043 overrides,1044 transaction_pool,1045 network,1046 sync_service,1047 );1048 move |deny_unsafe, subscription_task_executor: SubscriptionTaskExecutor| {1049 clone!(1050 backend,1051 eth_block_data_cache,1052 client,1053 eth_backend,1054 eth_filter_pool,1055 eth_pubsub_notification_sinks,1056 fee_history_cache,1057 eth_block_data_cache,1058 network,1059 runtime_id,1060 transaction_pool,1061 select_chain,1062 overrides,1063 );10641065 #[cfg(not(feature = "pov-estimate"))]1066 let _ = backend;10671068 let mut rpc_module = RpcModule::new(());10691070 let full_deps = FullDeps {1071 runtime_id,10721073 #[cfg(feature = "pov-estimate")]1074 exec_params: uc_rpc::pov_estimate::ExecutorParams {1075 wasm_method: config.wasm_method,1076 default_heap_pages: config.default_heap_pages,1077 max_runtime_instances: config.max_runtime_instances,1078 runtime_cache_size: config.runtime_cache_size,1079 },10801081 #[cfg(feature = "pov-estimate")]1082 backend,1083 // eth_backend,1084 deny_unsafe,1085 client: client.clone(),1086 pool: transaction_pool.clone(),1087 select_chain,1088 };10891090 create_full::<_, _, _, Runtime, _>(&mut rpc_module, full_deps)?;10911092 let eth_deps = EthDeps {1093 client,1094 graph: transaction_pool.pool().clone(),1095 pool: transaction_pool,1096 is_authority: true,1097 network,1098 eth_backend,1099 // TODO: Unhardcode1100 max_past_logs: 10000,1101 fee_history_limit,1102 fee_history_cache,1103 eth_block_data_cache,1104 // TODO: Unhardcode1105 enable_dev_signer: false,1106 eth_filter_pool,1107 eth_pubsub_notification_sinks,1108 overrides,1109 sync: sync_service.clone(),1110 // We don't have any inherents except parachain built-ins, which we can't even extract from inside `run_aura`.1111 pending_create_inherent_data_providers: |_, ()| async move { Ok(()) },1112 };11131114 create_eth::<1115 _,1116 _,1117 _,1118 _,1119 _,1120 _,1121 DefaultEthConfig<FullClient<RuntimeApi, ExecutorDispatch>>,1122 >(1123 &mut rpc_module,1124 eth_deps,1125 subscription_task_executor.clone(),1126 )?;11271128 Ok(rpc_module)1129 }1130 });11311132 sc_service::spawn_tasks(sc_service::SpawnTasksParams {1133 network,1134 sync_service,1135 client,1136 keystore: keystore_container.keystore(),1137 task_manager: &mut task_manager,1138 transaction_pool,1139 rpc_builder,1140 backend,1141 system_rpc_tx,1142 config,1143 telemetry: None,1144 tx_handler_controller,1145 })?;11461147 network_starter.start_network();1148 Ok(task_manager)1149}11501151fn overrides_handle<C, BE>(client: Arc<C>) -> Arc<OverrideHandle<Block>>1152where1153 C: ProvideRuntimeApi<Block> + StorageProvider<Block, BE> + AuxStore,1154 C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError>,1155 C: Send + Sync + 'static,1156 C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,1157 BE: Backend<Block> + 'static,1158 BE::State: StateBackend<BlakeTwo256>,1159{1160 let mut overrides_map = BTreeMap::new();1161 overrides_map.insert(1162 EthereumStorageSchema::V1,1163 Box::new(SchemaV1Override::new(client.clone())) as Box<dyn StorageOverride<_> + 'static>,1164 );1165 overrides_map.insert(1166 EthereumStorageSchema::V2,1167 Box::new(SchemaV2Override::new(client.clone())) as Box<dyn StorageOverride<_> + 'static>,1168 );1169 overrides_map.insert(1170 EthereumStorageSchema::V3,1171 Box::new(SchemaV3Override::new(client.clone())) as Box<dyn StorageOverride<_> + 'static>,1172 );11731174 Arc::new(OverrideHandle {1175 schemas: overrides_map,1176 fallback: Box::new(RuntimeApiStorageOverride::new(client)),1177 })1178}11791180pub struct FrontierTaskParams<'a, C, B> {1181 pub task_manager: &'a TaskManager,1182 pub client: Arc<C>,1183 pub substrate_backend: Arc<B>,1184 pub eth_backend: Arc<fc_db::kv::Backend<Block>>,1185 pub eth_filter_pool: Option<FilterPool>,1186 pub overrides: Arc<OverrideHandle<Block>>,1187 pub fee_history_limit: u64,1188 pub fee_history_cache: FeeHistoryCache,1189 pub sync_strategy: SyncStrategy,1190 pub prometheus_registry: Option<Registry>,1191}11921193pub fn spawn_frontier_tasks<C, B>(1194 params: FrontierTaskParams<C, B>,1195 sync: Arc<SyncingService<Block>>,1196 pubsub_notification_sinks: Arc<1197 EthereumBlockNotificationSinks<fc_mapping_sync::EthereumBlockNotification<Block>>,1198 >,1199) -> Arc<EthBlockDataCacheTask<Block>>1200where1201 C: ProvideRuntimeApi<Block> + BlockOf,1202 C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,1203 C: BlockchainEvents<Block> + StorageProvider<Block, B>,1204 C: Send + Sync + 'static,1205 C::Api: EthereumRuntimeRPCApi<Block>,1206 C::Api: BlockBuilder<Block>,1207 B: Backend<Block> + 'static,1208 B::State: StateBackend<BlakeTwo256>,1209{1210 let FrontierTaskParams {1211 task_manager,1212 client,1213 substrate_backend,1214 eth_backend,1215 eth_filter_pool,1216 overrides,1217 fee_history_limit,1218 fee_history_cache,1219 sync_strategy,1220 prometheus_registry,1221 } = params;1222 // Frontier offchain DB task. Essential.1223 // Maps emulated ethereum data to substrate native data.1224 params.task_manager.spawn_essential_handle().spawn(1225 "frontier-mapping-sync-worker",1226 Some("frontier"),1227 MappingSyncWorker::new(1228 client.import_notification_stream(),1229 Duration::new(6, 0),1230 client.clone(),1231 substrate_backend,1232 overrides.clone(),1233 eth_backend,1234 3,1235 0,1236 sync_strategy,1237 sync,1238 pubsub_notification_sinks,1239 )1240 .for_each(|()| futures::future::ready(())),1241 );12421243 // Frontier `EthFilterApi` maintenance.1244 // Manages the pool of user-created Filters.1245 if let Some(eth_filter_pool) = eth_filter_pool {1246 // Each filter is allowed to stay in the pool for 100 blocks.1247 const FILTER_RETAIN_THRESHOLD: u64 = 100;1248 params.task_manager.spawn_essential_handle().spawn(1249 "frontier-filter-pool",1250 Some("frontier"),1251 EthTask::filter_pool_task(client.clone(), eth_filter_pool, FILTER_RETAIN_THRESHOLD),1252 );1253 }12541255 // Spawn Frontier FeeHistory cache maintenance task.1256 params.task_manager.spawn_essential_handle().spawn(1257 "frontier-fee-history",1258 Some("frontier"),1259 EthTask::fee_history_task(1260 client,1261 overrides.clone(),1262 fee_history_cache,1263 fee_history_limit,1264 ),1265 );12661267 Arc::new(EthBlockDataCacheTask::new(1268 task_manager.spawn_handle(),1269 overrides,1270 50,1271 50,1272 prometheus_registry,1273 ))1274}1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// std18use std::{19 collections::BTreeMap,20 marker::PhantomData,21 pin::Pin,22 sync::{Arc, Mutex},23 time::Duration,24};2526use cumulus_client_cli::CollatorOptions;27use cumulus_client_collator::service::CollatorService;28#[cfg(not(feature = "lookahead"))]29use cumulus_client_consensus_aura::collators::basic::{30 run as run_aura, Params as BuildAuraConsensusParams,31};32#[cfg(feature = "lookahead")]33use cumulus_client_consensus_aura::collators::lookahead::{34 run as run_aura, Params as BuildAuraConsensusParams,35};36use cumulus_client_consensus_common::ParachainBlockImport as TParachainBlockImport;37use cumulus_client_consensus_proposer::Proposer;38use cumulus_client_service::{39 build_relay_chain_interface, prepare_node_config, start_relay_chain_tasks, DARecoveryProfile,40 StartRelayChainTasksParams,41};42use cumulus_primitives_core::ParaId;43use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface};44use fc_mapping_sync::{kv::MappingSyncWorker, EthereumBlockNotificationSinks, SyncStrategy};45use fc_rpc::{46 frontier_backend_client::SystemAccountId32StorageOverride, EthBlockDataCacheTask, EthConfig,47 EthTask, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override, SchemaV2Override,48 SchemaV3Override, StorageOverride,49};50use fc_rpc_core::types::{FeeHistoryCache, FilterPool};51use fp_rpc::EthereumRuntimeRPCApi;52use fp_storage::EthereumStorageSchema;53use futures::{54 stream::select,55 task::{Context, Poll},56 Stream, StreamExt,57};58use jsonrpsee::RpcModule;59use polkadot_service::CollatorPair;60use sc_client_api::{AuxStore, Backend, BlockOf, BlockchainEvents, StorageProvider};61use sc_consensus::ImportQueue;62use sc_executor::{NativeElseWasmExecutor, NativeExecutionDispatch};63use sc_network::NetworkBlock;64use sc_network_sync::SyncingService;65use sc_rpc::SubscriptionTaskExecutor;66use sc_service::{Configuration, PartialComponents, TaskManager};67use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};68use serde::{Deserialize, Serialize};69use sp_api::{ProvideRuntimeApi, StateBackend};70use sp_block_builder::BlockBuilder;71use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};72use sp_consensus_aura::sr25519::AuthorityPair as AuraAuthorityPair;73use sp_keystore::KeystorePtr;74use sp_runtime::traits::BlakeTwo256;75use substrate_prometheus_endpoint::Registry;76use tokio::time::Interval;77use up_common::types::{opaque::*, Nonce};7879use crate::{80 chain_spec::RuntimeIdentification,81 rpc::{create_eth, create_full, EthDeps, FullDeps},82};8384/// Unique native executor instance.85#[cfg(feature = "unique-runtime")]86pub struct UniqueRuntimeExecutor;8788#[cfg(feature = "quartz-runtime")]89/// Quartz native executor instance.90pub struct QuartzRuntimeExecutor;9192/// Opal native executor instance.93pub struct OpalRuntimeExecutor;9495#[cfg(feature = "unique-runtime")]96impl NativeExecutionDispatch for UniqueRuntimeExecutor {97 /// Only enable the benchmarking host functions when we actually want to benchmark.98 #[cfg(feature = "runtime-benchmarks")]99 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;100 /// Otherwise we only use the default Substrate host functions.101 #[cfg(not(feature = "runtime-benchmarks"))]102 type ExtendHostFunctions = ();103104 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {105 unique_runtime::api::dispatch(method, data)106 }107108 fn native_version() -> sc_executor::NativeVersion {109 unique_runtime::native_version()110 }111}112113#[cfg(feature = "quartz-runtime")]114impl NativeExecutionDispatch for QuartzRuntimeExecutor {115 /// Only enable the benchmarking host functions when we actually want to benchmark.116 #[cfg(feature = "runtime-benchmarks")]117 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;118 /// Otherwise we only use the default Substrate host functions.119 #[cfg(not(feature = "runtime-benchmarks"))]120 type ExtendHostFunctions = ();121122 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {123 quartz_runtime::api::dispatch(method, data)124 }125126 fn native_version() -> sc_executor::NativeVersion {127 quartz_runtime::native_version()128 }129}130131impl NativeExecutionDispatch for OpalRuntimeExecutor {132 /// Only enable the benchmarking host functions when we actually want to benchmark.133 #[cfg(feature = "runtime-benchmarks")]134 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;135 /// Otherwise we only use the default Substrate host functions.136 #[cfg(not(feature = "runtime-benchmarks"))]137 type ExtendHostFunctions = ();138139 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {140 opal_runtime::api::dispatch(method, data)141 }142143 fn native_version() -> sc_executor::NativeVersion {144 opal_runtime::native_version()145 }146}147148pub struct AutosealInterval {149 interval: Interval,150}151152impl AutosealInterval {153 pub fn new(config: &Configuration, interval: u64) -> Self {154 let _tokio_runtime = config.tokio_handle.enter();155 let interval = tokio::time::interval(Duration::from_millis(interval));156157 Self { interval }158 }159}160161impl Stream for AutosealInterval {162 type Item = tokio::time::Instant;163164 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {165 self.interval.poll_tick(cx).map(Some)166 }167}168169pub fn open_frontier_backend<C: HeaderBackend<Block>>(170 client: Arc<C>,171 config: &Configuration,172) -> Result<Arc<fc_db::kv::Backend<Block>>, String> {173 let config_dir = config.base_path.config_dir(config.chain_spec.id());174 let database_dir = config_dir.join("frontier").join("db");175176 Ok(Arc::new(fc_db::kv::Backend::<Block>::new(177 client,178 &fc_db::kv::DatabaseSettings {179 source: fc_db::DatabaseSource::RocksDb {180 path: database_dir,181 cache_size: 0,182 },183 },184 )?))185}186187type FullClient<RuntimeApi, ExecutorDispatch> =188 sc_service::TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<ExecutorDispatch>>;189type FullBackend = sc_service::TFullBackend<Block>;190type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;191type ParachainBlockImport<RuntimeApi, ExecutorDispatch> =192 TParachainBlockImport<Block, Arc<FullClient<RuntimeApi, ExecutorDispatch>>, FullBackend>;193194/// Generate a supertrait based on bounds, and blanket impl for it.195macro_rules! ez_bounds {196 ($vis:vis trait $name:ident$(<$($gen:ident $(: $($(+)? $bound:path)*)?),* $(,)?>)? $(:)? $($(+)? $super:path)* {}) => {197 $vis trait $name $(<$($gen $(: $($bound+)*)?,)*>)?: $($super +)* {}198 impl<T, $($($gen $(: $($bound+)*)?,)*)?> $name$(<$($gen,)*>)? for T199 where T: $($super +)* {}200 }201}202ez_bounds!(203 pub trait RuntimeApiDep<Runtime: RuntimeInstance>:204 sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>205 + sp_consensus_aura::AuraApi<Block, AuraId>206 + fp_rpc::EthereumRuntimeRPCApi<Block>207 + sp_session::SessionKeys<Block>208 + sp_block_builder::BlockBuilder<Block>209 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>210 + sp_api::ApiExt<Block>211 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>212 + app_promotion_rpc::AppPromotionApi<Block, BlockNumber, Runtime::CrossAccountId, AccountId>213 + up_pov_estimate_rpc::PovEstimateApi<Block>214 + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>215 + sp_api::Metadata<Block>216 + sp_offchain::OffchainWorkerApi<Block>217 + cumulus_primitives_core::CollectCollationInfo<Block>218 // Deprecated, not used.219 + fp_rpc::ConvertTransactionRuntimeApi<Block>220 {221 }222);223#[cfg(not(feature = "lookahead"))]224ez_bounds!(225 pub trait LookaheadApiDep {}226);227#[cfg(feature = "lookahead")]228ez_bounds!(229 pub trait LookaheadApiDep: cumulus_primitives_aura::AuraUnincludedSegmentApi<Block> {}230);231232/// Starts a `ServiceBuilder` for a full service.233///234/// Use this macro if you don't actually need the full service, but just the builder in order to235/// be able to perform chain operations.236#[allow(clippy::type_complexity)]237pub fn new_partial<Runtime, RuntimeApi, ExecutorDispatch, BIQ>(238 config: &Configuration,239 build_import_queue: BIQ,240) -> Result<241 PartialComponents<242 FullClient<RuntimeApi, ExecutorDispatch>,243 FullBackend,244 FullSelectChain,245 sc_consensus::DefaultImportQueue<Block>,246 sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,247 OtherPartial,248 >,249 sc_service::Error,250>251where252 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,253 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>254 + Send255 + Sync256 + 'static,257 RuntimeApi::RuntimeApi: RuntimeApiDep<Runtime> + 'static,258 Runtime: RuntimeInstance,259 ExecutorDispatch: NativeExecutionDispatch + 'static,260 BIQ: FnOnce(261 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,262 Arc<FullBackend>,263 &Configuration,264 Option<TelemetryHandle>,265 &TaskManager,266 ) -> Result<sc_consensus::DefaultImportQueue<Block>, sc_service::Error>,267{268 let telemetry = config269 .telemetry_endpoints270 .clone()271 .filter(|x| !x.is_empty())272 .map(|endpoints| -> Result<_, sc_telemetry::Error> {273 let worker = TelemetryWorker::new(16)?;274 let telemetry = worker.handle().new_telemetry(endpoints);275 Ok((worker, telemetry))276 })277 .transpose()?;278279 let executor = sc_service::new_native_or_wasm_executor(config);280281 let (client, backend, keystore_container, task_manager) =282 sc_service::new_full_parts::<Block, RuntimeApi, _>(283 config,284 telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),285 executor,286 )?;287 let client = Arc::new(client);288289 let telemetry_worker_handle = telemetry.as_ref().map(|(worker, _)| worker.handle());290291 let telemetry = telemetry.map(|(worker, telemetry)| {292 task_manager293 .spawn_handle()294 .spawn("telemetry", None, worker.run());295 telemetry296 });297298 let select_chain = sc_consensus::LongestChain::new(backend.clone());299300 let transaction_pool = sc_transaction_pool::BasicPool::new_full(301 config.transaction_pool.clone(),302 config.role.is_authority().into(),303 config.prometheus_registry(),304 task_manager.spawn_essential_handle(),305 client.clone(),306 );307308 let eth_filter_pool: Option<FilterPool> = Some(Arc::new(Mutex::new(BTreeMap::new())));309310 let eth_backend = open_frontier_backend(client.clone(), config)?;311312 let import_queue = build_import_queue(313 client.clone(),314 backend.clone(),315 config,316 telemetry.as_ref().map(|telemetry| telemetry.handle()),317 &task_manager,318 )?;319320 let params = PartialComponents {321 backend,322 client,323 import_queue,324 keystore_container,325 task_manager,326 transaction_pool,327 select_chain,328 other: OtherPartial {329 telemetry,330 eth_filter_pool,331 eth_backend,332 telemetry_worker_handle,333 },334 };335336 Ok(params)337}338339macro_rules! clone {340 ($($i:ident),* $(,)?) => {341 $(342 let $i = $i.clone();343 )*344 };345}346347/// Start a node with the given parachain `Configuration` and relay chain `Configuration`.348///349/// This is the actual implementation that is abstract over the executor and the runtime api.350#[sc_tracing::logging::prefix_logs_with("Parachain")]351pub async fn start_node<Runtime, RuntimeApi, ExecutorDispatch>(352 parachain_config: Configuration,353 polkadot_config: Configuration,354 collator_options: CollatorOptions,355 para_id: ParaId,356 hwbench: Option<sc_sysinfo::HwBench>,357) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>358where359 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,360 Runtime: RuntimeInstance + Send + Sync + 'static,361 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,362 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,363 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>364 + Send365 + Sync366 + 'static,367 RuntimeApi::RuntimeApi: RuntimeApiDep<Runtime> + 'static,368 RuntimeApi::RuntimeApi: LookaheadApiDep,369 Runtime: RuntimeInstance,370 ExecutorDispatch: NativeExecutionDispatch + 'static,371{372 let parachain_config = prepare_node_config(parachain_config);373374 let params = new_partial::<Runtime, RuntimeApi, ExecutorDispatch, _>(375 ¶chain_config,376 parachain_build_import_queue,377 )?;378 let OtherPartial {379 mut telemetry,380 telemetry_worker_handle,381 eth_filter_pool,382 eth_backend,383 } = params.other;384 let net_config = sc_network::config::FullNetworkConfiguration::new(¶chain_config.network);385386 let client = params.client.clone();387 let backend = params.backend.clone();388 let mut task_manager = params.task_manager;389390 let (relay_chain_interface, collator_key) = build_relay_chain_interface(391 polkadot_config,392 ¶chain_config,393 telemetry_worker_handle,394 &mut task_manager,395 collator_options.clone(),396 hwbench.clone(),397 )398 .await399 .map_err(|e| sc_service::Error::Application(Box::new(e) as Box<_>))?;400401 // Aura is sybil-resistant, collator-selection is generally too.402 let block_announce_validator =403 cumulus_client_network::AssumeSybilResistance::allow_seconded_messages();404405 let validator = parachain_config.role.is_authority();406 let prometheus_registry = parachain_config.prometheus_registry().cloned();407 let transaction_pool = params.transaction_pool.clone();408 let import_queue_service = params.import_queue.service();409410 let (network, system_rpc_tx, tx_handler_controller, start_network, sync_service) =411 sc_service::build_network(sc_service::BuildNetworkParams {412 config: ¶chain_config,413 net_config,414 client: client.clone(),415 transaction_pool: transaction_pool.clone(),416 spawn_handle: task_manager.spawn_handle(),417 import_queue: params.import_queue,418 block_announce_validator_builder: Some(Box::new(|_| {419 Box::new(block_announce_validator)420 })),421 warp_sync_params: None,422 block_relay: None,423 })?;424425 let select_chain = params.select_chain.clone();426427 let runtime_id = parachain_config.chain_spec.runtime_id();428429 // Frontier430 let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new()));431 let fee_history_limit = 2048;432433 let eth_pubsub_notification_sinks: Arc<434 EthereumBlockNotificationSinks<fc_mapping_sync::EthereumBlockNotification<Block>>,435 > = Default::default();436437 let overrides = overrides_handle(client.clone());438 let eth_block_data_cache = spawn_frontier_tasks(439 FrontierTaskParams {440 client: client.clone(),441 substrate_backend: backend.clone(),442 eth_filter_pool: eth_filter_pool.clone(),443 eth_backend: eth_backend.clone(),444 fee_history_limit,445 fee_history_cache: fee_history_cache.clone(),446 task_manager: &task_manager,447 prometheus_registry: prometheus_registry.clone(),448 overrides: overrides.clone(),449 sync_strategy: SyncStrategy::Parachain,450 },451 sync_service.clone(),452 eth_pubsub_notification_sinks.clone(),453 );454455 // Rpc456 let rpc_builder = Box::new({457 clone!(458 client,459 backend,460 eth_backend,461 eth_pubsub_notification_sinks,462 fee_history_cache,463 eth_block_data_cache,464 overrides,465 transaction_pool,466 network,467 sync_service,468 );469 move |deny_unsafe, subscription_task_executor: SubscriptionTaskExecutor| {470 clone!(471 backend,472 eth_block_data_cache,473 client,474 eth_backend,475 eth_filter_pool,476 eth_pubsub_notification_sinks,477 fee_history_cache,478 eth_block_data_cache,479 network,480 runtime_id,481 transaction_pool,482 select_chain,483 overrides,484 );485486 #[cfg(not(feature = "pov-estimate"))]487 let _ = backend;488489 let mut rpc_handle = RpcModule::new(());490491 let full_deps = FullDeps {492 client: client.clone(),493 runtime_id,494495 #[cfg(feature = "pov-estimate")]496 exec_params: uc_rpc::pov_estimate::ExecutorParams {497 wasm_method: parachain_config.wasm_method,498 default_heap_pages: parachain_config.default_heap_pages,499 max_runtime_instances: parachain_config.max_runtime_instances,500 runtime_cache_size: parachain_config.runtime_cache_size,501 },502503 #[cfg(feature = "pov-estimate")]504 backend,505506 deny_unsafe,507 pool: transaction_pool.clone(),508 select_chain,509 };510511 create_full::<_, _, _, Runtime, _>(&mut rpc_handle, full_deps)?;512513 let eth_deps = EthDeps {514 client,515 graph: transaction_pool.pool().clone(),516 pool: transaction_pool,517 is_authority: validator,518 network,519 eth_backend,520 // TODO: Unhardcode521 max_past_logs: 10000,522 fee_history_limit,523 fee_history_cache,524 eth_block_data_cache,525 // TODO: Unhardcode526 enable_dev_signer: false,527 eth_filter_pool,528 eth_pubsub_notification_sinks,529 overrides,530 sync: sync_service.clone(),531 pending_create_inherent_data_providers: |_, ()| async move { Ok(()) },532 };533534 create_eth::<535 _,536 _,537 _,538 _,539 _,540 _,541 DefaultEthConfig<FullClient<RuntimeApi, ExecutorDispatch>>,542 >(543 &mut rpc_handle,544 eth_deps,545 subscription_task_executor.clone(),546 )?;547548 Ok(rpc_handle)549 }550 });551552 sc_service::spawn_tasks(sc_service::SpawnTasksParams {553 rpc_builder,554 client: client.clone(),555 transaction_pool: transaction_pool.clone(),556 task_manager: &mut task_manager,557 config: parachain_config,558 keystore: params.keystore_container.keystore(),559 backend: backend.clone(),560 network,561 sync_service: sync_service.clone(),562 system_rpc_tx,563 telemetry: telemetry.as_mut(),564 tx_handler_controller,565 })?;566567 if let Some(hwbench) = hwbench {568 sc_sysinfo::print_hwbench(&hwbench);569570 if let Some(ref mut telemetry) = telemetry {571 let telemetry_handle = telemetry.handle();572 task_manager.spawn_handle().spawn(573 "telemetry_hwbench",574 None,575 sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench),576 );577 }578 }579580 let announce_block = {581 let sync_service = sync_service.clone();582 Arc::new(Box::new(move |hash, data| {583 sync_service.announce_block(hash, data)584 }))585 };586587 let relay_chain_slot_duration = Duration::from_secs(6);588589 let overseer_handle = relay_chain_interface590 .overseer_handle()591 .map_err(|e| sc_service::Error::Application(Box::new(e)))?;592593 start_relay_chain_tasks(StartRelayChainTasksParams {594 client: client.clone(),595 announce_block: announce_block.clone(),596 para_id,597 relay_chain_interface: relay_chain_interface.clone(),598 task_manager: &mut task_manager,599 da_recovery_profile: if validator {600 DARecoveryProfile::Collator601 } else {602 DARecoveryProfile::FullNode603 },604 import_queue: import_queue_service,605 relay_chain_slot_duration,606 recovery_handle: Box::new(overseer_handle.clone()),607 sync_service: sync_service.clone(),608 })?;609610 if validator {611 start_consensus(612 client.clone(),613 transaction_pool,614 StartConsensusParameters {615 backend: backend.clone(),616 prometheus_registry: prometheus_registry.as_ref(),617 telemetry: telemetry.as_ref().map(|t| t.handle()),618 task_manager: &task_manager,619 relay_chain_interface: relay_chain_interface.clone(),620 sync_oracle: sync_service,621 keystore: params.keystore_container.keystore(),622 overseer_handle,623 relay_chain_slot_duration,624 para_id,625 collator_key: collator_key.expect("cli args do not allow this"),626 announce_block,627 },628 )?;629 }630631 start_network.start_network();632633 Ok((task_manager, client))634}635636/// Build the import queue for the the parachain runtime.637pub fn parachain_build_import_queue<Runtime, RuntimeApi, ExecutorDispatch>(638 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,639 backend: Arc<FullBackend>,640 config: &Configuration,641 telemetry: Option<TelemetryHandle>,642 task_manager: &TaskManager,643) -> Result<sc_consensus::DefaultImportQueue<Block>, sc_service::Error>644where645 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>646 + Send647 + Sync648 + 'static,649 RuntimeApi::RuntimeApi: RuntimeApiDep<Runtime> + 'static,650 Runtime: RuntimeInstance,651 ExecutorDispatch: NativeExecutionDispatch + 'static,652{653 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;654655 let block_import = ParachainBlockImport::new(client.clone(), backend);656657 cumulus_client_consensus_aura::import_queue::<658 sp_consensus_aura::sr25519::AuthorityPair,659 _,660 _,661 _,662 _,663 _,664 >(cumulus_client_consensus_aura::ImportQueueParams {665 block_import,666 client,667 create_inherent_data_providers: move |_, _| async move {668 let time = sp_timestamp::InherentDataProvider::from_system_time();669670 let slot =671 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(672 *time,673 slot_duration,674 );675676 Ok((slot, time))677 },678 registry: config.prometheus_registry(),679 spawner: &task_manager.spawn_essential_handle(),680 telemetry,681 })682 .map_err(Into::into)683}684685pub struct StartConsensusParameters<'a> {686 backend: Arc<FullBackend>,687 prometheus_registry: Option<&'a Registry>,688 telemetry: Option<TelemetryHandle>,689 task_manager: &'a TaskManager,690 relay_chain_interface: Arc<dyn RelayChainInterface>,691 sync_oracle: Arc<SyncingService<Block>>,692 keystore: KeystorePtr,693 overseer_handle: OverseerHandle,694 relay_chain_slot_duration: Duration,695 para_id: ParaId,696 collator_key: CollatorPair,697 announce_block: Arc<dyn Fn(Hash, Option<Vec<u8>>) + Send + Sync>,698}699700// Clones ignored for optional lookahead collator701#[allow(clippy::redundant_clone)]702pub fn start_consensus<ExecutorDispatch, RuntimeApi, Runtime>(703 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,704 transaction_pool: Arc<705 sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,706 >,707 parameters: StartConsensusParameters<'_>,708) -> Result<(), sc_service::Error>709where710 ExecutorDispatch: NativeExecutionDispatch + 'static,711 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>712 + Send713 + Sync714 + 'static,715 RuntimeApi::RuntimeApi: RuntimeApiDep<Runtime> + 'static,716 RuntimeApi::RuntimeApi: LookaheadApiDep,717 Runtime: RuntimeInstance,718{719 let StartConsensusParameters {720 backend,721 prometheus_registry,722 telemetry,723 task_manager,724 relay_chain_interface,725 sync_oracle,726 keystore,727 overseer_handle,728 relay_chain_slot_duration,729 para_id,730 collator_key,731 announce_block,732 } = parameters;733 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;734735 let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(736 task_manager.spawn_handle(),737 client.clone(),738 transaction_pool,739 prometheus_registry,740 telemetry,741 );742 let proposer = Proposer::new(proposer_factory);743744 let collator_service = CollatorService::new(745 client.clone(),746 Arc::new(task_manager.spawn_handle()),747 announce_block,748 client.clone(),749 );750751 let block_import = ParachainBlockImport::new(client.clone(), backend.clone());752753 let params = BuildAuraConsensusParams {754 create_inherent_data_providers: move |_, ()| async move { Ok(()) },755 block_import,756 para_client: client.clone(),757 #[cfg(feature = "lookahead")]758 para_backend: backend,759 para_id,760 relay_client: relay_chain_interface,761 sync_oracle,762 keystore,763 slot_duration,764 proposer,765 collator_service,766 // With async-baking, we allowed to be both slower (longer authoring) and faster (multiple para blocks per relay block)767 #[cfg(not(feature = "lookahead"))]768 authoring_duration: Duration::from_millis(500),769 #[cfg(feature = "lookahead")]770 authoring_duration: Duration::from_millis(1500),771 overseer_handle,772 #[cfg(feature = "lookahead")]773 code_hash_provider: move |block_hash| {774 client775 .code_at(block_hash)776 .ok()777 .map(cumulus_primitives_core::relay_chain::ValidationCode)778 .map(|c| c.hash())779 },780 collator_key,781 relay_chain_slot_duration,782 };783784 task_manager.spawn_essential_handle().spawn(785 "aura",786 None,787 #[cfg(not(feature = "lookahead"))]788 run_aura::<_, AuraAuthorityPair, _, _, _, _, _, _, _>(params),789 #[cfg(feature = "lookahead")]790 run_aura::<_, AuraAuthorityPair, _, _, _, _, _, _, _, _, _>(params),791 );792 Ok(())793}794795fn dev_build_import_queue<RuntimeApi, ExecutorDispatch>(796 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,797 _: Arc<FullBackend>,798 config: &Configuration,799 _: Option<TelemetryHandle>,800 task_manager: &TaskManager,801) -> Result<sc_consensus::DefaultImportQueue<Block>, sc_service::Error>802where803 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>804 + Send805 + Sync806 + 'static,807 RuntimeApi::RuntimeApi:808 sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> + sp_api::ApiExt<Block>,809 ExecutorDispatch: NativeExecutionDispatch + 'static,810{811 Ok(sc_consensus_manual_seal::import_queue(812 Box::new(client),813 &task_manager.spawn_essential_handle(),814 config.prometheus_registry(),815 ))816}817818pub struct OtherPartial {819 pub telemetry: Option<Telemetry>,820 pub telemetry_worker_handle: Option<TelemetryWorkerHandle>,821 pub eth_filter_pool: Option<FilterPool>,822 pub eth_backend: Arc<fc_db::kv::Backend<Block>>,823}824825struct DefaultEthConfig<C>(PhantomData<C>);826impl<C> EthConfig<Block, C> for DefaultEthConfig<C>827where828 C: StorageProvider<Block, FullBackend> + Sync + Send + 'static,829{830 type EstimateGasAdapter = ();831 type RuntimeStorageOverride = SystemAccountId32StorageOverride<Block, C, FullBackend>;832}833834/// Builds a new development service. This service uses instant seal, and mocks835/// the parachain inherent836pub fn start_dev_node<Runtime, RuntimeApi, ExecutorDispatch>(837 config: Configuration,838 autoseal_interval: u64,839 autoseal_finalize_delay: Option<u64>,840 disable_autoseal_on_tx: bool,841) -> sc_service::error::Result<TaskManager>842where843 Runtime: RuntimeInstance + Send + Sync + 'static,844 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,845 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,846 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>847 + Send848 + Sync849 + 'static,850 RuntimeApi::RuntimeApi: RuntimeApiDep<Runtime> + 'static,851 ExecutorDispatch: NativeExecutionDispatch + 'static,852{853 use fc_consensus::FrontierBlockImport;854 use sc_consensus_manual_seal::{855 run_delayed_finalize, run_manual_seal, DelayedFinalizeParams, EngineCommand,856 ManualSealParams,857 };858859 let sc_service::PartialComponents {860 client,861 backend,862 mut task_manager,863 import_queue,864 keystore_container,865 select_chain: maybe_select_chain,866 transaction_pool,867 other:868 OtherPartial {869 telemetry,870 eth_filter_pool,871 eth_backend,872 telemetry_worker_handle: _,873 },874 } = new_partial::<Runtime, RuntimeApi, ExecutorDispatch, _>(875 &config,876 dev_build_import_queue::<RuntimeApi, ExecutorDispatch>,877 )?;878 let net_config = sc_network::config::FullNetworkConfiguration::new(&config.network);879 let prometheus_registry = config.prometheus_registry().cloned();880881 let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) =882 sc_service::build_network(sc_service::BuildNetworkParams {883 config: &config,884 net_config,885 client: client.clone(),886 transaction_pool: transaction_pool.clone(),887 spawn_handle: task_manager.spawn_handle(),888 import_queue,889 block_announce_validator_builder: None,890 warp_sync_params: None,891 block_relay: None,892 })?;893894 let collator = config.role.is_authority();895896 let select_chain = maybe_select_chain;897898 if collator {899 let block_import = FrontierBlockImport::new(client.clone(), client.clone());900901 let env = sc_basic_authorship::ProposerFactory::new(902 task_manager.spawn_handle(),903 client.clone(),904 transaction_pool.clone(),905 prometheus_registry.as_ref(),906 telemetry.as_ref().map(|x| x.handle()),907 );908909 let transactions_commands_stream: Box<910 dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin,911 > = Box::new(912 transaction_pool913 .pool()914 .validated_pool()915 .import_notification_stream()916 .filter(move |_| futures::future::ready(!disable_autoseal_on_tx))917 .map(|_| EngineCommand::SealNewBlock {918 create_empty: true,919 finalize: false,920 parent_hash: None,921 sender: None,922 }),923 );924925 let autoseal_interval = Box::pin(AutosealInterval::new(&config, autoseal_interval));926927 let idle_commands_stream: Box<928 dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin,929 > = Box::new(autoseal_interval.map(|_| EngineCommand::SealNewBlock {930 create_empty: true,931 finalize: false,932 parent_hash: None,933 sender: None,934 }));935936 let commands_stream = select(transactions_commands_stream, idle_commands_stream);937938 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;939 let client_set_aside_for_cidp = client.clone();940941 if let Some(delay_sec) = autoseal_finalize_delay {942 let spawn_handle = task_manager.spawn_handle();943944 task_manager.spawn_essential_handle().spawn_blocking(945 "finalization_task",946 Some("block-authoring"),947 run_delayed_finalize(DelayedFinalizeParams {948 client: client.clone(),949 delay_sec,950 spawn_handle,951 }),952 );953 }954955 task_manager.spawn_essential_handle().spawn_blocking(956 "authorship_task",957 Some("block-authoring"),958 run_manual_seal(ManualSealParams {959 block_import,960 env,961 client: client.clone(),962 pool: transaction_pool.clone(),963 commands_stream,964 select_chain: select_chain.clone(),965 consensus_data_provider: None,966 create_inherent_data_providers: move |block: Hash, ()| {967 let current_para_block = client_set_aside_for_cidp968 .number(block)969 .expect("Header lookup should succeed")970 .expect("Header passed in as parent should be present in backend.");971972 let client_for_xcm = client_set_aside_for_cidp.clone();973 async move {974 let time = sp_timestamp::InherentDataProvider::from_system_time();975976 let mocked_parachain = cumulus_primitives_parachain_inherent::MockValidationDataInherentDataProvider {977 current_para_block,978 relay_offset: 1000,979 relay_blocks_per_para_block: 2,980 para_blocks_per_relay_epoch: 0,981 xcm_config: cumulus_primitives_parachain_inherent::MockXcmConfig::new(982 &*client_for_xcm,983 block,984 Default::default(),985 Default::default(),986 ),987 relay_randomness_config: (),988 raw_downward_messages: vec![],989 raw_horizontal_messages: vec![],990 };991992 let slot =993 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(994 *time,995 slot_duration,996 );997998 Ok((time, slot, mocked_parachain))999 }1000 },1001 }),1002 );1003 }10041005 #[cfg(feature = "pov-estimate")]1006 let rpc_backend = backend.clone();10071008 let runtime_id = config.chain_spec.runtime_id();10091010 // Frontier1011 let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new()));1012 let fee_history_limit = 2048;10131014 let eth_pubsub_notification_sinks: Arc<1015 EthereumBlockNotificationSinks<fc_mapping_sync::EthereumBlockNotification<Block>>,1016 > = Default::default();10171018 let overrides = overrides_handle(client.clone());1019 let eth_block_data_cache = spawn_frontier_tasks(1020 FrontierTaskParams {1021 client: client.clone(),1022 substrate_backend: backend.clone(),1023 eth_filter_pool: eth_filter_pool.clone(),1024 eth_backend: eth_backend.clone(),1025 fee_history_limit,1026 fee_history_cache: fee_history_cache.clone(),1027 task_manager: &task_manager,1028 prometheus_registry,1029 overrides: overrides.clone(),1030 sync_strategy: SyncStrategy::Normal,1031 },1032 sync_service.clone(),1033 eth_pubsub_notification_sinks.clone(),1034 );10351036 // Rpc1037 let rpc_builder = Box::new({1038 clone!(1039 client,1040 backend,1041 eth_backend,1042 eth_pubsub_notification_sinks,1043 fee_history_cache,1044 eth_block_data_cache,1045 overrides,1046 transaction_pool,1047 network,1048 sync_service,1049 );1050 move |deny_unsafe, subscription_task_executor: SubscriptionTaskExecutor| {1051 clone!(1052 backend,1053 eth_block_data_cache,1054 client,1055 eth_backend,1056 eth_filter_pool,1057 eth_pubsub_notification_sinks,1058 fee_history_cache,1059 eth_block_data_cache,1060 network,1061 runtime_id,1062 transaction_pool,1063 select_chain,1064 overrides,1065 );10661067 #[cfg(not(feature = "pov-estimate"))]1068 let _ = backend;10691070 let mut rpc_module = RpcModule::new(());10711072 let full_deps = FullDeps {1073 runtime_id,10741075 #[cfg(feature = "pov-estimate")]1076 exec_params: uc_rpc::pov_estimate::ExecutorParams {1077 wasm_method: config.wasm_method,1078 default_heap_pages: config.default_heap_pages,1079 max_runtime_instances: config.max_runtime_instances,1080 runtime_cache_size: config.runtime_cache_size,1081 },10821083 #[cfg(feature = "pov-estimate")]1084 backend,1085 // eth_backend,1086 deny_unsafe,1087 client: client.clone(),1088 pool: transaction_pool.clone(),1089 select_chain,1090 };10911092 create_full::<_, _, _, Runtime, _>(&mut rpc_module, full_deps)?;10931094 let eth_deps = EthDeps {1095 client,1096 graph: transaction_pool.pool().clone(),1097 pool: transaction_pool,1098 is_authority: true,1099 network,1100 eth_backend,1101 // TODO: Unhardcode1102 max_past_logs: 10000,1103 fee_history_limit,1104 fee_history_cache,1105 eth_block_data_cache,1106 // TODO: Unhardcode1107 enable_dev_signer: false,1108 eth_filter_pool,1109 eth_pubsub_notification_sinks,1110 overrides,1111 sync: sync_service.clone(),1112 // We don't have any inherents except parachain built-ins, which we can't even extract from inside `run_aura`.1113 pending_create_inherent_data_providers: |_, ()| async move { Ok(()) },1114 };11151116 create_eth::<1117 _,1118 _,1119 _,1120 _,1121 _,1122 _,1123 DefaultEthConfig<FullClient<RuntimeApi, ExecutorDispatch>>,1124 >(1125 &mut rpc_module,1126 eth_deps,1127 subscription_task_executor.clone(),1128 )?;11291130 Ok(rpc_module)1131 }1132 });11331134 sc_service::spawn_tasks(sc_service::SpawnTasksParams {1135 network,1136 sync_service,1137 client,1138 keystore: keystore_container.keystore(),1139 task_manager: &mut task_manager,1140 transaction_pool,1141 rpc_builder,1142 backend,1143 system_rpc_tx,1144 config,1145 telemetry: None,1146 tx_handler_controller,1147 })?;11481149 network_starter.start_network();1150 Ok(task_manager)1151}11521153fn overrides_handle<C, BE>(client: Arc<C>) -> Arc<OverrideHandle<Block>>1154where1155 C: ProvideRuntimeApi<Block> + StorageProvider<Block, BE> + AuxStore,1156 C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError>,1157 C: Send + Sync + 'static,1158 C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,1159 BE: Backend<Block> + 'static,1160 BE::State: StateBackend<BlakeTwo256>,1161{1162 let mut overrides_map = BTreeMap::new();1163 overrides_map.insert(1164 EthereumStorageSchema::V1,1165 Box::new(SchemaV1Override::new(client.clone())) as Box<dyn StorageOverride<_> + 'static>,1166 );1167 overrides_map.insert(1168 EthereumStorageSchema::V2,1169 Box::new(SchemaV2Override::new(client.clone())) as Box<dyn StorageOverride<_> + 'static>,1170 );1171 overrides_map.insert(1172 EthereumStorageSchema::V3,1173 Box::new(SchemaV3Override::new(client.clone())) as Box<dyn StorageOverride<_> + 'static>,1174 );11751176 Arc::new(OverrideHandle {1177 schemas: overrides_map,1178 fallback: Box::new(RuntimeApiStorageOverride::new(client)),1179 })1180}11811182pub struct FrontierTaskParams<'a, C, B> {1183 pub task_manager: &'a TaskManager,1184 pub client: Arc<C>,1185 pub substrate_backend: Arc<B>,1186 pub eth_backend: Arc<fc_db::kv::Backend<Block>>,1187 pub eth_filter_pool: Option<FilterPool>,1188 pub overrides: Arc<OverrideHandle<Block>>,1189 pub fee_history_limit: u64,1190 pub fee_history_cache: FeeHistoryCache,1191 pub sync_strategy: SyncStrategy,1192 pub prometheus_registry: Option<Registry>,1193}11941195pub fn spawn_frontier_tasks<C, B>(1196 params: FrontierTaskParams<C, B>,1197 sync: Arc<SyncingService<Block>>,1198 pubsub_notification_sinks: Arc<1199 EthereumBlockNotificationSinks<fc_mapping_sync::EthereumBlockNotification<Block>>,1200 >,1201) -> Arc<EthBlockDataCacheTask<Block>>1202where1203 C: ProvideRuntimeApi<Block> + BlockOf,1204 C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,1205 C: BlockchainEvents<Block> + StorageProvider<Block, B>,1206 C: Send + Sync + 'static,1207 C::Api: EthereumRuntimeRPCApi<Block>,1208 C::Api: BlockBuilder<Block>,1209 B: Backend<Block> + 'static,1210 B::State: StateBackend<BlakeTwo256>,1211{1212 let FrontierTaskParams {1213 task_manager,1214 client,1215 substrate_backend,1216 eth_backend,1217 eth_filter_pool,1218 overrides,1219 fee_history_limit,1220 fee_history_cache,1221 sync_strategy,1222 prometheus_registry,1223 } = params;1224 // Frontier offchain DB task. Essential.1225 // Maps emulated ethereum data to substrate native data.1226 params.task_manager.spawn_essential_handle().spawn(1227 "frontier-mapping-sync-worker",1228 Some("frontier"),1229 MappingSyncWorker::new(1230 client.import_notification_stream(),1231 Duration::new(6, 0),1232 client.clone(),1233 substrate_backend,1234 overrides.clone(),1235 eth_backend,1236 3,1237 0,1238 sync_strategy,1239 sync,1240 pubsub_notification_sinks,1241 )1242 .for_each(|()| futures::future::ready(())),1243 );12441245 // Frontier `EthFilterApi` maintenance.1246 // Manages the pool of user-created Filters.1247 if let Some(eth_filter_pool) = eth_filter_pool {1248 // Each filter is allowed to stay in the pool for 100 blocks.1249 const FILTER_RETAIN_THRESHOLD: u64 = 100;1250 params.task_manager.spawn_essential_handle().spawn(1251 "frontier-filter-pool",1252 Some("frontier"),1253 EthTask::filter_pool_task(client.clone(), eth_filter_pool, FILTER_RETAIN_THRESHOLD),1254 );1255 }12561257 // Spawn Frontier FeeHistory cache maintenance task.1258 params.task_manager.spawn_essential_handle().spawn(1259 "frontier-fee-history",1260 Some("frontier"),1261 EthTask::fee_history_task(1262 client,1263 overrides.clone(),1264 fee_history_cache,1265 fee_history_limit,1266 ),1267 );12681269 Arc::new(EthBlockDataCacheTask::new(1270 task_manager.spawn_handle(),1271 overrides,1272 50,1273 50,1274 prometheus_registry,1275 ))1276}runtime/common/config/pallets/preimage.rsdiffbeforeafterboth--- a/runtime/common/config/pallets/preimage.rs
+++ b/runtime/common/config/pallets/preimage.rs
@@ -14,14 +14,18 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-use frame_support::parameter_types;
+use frame_support::{
+ parameter_types,
+ traits::{fungible::HoldConsideration, LinearStoragePrice},
+};
use frame_system::EnsureRoot;
use up_common::constants::*;
-use crate::{AccountId, Balance, Balances, Runtime, RuntimeEvent};
+use crate::{AccountId, Balance, Balances, Runtime, RuntimeEvent, RuntimeHoldReason};
parameter_types! {
pub PreimageBaseDeposit: Balance = 1000 * UNIQUE;
+ pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
}
impl pallet_preimage::Config for Runtime {
@@ -29,6 +33,10 @@
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type ManagerOrigin = EnsureRoot<AccountId>;
- type BaseDeposit = PreimageBaseDeposit;
- type ByteDeposit = TransactionByteFee;
+ type Consideration = HoldConsideration<
+ AccountId,
+ Balances,
+ PreimageHoldReason,
+ LinearStoragePrice<PreimageBaseDeposit, TransactionByteFee, Balance>,
+ >;
}