From 3cf83ca8e2d4a2828a8eeb0836556a092c0b7f59 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Wed, 2 Oct 2024 16:13:59 +0300 Subject: [PATCH] `polkadot-parachain`: add manual seal support (#5586) Resolves https://github.com/paritytech/polkadot-sdk/issues/5026 This PR adds support for starting a dev node with manual seal consensus. This can be done by using the `--dev-block-time` argument . For example: ``` polkadot-parachain --chain asset-hub-rococo-dev --dev-block-time 5000 --tmp ``` --- Cargo.lock | 46 +-- .../polkadot-parachain-lib/Cargo.toml | 2 + .../polkadot-parachain-lib/src/cli.rs | 8 + .../polkadot-parachain-lib/src/command.rs | 73 ++--- .../src/common/command.rs | 4 +- .../polkadot-parachain-lib/src/common/mod.rs | 6 +- .../polkadot-parachain-lib/src/common/spec.rs | 295 +++++++++--------- .../polkadot-parachain-lib/src/lib.rs | 2 +- .../src/{service.rs => nodes/aura.rs} | 137 ++------ .../src/nodes/manual_seal.rs | 233 ++++++++++++++ .../polkadot-parachain-lib/src/nodes/mod.rs | 58 ++++ .../polkadot-parachain-lib/src/nodes/shell.rs | 152 +++++++++ .../src/guides/enable_elastic_scaling_mvp.rs | 4 +- 13 files changed, 687 insertions(+), 333 deletions(-) rename cumulus/polkadot-parachain/polkadot-parachain-lib/src/{service.rs => nodes/aura.rs} (77%) create mode 100644 cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/manual_seal.rs create mode 100644 cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/mod.rs create mode 100644 cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/shell.rs diff --git a/Cargo.lock b/Cargo.lock index a572c37a4060..db33c59f803c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1179,7 +1179,7 @@ checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" dependencies = [ "async-lock 3.4.0", "blocking", - "futures-lite 2.0.0", + "futures-lite 2.3.0", ] [[package]] @@ -1227,7 +1227,7 @@ dependencies = [ "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.0.0", + "futures-lite 2.3.0", "parking", "polling 3.4.0", "rustix 0.38.21", @@ -1276,7 +1276,7 @@ checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" dependencies = [ "async-io 2.3.3", "blocking", - "futures-lite 2.0.0", + "futures-lite 2.3.0", ] [[package]] @@ -1311,7 +1311,7 @@ dependencies = [ "blocking", "cfg-if", "event-listener 5.2.0", - "futures-lite 2.0.0", + "futures-lite 2.3.0", "rustix 0.38.21", "tracing", ] @@ -2618,9 +2618,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "bzip2-sys" @@ -6736,17 +6736,15 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.0.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c1155db57329dca6d018b61e76b1488ce9a2e5e44028cac420a5898f4fcef63" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ "fastrand 2.1.0", "futures-core", "futures-io", - "memchr", "parking", "pin-project-lite", - "waker-fn", ] [[package]] @@ -10505,9 +10503,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -10537,9 +10535,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ "cc", "libc", @@ -13341,9 +13339,9 @@ checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" [[package]] name = "parking" -version = "2.1.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -14975,6 +14973,7 @@ dependencies = [ "frame-system-rpc-runtime-api", "frame-try-runtime", "futures", + "futures-timer", "jsonrpsee 0.24.3", "log", "nix 0.28.0", @@ -14991,6 +14990,7 @@ dependencies = [ "sc-client-api", "sc-client-db", "sc-consensus", + "sc-consensus-manual-seal", "sc-executor 0.32.0", "sc-network", "sc-rpc", @@ -16808,7 +16808,7 @@ checksum = "80b776a1b2dc779f5ee0641f8ade0125bc1298dd41a9a0c16d8bd57b42d222b1" dependencies = [ "bytes", "heck 0.5.0", - "itertools 0.12.1", + "itertools 0.11.0", "log", "multimap", "once_cell", @@ -16829,7 +16829,7 @@ checksum = "f8650aabb6c35b860610e9cff5dc1af886c9e25073b7b1712a68972af4281302" dependencies = [ "bytes", "heck 0.5.0", - "itertools 0.12.1", + "itertools 0.11.0", "log", "multimap", "once_cell", @@ -16862,7 +16862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.12.1", + "itertools 0.11.0", "proc-macro2 1.0.86", "quote 1.0.37", "syn 2.0.79", @@ -16875,7 +16875,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" dependencies = [ "anyhow", - "itertools 0.12.1", + "itertools 0.11.0", "proc-macro2 1.0.86", "quote 1.0.37", "syn 2.0.79", @@ -20746,7 +20746,7 @@ dependencies = [ "async-net 2.0.0", "async-process 2.3.0", "blocking", - "futures-lite 2.0.0", + "futures-lite 2.3.0", ] [[package]] @@ -20832,7 +20832,7 @@ dependencies = [ "either", "event-listener 4.0.3", "fnv", - "futures-lite 2.0.0", + "futures-lite 2.3.0", "futures-util", "hashbrown 0.14.5", "hex", @@ -20918,7 +20918,7 @@ dependencies = [ "event-listener 4.0.3", "fnv", "futures-channel", - "futures-lite 2.0.0", + "futures-lite 2.3.0", "futures-util", "hashbrown 0.14.5", "hex", diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/Cargo.toml b/cumulus/polkadot-parachain/polkadot-parachain-lib/Cargo.toml index 066cbfae53ae..5e4c9fcf1a3d 100644 --- a/cumulus/polkadot-parachain/polkadot-parachain-lib/Cargo.toml +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/Cargo.toml @@ -61,6 +61,7 @@ pallet-transaction-payment-rpc-runtime-api = { workspace = true, default-feature sp-inherents = { workspace = true, default-features = true } sp-api = { workspace = true, default-features = true } sp-consensus-aura = { workspace = true, default-features = true } +sc-consensus-manual-seal = { workspace = true, default-features = true } sc-sysinfo = { workspace = true, default-features = true } prometheus-endpoint = { workspace = true, default-features = true } substrate-frame-rpc-system = { workspace = true, default-features = true } @@ -83,6 +84,7 @@ cumulus-client-service = { workspace = true, default-features = true } cumulus-primitives-aura = { workspace = true, default-features = true } cumulus-primitives-core = { workspace = true, default-features = true } cumulus-relay-chain-interface = { workspace = true, default-features = true } +futures-timer = "3.0.3" [dev-dependencies] assert_cmd = { workspace = true } diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/cli.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/cli.rs index 349dc01d8a4f..6ca328912bba 100644 --- a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/cli.rs +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/cli.rs @@ -119,6 +119,14 @@ pub struct Cli { #[command(flatten)] pub run: cumulus_client_cli::RunCmd, + /// Start a dev node that produces a block each `dev_block_time` ms. + /// + /// This is a dev option, and it won't result in starting or connecting to a parachain network. + /// The resulting node will work on its own, running the wasm blob and artificially producing + /// a block each `dev_block_time` ms, as if it was part of a parachain. + #[arg(long)] + pub dev_block_time: Option, + /// EXPERIMENTAL: Use slot-based collator which can handle elastic scaling. /// /// Use with care, this flag is unstable and subject to change. diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/command.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/command.rs index 63562f192aee..ff85bdf9401b 100644 --- a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/command.rs +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/command.rs @@ -22,13 +22,12 @@ use crate::{ AuraConsensusId, Consensus, Runtime, RuntimeResolver as RuntimeResolverT, RuntimeResolver, }, - spec::DynNodeSpec, types::Block, NodeBlock, NodeExtraArgs, }, fake_runtime_api, + nodes::{shell::ShellNode, DynNodeSpecExt}, runtime::BlockNumber, - service::ShellNode, }; #[cfg(feature = "runtime-benchmarks")] use cumulus_client_service::storage_proof_size::HostFunctions as ReclaimHostFunctions; @@ -52,17 +51,17 @@ pub struct RunConfig { pub fn new_aura_node_spec( aura_id: AuraConsensusId, extra_args: &NodeExtraArgs, -) -> Box +) -> Box where Block: NodeBlock, { match aura_id { - AuraConsensusId::Sr25519 => crate::service::new_aura_node_spec::< + AuraConsensusId::Sr25519 => crate::nodes::aura::new_aura_node_spec::< Block, fake_runtime_api::aura_sr25519::RuntimeApi, sp_consensus_aura::sr25519::AuthorityId, >(extra_args), - AuraConsensusId::Ed25519 => crate::service::new_aura_node_spec::< + AuraConsensusId::Ed25519 => crate::nodes::aura::new_aura_node_spec::< Block, fake_runtime_api::aura_ed25519::RuntimeApi, sp_consensus_aura::ed25519::AuthorityId, @@ -74,7 +73,7 @@ fn new_node_spec( config: &sc_service::Configuration, runtime_resolver: &Box, extra_args: &NodeExtraArgs, -) -> std::result::Result, sc_cli::Error> { +) -> std::result::Result, sc_cli::Error> { let runtime = runtime_resolver.runtime(config.chain_spec.as_ref())?; Ok(match runtime { @@ -214,6 +213,20 @@ pub fn run(cmd_config: RunConfig) -> Result<() let collator_options = cli.run.collator_options(); runner.run_node_until_exit(|config| async move { + let node_spec = + new_node_spec(&config, &cmd_config.runtime_resolver, &cli.node_extra_args())?; + let para_id = ParaId::from( + Extensions::try_get(&*config.chain_spec) + .map(|e| e.para_id) + .ok_or("Could not find parachain extension in chain-spec.")?, + ); + + if let Some(dev_block_time) = cli.dev_block_time { + return node_spec + .start_manual_seal_node(config, para_id, dev_block_time) + .map_err(Into::into) + } + // If Statemint (Statemine, Westmint, Rockmine) DB exists and we're using the // asset-hub chain spec, then rename the base path to the new chain ID. In the case // that both file paths exist, the node will exit, as the user must decide (by @@ -263,15 +276,9 @@ pub fn run(cmd_config: RunConfig) -> Result<() })) .flatten(); - let para_id = Extensions::try_get(&*config.chain_spec) - .map(|e| e.para_id) - .ok_or("Could not find parachain extension in chain-spec.")?; - - let id = ParaId::from(para_id); - let parachain_account = AccountIdConversion::::into_account_truncating( - &id, + ¶_id, ); let tokio_handle = config.tokio_handle.clone(); @@ -279,38 +286,22 @@ pub fn run(cmd_config: RunConfig) -> Result<() SubstrateCli::create_configuration(&polkadot_cli, &polkadot_cli, tokio_handle) .map_err(|err| format!("Relay chain argument error: {}", err))?; - info!("🪪 Parachain id: {:?}", id); + info!("🪪 Parachain id: {:?}", para_id); info!("🧾 Parachain Account: {}", parachain_account); info!("✍️ Is collating: {}", if config.role.is_authority() { "yes" } else { "no" }); - start_node( - config, - &cmd_config.runtime_resolver, - polkadot_config, - collator_options, - id, - cli.node_extra_args(), - hwbench, - ) - .await + node_spec + .start_node( + config, + polkadot_config, + collator_options, + para_id, + hwbench, + cli.node_extra_args(), + ) + .await + .map_err(Into::into) }) }, } } - -#[sc_tracing::logging::prefix_logs_with("Parachain")] -async fn start_node( - config: sc_service::Configuration, - runtime_resolver: &Box, - polkadot_config: sc_service::Configuration, - collator_options: cumulus_client_cli::CollatorOptions, - id: ParaId, - extra_args: NodeExtraArgs, - hwbench: Option, -) -> Result { - let node_spec = new_node_spec(&config, runtime_resolver, &extra_args)?; - node_spec - .start_node(config, polkadot_config, collator_options, id, hwbench, extra_args) - .await - .map_err(Into::into) -} diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/command.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/command.rs index e2826826d40e..a60fc9232d91 100644 --- a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/command.rs +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/command.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . -use crate::common::spec::NodeSpec; +use crate::common::spec::BaseNodeSpec; use cumulus_client_cli::ExportGenesisHeadCommand; use frame_benchmarking_cli::BlockCmd; #[cfg(any(feature = "runtime-benchmarks"))] @@ -81,7 +81,7 @@ pub trait NodeCommandRunner { impl NodeCommandRunner for T where - T: NodeSpec, + T: BaseNodeSpec, { fn prepare_check_block_cmd( self: Box, diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/mod.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/mod.rs index c6dce521e4ae..37660a5347a2 100644 --- a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/mod.rs +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/mod.rs @@ -28,6 +28,7 @@ pub mod types; use cumulus_primitives_core::{CollectCollationInfo, GetCoreSelectorApi}; use sc_client_db::DbHash; +use serde::de::DeserializeOwned; use sp_api::{ApiExt, CallApiAt, ConstructRuntimeApi, Metadata}; use sp_block_builder::BlockBuilder; use sp_runtime::{ @@ -39,8 +40,7 @@ use sp_transaction_pool::runtime_api::TaggedTransactionQueue; use std::{fmt::Debug, path::PathBuf, str::FromStr}; pub trait NodeBlock: - BlockT - + for<'de> serde::Deserialize<'de> + BlockT + DeserializeOwned { type BoundedFromStrErr: Debug; type BoundedNumber: FromStr + BlockNumber; @@ -49,7 +49,7 @@ pub trait NodeBlock: impl NodeBlock for T where - T: BlockT + for<'de> serde::Deserialize<'de>, + T: BlockT + DeserializeOwned, ::Header: Unpin, as FromStr>::Err: Debug, { diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs index 0c0230296eb8..dca28b3c28f7 100644 --- a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs @@ -39,6 +39,7 @@ use sc_network::{config::FullNetworkConfiguration, NetworkBackend, NetworkBlock} use sc_service::{Configuration, ImportQueue, PartialComponents, TaskManager}; use sc_sysinfo::HwBench; use sc_telemetry::{TelemetryHandle, TelemetryWorker}; +use sc_tracing::tracing::Instrument; use sc_transaction_pool::FullPool; use sp_keystore::KeystorePtr; use std::{future::Future, pin::Pin, sync::Arc, time::Duration}; @@ -91,7 +92,7 @@ fn warn_if_slow_hardware(hwbench: &sc_sysinfo::HwBench) { } } -pub(crate) trait NodeSpec { +pub(crate) trait BaseNodeSpec { type Block: NodeBlock; type RuntimeApi: ConstructNodeRuntimeApi< @@ -101,16 +102,6 @@ pub(crate) trait NodeSpec { type BuildImportQueue: BuildImportQueue; - type BuildRpcExtensions: BuildRpcExtensions< - ParachainClient, - ParachainBackend, - FullPool>, - >; - - type StartConsensus: StartConsensus; - - const SYBIL_RESISTANCE: CollatorSybilResistance; - /// Starts a `ServiceBuilder` for a full service. /// /// Use this macro if you don't actually need the full service, but just the builder in order to @@ -187,6 +178,18 @@ pub(crate) trait NodeSpec { other: (block_import, telemetry, telemetry_worker_handle), }) } +} + +pub(crate) trait NodeSpec: BaseNodeSpec { + type BuildRpcExtensions: BuildRpcExtensions< + ParachainClient, + ParachainBackend, + FullPool>, + >; + + type StartConsensus: StartConsensus; + + const SYBIL_RESISTANCE: CollatorSybilResistance; /// Start a node with the given parachain spec. /// @@ -202,147 +205,153 @@ pub(crate) trait NodeSpec { where Net: NetworkBackend, { - Box::pin(async move { - let parachain_config = prepare_node_config(parachain_config); - - let params = Self::new_partial(¶chain_config)?; - let (block_import, mut telemetry, telemetry_worker_handle) = params.other; - - let client = params.client.clone(); - let backend = params.backend.clone(); - - let mut task_manager = params.task_manager; - let (relay_chain_interface, collator_key) = build_relay_chain_interface( - polkadot_config, - ¶chain_config, - telemetry_worker_handle, - &mut task_manager, - collator_options.clone(), - hwbench.clone(), - ) - .await - .map_err(|e| sc_service::Error::Application(Box::new(e) as Box<_>))?; - - let validator = parachain_config.role.is_authority(); - let prometheus_registry = parachain_config.prometheus_registry().cloned(); - let transaction_pool = params.transaction_pool.clone(); - let import_queue_service = params.import_queue.service(); - let net_config = FullNetworkConfiguration::<_, _, Net>::new( - ¶chain_config.network, - prometheus_registry.clone(), - ); - - let (network, system_rpc_tx, tx_handler_controller, start_network, sync_service) = - build_network(BuildNetworkParams { - parachain_config: ¶chain_config, - net_config, + Box::pin( + async move { + let parachain_config = prepare_node_config(parachain_config); + + let params = Self::new_partial(¶chain_config)?; + let (block_import, mut telemetry, telemetry_worker_handle) = params.other; + + let client = params.client.clone(); + let backend = params.backend.clone(); + + let mut task_manager = params.task_manager; + let (relay_chain_interface, collator_key) = build_relay_chain_interface( + polkadot_config, + ¶chain_config, + telemetry_worker_handle, + &mut task_manager, + collator_options.clone(), + hwbench.clone(), + ) + .await + .map_err(|e| sc_service::Error::Application(Box::new(e) as Box<_>))?; + + let validator = parachain_config.role.is_authority(); + let prometheus_registry = parachain_config.prometheus_registry().cloned(); + let transaction_pool = params.transaction_pool.clone(); + let import_queue_service = params.import_queue.service(); + let net_config = FullNetworkConfiguration::<_, _, Net>::new( + ¶chain_config.network, + prometheus_registry.clone(), + ); + + let (network, system_rpc_tx, tx_handler_controller, start_network, sync_service) = + build_network(BuildNetworkParams { + parachain_config: ¶chain_config, + net_config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + para_id, + spawn_handle: task_manager.spawn_handle(), + relay_chain_interface: relay_chain_interface.clone(), + import_queue: params.import_queue, + sybil_resistance_level: Self::SYBIL_RESISTANCE, + }) + .await?; + + let rpc_builder = { + let client = client.clone(); + let transaction_pool = transaction_pool.clone(); + let backend_for_rpc = backend.clone(); + + Box::new(move |_| { + Self::BuildRpcExtensions::build_rpc_extensions( + client.clone(), + backend_for_rpc.clone(), + transaction_pool.clone(), + ) + }) + }; + + sc_service::spawn_tasks(sc_service::SpawnTasksParams { + rpc_builder, client: client.clone(), transaction_pool: transaction_pool.clone(), + task_manager: &mut task_manager, + config: parachain_config, + keystore: params.keystore_container.keystore(), + backend: backend.clone(), + network: network.clone(), + sync_service: sync_service.clone(), + system_rpc_tx, + tx_handler_controller, + telemetry: telemetry.as_mut(), + })?; + + if let Some(hwbench) = hwbench { + sc_sysinfo::print_hwbench(&hwbench); + if validator { + warn_if_slow_hardware(&hwbench); + } + + if let Some(ref mut telemetry) = telemetry { + let telemetry_handle = telemetry.handle(); + task_manager.spawn_handle().spawn( + "telemetry_hwbench", + None, + sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench), + ); + } + } + + let announce_block = { + let sync_service = sync_service.clone(); + Arc::new(move |hash, data| sync_service.announce_block(hash, data)) + }; + + let relay_chain_slot_duration = Duration::from_secs(6); + + let overseer_handle = relay_chain_interface + .overseer_handle() + .map_err(|e| sc_service::Error::Application(Box::new(e)))?; + + start_relay_chain_tasks(StartRelayChainTasksParams { + client: client.clone(), + announce_block: announce_block.clone(), para_id, - spawn_handle: task_manager.spawn_handle(), relay_chain_interface: relay_chain_interface.clone(), - import_queue: params.import_queue, - sybil_resistance_level: Self::SYBIL_RESISTANCE, - }) - .await?; - - let rpc_builder = { - let client = client.clone(); - let transaction_pool = transaction_pool.clone(); - let backend_for_rpc = backend.clone(); - - Box::new(move |_| { - Self::BuildRpcExtensions::build_rpc_extensions( - client.clone(), - backend_for_rpc.clone(), - transaction_pool.clone(), - ) - }) - }; - - sc_service::spawn_tasks(sc_service::SpawnTasksParams { - rpc_builder, - client: client.clone(), - transaction_pool: transaction_pool.clone(), - task_manager: &mut task_manager, - config: parachain_config, - keystore: params.keystore_container.keystore(), - backend: backend.clone(), - network: network.clone(), - sync_service: sync_service.clone(), - system_rpc_tx, - tx_handler_controller, - telemetry: telemetry.as_mut(), - })?; - - if let Some(hwbench) = hwbench { - sc_sysinfo::print_hwbench(&hwbench); + task_manager: &mut task_manager, + da_recovery_profile: if validator { + DARecoveryProfile::Collator + } else { + DARecoveryProfile::FullNode + }, + import_queue: import_queue_service, + relay_chain_slot_duration, + recovery_handle: Box::new(overseer_handle.clone()), + sync_service, + })?; + if validator { - warn_if_slow_hardware(&hwbench); + Self::StartConsensus::start_consensus( + client.clone(), + block_import, + prometheus_registry.as_ref(), + telemetry.as_ref().map(|t| t.handle()), + &task_manager, + relay_chain_interface.clone(), + transaction_pool, + params.keystore_container.keystore(), + relay_chain_slot_duration, + para_id, + collator_key.expect("Command line arguments do not allow this. qed"), + overseer_handle, + announce_block, + backend.clone(), + node_extra_args, + )?; } - if let Some(ref mut telemetry) = telemetry { - let telemetry_handle = telemetry.handle(); - task_manager.spawn_handle().spawn( - "telemetry_hwbench", - None, - sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench), - ); - } - } + start_network.start_network(); - let announce_block = { - let sync_service = sync_service.clone(); - Arc::new(move |hash, data| sync_service.announce_block(hash, data)) - }; - - let relay_chain_slot_duration = Duration::from_secs(6); - - let overseer_handle = relay_chain_interface - .overseer_handle() - .map_err(|e| sc_service::Error::Application(Box::new(e)))?; - - start_relay_chain_tasks(StartRelayChainTasksParams { - client: client.clone(), - announce_block: announce_block.clone(), - para_id, - relay_chain_interface: relay_chain_interface.clone(), - task_manager: &mut task_manager, - da_recovery_profile: if validator { - DARecoveryProfile::Collator - } else { - DARecoveryProfile::FullNode - }, - import_queue: import_queue_service, - relay_chain_slot_duration, - recovery_handle: Box::new(overseer_handle.clone()), - sync_service, - })?; - - if validator { - Self::StartConsensus::start_consensus( - client.clone(), - block_import, - prometheus_registry.as_ref(), - telemetry.as_ref().map(|t| t.handle()), - &task_manager, - relay_chain_interface.clone(), - transaction_pool, - params.keystore_container.keystore(), - relay_chain_slot_duration, - para_id, - collator_key.expect("Command line arguments do not allow this. qed"), - overseer_handle, - announce_block, - backend.clone(), - node_extra_args, - )?; + Ok(task_manager) } - - start_network.start_network(); - - Ok(task_manager) - }) + .instrument(sc_tracing::tracing::info_span!( + sc_tracing::logging::PREFIX_LOG_SPAN, + name = "Parachain", + )), + ) } } diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/lib.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/lib.rs index 6aa2f656a48b..a293ab225c6f 100644 --- a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/lib.rs +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/lib.rs @@ -45,7 +45,7 @@ mod cli; mod command; mod common; mod fake_runtime_api; -mod service; +mod nodes; pub use cli::CliConfig; pub use command::{run, RunConfig}; diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/service.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/aura.rs similarity index 77% rename from cumulus/polkadot-parachain/polkadot-parachain-lib/src/service.rs rename to cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/aura.rs index b1c714784f4c..cf1ee91cbab5 100644 --- a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/service.rs +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/aura.rs @@ -17,15 +17,15 @@ use crate::{ common::{ aura::{AuraIdT, AuraRuntimeApi}, - rpc::{BuildEmptyRpcExtensions, BuildParachainRpcExtensions}, - spec::{BuildImportQueue, DynNodeSpec, NodeSpec, StartConsensus}, + rpc::BuildParachainRpcExtensions, + spec::{BaseNodeSpec, BuildImportQueue, NodeSpec, StartConsensus}, types::{ - AccountId, Balance, Block, Hash, Nonce, ParachainBackend, ParachainBlockImport, + AccountId, Balance, Hash, Nonce, ParachainBackend, ParachainBlockImport, ParachainClient, }, ConstructNodeRuntimeApi, NodeBlock, NodeExtraArgs, }, - fake_runtime_api::aura_sr25519::RuntimeApi as FakeRuntimeApi, + nodes::DynNodeSpecExt, }; use cumulus_client_collator::service::{ CollatorService, ServiceInterface as CollatorServiceInterface, @@ -38,7 +38,6 @@ use cumulus_client_consensus_aura::collators::slot_based::{ use cumulus_client_consensus_proposer::{Proposer, ProposerInterface}; use cumulus_client_consensus_relay_chain::Verifier as RelayChainVerifier; #[allow(deprecated)] -use cumulus_client_service::old_consensus; use cumulus_client_service::CollatorSybilResistance; use cumulus_primitives_core::{relay_chain::ValidationCode, ParaId}; use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface}; @@ -63,40 +62,6 @@ use sp_runtime::{ }; use std::{marker::PhantomData, sync::Arc, time::Duration}; -/// Build the import queue for the shell runtime. -pub(crate) struct BuildShellImportQueue; - -impl BuildImportQueue, FakeRuntimeApi> for BuildShellImportQueue { - fn build_import_queue( - client: Arc, FakeRuntimeApi>>, - block_import: ParachainBlockImport, FakeRuntimeApi>, - config: &Configuration, - _telemetry_handle: Option, - task_manager: &TaskManager, - ) -> sc_service::error::Result>> { - cumulus_client_consensus_relay_chain::import_queue( - client, - block_import, - |_, _| async { Ok(()) }, - &task_manager.spawn_essential_handle(), - config.prometheus_registry(), - ) - .map_err(Into::into) - } -} - -pub(crate) struct ShellNode; - -impl NodeSpec for ShellNode { - type Block = Block; - type RuntimeApi = FakeRuntimeApi; - type BuildImportQueue = BuildShellImportQueue; - type BuildRpcExtensions = BuildEmptyRpcExtensions, Self::RuntimeApi>; - type StartConsensus = StartRelayChainConsensus; - - const SYBIL_RESISTANCE: CollatorSybilResistance = CollatorSybilResistance::Unresistant; -} - struct Verifier { client: Arc, aura_verifier: Box>, @@ -205,7 +170,7 @@ impl Default } } -impl NodeSpec +impl BaseNodeSpec for AuraNode where Block: NodeBlock, @@ -214,11 +179,23 @@ where + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + substrate_frame_rpc_system::AccountNonceApi, AuraId: AuraIdT + Sync, - StartConsensus: self::StartConsensus + 'static, { type Block = Block; type RuntimeApi = RuntimeApi; type BuildImportQueue = BuildRelayToAuraImportQueue; +} + +impl NodeSpec + for AuraNode +where + Block: NodeBlock, + RuntimeApi: ConstructNodeRuntimeApi>, + RuntimeApi::RuntimeApi: AuraRuntimeApi + + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + + substrate_frame_rpc_system::AccountNonceApi, + AuraId: AuraIdT + Sync, + StartConsensus: self::StartConsensus + 'static, +{ type BuildRpcExtensions = BuildParachainRpcExtensions; type StartConsensus = StartConsensus; const SYBIL_RESISTANCE: CollatorSybilResistance = CollatorSybilResistance::Resistant; @@ -226,7 +203,7 @@ where pub fn new_aura_node_spec( extra_args: &NodeExtraArgs, -) -> Box +) -> Box where Block: NodeBlock, RuntimeApi: ConstructNodeRuntimeApi>, @@ -252,82 +229,6 @@ where } } -/// Start relay-chain consensus that is free for all. Everyone can submit a block, the relay-chain -/// decides what is backed and included. -pub(crate) struct StartRelayChainConsensus; - -impl StartConsensus, FakeRuntimeApi> for StartRelayChainConsensus { - fn start_consensus( - client: Arc, FakeRuntimeApi>>, - block_import: ParachainBlockImport, FakeRuntimeApi>, - prometheus_registry: Option<&Registry>, - telemetry: Option, - task_manager: &TaskManager, - relay_chain_interface: Arc, - transaction_pool: Arc, ParachainClient, FakeRuntimeApi>>>, - _keystore: KeystorePtr, - _relay_chain_slot_duration: Duration, - para_id: ParaId, - collator_key: CollatorPair, - overseer_handle: OverseerHandle, - announce_block: Arc>) + Send + Sync>, - _backend: Arc>>, - _node_extra_args: NodeExtraArgs, - ) -> Result<(), Error> { - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( - task_manager.spawn_handle(), - client.clone(), - transaction_pool, - prometheus_registry, - telemetry, - ); - - let free_for_all = cumulus_client_consensus_relay_chain::build_relay_chain_consensus( - cumulus_client_consensus_relay_chain::BuildRelayChainConsensusParams { - para_id, - proposer_factory, - block_import, - relay_chain_interface: relay_chain_interface.clone(), - create_inherent_data_providers: move |_, (relay_parent, validation_data)| { - let relay_chain_interface = relay_chain_interface.clone(); - async move { - let parachain_inherent = - cumulus_client_parachain_inherent::ParachainInherentDataProvider::create_at( - relay_parent, - &relay_chain_interface, - &validation_data, - para_id, - ).await; - let parachain_inherent = parachain_inherent.ok_or_else(|| { - Box::::from( - "Failed to create parachain inherent", - ) - })?; - Ok(parachain_inherent) - } - }, - }, - ); - - let spawner = task_manager.spawn_handle(); - - // Required for free-for-all consensus - #[allow(deprecated)] - old_consensus::start_collator_sync(old_consensus::StartCollatorParams { - para_id, - block_status: client.clone(), - announce_block, - overseer_handle, - spawner, - key: collator_key, - parachain_consensus: free_for_all, - runtime_api: client.clone(), - }); - - Ok(()) - } -} - /// Start consensus using the lookahead aura collator. pub(crate) struct StartSlotBasedAuraConsensus( PhantomData<(Block, RuntimeApi, AuraId)>, diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/manual_seal.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/manual_seal.rs new file mode 100644 index 000000000000..d00d7adf27e1 --- /dev/null +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/manual_seal.rs @@ -0,0 +1,233 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus 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 Cumulus. If not, see . + +use crate::common::{ + rpc::BuildRpcExtensions as BuildRpcExtensionsT, + spec::{BaseNodeSpec, BuildImportQueue, NodeSpec as NodeSpecT}, + types::{Hash, ParachainBlockImport, ParachainClient}, +}; +use codec::Encode; +use cumulus_client_parachain_inherent::{MockValidationDataInherentDataProvider, MockXcmConfig}; +use cumulus_primitives_core::ParaId; +use sc_consensus::{DefaultImportQueue, LongestChain}; +use sc_consensus_manual_seal::rpc::{ManualSeal, ManualSealApiServer}; +use sc_network::NetworkBackend; +use sc_service::{build_polkadot_syncing_strategy, Configuration, PartialComponents, TaskManager}; +use sc_telemetry::TelemetryHandle; +use sp_runtime::traits::Header; +use sp_timestamp::Timestamp; +use std::{marker::PhantomData, sync::Arc}; + +pub struct ManualSealNode(PhantomData); + +impl BuildImportQueue + for ManualSealNode +{ + fn build_import_queue( + client: Arc>, + _block_import: ParachainBlockImport, + config: &Configuration, + _telemetry_handle: Option, + task_manager: &TaskManager, + ) -> sc_service::error::Result> { + Ok(sc_consensus_manual_seal::import_queue( + Box::new(client.clone()), + &task_manager.spawn_essential_handle(), + config.prometheus_registry(), + )) + } +} + +impl BaseNodeSpec for ManualSealNode { + type Block = NodeSpec::Block; + type RuntimeApi = NodeSpec::RuntimeApi; + type BuildImportQueue = Self; +} + +impl ManualSealNode { + pub fn new() -> Self { + Self(Default::default()) + } + + pub fn start_node( + &self, + mut config: Configuration, + para_id: ParaId, + block_time: u64, + ) -> sc_service::error::Result + where + Net: NetworkBackend, + { + let PartialComponents { + client, + backend, + mut task_manager, + import_queue, + keystore_container, + select_chain: _, + transaction_pool, + other: (_, mut telemetry, _), + } = Self::new_partial(&config)?; + let select_chain = LongestChain::new(backend.clone()); + + // Since this is a dev node, prevent it from connecting to peers. + config.network.default_peers_set.in_peers = 0; + config.network.default_peers_set.out_peers = 0; + let mut net_config = sc_network::config::FullNetworkConfiguration::<_, _, Net>::new( + &config.network, + config.prometheus_config.as_ref().map(|cfg| cfg.registry.clone()), + ); + let metrics = Net::register_notification_metrics( + config.prometheus_config.as_ref().map(|cfg| &cfg.registry), + ); + + let syncing_strategy = build_polkadot_syncing_strategy( + config.protocol_id(), + config.chain_spec.fork_id(), + &mut net_config, + None, + client.clone(), + &task_manager.spawn_handle(), + config.prometheus_config.as_ref().map(|config| &config.registry), + )?; + + let (network, system_rpc_tx, tx_handler_controller, start_network, sync_service) = + sc_service::build_network(sc_service::BuildNetworkParams { + config: &config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue, + net_config, + block_announce_validator_builder: None, + syncing_strategy, + block_relay: None, + metrics, + })?; + + let proposer = sc_basic_authorship::ProposerFactory::new( + task_manager.spawn_handle(), + client.clone(), + transaction_pool.clone(), + None, + None, + ); + + let (manual_seal_sink, manual_seal_stream) = futures::channel::mpsc::channel(1024); + let mut manual_seal_sink_clone = manual_seal_sink.clone(); + task_manager + .spawn_essential_handle() + .spawn("block_authoring", None, async move { + loop { + futures_timer::Delay::new(std::time::Duration::from_millis(block_time)).await; + manual_seal_sink_clone + .try_send(sc_consensus_manual_seal::EngineCommand::SealNewBlock { + create_empty: true, + finalize: true, + parent_hash: None, + sender: None, + }) + .unwrap(); + } + }); + + let client_for_cidp = client.clone(); + let params = sc_consensus_manual_seal::ManualSealParams { + block_import: client.clone(), + env: proposer, + client: client.clone(), + pool: transaction_pool.clone(), + select_chain, + commands_stream: Box::pin(manual_seal_stream), + consensus_data_provider: None, + create_inherent_data_providers: move |block: Hash, ()| { + let current_para_head = client_for_cidp + .header(block) + .expect("Header lookup should succeed") + .expect("Header passed in as parent should be present in backend."); + let current_para_block_head = + Some(polkadot_primitives::HeadData(current_para_head.encode())); + let client_for_xcm = client_for_cidp.clone(); + async move { + use sp_runtime::traits::UniqueSaturatedInto; + + let mocked_parachain = MockValidationDataInherentDataProvider { + // When using manual seal we start from block 0, and it's very unlikely to + // reach a block number > u32::MAX. + current_para_block: UniqueSaturatedInto::::unique_saturated_into( + *current_para_head.number(), + ), + para_id, + current_para_block_head, + relay_offset: 1000, + relay_blocks_per_para_block: 1, + para_blocks_per_relay_epoch: 10, + relay_randomness_config: (), + xcm_config: MockXcmConfig::new(&*client_for_xcm, block, Default::default()), + raw_downward_messages: vec![], + raw_horizontal_messages: vec![], + additional_key_values: None, + }; + Ok(( + sp_timestamp::InherentDataProvider::new(Timestamp::new(0)), + mocked_parachain, + )) + } + }, + }; + let authorship_future = sc_consensus_manual_seal::run_manual_seal(params); + task_manager.spawn_essential_handle().spawn_blocking( + "manual-seal", + None, + authorship_future, + ); + let rpc_extensions_builder = { + let client = client.clone(); + let transaction_pool = transaction_pool.clone(); + let backend_for_rpc = backend.clone(); + + Box::new(move |_| { + let mut module = NodeSpec::BuildRpcExtensions::build_rpc_extensions( + client.clone(), + backend_for_rpc.clone(), + transaction_pool.clone(), + )?; + module + .merge(ManualSeal::new(manual_seal_sink.clone()).into_rpc()) + .map_err(|e| sc_service::Error::Application(e.into()))?; + Ok(module) + }) + }; + + let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { + network, + client: client.clone(), + keystore: keystore_container.keystore(), + task_manager: &mut task_manager, + transaction_pool: transaction_pool.clone(), + rpc_builder: rpc_extensions_builder, + backend, + system_rpc_tx, + tx_handler_controller, + sync_service, + config, + telemetry: telemetry.as_mut(), + })?; + + start_network.start_network(); + Ok(task_manager) + } +} diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/mod.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/mod.rs new file mode 100644 index 000000000000..36f54fa3d051 --- /dev/null +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/mod.rs @@ -0,0 +1,58 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus 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 Cumulus. If not, see . + +pub mod aura; +mod manual_seal; +pub mod shell; + +use crate::common::spec::{DynNodeSpec, NodeSpec as NodeSpecT}; +use cumulus_primitives_core::ParaId; +use manual_seal::ManualSealNode; +use sc_service::{Configuration, TaskManager}; + +/// Trait that extends the `DynNodeSpec` trait with manual seal related logic. +/// +/// We need it in order to be able to access both the `DynNodeSpec` and the manual seal logic +/// through dynamic dispatch. +pub trait DynNodeSpecExt: DynNodeSpec { + fn start_manual_seal_node( + &self, + config: Configuration, + para_id: ParaId, + block_time: u64, + ) -> sc_service::error::Result; +} + +impl DynNodeSpecExt for T +where + T: NodeSpecT + DynNodeSpec, +{ + #[sc_tracing::logging::prefix_logs_with("Parachain")] + fn start_manual_seal_node( + &self, + config: Configuration, + para_id: ParaId, + block_time: u64, + ) -> sc_service::error::Result { + let node = ManualSealNode::::new(); + match config.network.network_backend { + sc_network::config::NetworkBackendType::Libp2p => + node.start_node::>(config, para_id, block_time), + sc_network::config::NetworkBackendType::Litep2p => + node.start_node::(config, para_id, block_time), + } + } +} diff --git a/cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/shell.rs b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/shell.rs new file mode 100644 index 000000000000..5f9c671d7107 --- /dev/null +++ b/cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/shell.rs @@ -0,0 +1,152 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus 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 Cumulus. If not, see . + +use crate::{ + common::{ + rpc::BuildEmptyRpcExtensions, + spec::{BaseNodeSpec, BuildImportQueue, NodeSpec, StartConsensus}, + types::{Block, Hash, ParachainBackend, ParachainBlockImport, ParachainClient}, + NodeExtraArgs, + }, + fake_runtime_api::aura_sr25519::RuntimeApi as FakeRuntimeApi, +}; +#[docify::export(slot_based_colator_import)] +#[allow(deprecated)] +use cumulus_client_service::old_consensus; +use cumulus_client_service::CollatorSybilResistance; +use cumulus_primitives_core::ParaId; +use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface}; +use polkadot_primitives::CollatorPair; +use prometheus_endpoint::Registry; +use sc_consensus::DefaultImportQueue; +use sc_service::{Configuration, Error, TaskManager}; +use sc_telemetry::TelemetryHandle; +use sc_transaction_pool::FullPool; +use sp_keystore::KeystorePtr; +use std::{sync::Arc, time::Duration}; + +/// Build the import queue for the shell runtime. +pub(crate) struct BuildShellImportQueue; + +impl BuildImportQueue, FakeRuntimeApi> for BuildShellImportQueue { + fn build_import_queue( + client: Arc, FakeRuntimeApi>>, + block_import: ParachainBlockImport, FakeRuntimeApi>, + config: &Configuration, + _telemetry_handle: Option, + task_manager: &TaskManager, + ) -> sc_service::error::Result>> { + cumulus_client_consensus_relay_chain::import_queue( + client, + block_import, + |_, _| async { Ok(()) }, + &task_manager.spawn_essential_handle(), + config.prometheus_registry(), + ) + .map_err(Into::into) + } +} + +/// Start relay-chain consensus that is free for all. Everyone can submit a block, the relay-chain +/// decides what is backed and included. +pub(crate) struct StartRelayChainConsensus; + +impl StartConsensus, FakeRuntimeApi> for StartRelayChainConsensus { + fn start_consensus( + client: Arc, FakeRuntimeApi>>, + block_import: ParachainBlockImport, FakeRuntimeApi>, + prometheus_registry: Option<&Registry>, + telemetry: Option, + task_manager: &TaskManager, + relay_chain_interface: Arc, + transaction_pool: Arc, ParachainClient, FakeRuntimeApi>>>, + _keystore: KeystorePtr, + _relay_chain_slot_duration: Duration, + para_id: ParaId, + collator_key: CollatorPair, + overseer_handle: OverseerHandle, + announce_block: Arc>) + Send + Sync>, + _backend: Arc>>, + _node_extra_args: NodeExtraArgs, + ) -> Result<(), Error> { + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + task_manager.spawn_handle(), + client.clone(), + transaction_pool, + prometheus_registry, + telemetry, + ); + + let free_for_all = cumulus_client_consensus_relay_chain::build_relay_chain_consensus( + cumulus_client_consensus_relay_chain::BuildRelayChainConsensusParams { + para_id, + proposer_factory, + block_import, + relay_chain_interface: relay_chain_interface.clone(), + create_inherent_data_providers: move |_, (relay_parent, validation_data)| { + let relay_chain_interface = relay_chain_interface.clone(); + async move { + let parachain_inherent = + cumulus_client_parachain_inherent::ParachainInherentDataProvider::create_at( + relay_parent, + &relay_chain_interface, + &validation_data, + para_id, + ).await; + let parachain_inherent = parachain_inherent.ok_or_else(|| { + Box::::from( + "Failed to create parachain inherent", + ) + })?; + Ok(parachain_inherent) + } + }, + }, + ); + + let spawner = task_manager.spawn_handle(); + + // Required for free-for-all consensus + #[allow(deprecated)] + old_consensus::start_collator_sync(old_consensus::StartCollatorParams { + para_id, + block_status: client.clone(), + announce_block, + overseer_handle, + spawner, + key: collator_key, + parachain_consensus: free_for_all, + runtime_api: client.clone(), + }); + + Ok(()) + } +} + +pub(crate) struct ShellNode; + +impl BaseNodeSpec for ShellNode { + type Block = Block; + type RuntimeApi = FakeRuntimeApi; + type BuildImportQueue = BuildShellImportQueue; +} + +impl NodeSpec for ShellNode { + type BuildRpcExtensions = BuildEmptyRpcExtensions, Self::RuntimeApi>; + type StartConsensus = StartRelayChainConsensus; + + const SYBIL_RESISTANCE: CollatorSybilResistance = CollatorSybilResistance::Unresistant; +} diff --git a/docs/sdk/src/guides/enable_elastic_scaling_mvp.rs b/docs/sdk/src/guides/enable_elastic_scaling_mvp.rs index 38ef18b88e0d..14a0b6107966 100644 --- a/docs/sdk/src/guides/enable_elastic_scaling_mvp.rs +++ b/docs/sdk/src/guides/enable_elastic_scaling_mvp.rs @@ -85,7 +85,7 @@ //! This phase consists of plugging in the new slot-based collator. //! //! 1. In `node/src/service.rs` import the slot based collator instead of the lookahead collator. -#![doc = docify::embed!("../../cumulus/polkadot-parachain/polkadot-parachain-lib/src/service.rs", slot_based_colator_import)] +#![doc = docify::embed!("../../cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/aura.rs", slot_based_colator_import)] //! //! 2. In `start_consensus()` //! - Remove the `overseer_handle` param (also remove the @@ -94,7 +94,7 @@ //! `slot_drift` field with a value of `Duration::from_secs(1)`. //! - Replace the single future returned by `aura::run` with the two futures returned by it and //! spawn them as separate tasks: -#![doc = docify::embed!("../../cumulus/polkadot-parachain/polkadot-parachain-lib/src/service.rs", launch_slot_based_collator)] +#![doc = docify::embed!("../../cumulus/polkadot-parachain/polkadot-parachain-lib/src/nodes/aura.rs", launch_slot_based_collator)] //! //! 3. In `start_parachain_node()` remove the `overseer_handle` param passed to `start_consensus`. //!