Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

polkadot-parachain: add manual seal support #5586

Merged
merged 15 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 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 @@ -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 }
Expand All @@ -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 }
Expand Down
6 changes: 6 additions & 0 deletions cumulus/polkadot-parachain/polkadot-parachain-lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ pub struct Cli<Config: CliConfig> {
#[command(flatten)]
pub run: cumulus_client_cli::RunCmd,

/// Use manual seal consensus.
///
/// This works only with dev chains (e.g. asset-hub-rococo-dev).
serban300 marked this conversation as resolved.
Show resolved Hide resolved
#[arg(long)]
pub manual_seal: bool,
serban300 marked this conversation as resolved.
Show resolved Hide resolved

/// EXPERIMENTAL: Use slot-based collator which can handle elastic scaling.
///
/// Use with care, this flag is unstable and subject to change.
Expand Down
53 changes: 32 additions & 21 deletions cumulus/polkadot-parachain/polkadot-parachain-lib/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -39,7 +38,6 @@ 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.
Expand All @@ -53,18 +51,17 @@ pub struct RunConfig {
pub fn new_aura_node_spec<Block>(
aura_id: AuraConsensusId,
extra_args: &NodeExtraArgs,
) -> Box<dyn DynNodeSpec>
) -> Box<dyn DynNodeSpecExt>
where
Block: NodeBlock + UnwindSafe + RefUnwindSafe,
Block::BoundedHeader: UnwindSafe + RefUnwindSafe,
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,
Expand All @@ -76,7 +73,7 @@ fn new_node_spec(
config: &sc_service::Configuration,
runtime_resolver: &Box<dyn RuntimeResolverT>,
extra_args: &NodeExtraArgs,
) -> std::result::Result<Box<dyn DynNodeSpec>, sc_cli::Error> {
) -> std::result::Result<Box<dyn DynNodeSpecExt>, sc_cli::Error> {
let runtime = runtime_resolver.runtime(config.chain_spec.as_ref())?;

Ok(match runtime {
Expand Down Expand Up @@ -215,7 +212,24 @@ pub fn run<CliConfig: crate::cli::CliConfig>(cmd_config: RunConfig) -> Result<()
RelayChainCli::<CliConfig>::new(runner.config(), cli.relay_chain_args.iter());
let collator_options = cli.run.collator_options();

let is_dev_chain = runner.config().chain_spec.id().ends_with("-dev");
serban300 marked this conversation as resolved.
Show resolved Hide resolved
if cli.manual_seal && !is_dev_chain {
return Err("Manual sealing can be turned on only for dev chains".into());
}

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 cli.manual_seal {
return node_spec.start_manual_seal_node(config, para_id).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
Expand Down Expand Up @@ -262,32 +276,26 @@ pub fn run<CliConfig: crate::cli::CliConfig>(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::<polkadot_primitives::AccountId>::into_account_truncating(
&id,
&para_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 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(
node_spec,
config,
&cmd_config.runtime_resolver,
polkadot_config,
collator_options,
id,
para_id,
cli.node_extra_args(),
hwbench,
)
Expand All @@ -297,17 +305,20 @@ pub fn run<CliConfig: crate::cli::CliConfig>(cmd_config: RunConfig) -> Result<()
}
}

/// This method is needed only for `#[sc_tracing::logging::prefix_logs_with("Parachain")]`.
///
/// Adding this annotation to `DynNodeSpec::start_node()` doesn't work, probably because of the
serban300 marked this conversation as resolved.
Show resolved Hide resolved
/// `Pin<Box<dyn Future<...>>>` return type.
#[sc_tracing::logging::prefix_logs_with("Parachain")]
async fn start_node(
node_spec: Box<dyn DynNodeSpecExt>,
config: sc_service::Configuration,
runtime_resolver: &Box<dyn RuntimeResolverT>,
polkadot_config: sc_service::Configuration,
collator_options: cumulus_client_cli::CollatorOptions,
id: ParaId,
extra_args: NodeExtraArgs,
hwbench: Option<sc_sysinfo::HwBench>,
) -> Result<sc_service::TaskManager> {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// 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 crate::common::spec::BaseNodeSpec;
use cumulus_client_cli::ExportGenesisHeadCommand;
use frame_benchmarking_cli::BlockCmd;
#[cfg(any(feature = "runtime-benchmarks"))]
Expand Down Expand Up @@ -81,7 +81,7 @@ pub trait NodeCommandRunner {

impl<T> NodeCommandRunner for T
where
T: NodeSpec,
T: BaseNodeSpec,
{
fn prepare_check_block_cmd(
self: Box<Self>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,31 @@ use sp_runtime::{
};
use sp_session::SessionKeys;
use sp_transaction_pool::runtime_api::TaggedTransactionQueue;
use std::{fmt::Debug, path::PathBuf, str::FromStr};
use std::{
fmt::Debug,
panic::{RefUnwindSafe, UnwindSafe},
path::PathBuf,
str::FromStr,
};

pub trait NodeBlock:
BlockT<Extrinsic = OpaqueExtrinsic, Header = Self::BoundedHeader, Hash = DbHash>
+ for<'de> serde::Deserialize<'de>
serban300 marked this conversation as resolved.
Show resolved Hide resolved
+ UnwindSafe
serban300 marked this conversation as resolved.
Show resolved Hide resolved
+ RefUnwindSafe
{
type BoundedFromStrErr: Debug;
type BoundedNumber: FromStr<Err = Self::BoundedFromStrErr> + BlockNumber;
type BoundedHeader: HeaderT<Number = Self::BoundedNumber> + Unpin;
type BoundedHeader: HeaderT<Number = Self::BoundedNumber> + Unpin + UnwindSafe + RefUnwindSafe;
}

impl<T> NodeBlock for T
where
T: BlockT<Extrinsic = OpaqueExtrinsic, Hash = DbHash> + for<'de> serde::Deserialize<'de>,
<T as BlockT>::Header: Unpin,
T: BlockT<Extrinsic = OpaqueExtrinsic, Hash = DbHash>
+ for<'de> serde::Deserialize<'de>
+ UnwindSafe
+ RefUnwindSafe,
<T as BlockT>::Header: Unpin + UnwindSafe + RefUnwindSafe,
<NumberFor<T> as FromStr>::Err: Debug,
{
type BoundedFromStrErr = <NumberFor<T> as FromStr>::Err;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ fn warn_if_slow_hardware(hwbench: &sc_sysinfo::HwBench) {
}
}

pub(crate) trait NodeSpec {
pub(crate) trait BaseNodeSpec {
type Block: NodeBlock;

type RuntimeApi: ConstructNodeRuntimeApi<
Expand All @@ -99,16 +99,6 @@ pub(crate) trait NodeSpec {

type BuildImportQueue: BuildImportQueue<Self::Block, Self::RuntimeApi>;

type BuildRpcExtensions: BuildRpcExtensions<
ParachainClient<Self::Block, Self::RuntimeApi>,
ParachainBackend<Self::Block>,
FullPool<Self::Block, ParachainClient<Self::Block, Self::RuntimeApi>>,
>;

type StartConsensus: StartConsensus<Self::Block, Self::RuntimeApi>;

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
Expand Down Expand Up @@ -185,6 +175,18 @@ pub(crate) trait NodeSpec {
other: (block_import, telemetry, telemetry_worker_handle),
})
}
}

pub(crate) trait NodeSpec: BaseNodeSpec {
type BuildRpcExtensions: BuildRpcExtensions<
ParachainClient<Self::Block, Self::RuntimeApi>,
ParachainBackend<Self::Block>,
FullPool<Self::Block, ParachainClient<Self::Block, Self::RuntimeApi>>,
>;

type StartConsensus: StartConsensus<Self::Block, Self::RuntimeApi>;

const SYBIL_RESISTANCE: CollatorSybilResistance;

/// Start a node with the given parachain spec.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
Loading
Loading