Skip to content

Commit

Permalink
polkadot-parachain: Add omni-node variant with u64 block number (#5269)
Browse files Browse the repository at this point in the history
Related to #4787

The main changes in this PR are the following:
- making the NodeSpec logic generic on the Block type
- adding an omni-node variant with u64 block number

Apart from this, the PR also moves some of the logic in `service.rs` to
the `common` subfolder

The omni-node variant with u64 block number is not used yet. We have to
either expose the option in the CLI or to read the block number from the
chain spec somehow. Will do it in a future PR.
  • Loading branch information
serban300 authored Aug 28, 2024
1 parent 97fa922 commit c4ced11
Show file tree
Hide file tree
Showing 18 changed files with 1,109 additions and 1,061 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions cumulus/polkadot-parachain/polkadot-parachain-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ sc-consensus = { workspace = true, default-features = true }
frame-support = { optional = true, workspace = true, default-features = true }
sc-cli = { workspace = true, default-features = true }
sc-client-api = { workspace = true, default-features = true }
sc-client-db = { workspace = true, default-features = true }
sc-executor = { workspace = true, default-features = true }
sc-service = { workspace = true, default-features = true }
sc-telemetry = { workspace = true, default-features = true }
Expand Down Expand Up @@ -105,6 +106,7 @@ runtime-benchmarks = [
"parachains-common/runtime-benchmarks",
"polkadot-cli/runtime-benchmarks",
"polkadot-primitives/runtime-benchmarks",
"sc-client-db/runtime-benchmarks",
"sc-service/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
Expand Down
5 changes: 5 additions & 0 deletions cumulus/polkadot-parachain/polkadot-parachain-lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ use std::{fmt::Debug, marker::PhantomData, path::PathBuf};
/// The related info is shown to the customer as part of logs or help messages.
/// It does not impact functionality.
pub trait CliConfig {
/// The version of the resulting node binary.
fn impl_version() -> String;

/// The description of the resulting node binary.
fn description(executable_name: String) -> String {
format!(
"The command-line arguments provided first will be passed to the parachain node, \n\
Expand All @@ -50,10 +52,13 @@ pub trait CliConfig {
)
}

/// The author of the resulting node binary.
fn author() -> String;

/// The support URL for the resulting node binary.
fn support_url() -> String;

/// The starting copyright year of the resulting node binary.
fn copyright_start_year() -> u16;
}

Expand Down
52 changes: 37 additions & 15 deletions cumulus/polkadot-parachain/polkadot-parachain-lib/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.

#[cfg(feature = "runtime-benchmarks")]
use crate::service::Block;
use crate::{
cli::{Cli, RelayChainCli, Subcommand},
common::{
Expand All @@ -24,32 +22,56 @@ use crate::{
AuraConsensusId, Consensus, Runtime, RuntimeResolver as RuntimeResolverT,
RuntimeResolver,
},
NodeExtraArgs,
},
fake_runtime_api::{
asset_hub_polkadot_aura::RuntimeApi as AssetHubPolkadotRuntimeApi,
aura::RuntimeApi as AuraRuntimeApi,
spec::DynNodeSpec,
types::Block,
NodeBlock, NodeExtraArgs,
},
service::{new_aura_node_spec, DynNodeSpec, ShellNode},
fake_runtime_api,
runtime::BlockNumber,
service::ShellNode,
};
#[cfg(feature = "runtime-benchmarks")]
use cumulus_client_service::storage_proof_size::HostFunctions as ReclaimHostFunctions;
use cumulus_primitives_core::ParaId;
use frame_benchmarking_cli::{BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE};
use log::info;
use parachains_common::{AssetHubPolkadotAuraId, AuraId};
use sc_cli::{Result, SubstrateCli};
use sp_runtime::traits::AccountIdConversion;
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::traits::HashingFor;
use std::panic::{RefUnwindSafe, UnwindSafe};

/// Structure that can be used in order to provide customizers for different functionalities of the
/// node binary that is being built using this library.
pub struct RunConfig {
/// A custom chain spec loader.
pub chain_spec_loader: Box<dyn LoadSpec>,
/// A custom runtime resolver.
pub runtime_resolver: Box<dyn RuntimeResolver>,
}

pub fn new_aura_node_spec<Block>(
aura_id: AuraConsensusId,
extra_args: &NodeExtraArgs,
) -> Box<dyn DynNodeSpec>
where
Block: NodeBlock + UnwindSafe + RefUnwindSafe,
Block::BoundedHeader: UnwindSafe + RefUnwindSafe,
{
match aura_id {
AuraConsensusId::Sr25519 => crate::service::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::<
Block,
fake_runtime_api::aura_ed25519::RuntimeApi,
sp_consensus_aura::ed25519::AuthorityId,
>(extra_args),
}
}

fn new_node_spec(
config: &sc_service::Configuration,
runtime_resolver: &Box<dyn RuntimeResolverT>,
Expand All @@ -59,11 +81,11 @@ fn new_node_spec(

Ok(match runtime {
Runtime::Shell => Box::new(ShellNode),
Runtime::Omni(consensus) => match consensus {
Consensus::Aura(AuraConsensusId::Sr25519) =>
new_aura_node_spec::<AuraRuntimeApi, AuraId>(extra_args),
Consensus::Aura(AuraConsensusId::Ed25519) =>
new_aura_node_spec::<AssetHubPolkadotRuntimeApi, AssetHubPolkadotAuraId>(extra_args),
Runtime::Omni(block_number, consensus) => match (block_number, consensus) {
(BlockNumber::U32, Consensus::Aura(aura_id)) =>
new_aura_node_spec::<Block<u32>>(aura_id, extra_args),
(BlockNumber::U64, Consensus::Aura(aura_id)) =>
new_aura_node_spec::<Block<u64>>(aura_id, extra_args),
},
})
}
Expand Down Expand Up @@ -156,7 +178,7 @@ pub fn run<CliConfig: crate::cli::CliConfig>(cmd_config: RunConfig) -> Result<()
match cmd {
#[cfg(feature = "runtime-benchmarks")]
BenchmarkCmd::Pallet(cmd) => runner.sync_run(|config| {
cmd.run_with_spec::<HashingFor<Block>, ReclaimHostFunctions>(Some(
cmd.run_with_spec::<HashingFor<Block<u32>>, ReclaimHostFunctions>(Some(
config.chain_spec,
))
}),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// 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 <http://www.gnu.org/licenses/>.

use crate::common::spec::NodeSpec;
use cumulus_client_cli::ExportGenesisHeadCommand;
use frame_benchmarking_cli::BlockCmd;
#[cfg(any(feature = "runtime-benchmarks"))]
use frame_benchmarking_cli::StorageCmd;
use sc_cli::{CheckBlockCmd, ExportBlocksCmd, ExportStateCmd, ImportBlocksCmd, RevertCmd};
use sc_service::{Configuration, TaskManager};
use std::{future::Future, pin::Pin};

type SyncCmdResult = sc_cli::Result<()>;

type AsyncCmdResult<'a> =
sc_cli::Result<(Pin<Box<dyn Future<Output = SyncCmdResult> + 'a>>, TaskManager)>;

pub trait NodeCommandRunner {
fn prepare_check_block_cmd(
self: Box<Self>,
config: Configuration,
cmd: &CheckBlockCmd,
) -> AsyncCmdResult<'_>;

fn prepare_export_blocks_cmd(
self: Box<Self>,
config: Configuration,
cmd: &ExportBlocksCmd,
) -> AsyncCmdResult<'_>;

fn prepare_export_state_cmd(
self: Box<Self>,
config: Configuration,
cmd: &ExportStateCmd,
) -> AsyncCmdResult<'_>;

fn prepare_import_blocks_cmd(
self: Box<Self>,
config: Configuration,
cmd: &ImportBlocksCmd,
) -> AsyncCmdResult<'_>;

fn prepare_revert_cmd(
self: Box<Self>,
config: Configuration,
cmd: &RevertCmd,
) -> AsyncCmdResult<'_>;

fn run_export_genesis_head_cmd(
self: Box<Self>,
config: Configuration,
cmd: &ExportGenesisHeadCommand,
) -> SyncCmdResult;

fn run_benchmark_block_cmd(
self: Box<Self>,
config: Configuration,
cmd: &BlockCmd,
) -> SyncCmdResult;

#[cfg(any(feature = "runtime-benchmarks"))]
fn run_benchmark_storage_cmd(
self: Box<Self>,
config: Configuration,
cmd: &StorageCmd,
) -> SyncCmdResult;
}

impl<T> NodeCommandRunner for T
where
T: NodeSpec,
{
fn prepare_check_block_cmd(
self: Box<Self>,
config: Configuration,
cmd: &CheckBlockCmd,
) -> AsyncCmdResult<'_> {
let partial = T::new_partial(&config).map_err(sc_cli::Error::Service)?;
Ok((Box::pin(cmd.run(partial.client, partial.import_queue)), partial.task_manager))
}

fn prepare_export_blocks_cmd(
self: Box<Self>,
config: Configuration,
cmd: &ExportBlocksCmd,
) -> AsyncCmdResult<'_> {
let partial = T::new_partial(&config).map_err(sc_cli::Error::Service)?;
Ok((Box::pin(cmd.run(partial.client, config.database)), partial.task_manager))
}

fn prepare_export_state_cmd(
self: Box<Self>,
config: Configuration,
cmd: &ExportStateCmd,
) -> AsyncCmdResult<'_> {
let partial = T::new_partial(&config).map_err(sc_cli::Error::Service)?;
Ok((Box::pin(cmd.run(partial.client, config.chain_spec)), partial.task_manager))
}

fn prepare_import_blocks_cmd(
self: Box<Self>,
config: Configuration,
cmd: &ImportBlocksCmd,
) -> AsyncCmdResult<'_> {
let partial = T::new_partial(&config).map_err(sc_cli::Error::Service)?;
Ok((Box::pin(cmd.run(partial.client, partial.import_queue)), partial.task_manager))
}

fn prepare_revert_cmd(
self: Box<Self>,
config: Configuration,
cmd: &RevertCmd,
) -> AsyncCmdResult<'_> {
let partial = T::new_partial(&config).map_err(sc_cli::Error::Service)?;
Ok((Box::pin(cmd.run(partial.client, partial.backend, None)), partial.task_manager))
}

fn run_export_genesis_head_cmd(
self: Box<Self>,
config: Configuration,
cmd: &ExportGenesisHeadCommand,
) -> SyncCmdResult {
let partial = T::new_partial(&config).map_err(sc_cli::Error::Service)?;
cmd.run(partial.client)
}

fn run_benchmark_block_cmd(
self: Box<Self>,
config: Configuration,
cmd: &BlockCmd,
) -> SyncCmdResult {
let partial = T::new_partial(&config).map_err(sc_cli::Error::Service)?;
cmd.run(partial.client)
}

#[cfg(any(feature = "runtime-benchmarks"))]
fn run_benchmark_storage_cmd(
self: Box<Self>,
config: Configuration,
cmd: &StorageCmd,
) -> SyncCmdResult {
let partial = T::new_partial(&config).map_err(sc_cli::Error::Service)?;
let db = partial.backend.expose_db();
let storage = partial.backend.expose_storage();

cmd.run(config, partial.client, db, storage)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,43 @@

pub(crate) mod aura;
pub mod chain_spec;
pub mod command;
pub mod rpc;
pub mod runtime;
pub mod spec;
pub mod types;

use cumulus_primitives_core::CollectCollationInfo;
use sc_client_db::DbHash;
use sp_api::{ApiExt, CallApiAt, ConstructRuntimeApi, Metadata};
use sp_block_builder::BlockBuilder;
use sp_runtime::traits::Block as BlockT;
use sp_runtime::{
traits::{Block as BlockT, BlockNumber, Header as HeaderT, NumberFor},
OpaqueExtrinsic,
};
use sp_session::SessionKeys;
use sp_transaction_pool::runtime_api::TaggedTransactionQueue;
use std::path::PathBuf;
use std::{fmt::Debug, path::PathBuf, str::FromStr};

pub trait NodeBlock:
BlockT<Extrinsic = OpaqueExtrinsic, Header = Self::BoundedHeader, Hash = DbHash>
+ for<'de> serde::Deserialize<'de>
{
type BoundedFromStrErr: Debug;
type BoundedNumber: FromStr<Err = Self::BoundedFromStrErr> + BlockNumber;
type BoundedHeader: HeaderT<Number = Self::BoundedNumber> + Unpin;
}

impl<T> NodeBlock for T
where
T: BlockT<Extrinsic = OpaqueExtrinsic, Hash = DbHash> + for<'de> serde::Deserialize<'de>,
<T as BlockT>::Header: Unpin,
<NumberFor<T> as FromStr>::Err: Debug,
{
type BoundedFromStrErr = <NumberFor<T> as FromStr>::Err;
type BoundedNumber = NumberFor<T>;
type BoundedHeader = <T as BlockT>::Header;
}

/// Convenience trait that defines the basic bounds for the `RuntimeApi` of a parachain node.
pub trait NodeRuntimeApi<Block: BlockT>:
Expand Down
Loading

0 comments on commit c4ced11

Please sign in to comment.