diff --git a/polkadot-parachains/src/chain_spec.rs b/polkadot-parachains/src/chain_spec.rs index 2c32602..b7be0e3 100644 --- a/polkadot-parachains/src/chain_spec.rs +++ b/polkadot-parachains/src/chain_spec.rs @@ -28,7 +28,7 @@ use sp_keyring::AccountKeyring::{Alice, Bob, Dave, Eve}; use std::str::FromStr; /// Specialized `ChainSpec` for the normal parachain runtime. -pub type ChainSpec = sc_service::GenericChainSpec<(), Extensions>; +pub type ChainSpec = sc_service::GenericChainSpec; /// The default XCM version to set in genesis config. const SAFE_XCM_VERSION: u32 = staging_xcm::prelude::XCM_VERSION; diff --git a/polkadot-parachains/src/cli.rs b/polkadot-parachains/src/cli.rs index 957b7e8..4f100de 100644 --- a/polkadot-parachains/src/cli.rs +++ b/polkadot-parachains/src/cli.rs @@ -40,11 +40,6 @@ pub enum Subcommand { /// The pallet benchmarking moved to the `pallet` sub-command. #[command(subcommand)] Benchmark(frame_benchmarking_cli::BenchmarkCmd), - - /// Try-runtime has migrated to a standalone - /// [CLI](). The subcommand exists as a stub and - /// deprecation notice. It will be removed entirely some time after January 2024. - TryRuntime, } const AFTER_HELP_EXAMPLE: &str = color_print::cstr!( diff --git a/polkadot-parachains/src/command.rs b/polkadot-parachains/src/command.rs index fab689d..e384c8a 100644 --- a/polkadot-parachains/src/command.rs +++ b/polkadot-parachains/src/command.rs @@ -1,20 +1,3 @@ -// Copyright 2021 Integritee AG and Supercomputing Systems AG -// This file is part of the "Integritee parachain" and is -// based on Cumulus from Parity Technologies (UK) Ltd. - -// Integritee parachain 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. - -// Cumulus 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 Integritee parachain. If not, see . - //! //! this file DOES HAVE CUSTOMIZATIONS for integritee runtimes. Upon upgrades of polkadot-sdk, //! look for blocks with `is_shell()` branching @@ -242,170 +225,166 @@ pub fn run() -> Result<()> { let cli = Cli::from_args(); match &cli.subcommand { - Some(Subcommand::BuildSpec(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| cmd.run(config.chain_spec, config.network)) - } - Some(Subcommand::CheckBlock(cmd)) => { - construct_async_run!(|components, cli, cmd, config| { + Some(Subcommand::BuildSpec(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| cmd.run(config.chain_spec, config.network)) + }, + Some(Subcommand::CheckBlock(cmd)) => { + construct_async_run!(|components, cli, cmd, config| { Ok(cmd.run(components.client, components.import_queue)) }) - } - Some(Subcommand::ExportBlocks(cmd)) => { - construct_async_run!(|components, cli, cmd, config| { + }, + Some(Subcommand::ExportBlocks(cmd)) => { + construct_async_run!(|components, cli, cmd, config| { Ok(cmd.run(components.client, config.database)) }) - } - Some(Subcommand::ExportState(cmd)) => { - construct_async_run!(|components, cli, cmd, config| { + }, + Some(Subcommand::ExportState(cmd)) => { + construct_async_run!(|components, cli, cmd, config| { Ok(cmd.run(components.client, config.chain_spec)) }) - } - Some(Subcommand::ImportBlocks(cmd)) => { - construct_async_run!(|components, cli, cmd, config| { + }, + Some(Subcommand::ImportBlocks(cmd)) => { + construct_async_run!(|components, cli, cmd, config| { Ok(cmd.run(components.client, components.import_queue)) }) - } - Some(Subcommand::Revert(cmd)) => { - construct_async_run!(|components, cli, cmd, config| { + }, + Some(Subcommand::Revert(cmd)) => { + construct_async_run!(|components, cli, cmd, config| { Ok(cmd.run(components.client, components.backend, None)) }) - } - Some(Subcommand::PurgeChain(cmd)) => { - let runner = cli.create_runner(cmd)?; - - runner.sync_run(|config| { - let polkadot_cli = RelayChainCli::new( - &config, - [RelayChainCli::executable_name()].iter().chain(cli.relay_chain_args.iter()), - ); - - let polkadot_config = SubstrateCli::create_configuration( - &polkadot_cli, - &polkadot_cli, - config.tokio_handle.clone(), - ) - .map_err(|err| format!("Relay chain argument error: {}", err))?; - - cmd.run(config, polkadot_config) - }) - } - Some(Subcommand::ExportGenesisHead(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| { - construct_partials!(config, |partials| cmd.run(partials.client)) - }) - } - Some(Subcommand::ExportGenesisWasm(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.sync_run(|_config| { - let spec = cli.load_spec(&cmd.shared_params.chain.clone().unwrap_or_default())?; - cmd.run(&*spec) - }) - } - Some(Subcommand::Benchmark(cmd)) => { - let runner = cli.create_runner(cmd)?; - // Switch on the concrete benchmark sub-command- - match cmd { - BenchmarkCmd::Pallet(cmd) => - if cfg!(feature = "runtime-benchmarks") { - runner.sync_run(|config| cmd.run::, ReclaimHostFunctions>(config)) - } else { - Err("Benchmarking wasn't enabled when building the node. \ + }, + Some(Subcommand::PurgeChain(cmd)) => { + let runner = cli.create_runner(cmd)?; + + runner.sync_run(|config| { + let polkadot_cli = RelayChainCli::new( + &config, + [RelayChainCli::executable_name()].iter().chain(cli.relay_chain_args.iter()), + ); + + let polkadot_config = SubstrateCli::create_configuration( + &polkadot_cli, + &polkadot_cli, + config.tokio_handle.clone(), + ) + .map_err(|err| format!("Relay chain argument error: {}", err))?; + + cmd.run(config, polkadot_config) + }) + }, + Some(Subcommand::ExportGenesisHead(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner + .sync_run(|config| construct_partials!(config, |partials| cmd.run(partials.client))) + }, + Some(Subcommand::ExportGenesisWasm(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|_config| { + let spec = cli.load_spec(&cmd.shared_params.chain.clone().unwrap_or_default())?; + cmd.run(&*spec) + }) + }, + Some(Subcommand::Benchmark(cmd)) => { + let runner = cli.create_runner(cmd)?; + // Switch on the concrete benchmark sub-command- + match cmd { + BenchmarkCmd::Pallet(cmd) => + if cfg!(feature = "runtime-benchmarks") { + runner.sync_run(|config| cmd.run_with_spec::, ReclaimHostFunctions>(Some(config.chain_spec))) + } else { + Err("Benchmarking wasn't enabled when building the node. \ You can enable it with `--features runtime-benchmarks`." - .into()) - }, - BenchmarkCmd::Block(cmd) => runner.sync_run(|config| { - construct_partials!(config, |partials| cmd.run(partials.client)) - }), - #[cfg(not(feature = "runtime-benchmarks"))] - BenchmarkCmd::Storage(_) => - return Err(sc_cli::Error::Input( - "Compile with --features=runtime-benchmarks \ + .into()) + }, + BenchmarkCmd::Block(cmd) => runner.sync_run(|config| { + construct_partials!(config, |partials| cmd.run(partials.client)) + }), + #[cfg(not(feature = "runtime-benchmarks"))] + BenchmarkCmd::Storage(_) => Err(sc_cli::Error::Input( + "Compile with --features=runtime-benchmarks \ to enable storage benchmarks." - .into(), - ) - .into()), - #[cfg(feature = "runtime-benchmarks")] - BenchmarkCmd::Storage(cmd) => runner.sync_run(|config| { - construct_partials!(config, |partials| { + .into(), + )), + #[cfg(feature = "runtime-benchmarks")] + BenchmarkCmd::Storage(cmd) => runner.sync_run(|config| { + construct_partials!(config, |partials| { let db = partials.backend.expose_db(); let storage = partials.backend.expose_storage(); cmd.run(config, partials.client.clone(), db, storage) }) - }), - BenchmarkCmd::Machine(cmd) => - runner.sync_run(|config| cmd.run(&config, SUBSTRATE_REFERENCE_HARDWARE.clone())), - // NOTE: this allows the Client to leniently implement - // new benchmark commands without requiring a companion MR. - #[allow(unreachable_patterns)] - _ => Err("Benchmarking sub-command unsupported".into()), - } - } - Some(Subcommand::TryRuntime) => Err("The `try-runtime` subcommand has been migrated to a standalone CLI (https://github.com/paritytech/try-runtime-cli). It is no longer being maintained here and will be removed entirely some time after January 2024. Please remove this subcommand from your runtime and use the standalone CLI.".into()), - None => { - let runner = cli.create_runner(&cli.run.normalize())?; - let collator_options = cli.run.collator_options(); - - runner.run_node_until_exit(|config| async move { - let hwbench = (!cli.no_hardware_benchmarks) - .then_some(config.database.path().map(|database_path| { - let _ = std::fs::create_dir_all(database_path); - sc_sysinfo::gather_hwbench(Some(database_path)) - })) - .flatten(); - - let para_id = chain_spec::Extensions::try_get(&*config.chain_spec) - .map(|e| e.para_id) - .ok_or("Could not find parachain ID in chain-spec.")?; - - let polkadot_cli = RelayChainCli::new( - &config, - [RelayChainCli::executable_name()].iter().chain(cli.relay_chain_args.iter()), - ); - - let id = ParaId::from(para_id); - - let parachain_account = - AccountIdConversion::::into_account_truncating( - &id, - ); - - let tokio_handle = config.tokio_handle.clone(); - let polkadot_config = - SubstrateCli::create_configuration(&polkadot_cli, &polkadot_cli, tokio_handle) - .map_err(|err| format!("Relay chain argument error: {}", err))?; - - info!("Parachain Account: {parachain_account}"); - info!("Is collating: {}", if config.role.is_authority() { "yes" } else { "no" }); - - if config.chain_spec.is_shell() { - crate::service_shell::start_parachain_node( - config, - polkadot_config, - collator_options, - id, - hwbench, - ) - .await - .map(|r| r.0) - .map_err(Into::into) - } else { - crate::service::start_parachain_node( - config, - polkadot_config, - collator_options, - id, - hwbench, - ) - .await - .map(|r| r.0) - .map_err(Into::into) - } - }) - } - } + }), + BenchmarkCmd::Machine(cmd) => + runner.sync_run(|config| cmd.run(&config, SUBSTRATE_REFERENCE_HARDWARE.clone())), + // NOTE: this allows the Client to leniently implement + // new benchmark commands without requiring a companion MR. + #[allow(unreachable_patterns)] + _ => Err("Benchmarking sub-command unsupported".into()), + } + }, + None => { + let runner = cli.create_runner(&cli.run.normalize())?; + let collator_options = cli.run.collator_options(); + + runner.run_node_until_exit(|config| async move { + let hwbench = (!cli.no_hardware_benchmarks) + .then_some(config.database.path().map(|database_path| { + let _ = std::fs::create_dir_all(database_path); + sc_sysinfo::gather_hwbench(Some(database_path)) + })) + .flatten(); + + let para_id = chain_spec::Extensions::try_get(&*config.chain_spec) + .map(|e| e.para_id) + .ok_or("Could not find parachain ID in chain-spec.")?; + + let polkadot_cli = RelayChainCli::new( + &config, + [RelayChainCli::executable_name()].iter().chain(cli.relay_chain_args.iter()), + ); + + let id = ParaId::from(para_id); + + let parachain_account = + AccountIdConversion::::into_account_truncating( + &id, + ); + + let tokio_handle = config.tokio_handle.clone(); + let polkadot_config = + SubstrateCli::create_configuration(&polkadot_cli, &polkadot_cli, tokio_handle) + .map_err(|err| format!("Relay chain argument error: {}", err))?; + + info!("Parachain Account: {parachain_account}"); + info!("Is collating: {}", if config.role.is_authority() { "yes" } else { "no" }); + + if config.chain_spec.is_shell() { + crate::service_shell::start_parachain_node( + config, + polkadot_config, + collator_options, + id, + hwbench, + ) + .await + .map(|r| r.0) + .map_err(Into::into) + } else { + crate::service::start_parachain_node( + config, + polkadot_config, + collator_options, + id, + hwbench, + ) + .await + .map(|r| r.0) + .map_err(Into::into) + } + }) + }, + } } impl DefaultConfigurationValues for RelayChainCli { diff --git a/polkadot-parachains/src/service.rs b/polkadot-parachains/src/service.rs index 55b0071..5b63bd2 100644 --- a/polkadot-parachains/src/service.rs +++ b/polkadot-parachains/src/service.rs @@ -1,7 +1,7 @@ //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. -//! -//! this file has no customizations for integritee runtimes. Upon upgrades of polkadot-sdk, -//! just overwrite from parachain_template and replace name of runtime crate + +// Integritee customization +use substrate_prometheus_endpoint as prometheus_endpoint; // std use std::{sync::Arc, time::Duration}; @@ -13,6 +13,7 @@ use integritee_runtime::RuntimeApi; // Cumulus Imports use cumulus_client_collator::service::CollatorService; +use cumulus_client_consensus_aura::collators::lookahead::{self as aura, Params as AuraParams}; use cumulus_client_consensus_common::ParachainBlockImport as TParachainBlockImport; use cumulus_client_consensus_proposer::Proposer; use cumulus_client_service::{ @@ -20,11 +21,15 @@ use cumulus_client_service::{ BuildNetworkParams, CollatorSybilResistance, DARecoveryProfile, ParachainHostFunctions, StartRelayChainTasksParams, }; -use cumulus_primitives_core::{relay_chain::CollatorPair, ParaId}; +use cumulus_primitives_core::{ + relay_chain::{CollatorPair, ValidationCode}, + ParaId, +}; use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface}; // Substrate Imports use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE; +use prometheus_endpoint::Registry; use sc_client_api::Backend; use sc_consensus::ImportQueue; use sc_executor::{HeapAllocStrategy, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY}; @@ -34,7 +39,6 @@ use sc_service::{Configuration, PartialComponents, TFullBackend, TFullClient, Ta use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle}; use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sp_keystore::KeystorePtr; -use substrate_prometheus_endpoint::Registry; type ParachainExecutor = WasmExecutor; @@ -114,7 +118,7 @@ pub fn new_partial(config: &Configuration) -> Result config, telemetry.as_ref().map(|telemetry| telemetry.handle()), &task_manager, - )?; + ); Ok(PartialComponents { backend, @@ -128,11 +132,103 @@ pub fn new_partial(config: &Configuration) -> Result }) } +/// Build the import queue for the parachain runtime. +fn build_import_queue( + client: Arc, + block_import: ParachainBlockImport, + config: &Configuration, + telemetry: Option, + task_manager: &TaskManager, +) -> sc_consensus::DefaultImportQueue { + cumulus_client_consensus_aura::equivocation_import_queue::fully_verifying_import_queue::< + sp_consensus_aura::sr25519::AuthorityPair, + _, + _, + _, + _, + >( + client, + block_import, + move |_, _| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + Ok(timestamp) + }, + &task_manager.spawn_essential_handle(), + config.prometheus_registry(), + telemetry, + ) +} + +#[allow(clippy::too_many_arguments)] +fn start_consensus( + client: Arc, + backend: Arc, + block_import: ParachainBlockImport, + prometheus_registry: Option<&Registry>, + telemetry: Option, + task_manager: &TaskManager, + relay_chain_interface: Arc, + transaction_pool: Arc>, + sync_oracle: Arc>, + keystore: KeystorePtr, + relay_chain_slot_duration: Duration, + para_id: ParaId, + collator_key: CollatorPair, + overseer_handle: OverseerHandle, + announce_block: Arc>) + Send + Sync>, +) -> Result<(), sc_service::Error> { + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + task_manager.spawn_handle(), + client.clone(), + transaction_pool, + prometheus_registry, + telemetry.clone(), + ); + + let proposer = Proposer::new(proposer_factory); + + let collator_service = CollatorService::new( + client.clone(), + Arc::new(task_manager.spawn_handle()), + announce_block, + client.clone(), + ); + + let params = AuraParams { + create_inherent_data_providers: move |_, ()| async move { Ok(()) }, + block_import, + para_client: client.clone(), + para_backend: backend, + relay_client: relay_chain_interface, + code_hash_provider: move |block_hash| { + client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()) + }, + sync_oracle, + keystore, + collator_key, + para_id, + overseer_handle, + relay_chain_slot_duration, + proposer, + collator_service, + authoring_duration: Duration::from_millis(2000), + reinitialize: false, + }; + + let fut = + aura::run::( + params, + ); + task_manager.spawn_essential_handle().spawn("aura", None, fut); + + Ok(()) +} + /// Start a node with the given parachain `Configuration` and relay chain `Configuration`. /// /// This is the actual implementation that is abstract over the executor and the runtime api. #[sc_tracing::logging::prefix_logs_with("Parachain")] -async fn start_node_impl( +pub async fn start_parachain_node( parachain_config: Configuration, polkadot_config: Configuration, collator_options: CollatorOptions, @@ -143,7 +239,11 @@ async fn start_node_impl( let params = new_partial(¶chain_config)?; let (block_import, mut telemetry, telemetry_worker_handle) = params.other; - let net_config = sc_network::config::FullNetworkConfiguration::new(¶chain_config.network); + let net_config = sc_network::config::FullNetworkConfiguration::< + _, + _, + sc_network::NetworkWorker, + >::new(¶chain_config.network); let client = params.client.clone(); let backend = params.backend.clone(); @@ -165,6 +265,8 @@ async fn start_node_impl( let transaction_pool = params.transaction_pool.clone(); let import_queue_service = params.import_queue.service(); + // NOTE: because we use Aura here explicitly, we can use `CollatorSybilResistance::Resistant` + // when starting the network. let (network, system_rpc_tx, tx_handler_controller, start_network, sync_service) = build_network(BuildNetworkParams { parachain_config: ¶chain_config, @@ -192,7 +294,7 @@ async fn start_node_impl( transaction_pool: Some(OffchainTransactionPoolFactory::new( transaction_pool.clone(), )), - network_provider: network.clone(), + network_provider: Arc::new(network.clone()), is_validator: parachain_config.role.is_authority(), enable_http_requests: false, custom_extensions: move |_| vec![], @@ -224,8 +326,8 @@ async fn start_node_impl( task_manager: &mut task_manager, config: parachain_config, keystore: params.keystore_container.keystore(), - backend, - network: network.clone(), + backend: backend.clone(), + network, sync_service: sync_service.clone(), system_rpc_tx, tx_handler_controller, @@ -288,13 +390,14 @@ async fn start_node_impl( if validator { start_consensus( client.clone(), + backend, block_import, prometheus_registry.as_ref(), telemetry.as_ref().map(|t| t.handle()), &task_manager, - relay_chain_interface.clone(), + relay_chain_interface, transaction_pool, - sync_service.clone(), + sync_service, params.keystore_container.keystore(), relay_chain_slot_duration, para_id, @@ -308,114 +411,3 @@ async fn start_node_impl( Ok((task_manager, client)) } - -/// Build the import queue for the parachain runtime. -fn build_import_queue( - client: Arc, - block_import: ParachainBlockImport, - config: &Configuration, - telemetry: Option, - task_manager: &TaskManager, -) -> Result, sc_service::Error> { - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; - - Ok(cumulus_client_consensus_aura::equivocation_import_queue::fully_verifying_import_queue::< - sp_consensus_aura::sr25519::AuthorityPair, - _, - _, - _, - _, - >( - client, - block_import, - move |_, _| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - Ok(timestamp) - }, - slot_duration, - &task_manager.spawn_essential_handle(), - config.prometheus_registry(), - telemetry, - )) -} - -fn start_consensus( - client: Arc, - block_import: ParachainBlockImport, - prometheus_registry: Option<&Registry>, - telemetry: Option, - task_manager: &TaskManager, - relay_chain_interface: Arc, - transaction_pool: Arc>, - sync_oracle: Arc>, - keystore: KeystorePtr, - relay_chain_slot_duration: Duration, - para_id: ParaId, - collator_key: CollatorPair, - overseer_handle: OverseerHandle, - announce_block: Arc>) + Send + Sync>, -) -> Result<(), sc_service::Error> { - use cumulus_client_consensus_aura::collators::basic::{ - self as basic_aura, Params as BasicAuraParams, - }; - - // NOTE: because we use Aura here explicitly, we can use `CollatorSybilResistance::Resistant` - // when starting the network. - - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; - - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( - task_manager.spawn_handle(), - client.clone(), - transaction_pool, - prometheus_registry, - telemetry.clone(), - ); - - let proposer = Proposer::new(proposer_factory); - - let collator_service = CollatorService::new( - client.clone(), - Arc::new(task_manager.spawn_handle()), - announce_block, - client.clone(), - ); - - let params = BasicAuraParams { - create_inherent_data_providers: move |_, ()| async move { Ok(()) }, - block_import, - para_client: client, - relay_client: relay_chain_interface, - sync_oracle, - keystore, - collator_key, - para_id, - overseer_handle, - slot_duration, - relay_chain_slot_duration, - proposer, - collator_service, - // Very limited proposal time. - authoring_duration: Duration::from_millis(500), - collation_request_receiver: None, - }; - - let fut = - basic_aura::run::( - params, - ); - task_manager.spawn_essential_handle().spawn("aura", None, fut); - - Ok(()) -} - -/// Start a parachain node. -pub async fn start_parachain_node( - parachain_config: Configuration, - polkadot_config: Configuration, - collator_options: CollatorOptions, - para_id: ParaId, - hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc)> { - start_node_impl(parachain_config, polkadot_config, collator_options, para_id, hwbench).await -} diff --git a/polkadot-parachains/src/service_shell.rs b/polkadot-parachains/src/service_shell.rs index 1feb26c..cc23854 100644 --- a/polkadot-parachains/src/service_shell.rs +++ b/polkadot-parachains/src/service_shell.rs @@ -1,7 +1,7 @@ //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. -//! -//! this file has no customizations for integritee runtimes. Upon upgrades of polkadot-sdk, -//! just overwrite from parachain_template and replace name of runtime crate + +// Integritee customization +use substrate_prometheus_endpoint as prometheus_endpoint; // std use std::{sync::Arc, time::Duration}; @@ -13,6 +13,7 @@ use shell_runtime::RuntimeApi; // Cumulus Imports use cumulus_client_collator::service::CollatorService; +use cumulus_client_consensus_aura::collators::lookahead::{self as aura, Params as AuraParams}; use cumulus_client_consensus_common::ParachainBlockImport as TParachainBlockImport; use cumulus_client_consensus_proposer::Proposer; use cumulus_client_service::{ @@ -20,11 +21,15 @@ use cumulus_client_service::{ BuildNetworkParams, CollatorSybilResistance, DARecoveryProfile, ParachainHostFunctions, StartRelayChainTasksParams, }; -use cumulus_primitives_core::{relay_chain::CollatorPair, ParaId}; +use cumulus_primitives_core::{ + relay_chain::{CollatorPair, ValidationCode}, + ParaId, +}; use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface}; // Substrate Imports use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE; +use prometheus_endpoint::Registry; use sc_client_api::Backend; use sc_consensus::ImportQueue; use sc_executor::{HeapAllocStrategy, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY}; @@ -34,7 +39,6 @@ use sc_service::{Configuration, PartialComponents, TFullBackend, TFullClient, Ta use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle}; use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sp_keystore::KeystorePtr; -use substrate_prometheus_endpoint::Registry; type ParachainExecutor = WasmExecutor; @@ -114,7 +118,7 @@ pub fn new_partial(config: &Configuration) -> Result config, telemetry.as_ref().map(|telemetry| telemetry.handle()), &task_manager, - )?; + ); Ok(PartialComponents { backend, @@ -128,11 +132,101 @@ pub fn new_partial(config: &Configuration) -> Result }) } +/// Build the import queue for the parachain runtime. +fn build_import_queue( + client: Arc, + block_import: ParachainBlockImport, + config: &Configuration, + telemetry: Option, + task_manager: &TaskManager, +) -> sc_consensus::DefaultImportQueue { + cumulus_client_consensus_aura::equivocation_import_queue::fully_verifying_import_queue::< + sp_consensus_aura::sr25519::AuthorityPair, + _, + _, + _, + _, + >( + client, + block_import, + move |_, _| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + Ok(timestamp) + }, + &task_manager.spawn_essential_handle(), + config.prometheus_registry(), + telemetry, + ) +} + +#[allow(clippy::too_many_arguments)] +fn start_consensus( + client: Arc, + backend: Arc, + block_import: ParachainBlockImport, + prometheus_registry: Option<&Registry>, + telemetry: Option, + task_manager: &TaskManager, + relay_chain_interface: Arc, + transaction_pool: Arc>, + sync_oracle: Arc>, + keystore: KeystorePtr, + relay_chain_slot_duration: Duration, + para_id: ParaId, + collator_key: CollatorPair, + overseer_handle: OverseerHandle, + announce_block: Arc>) + Send + Sync>, +) -> Result<(), sc_service::Error> { + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + task_manager.spawn_handle(), + client.clone(), + transaction_pool, + prometheus_registry, + telemetry.clone(), + ); + + let proposer = Proposer::new(proposer_factory); + + let collator_service = CollatorService::new( + client.clone(), + Arc::new(task_manager.spawn_handle()), + announce_block, + client.clone(), + ); + + let params = AuraParams { + create_inherent_data_providers: move |_, ()| async move { Ok(()) }, + block_import, + para_client: client.clone(), + para_backend: backend, + relay_client: relay_chain_interface, + code_hash_provider: move |block_hash| { + client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()) + }, + sync_oracle, + keystore, + collator_key, + para_id, + overseer_handle, + relay_chain_slot_duration, + proposer, + collator_service, + authoring_duration: Duration::from_millis(2000), + reinitialize: false, + }; + + let fut = + aura::run::( + params, + ); + task_manager.spawn_essential_handle().spawn("aura", None, fut); + + Ok(()) +} + /// Start a node with the given parachain `Configuration` and relay chain `Configuration`. -/// -/// This is the actual implementation that is abstract over the executor and the runtime api. #[sc_tracing::logging::prefix_logs_with("Parachain")] -async fn start_node_impl( +pub async fn start_parachain_node( parachain_config: Configuration, polkadot_config: Configuration, collator_options: CollatorOptions, @@ -143,7 +237,11 @@ async fn start_node_impl( let params = new_partial(¶chain_config)?; let (block_import, mut telemetry, telemetry_worker_handle) = params.other; - let net_config = sc_network::config::FullNetworkConfiguration::new(¶chain_config.network); + let net_config = sc_network::config::FullNetworkConfiguration::< + _, + _, + sc_network::NetworkWorker, + >::new(¶chain_config.network); let client = params.client.clone(); let backend = params.backend.clone(); @@ -165,6 +263,8 @@ async fn start_node_impl( let transaction_pool = params.transaction_pool.clone(); let import_queue_service = params.import_queue.service(); + // NOTE: because we use Aura here explicitly, we can use `CollatorSybilResistance::Resistant` + // when starting the network. let (network, system_rpc_tx, tx_handler_controller, start_network, sync_service) = build_network(BuildNetworkParams { parachain_config: ¶chain_config, @@ -192,7 +292,7 @@ async fn start_node_impl( transaction_pool: Some(OffchainTransactionPoolFactory::new( transaction_pool.clone(), )), - network_provider: network.clone(), + network_provider: Arc::new(network.clone()), is_validator: parachain_config.role.is_authority(), enable_http_requests: false, custom_extensions: move |_| vec![], @@ -224,8 +324,8 @@ async fn start_node_impl( task_manager: &mut task_manager, config: parachain_config, keystore: params.keystore_container.keystore(), - backend, - network: network.clone(), + backend: backend.clone(), + network, sync_service: sync_service.clone(), system_rpc_tx, tx_handler_controller, @@ -288,13 +388,14 @@ async fn start_node_impl( if validator { start_consensus( client.clone(), + backend, block_import, prometheus_registry.as_ref(), telemetry.as_ref().map(|t| t.handle()), &task_manager, - relay_chain_interface.clone(), + relay_chain_interface, transaction_pool, - sync_service.clone(), + sync_service, params.keystore_container.keystore(), relay_chain_slot_duration, para_id, @@ -308,114 +409,3 @@ async fn start_node_impl( Ok((task_manager, client)) } - -/// Build the import queue for the parachain runtime. -fn build_import_queue( - client: Arc, - block_import: ParachainBlockImport, - config: &Configuration, - telemetry: Option, - task_manager: &TaskManager, -) -> Result, sc_service::Error> { - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; - - Ok(cumulus_client_consensus_aura::equivocation_import_queue::fully_verifying_import_queue::< - sp_consensus_aura::sr25519::AuthorityPair, - _, - _, - _, - _, - >( - client, - block_import, - move |_, _| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - Ok(timestamp) - }, - slot_duration, - &task_manager.spawn_essential_handle(), - config.prometheus_registry(), - telemetry, - )) -} - -fn start_consensus( - client: Arc, - block_import: ParachainBlockImport, - prometheus_registry: Option<&Registry>, - telemetry: Option, - task_manager: &TaskManager, - relay_chain_interface: Arc, - transaction_pool: Arc>, - sync_oracle: Arc>, - keystore: KeystorePtr, - relay_chain_slot_duration: Duration, - para_id: ParaId, - collator_key: CollatorPair, - overseer_handle: OverseerHandle, - announce_block: Arc>) + Send + Sync>, -) -> Result<(), sc_service::Error> { - use cumulus_client_consensus_aura::collators::basic::{ - self as basic_aura, Params as BasicAuraParams, - }; - - // NOTE: because we use Aura here explicitly, we can use `CollatorSybilResistance::Resistant` - // when starting the network. - - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; - - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( - task_manager.spawn_handle(), - client.clone(), - transaction_pool, - prometheus_registry, - telemetry.clone(), - ); - - let proposer = Proposer::new(proposer_factory); - - let collator_service = CollatorService::new( - client.clone(), - Arc::new(task_manager.spawn_handle()), - announce_block, - client.clone(), - ); - - let params = BasicAuraParams { - create_inherent_data_providers: move |_, ()| async move { Ok(()) }, - block_import, - para_client: client, - relay_client: relay_chain_interface, - sync_oracle, - keystore, - collator_key, - para_id, - overseer_handle, - slot_duration, - relay_chain_slot_duration, - proposer, - collator_service, - // Very limited proposal time. - authoring_duration: Duration::from_millis(500), - collation_request_receiver: None, - }; - - let fut = - basic_aura::run::( - params, - ); - task_manager.spawn_essential_handle().spawn("aura", None, fut); - - Ok(()) -} - -/// Start a parachain node. -pub async fn start_parachain_node( - parachain_config: Configuration, - polkadot_config: Configuration, - collator_options: CollatorOptions, - para_id: ParaId, - hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc)> { - start_node_impl(parachain_config, polkadot_config, collator_options, para_id, hwbench).await -}