difftreelog
Make opal runtime mandatory
in: master
5 files changed
node/cli/Cargo.tomldiffbeforeafterboth--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -252,7 +252,6 @@
[dependencies.opal-runtime]
path = '../../runtime/opal'
-optional = true
[dependencies.up-data-structs]
path = "../../primitives/data-structs"
@@ -306,7 +305,7 @@
unique-rpc = { default-features = false, path = "../rpc" }
[features]
-default = ["unique-runtime", "quartz-runtime", "opal-runtime"]
+default = ["unique-runtime", "quartz-runtime"]
runtime-benchmarks = [
'unique-runtime/runtime-benchmarks',
'polkadot-service/runtime-benchmarks',
node/cli/src/chain_spec.rsdiffbeforeafterboth--- a/node/cli/src/chain_spec.rs
+++ b/node/cli/src/chain_spec.rs
@@ -35,7 +35,6 @@
pub type QuartzChainSpec = sc_service::GenericChainSpec<quartz_runtime::GenesisConfig, Extensions>;
/// The `ChainSpec` parameterized for the opal runtime.
-#[cfg(feature = "opal-runtime")]
pub type OpalChainSpec = sc_service::GenericChainSpec<opal_runtime::GenesisConfig, Extensions>;
pub enum RuntimeId {
@@ -61,7 +60,6 @@
return RuntimeId::Quartz;
}
- #[cfg(feature = "opal-runtime")]
if self.id().starts_with("opal") {
return RuntimeId::Opal;
}
node/cli/src/command.rsdiffbeforeafterboth--- a/node/cli/src/command.rs
+++ b/node/cli/src/command.rs
@@ -44,7 +44,6 @@
#[cfg(feature = "quartz-runtime")]
use crate::service::QuartzRuntimeExecutor;
-#[cfg(feature = "opal-runtime")]
use crate::service::OpalRuntimeExecutor;
use codec::Encode;
@@ -82,7 +81,7 @@
"" | "local" => Box::new(chain_spec::local_testnet_rococo_config()),
path => {
let path = std::path::PathBuf::from(path);
- let chain_spec = Box::new(sc_service::GenericChainSpec::<()>::from_json_file(
+ let chain_spec = Box::new(chain_spec::OpalChainSpec::from_json_file(
path.clone(),
)?) as Box<dyn sc_service::ChainSpec>;
@@ -93,9 +92,7 @@
#[cfg(feature = "quartz-runtime")]
RuntimeId::Quartz => Box::new(chain_spec::QuartzChainSpec::from_json_file(path)?),
- #[cfg(feature = "opal-runtime")]
RuntimeId::Opal => Box::new(chain_spec::OpalChainSpec::from_json_file(path)?),
-
RuntimeId::Unknown(chain) => return Err(no_runtime_err!(chain)),
}
}
@@ -147,9 +144,7 @@
#[cfg(feature = "quartz-runtime")]
RuntimeId::Quartz => &quartz_runtime::VERSION,
- #[cfg(feature = "opal-runtime")]
RuntimeId::Opal => &opal_runtime::VERSION,
-
RuntimeId::Unknown(chain) => panic!("{}", no_runtime_err!(chain)),
}
}
@@ -241,7 +236,6 @@
runner, $components, $cli, $cmd, $config, $( $code )*
),
- #[cfg(feature = "opal-runtime")]
RuntimeId::Opal => async_run_with_runtime!(
opal_runtime::RuntimeApi, OpalRuntimeExecutor,
runner, $components, $cli, $cmd, $config, $( $code )*
@@ -359,9 +353,7 @@
#[cfg(feature = "quartz-runtime")]
RuntimeId::Quartz => cmd.run::<Block, QuartzRuntimeExecutor>(config),
- #[cfg(feature = "opal-runtime")]
RuntimeId::Opal => cmd.run::<Block, OpalRuntimeExecutor>(config),
-
RuntimeId::Unknown(chain) => Err(no_runtime_err!(chain).into()),
})
} else {
@@ -438,7 +430,6 @@
.map(|r| r.0)
.map_err(Into::into),
- #[cfg(feature = "opal-runtime")]
RuntimeId::Opal => crate::service::start_node::<
opal_runtime::Runtime,
opal_runtime::RuntimeApi,
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//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.1819// std20use std::sync::Arc;21use std::sync::Mutex;22use std::collections::BTreeMap;23use std::time::Duration;24use fc_rpc_core::types::FeeHistoryCache;25use futures::StreamExt;2627use unique_rpc::overrides_handle;2829use serde::{Serialize, Deserialize};3031// Cumulus Imports32use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion};33use cumulus_client_consensus_common::ParachainConsensus;34use cumulus_client_service::{35 prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams,36};37use cumulus_client_network::BlockAnnounceValidator;38use cumulus_primitives_core::ParaId;39use cumulus_relay_chain_interface::RelayChainInterface;40use cumulus_relay_chain_local::build_relay_chain_interface;4142// Substrate Imports43use sc_client_api::ExecutorProvider;44use sc_executor::NativeElseWasmExecutor;45use sc_executor::NativeExecutionDispatch;46use sc_network::NetworkService;47use sc_service::{BasePath, Configuration, PartialComponents, Role, TaskManager};48use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};49use sp_consensus::SlotData;50use sp_keystore::SyncCryptoStorePtr;51use sp_runtime::traits::BlakeTwo256;52use substrate_prometheus_endpoint::Registry;53use sc_client_api::BlockchainEvents;5455// Frontier Imports56use fc_rpc_core::types::FilterPool;57use fc_mapping_sync::{MappingSyncWorker, SyncStrategy};5859// Runtime type overrides60type BlockNumber = u32;61type Header = sp_runtime::generic::Header<BlockNumber, sp_runtime::traits::BlakeTwo256>;62pub type Block = sp_runtime::generic::Block<Header, sp_runtime::OpaqueExtrinsic>;63type Hash = sp_core::H256;6465use unique_runtime_common::types::{AuraId, RuntimeInstance, AccountId, Balance, Index};6667/// Native executor instance.68pub struct UniqueRuntimeExecutor;69pub struct QuartzRuntimeExecutor;70pub struct OpalRuntimeExecutor;7172#[cfg(feature = "unique-runtime")]73impl NativeExecutionDispatch for UniqueRuntimeExecutor {74 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;7576 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {77 unique_runtime::api::dispatch(method, data)78 }7980 fn native_version() -> sc_executor::NativeVersion {81 unique_runtime::native_version()82 }83}8485#[cfg(feature = "quartz-runtime")]86impl NativeExecutionDispatch for QuartzRuntimeExecutor {87 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;8889 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {90 quartz_runtime::api::dispatch(method, data)91 }9293 fn native_version() -> sc_executor::NativeVersion {94 quartz_runtime::native_version()95 }96}9798#[cfg(feature = "opal-runtime")]99impl NativeExecutionDispatch for OpalRuntimeExecutor {100 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;101102 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {103 opal_runtime::api::dispatch(method, data)104 }105106 fn native_version() -> sc_executor::NativeVersion {107 opal_runtime::native_version()108 }109}110111pub fn open_frontier_backend(config: &Configuration) -> Result<Arc<fc_db::Backend<Block>>, String> {112 let config_dir = config113 .base_path114 .as_ref()115 .map(|base_path| base_path.config_dir(config.chain_spec.id()))116 .unwrap_or_else(|| {117 BasePath::from_project("", "", "unique").config_dir(config.chain_spec.id())118 });119 let database_dir = config_dir.join("frontier").join("db");120121 Ok(Arc::new(fc_db::Backend::<Block>::new(122 &fc_db::DatabaseSettings {123 source: fc_db::DatabaseSettingsSrc::RocksDb {124 path: database_dir,125 cache_size: 0,126 },127 },128 )?))129}130131type FullClient<RuntimeApi, ExecutorDispatch> =132 sc_service::TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<ExecutorDispatch>>;133type FullBackend = sc_service::TFullBackend<Block>;134type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;135136/// Starts a `ServiceBuilder` for a full service.137///138/// Use this macro if you don't actually need the full service, but just the builder in order to139/// be able to perform chain operations.140#[allow(clippy::type_complexity)]141pub fn new_partial<RuntimeApi, ExecutorDispatch, BIQ>(142 config: &Configuration,143 build_import_queue: BIQ,144) -> Result<145 PartialComponents<146 FullClient<RuntimeApi, ExecutorDispatch>,147 FullBackend,148 FullSelectChain,149 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,150 sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,151 (152 Option<Telemetry>,153 Option<FilterPool>,154 Arc<fc_db::Backend<Block>>,155 Option<TelemetryWorkerHandle>,156 FeeHistoryCache,157 ),158 >,159 sc_service::Error,160>161where162 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,163 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>164 + Send165 + Sync166 + 'static,167 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>,168 ExecutorDispatch: NativeExecutionDispatch + 'static,169 BIQ: FnOnce(170 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,171 &Configuration,172 Option<TelemetryHandle>,173 &TaskManager,174 ) -> Result<175 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,176 sc_service::Error,177 >,178{179 let _telemetry = config180 .telemetry_endpoints181 .clone()182 .filter(|x| !x.is_empty())183 .map(|endpoints| -> Result<_, sc_telemetry::Error> {184 let worker = TelemetryWorker::new(16)?;185 let telemetry = worker.handle().new_telemetry(endpoints);186 Ok((worker, telemetry))187 })188 .transpose()?;189190 let telemetry = config191 .telemetry_endpoints192 .clone()193 .filter(|x| !x.is_empty())194 .map(|endpoints| -> Result<_, sc_telemetry::Error> {195 let worker = TelemetryWorker::new(16)?;196 let telemetry = worker.handle().new_telemetry(endpoints);197 Ok((worker, telemetry))198 })199 .transpose()?;200201 let executor = NativeElseWasmExecutor::<ExecutorDispatch>::new(202 config.wasm_method,203 config.default_heap_pages,204 config.max_runtime_instances,205 config.runtime_cache_size,206 );207208 let (client, backend, keystore_container, task_manager) =209 sc_service::new_full_parts::<Block, RuntimeApi, _>(210 config,211 telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),212 executor,213 )?;214 let client = Arc::new(client);215216 let telemetry_worker_handle = telemetry.as_ref().map(|(worker, _)| worker.handle());217218 let telemetry = telemetry.map(|(worker, telemetry)| {219 task_manager220 .spawn_handle()221 .spawn("telemetry", None, worker.run());222 telemetry223 });224225 let select_chain = sc_consensus::LongestChain::new(backend.clone());226227 let transaction_pool = sc_transaction_pool::BasicPool::new_full(228 config.transaction_pool.clone(),229 config.role.is_authority().into(),230 config.prometheus_registry(),231 task_manager.spawn_essential_handle(),232 client.clone(),233 );234235 let filter_pool: Option<FilterPool> = Some(Arc::new(Mutex::new(BTreeMap::new())));236237 let frontier_backend = open_frontier_backend(config)?;238239 let import_queue = build_import_queue(240 client.clone(),241 config,242 telemetry.as_ref().map(|telemetry| telemetry.handle()),243 &task_manager,244 )?;245 let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new()));246247 let params = PartialComponents {248 backend,249 client,250 import_queue,251 keystore_container,252 task_manager,253 transaction_pool,254 select_chain,255 other: (256 telemetry,257 filter_pool,258 frontier_backend,259 telemetry_worker_handle,260 fee_history_cache,261 ),262 };263264 Ok(params)265}266267/// Start a node with the given parachain `Configuration` and relay chain `Configuration`.268///269/// This is the actual implementation that is abstract over the executor and the runtime api.270#[sc_tracing::logging::prefix_logs_with("Parachain")]271async fn start_node_impl<Runtime, RuntimeApi, ExecutorDispatch, BIQ, BIC>(272 parachain_config: Configuration,273 polkadot_config: Configuration,274 id: ParaId,275 build_import_queue: BIQ,276 build_consensus: BIC,277) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>278where279 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,280 Runtime: RuntimeInstance + Send + Sync + 'static,281 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,282 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,283 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>284 + Send285 + Sync286 + 'static,287 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>288 + fp_rpc::EthereumRuntimeRPCApi<Block>289 + sp_session::SessionKeys<Block>290 + sp_block_builder::BlockBuilder<Block>291 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>292 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>293 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>294 + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>295 + sp_api::Metadata<Block>296 + sp_offchain::OffchainWorkerApi<Block>297 + cumulus_primitives_core::CollectCollationInfo<Block>,298 ExecutorDispatch: NativeExecutionDispatch + 'static,299 BIQ: FnOnce(300 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,301 &Configuration,302 Option<TelemetryHandle>,303 &TaskManager,304 ) -> Result<305 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,306 sc_service::Error,307 >,308 BIC: FnOnce(309 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,310 Option<&Registry>,311 Option<TelemetryHandle>,312 &TaskManager,313 Arc<dyn RelayChainInterface>,314 Arc<sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>>,315 Arc<NetworkService<Block, Hash>>,316 SyncCryptoStorePtr,317 bool,318 ) -> Result<Box<dyn ParachainConsensus<Block>>, sc_service::Error>,319{320 if matches!(parachain_config.role, Role::Light) {321 return Err("Light client not supported!".into());322 }323324 let parachain_config = prepare_node_config(parachain_config);325326 let params =327 new_partial::<RuntimeApi, ExecutorDispatch, BIQ>(¶chain_config, build_import_queue)?;328 let (mut telemetry, filter_pool, frontier_backend, telemetry_worker_handle, fee_history_cache) =329 params.other;330331 let client = params.client.clone();332 let backend = params.backend.clone();333 let mut task_manager = params.task_manager;334335 let (relay_chain_interface, collator_key) =336 build_relay_chain_interface(polkadot_config, telemetry_worker_handle, &mut task_manager)337 .map_err(|e| match e {338 polkadot_service::Error::Sub(x) => x,339 s => format!("{}", s).into(),340 })?;341342 let block_announce_validator = BlockAnnounceValidator::new(relay_chain_interface.clone(), id);343344 let force_authoring = parachain_config.force_authoring;345 let validator = parachain_config.role.is_authority();346 let prometheus_registry = parachain_config.prometheus_registry().cloned();347 let transaction_pool = params.transaction_pool.clone();348 let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue);349350 let (network, system_rpc_tx, start_network) =351 sc_service::build_network(sc_service::BuildNetworkParams {352 config: ¶chain_config,353 client: client.clone(),354 transaction_pool: transaction_pool.clone(),355 spawn_handle: task_manager.spawn_handle(),356 import_queue: import_queue.clone(),357 block_announce_validator_builder: Some(Box::new(|_| {358 Box::new(block_announce_validator)359 })),360 warp_sync: None,361 })?;362363 let subscription_executor = sc_rpc::SubscriptionTaskExecutor::new(task_manager.spawn_handle());364 let rpc_client = client.clone();365 let rpc_pool = transaction_pool.clone();366 let select_chain = params.select_chain.clone();367 let rpc_network = network.clone();368369 let rpc_frontier_backend = frontier_backend.clone();370371 let block_data_cache = Arc::new(fc_rpc::EthBlockDataCache::new(372 task_manager.spawn_handle(),373 overrides_handle::<_, _, Runtime>(client.clone()),374 50,375 50,376 ));377378 let rpc_extensions_builder = Box::new(move |deny_unsafe, _| {379 let full_deps = unique_rpc::FullDeps {380 backend: rpc_frontier_backend.clone(),381 deny_unsafe,382 client: rpc_client.clone(),383 pool: rpc_pool.clone(),384 graph: rpc_pool.pool().clone(),385 // TODO: Unhardcode386 enable_dev_signer: false,387 filter_pool: filter_pool.clone(),388 network: rpc_network.clone(),389 select_chain: select_chain.clone(),390 is_authority: validator,391 // TODO: Unhardcode392 max_past_logs: 10000,393 block_data_cache: block_data_cache.clone(),394 fee_history_cache: fee_history_cache.clone(),395 // TODO: Unhardcode396 fee_history_limit: 2048,397 };398399 Ok(400 unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(401 full_deps,402 subscription_executor.clone(),403 ),404 )405 });406407 task_manager.spawn_essential_handle().spawn(408 "frontier-mapping-sync-worker",409 None,410 MappingSyncWorker::new(411 client.import_notification_stream(),412 Duration::new(6, 0),413 client.clone(),414 backend.clone(),415 frontier_backend.clone(),416 SyncStrategy::Normal,417 )418 .for_each(|()| futures::future::ready(())),419 );420421 sc_service::spawn_tasks(sc_service::SpawnTasksParams {422 rpc_extensions_builder,423 client: client.clone(),424 transaction_pool: transaction_pool.clone(),425 task_manager: &mut task_manager,426 config: parachain_config,427 keystore: params.keystore_container.sync_keystore(),428 backend: backend.clone(),429 network: network.clone(),430 system_rpc_tx,431 telemetry: telemetry.as_mut(),432 })?;433434 let announce_block = {435 let network = network.clone();436 Arc::new(move |hash, data| network.announce_block(hash, data))437 };438439 let relay_chain_slot_duration = Duration::from_secs(6);440441 if validator {442 let parachain_consensus = build_consensus(443 client.clone(),444 prometheus_registry.as_ref(),445 telemetry.as_ref().map(|t| t.handle()),446 &task_manager,447 relay_chain_interface.clone(),448 transaction_pool,449 network,450 params.keystore_container.sync_keystore(),451 force_authoring,452 )?;453454 let spawner = task_manager.spawn_handle();455456 let params = StartCollatorParams {457 para_id: id,458 block_status: client.clone(),459 announce_block,460 client: client.clone(),461 task_manager: &mut task_manager,462 spawner,463 parachain_consensus,464 import_queue,465 collator_key,466 relay_chain_interface,467 relay_chain_slot_duration,468 };469470 start_collator(params).await?;471 } else {472 let params = StartFullNodeParams {473 client: client.clone(),474 announce_block,475 task_manager: &mut task_manager,476 para_id: id,477 import_queue,478 relay_chain_interface,479 relay_chain_slot_duration,480 };481482 start_full_node(params)?;483 }484485 start_network.start_network();486487 Ok((task_manager, client))488}489490/// Build the import queue for the the parachain runtime.491pub fn parachain_build_import_queue<RuntimeApi, ExecutorDispatch>(492 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,493 config: &Configuration,494 telemetry: Option<TelemetryHandle>,495 task_manager: &TaskManager,496) -> Result<497 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,498 sc_service::Error,499>500where501 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>502 + Send503 + Sync504 + 'static,505 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>506 + sp_block_builder::BlockBuilder<Block>507 + sp_consensus_aura::AuraApi<Block, AuraId>508 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,509 ExecutorDispatch: NativeExecutionDispatch + 'static,510{511 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;512513 cumulus_client_consensus_aura::import_queue::<514 sp_consensus_aura::sr25519::AuthorityPair,515 _,516 _,517 _,518 _,519 _,520 _,521 >(cumulus_client_consensus_aura::ImportQueueParams {522 block_import: client.clone(),523 client: client.clone(),524 create_inherent_data_providers: move |_, _| async move {525 let time = sp_timestamp::InherentDataProvider::from_system_time();526527 let slot =528 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(529 *time,530 slot_duration.slot_duration(),531 );532533 Ok((time, slot))534 },535 registry: config.prometheus_registry(),536 can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),537 spawner: &task_manager.spawn_essential_handle(),538 telemetry,539 })540 .map_err(Into::into)541}542543/// Start a normal parachain node.544pub async fn start_node<Runtime, RuntimeApi, ExecutorDispatch>(545 parachain_config: Configuration,546 polkadot_config: Configuration,547 id: ParaId,548) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>549where550 Runtime: RuntimeInstance + Send + Sync + 'static,551 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,552 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,553 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>554 + Send555 + Sync556 + 'static,557 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>558 + fp_rpc::EthereumRuntimeRPCApi<Block>559 + sp_session::SessionKeys<Block>560 + sp_block_builder::BlockBuilder<Block>561 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>562 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>563 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>564 + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>565 + sp_api::Metadata<Block>566 + sp_offchain::OffchainWorkerApi<Block>567 + cumulus_primitives_core::CollectCollationInfo<Block>568 + sp_consensus_aura::AuraApi<Block, AuraId>,569 ExecutorDispatch: NativeExecutionDispatch + 'static,570{571 start_node_impl::<Runtime, RuntimeApi, ExecutorDispatch, _, _>(572 parachain_config,573 polkadot_config,574 id,575 parachain_build_import_queue,576 |client,577 prometheus_registry,578 telemetry,579 task_manager,580 relay_chain_interface,581 transaction_pool,582 sync_oracle,583 keystore,584 force_authoring| {585 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;586587 let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(588 task_manager.spawn_handle(),589 client.clone(),590 transaction_pool,591 prometheus_registry,592 telemetry.clone(),593 );594595 Ok(AuraConsensus::build::<596 sp_consensus_aura::sr25519::AuthorityPair,597 _,598 _,599 _,600 _,601 _,602 _,603 >(BuildAuraConsensusParams {604 proposer_factory,605 create_inherent_data_providers: move |_, (relay_parent, validation_data)| {606 let relay_chain_interface = relay_chain_interface.clone();607 async move {608 let parachain_inherent =609 cumulus_primitives_parachain_inherent::ParachainInherentData::create_at(610 relay_parent,611 &relay_chain_interface,612 &validation_data,613 id,614 ).await;615616 let time = sp_timestamp::InherentDataProvider::from_system_time();617618 let slot =619 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(620 *time,621 slot_duration.slot_duration(),622 );623624 let parachain_inherent = parachain_inherent.ok_or_else(|| {625 Box::<dyn std::error::Error + Send + Sync>::from(626 "Failed to create parachain inherent",627 )628 })?;629 Ok((time, slot, parachain_inherent))630 }631 },632 block_import: client.clone(),633 para_client: client,634 backoff_authoring_blocks: Option::<()>::None,635 sync_oracle,636 keystore,637 force_authoring,638 slot_duration: *slot_duration,639 // We got around 500ms for proposing640 block_proposal_slot_portion: SlotProportion::new(1f32 / 24f32),641 telemetry,642 max_block_proposal_slot_portion: None,643 }))644 },645 )646 .await647}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//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.1819// std20use std::sync::Arc;21use std::sync::Mutex;22use std::collections::BTreeMap;23use std::time::Duration;24use fc_rpc_core::types::FeeHistoryCache;25use futures::StreamExt;2627use unique_rpc::overrides_handle;2829use serde::{Serialize, Deserialize};3031// Cumulus Imports32use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion};33use cumulus_client_consensus_common::ParachainConsensus;34use cumulus_client_service::{35 prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams,36};37use cumulus_client_network::BlockAnnounceValidator;38use cumulus_primitives_core::ParaId;39use cumulus_relay_chain_interface::RelayChainInterface;40use cumulus_relay_chain_local::build_relay_chain_interface;4142// Substrate Imports43use sc_client_api::ExecutorProvider;44use sc_executor::NativeElseWasmExecutor;45use sc_executor::NativeExecutionDispatch;46use sc_network::NetworkService;47use sc_service::{BasePath, Configuration, PartialComponents, Role, TaskManager};48use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};49use sp_consensus::SlotData;50use sp_keystore::SyncCryptoStorePtr;51use sp_runtime::traits::BlakeTwo256;52use substrate_prometheus_endpoint::Registry;53use sc_client_api::BlockchainEvents;5455// Frontier Imports56use fc_rpc_core::types::FilterPool;57use fc_mapping_sync::{MappingSyncWorker, SyncStrategy};5859// Runtime type overrides60type BlockNumber = u32;61type Header = sp_runtime::generic::Header<BlockNumber, sp_runtime::traits::BlakeTwo256>;62pub type Block = sp_runtime::generic::Block<Header, sp_runtime::OpaqueExtrinsic>;63type Hash = sp_core::H256;6465use unique_runtime_common::types::{AuraId, RuntimeInstance, AccountId, Balance, Index};6667/// Native executor instance.68pub struct UniqueRuntimeExecutor;69pub struct QuartzRuntimeExecutor;70pub struct OpalRuntimeExecutor;7172#[cfg(feature = "unique-runtime")]73impl NativeExecutionDispatch for UniqueRuntimeExecutor {74 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;7576 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {77 unique_runtime::api::dispatch(method, data)78 }7980 fn native_version() -> sc_executor::NativeVersion {81 unique_runtime::native_version()82 }83}8485#[cfg(feature = "quartz-runtime")]86impl NativeExecutionDispatch for QuartzRuntimeExecutor {87 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;8889 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {90 quartz_runtime::api::dispatch(method, data)91 }9293 fn native_version() -> sc_executor::NativeVersion {94 quartz_runtime::native_version()95 }96}9798impl NativeExecutionDispatch for OpalRuntimeExecutor {99 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;100101 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {102 opal_runtime::api::dispatch(method, data)103 }104105 fn native_version() -> sc_executor::NativeVersion {106 opal_runtime::native_version()107 }108}109110pub fn open_frontier_backend(config: &Configuration) -> Result<Arc<fc_db::Backend<Block>>, String> {111 let config_dir = config112 .base_path113 .as_ref()114 .map(|base_path| base_path.config_dir(config.chain_spec.id()))115 .unwrap_or_else(|| {116 BasePath::from_project("", "", "unique").config_dir(config.chain_spec.id())117 });118 let database_dir = config_dir.join("frontier").join("db");119120 Ok(Arc::new(fc_db::Backend::<Block>::new(121 &fc_db::DatabaseSettings {122 source: fc_db::DatabaseSettingsSrc::RocksDb {123 path: database_dir,124 cache_size: 0,125 },126 },127 )?))128}129130type FullClient<RuntimeApi, ExecutorDispatch> =131 sc_service::TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<ExecutorDispatch>>;132type FullBackend = sc_service::TFullBackend<Block>;133type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;134135/// Starts a `ServiceBuilder` for a full service.136///137/// Use this macro if you don't actually need the full service, but just the builder in order to138/// be able to perform chain operations.139#[allow(clippy::type_complexity)]140pub fn new_partial<RuntimeApi, ExecutorDispatch, BIQ>(141 config: &Configuration,142 build_import_queue: BIQ,143) -> Result<144 PartialComponents<145 FullClient<RuntimeApi, ExecutorDispatch>,146 FullBackend,147 FullSelectChain,148 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,149 sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,150 (151 Option<Telemetry>,152 Option<FilterPool>,153 Arc<fc_db::Backend<Block>>,154 Option<TelemetryWorkerHandle>,155 FeeHistoryCache,156 ),157 >,158 sc_service::Error,159>160where161 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,162 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>163 + Send164 + Sync165 + 'static,166 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>,167 ExecutorDispatch: NativeExecutionDispatch + 'static,168 BIQ: FnOnce(169 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,170 &Configuration,171 Option<TelemetryHandle>,172 &TaskManager,173 ) -> Result<174 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,175 sc_service::Error,176 >,177{178 let _telemetry = config179 .telemetry_endpoints180 .clone()181 .filter(|x| !x.is_empty())182 .map(|endpoints| -> Result<_, sc_telemetry::Error> {183 let worker = TelemetryWorker::new(16)?;184 let telemetry = worker.handle().new_telemetry(endpoints);185 Ok((worker, telemetry))186 })187 .transpose()?;188189 let telemetry = config190 .telemetry_endpoints191 .clone()192 .filter(|x| !x.is_empty())193 .map(|endpoints| -> Result<_, sc_telemetry::Error> {194 let worker = TelemetryWorker::new(16)?;195 let telemetry = worker.handle().new_telemetry(endpoints);196 Ok((worker, telemetry))197 })198 .transpose()?;199200 let executor = NativeElseWasmExecutor::<ExecutorDispatch>::new(201 config.wasm_method,202 config.default_heap_pages,203 config.max_runtime_instances,204 config.runtime_cache_size,205 );206207 let (client, backend, keystore_container, task_manager) =208 sc_service::new_full_parts::<Block, RuntimeApi, _>(209 config,210 telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),211 executor,212 )?;213 let client = Arc::new(client);214215 let telemetry_worker_handle = telemetry.as_ref().map(|(worker, _)| worker.handle());216217 let telemetry = telemetry.map(|(worker, telemetry)| {218 task_manager219 .spawn_handle()220 .spawn("telemetry", None, worker.run());221 telemetry222 });223224 let select_chain = sc_consensus::LongestChain::new(backend.clone());225226 let transaction_pool = sc_transaction_pool::BasicPool::new_full(227 config.transaction_pool.clone(),228 config.role.is_authority().into(),229 config.prometheus_registry(),230 task_manager.spawn_essential_handle(),231 client.clone(),232 );233234 let filter_pool: Option<FilterPool> = Some(Arc::new(Mutex::new(BTreeMap::new())));235236 let frontier_backend = open_frontier_backend(config)?;237238 let import_queue = build_import_queue(239 client.clone(),240 config,241 telemetry.as_ref().map(|telemetry| telemetry.handle()),242 &task_manager,243 )?;244 let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new()));245246 let params = PartialComponents {247 backend,248 client,249 import_queue,250 keystore_container,251 task_manager,252 transaction_pool,253 select_chain,254 other: (255 telemetry,256 filter_pool,257 frontier_backend,258 telemetry_worker_handle,259 fee_history_cache,260 ),261 };262263 Ok(params)264}265266/// Start a node with the given parachain `Configuration` and relay chain `Configuration`.267///268/// This is the actual implementation that is abstract over the executor and the runtime api.269#[sc_tracing::logging::prefix_logs_with("Parachain")]270async fn start_node_impl<Runtime, RuntimeApi, ExecutorDispatch, BIQ, BIC>(271 parachain_config: Configuration,272 polkadot_config: Configuration,273 id: ParaId,274 build_import_queue: BIQ,275 build_consensus: BIC,276) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>277where278 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,279 Runtime: RuntimeInstance + Send + Sync + 'static,280 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,281 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,282 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>283 + Send284 + Sync285 + 'static,286 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>287 + fp_rpc::EthereumRuntimeRPCApi<Block>288 + sp_session::SessionKeys<Block>289 + sp_block_builder::BlockBuilder<Block>290 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>291 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>292 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>293 + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>294 + sp_api::Metadata<Block>295 + sp_offchain::OffchainWorkerApi<Block>296 + cumulus_primitives_core::CollectCollationInfo<Block>,297 ExecutorDispatch: NativeExecutionDispatch + 'static,298 BIQ: FnOnce(299 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,300 &Configuration,301 Option<TelemetryHandle>,302 &TaskManager,303 ) -> Result<304 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,305 sc_service::Error,306 >,307 BIC: FnOnce(308 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,309 Option<&Registry>,310 Option<TelemetryHandle>,311 &TaskManager,312 Arc<dyn RelayChainInterface>,313 Arc<sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>>,314 Arc<NetworkService<Block, Hash>>,315 SyncCryptoStorePtr,316 bool,317 ) -> Result<Box<dyn ParachainConsensus<Block>>, sc_service::Error>,318{319 if matches!(parachain_config.role, Role::Light) {320 return Err("Light client not supported!".into());321 }322323 let parachain_config = prepare_node_config(parachain_config);324325 let params =326 new_partial::<RuntimeApi, ExecutorDispatch, BIQ>(¶chain_config, build_import_queue)?;327 let (mut telemetry, filter_pool, frontier_backend, telemetry_worker_handle, fee_history_cache) =328 params.other;329330 let client = params.client.clone();331 let backend = params.backend.clone();332 let mut task_manager = params.task_manager;333334 let (relay_chain_interface, collator_key) =335 build_relay_chain_interface(polkadot_config, telemetry_worker_handle, &mut task_manager)336 .map_err(|e| match e {337 polkadot_service::Error::Sub(x) => x,338 s => format!("{}", s).into(),339 })?;340341 let block_announce_validator = BlockAnnounceValidator::new(relay_chain_interface.clone(), id);342343 let force_authoring = parachain_config.force_authoring;344 let validator = parachain_config.role.is_authority();345 let prometheus_registry = parachain_config.prometheus_registry().cloned();346 let transaction_pool = params.transaction_pool.clone();347 let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue);348349 let (network, system_rpc_tx, start_network) =350 sc_service::build_network(sc_service::BuildNetworkParams {351 config: ¶chain_config,352 client: client.clone(),353 transaction_pool: transaction_pool.clone(),354 spawn_handle: task_manager.spawn_handle(),355 import_queue: import_queue.clone(),356 block_announce_validator_builder: Some(Box::new(|_| {357 Box::new(block_announce_validator)358 })),359 warp_sync: None,360 })?;361362 let subscription_executor = sc_rpc::SubscriptionTaskExecutor::new(task_manager.spawn_handle());363 let rpc_client = client.clone();364 let rpc_pool = transaction_pool.clone();365 let select_chain = params.select_chain.clone();366 let rpc_network = network.clone();367368 let rpc_frontier_backend = frontier_backend.clone();369370 let block_data_cache = Arc::new(fc_rpc::EthBlockDataCache::new(371 task_manager.spawn_handle(),372 overrides_handle::<_, _, Runtime>(client.clone()),373 50,374 50,375 ));376377 let rpc_extensions_builder = Box::new(move |deny_unsafe, _| {378 let full_deps = unique_rpc::FullDeps {379 backend: rpc_frontier_backend.clone(),380 deny_unsafe,381 client: rpc_client.clone(),382 pool: rpc_pool.clone(),383 graph: rpc_pool.pool().clone(),384 // TODO: Unhardcode385 enable_dev_signer: false,386 filter_pool: filter_pool.clone(),387 network: rpc_network.clone(),388 select_chain: select_chain.clone(),389 is_authority: validator,390 // TODO: Unhardcode391 max_past_logs: 10000,392 block_data_cache: block_data_cache.clone(),393 fee_history_cache: fee_history_cache.clone(),394 // TODO: Unhardcode395 fee_history_limit: 2048,396 };397398 Ok(399 unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(400 full_deps,401 subscription_executor.clone(),402 ),403 )404 });405406 task_manager.spawn_essential_handle().spawn(407 "frontier-mapping-sync-worker",408 None,409 MappingSyncWorker::new(410 client.import_notification_stream(),411 Duration::new(6, 0),412 client.clone(),413 backend.clone(),414 frontier_backend.clone(),415 SyncStrategy::Normal,416 )417 .for_each(|()| futures::future::ready(())),418 );419420 sc_service::spawn_tasks(sc_service::SpawnTasksParams {421 rpc_extensions_builder,422 client: client.clone(),423 transaction_pool: transaction_pool.clone(),424 task_manager: &mut task_manager,425 config: parachain_config,426 keystore: params.keystore_container.sync_keystore(),427 backend: backend.clone(),428 network: network.clone(),429 system_rpc_tx,430 telemetry: telemetry.as_mut(),431 })?;432433 let announce_block = {434 let network = network.clone();435 Arc::new(move |hash, data| network.announce_block(hash, data))436 };437438 let relay_chain_slot_duration = Duration::from_secs(6);439440 if validator {441 let parachain_consensus = build_consensus(442 client.clone(),443 prometheus_registry.as_ref(),444 telemetry.as_ref().map(|t| t.handle()),445 &task_manager,446 relay_chain_interface.clone(),447 transaction_pool,448 network,449 params.keystore_container.sync_keystore(),450 force_authoring,451 )?;452453 let spawner = task_manager.spawn_handle();454455 let params = StartCollatorParams {456 para_id: id,457 block_status: client.clone(),458 announce_block,459 client: client.clone(),460 task_manager: &mut task_manager,461 spawner,462 parachain_consensus,463 import_queue,464 collator_key,465 relay_chain_interface,466 relay_chain_slot_duration,467 };468469 start_collator(params).await?;470 } else {471 let params = StartFullNodeParams {472 client: client.clone(),473 announce_block,474 task_manager: &mut task_manager,475 para_id: id,476 import_queue,477 relay_chain_interface,478 relay_chain_slot_duration,479 };480481 start_full_node(params)?;482 }483484 start_network.start_network();485486 Ok((task_manager, client))487}488489/// Build the import queue for the the parachain runtime.490pub fn parachain_build_import_queue<RuntimeApi, ExecutorDispatch>(491 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,492 config: &Configuration,493 telemetry: Option<TelemetryHandle>,494 task_manager: &TaskManager,495) -> Result<496 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,497 sc_service::Error,498>499where500 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>501 + Send502 + Sync503 + 'static,504 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>505 + sp_block_builder::BlockBuilder<Block>506 + sp_consensus_aura::AuraApi<Block, AuraId>507 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,508 ExecutorDispatch: NativeExecutionDispatch + 'static,509{510 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;511512 cumulus_client_consensus_aura::import_queue::<513 sp_consensus_aura::sr25519::AuthorityPair,514 _,515 _,516 _,517 _,518 _,519 _,520 >(cumulus_client_consensus_aura::ImportQueueParams {521 block_import: client.clone(),522 client: client.clone(),523 create_inherent_data_providers: move |_, _| async move {524 let time = sp_timestamp::InherentDataProvider::from_system_time();525526 let slot =527 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(528 *time,529 slot_duration.slot_duration(),530 );531532 Ok((time, slot))533 },534 registry: config.prometheus_registry(),535 can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),536 spawner: &task_manager.spawn_essential_handle(),537 telemetry,538 })539 .map_err(Into::into)540}541542/// Start a normal parachain node.543pub async fn start_node<Runtime, RuntimeApi, ExecutorDispatch>(544 parachain_config: Configuration,545 polkadot_config: Configuration,546 id: ParaId,547) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>548where549 Runtime: RuntimeInstance + Send + Sync + 'static,550 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,551 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,552 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>553 + Send554 + Sync555 + 'static,556 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>557 + fp_rpc::EthereumRuntimeRPCApi<Block>558 + sp_session::SessionKeys<Block>559 + sp_block_builder::BlockBuilder<Block>560 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>561 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>562 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>563 + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>564 + sp_api::Metadata<Block>565 + sp_offchain::OffchainWorkerApi<Block>566 + cumulus_primitives_core::CollectCollationInfo<Block>567 + sp_consensus_aura::AuraApi<Block, AuraId>,568 ExecutorDispatch: NativeExecutionDispatch + 'static,569{570 start_node_impl::<Runtime, RuntimeApi, ExecutorDispatch, _, _>(571 parachain_config,572 polkadot_config,573 id,574 parachain_build_import_queue,575 |client,576 prometheus_registry,577 telemetry,578 task_manager,579 relay_chain_interface,580 transaction_pool,581 sync_oracle,582 keystore,583 force_authoring| {584 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;585586 let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(587 task_manager.spawn_handle(),588 client.clone(),589 transaction_pool,590 prometheus_registry,591 telemetry.clone(),592 );593594 Ok(AuraConsensus::build::<595 sp_consensus_aura::sr25519::AuthorityPair,596 _,597 _,598 _,599 _,600 _,601 _,602 >(BuildAuraConsensusParams {603 proposer_factory,604 create_inherent_data_providers: move |_, (relay_parent, validation_data)| {605 let relay_chain_interface = relay_chain_interface.clone();606 async move {607 let parachain_inherent =608 cumulus_primitives_parachain_inherent::ParachainInherentData::create_at(609 relay_parent,610 &relay_chain_interface,611 &validation_data,612 id,613 ).await;614615 let time = sp_timestamp::InherentDataProvider::from_system_time();616617 let slot =618 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(619 *time,620 slot_duration.slot_duration(),621 );622623 let parachain_inherent = parachain_inherent.ok_or_else(|| {624 Box::<dyn std::error::Error + Send + Sync>::from(625 "Failed to create parachain inherent",626 )627 })?;628 Ok((time, slot, parachain_inherent))629 }630 },631 block_import: client.clone(),632 para_client: client,633 backoff_authoring_blocks: Option::<()>::None,634 sync_oracle,635 keystore,636 force_authoring,637 slot_duration: *slot_duration,638 // We got around 500ms for proposing639 block_proposal_slot_portion: SlotProportion::new(1f32 / 24f32),640 telemetry,641 max_block_proposal_slot_portion: None,642 }))643 },644 )645 .await646}node/rpc/src/lib.rs.expdiffbeforeafterboth--- /dev/null
+++ b/node/rpc/src/lib.rs.exp
@@ -0,0 +1,294 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// 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 sp_runtime::traits::BlakeTwo256;
+use fc_rpc::{
+ EthBlockDataCache, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override,
+ StorageOverride, SchemaV2Override, SchemaV3Override,
+};
+use fc_rpc_core::types::{FilterPool, FeeHistoryCache};
+use jsonrpc_pubsub::manager::SubscriptionManager;
+use pallet_ethereum::EthereumStorageSchema;
+use sc_client_api::{
+ backend::{AuxStore, StorageProvider},
+ client::BlockchainEvents,
+ StateBackend, Backend,
+};
+use sc_finality_grandpa::{
+ FinalityProofProvider, GrandpaJustificationStream, SharedAuthoritySet, SharedVoterState,
+};
+use sc_network::NetworkService;
+use sc_rpc::SubscriptionTaskExecutor;
+pub use sc_rpc_api::DenyUnsafe;
+use sc_transaction_pool::{ChainApi, Pool};
+use sp_api::ProvideRuntimeApi;
+use sp_block_builder::BlockBuilder;
+use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
+use sc_service::TransactionPool;
+use std::{collections::BTreeMap, marker::PhantomData, sync::Arc};
+
+#[cfg(feature = "unique-runtime")]
+use unique_runtime as runtime;
+
+#[cfg(feature = "quartz-runtime")]
+use quartz_runtime as runtime;
+
+#[cfg(feature = "opal-runtime")]
+use opal_runtime as runtime;
+
+use runtime::opaque::{Hash, AccountId, CrossAccountId, Index, Block, BlockNumber, Balance};
+
+/// Public io handler for exporting into other modules
+pub type IoHandler = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
+
+/// Extra dependencies for GRANDPA
+pub struct GrandpaDeps<B> {
+ /// Voting round info.
+ pub shared_voter_state: SharedVoterState,
+ /// Authority set info.
+ pub shared_authority_set: SharedAuthoritySet<Hash, BlockNumber>,
+ /// Receives notifications about justification events from Grandpa.
+ pub justification_stream: GrandpaJustificationStream<Block>,
+ /// Executor to drive the subscription manager in the Grandpa RPC handler.
+ pub subscription_executor: SubscriptionTaskExecutor,
+ /// Finality proof provider.
+ pub finality_provider: Arc<FinalityProofProvider<B, Block>>,
+}
+
+/// Full client dependencies.
+pub struct FullDeps<C, P, SC, CA: ChainApi> {
+ /// The client instance to use.
+ pub client: Arc<C>,
+ /// Transaction pool instance.
+ pub pool: Arc<P>,
+ /// Graph pool instance.
+ pub graph: Arc<Pool<CA>>,
+ /// The SelectChain Strategy
+ pub select_chain: SC,
+ /// The Node authority flag
+ pub is_authority: bool,
+ /// Whether to enable dev signer
+ pub enable_dev_signer: bool,
+ /// Network service
+ pub network: Arc<NetworkService<Block, Hash>>,
+ /// Whether to deny unsafe calls
+ pub deny_unsafe: DenyUnsafe,
+ /// EthFilterApi pool.
+ pub filter_pool: Option<FilterPool>,
+ /// Backend.
+ pub backend: Arc<fc_db::Backend<Block>>,
+ /// Maximum number of logs in a query.
+ pub max_past_logs: u32,
+ /// Maximum fee history cache size.
+ pub fee_history_limit: u64,
+ /// Fee history cache.
+ pub fee_history_cache: FeeHistoryCache,
+ /// Cache for Ethereum block data.
+ pub block_data_cache: Arc<EthBlockDataCache<Block>>,
+}
+
+struct AccountCodes<C, B, CAId> {
+ client: Arc<C>,
+ _blk_marker: PhantomData<B>,
+ _caid_marker: PhantomData<CAId>,
+}
+
+impl<C, Block, CAId> AccountCodes<C, Block, CAId>
+where
+ Block: sp_api::BlockT,
+ C: ProvideRuntimeApi<Block>,
+{
+ fn new(client: Arc<C>) -> Self {
+ Self {
+ client,
+ _blk_marker: PhantomData,
+ _caid_marker: PhantomData,
+ }
+ }
+}
+
+impl<C, Block, CAId> fc_rpc::AccountCodeProvider<Block> for AccountCodes<C, Block, CAId>
+where
+ Block: sp_api::BlockT,
+ C: ProvideRuntimeApi<Block>,
+ C::Api: up_rpc::UniqueApi<Block, CAId, AccountId>,
+ CAId: pallet_common::account::CrossAccountId<sp_runtime::AccountId32>,
+{
+ fn code(&self, block: &sp_api::BlockId<Block>, account: sp_core::H160) -> Option<Vec<u8>> {
+ use up_rpc::UniqueApi;
+ self.client
+ .runtime_api()
+ .eth_contract_code(block, account)
+ .ok()
+ .flatten()
+ }
+}
+
+pub fn overrides_handle<C, BE, CAId>(client: Arc<C>) -> Arc<OverrideHandle<Block>>
+where
+ C: ProvideRuntimeApi<Block> + StorageProvider<Block, BE> + AuxStore,
+ C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError>,
+ C: Send + Sync + 'static,
+ C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,
+ C::Api: up_rpc::UniqueApi<Block, CAId, AccountId>,
+ BE: Backend<Block> + 'static,
+ BE::State: StateBackend<BlakeTwo256>,
+ CAId: pallet_common::account::CrossAccountId<sp_runtime::AccountId32> + Sync + Send + 'static,
+{
+ let mut overrides_map = BTreeMap::new();
+ overrides_map.insert(
+ EthereumStorageSchema::V1,
+ Box::new(SchemaV1Override::new_with_code_provider(
+ client.clone(),
+ Arc::new(AccountCodes::<C, Block, CAId>::new(client.clone())),
+ )) as Box<dyn StorageOverride<_> + Send + Sync>,
+ );
+ overrides_map.insert(
+ EthereumStorageSchema::V2,
+ Box::new(SchemaV2Override::new(client.clone()))
+ as Box<dyn StorageOverride<_> + Send + Sync>,
+ );
+ overrides_map.insert(
+ EthereumStorageSchema::V3,
+ Box::new(SchemaV3Override::new(client.clone()))
+ as Box<dyn StorageOverride<_> + Send + Sync>,
+ );
+
+ Arc::new(OverrideHandle {
+ schemas: overrides_map,
+ fallback: Box::new(RuntimeApiStorageOverride::new(client)),
+ })
+}
+
+/// Instantiate all Full RPC extensions.
+pub fn create_full<C, P, SC, CA, CAId, A, B>(
+ deps: FullDeps<C, P, SC, CA>,
+ subscription_task_executor: SubscriptionTaskExecutor,
+) -> jsonrpc_core::IoHandler<sc_rpc_api::Metadata>
+where
+ C: ProvideRuntimeApi<Block> + StorageProvider<Block, B> + AuxStore,
+ C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
+ C: Send + Sync + 'static,
+ C: BlockchainEvents<Block>,
+ C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
+ C::Api: BlockBuilder<Block>,
+ // C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber, Hash>,
+ C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
+ C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,
+ C::Api: up_rpc::UniqueApi<Block, CAId, AccountId>,
+ B: sc_client_api::Backend<Block> + Send + Sync + 'static,
+ B::State: sc_client_api::backend::StateBackend<sp_runtime::traits::HashFor<Block>>,
+ P: TransactionPool<Block = Block> + 'static,
+ CA: ChainApi<Block = Block> + 'static,
+ CAId: pallet_common::account::CrossAccountId<sp_runtime::AccountId32> + Sync + Send + 'static,
+{
+ use fc_rpc::{
+ EthApi, EthApiServer, EthDevSigner, EthFilterApi, EthFilterApiServer, EthPubSubApi,
+ EthPubSubApiServer, EthSigner, HexEncodedIdProvider, NetApi, NetApiServer, Web3Api,
+ Web3ApiServer,
+ };
+ use uc_rpc::{UniqueApi, Unique};
+ // use pallet_contracts_rpc::{Contracts, ContractsApi};
+ use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
+ use substrate_frame_rpc_system::{FullSystem, SystemApi};
+
+ let mut io = jsonrpc_core::IoHandler::default();
+ let FullDeps {
+ client,
+ pool,
+ graph,
+ select_chain: _,
+ fee_history_limit,
+ fee_history_cache,
+ block_data_cache,
+ enable_dev_signer,
+ is_authority,
+ network,
+ deny_unsafe,
+ filter_pool,
+ backend,
+ max_past_logs,
+ } = deps;
+
+ io.extend_with(SystemApi::to_delegate(FullSystem::new(
+ client.clone(),
+ pool.clone(),
+ deny_unsafe,
+ )));
+
+ io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(
+ client.clone(),
+ )));
+
+ // io.extend_with(ContractsApi::to_delegate(Contracts::new(client.clone())));
+
+ let mut signers = Vec::new();
+ if enable_dev_signer {
+ signers.push(Box::new(EthDevSigner::new()) as Box<dyn EthSigner>);
+ }
+
+ let overrides = overrides_handle::<_, _, CAId>(client.clone());
+
+ io.extend_with(EthApiServer::to_delegate(EthApi::new(
+ client.clone(),
+ pool.clone(),
+ graph,
+ runtime::TransactionConverter,
+ network.clone(),
+ signers,
+ overrides.clone(),
+ backend.clone(),
+ is_authority,
+ max_past_logs,
+ block_data_cache.clone(),
+ fee_history_limit,
+ fee_history_cache,
+ )));
+ io.extend_with(UniqueApi::to_delegate(Unique::new(client.clone())));
+
+ if let Some(filter_pool) = filter_pool {
+ io.extend_with(EthFilterApiServer::to_delegate(EthFilterApi::new(
+ client.clone(),
+ backend,
+ filter_pool,
+ 500_usize, // max stored filters
+ max_past_logs,
+ block_data_cache,
+ )));
+ }
+
+ io.extend_with(NetApiServer::to_delegate(NetApi::new(
+ client.clone(),
+ network.clone(),
+ // Whether to format the `peer_count` response as Hex (default) or not.
+ true,
+ )));
+
+ io.extend_with(Web3ApiServer::to_delegate(Web3Api::new(client.clone())));
+
+ io.extend_with(EthPubSubApiServer::to_delegate(EthPubSubApi::new(
+ pool,
+ client,
+ network,
+ SubscriptionManager::<HexEncodedIdProvider>::with_id_provider(
+ HexEncodedIdProvider::default(),
+ Arc::new(subscription_task_executor),
+ ),
+ overrides,
+ )));
+
+ io
+}