difftreelog
Merge pull request #332 from UniqueNetwork/feature/autoseal-every-n-secs
in: master
Feature/autoseal every n secs
4 files changed
node/cli/Cargo.tomldiffbeforeafterboth--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -300,6 +300,7 @@
clap = "3.1.2"
jsonrpc-core = '18.0.0'
jsonrpc-pubsub = "18.0.0"
+tokio = { version = "1.17.0", features = ["time"] }
fc-rpc-core = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.18" }
fc-consensus = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.18" }
node/cli/src/cli.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use crate::chain_spec;18use std::{path::PathBuf, env};19use clap::Parser;2021const NODE_NAME_ENV: &str = "UNIQUE_NODE_NAME";2223/// Sub-commands supported by the collator.24#[derive(Debug, Parser)]25pub enum Subcommand {26 /// Export the genesis state of the parachain.27 #[clap(name = "export-genesis-state")]28 ExportGenesisState(ExportGenesisStateCommand),2930 /// Export the genesis wasm of the parachain.31 #[clap(name = "export-genesis-wasm")]32 ExportGenesisWasm(ExportGenesisWasmCommand),3334 /// Build a chain specification.35 BuildSpec(sc_cli::BuildSpecCmd),3637 /// Validate blocks.38 CheckBlock(sc_cli::CheckBlockCmd),3940 /// Export blocks.41 ExportBlocks(sc_cli::ExportBlocksCmd),4243 /// Export the state of a given block into a chain spec.44 ExportState(sc_cli::ExportStateCmd),4546 /// Import blocks.47 ImportBlocks(sc_cli::ImportBlocksCmd),4849 /// Remove the whole chain.50 PurgeChain(cumulus_client_cli::PurgeChainCmd),5152 /// Revert the chain to a previous state.53 Revert(sc_cli::RevertCmd),5455 /// The custom benchmark subcommmand benchmarking runtime pallets.56 #[structopt(name = "benchmark", about = "Benchmark runtime pallets.")]57 Benchmark(frame_benchmarking_cli::BenchmarkCmd),58}5960/// Command for exporting the genesis state of the parachain61#[derive(Debug, Parser)]62pub struct ExportGenesisStateCommand {63 /// Output file name or stdout if unspecified.64 #[clap(parse(from_os_str))]65 pub output: Option<PathBuf>,6667 /// Id of the parachain this state is for.68 ///69 /// Default: 10070 #[clap(long, conflicts_with = "chain")]71 pub parachain_id: Option<u32>,7273 /// Write output in binary. Default is to write in hex.74 #[clap(short, long)]75 pub raw: bool,7677 /// The name of the chain for that the genesis state should be exported.78 #[clap(long, conflicts_with = "parachain-id")]79 pub chain: Option<String>,80}8182/// Command for exporting the genesis wasm file.83#[derive(Debug, Parser)]84pub struct ExportGenesisWasmCommand {85 /// Output file name or stdout if unspecified.86 #[clap(parse(from_os_str))]87 pub output: Option<PathBuf>,8889 /// Write output in binary. Default is to write in hex.90 #[clap(short, long)]91 pub raw: bool,9293 /// The name of the chain for that the genesis wasm file should be exported.94 #[clap(long)]95 pub chain: Option<String>,96}9798#[derive(Debug, Parser)]99#[clap(args_conflicts_with_subcommands = true, subcommand_negates_reqs = true)]100pub struct Cli {101 #[structopt(subcommand)]102 pub subcommand: Option<Subcommand>,103104 #[structopt(flatten)]105 pub run: cumulus_client_cli::RunCmd,106107 /// Relaychain arguments108 #[structopt(raw = true)]109 pub relaychain_args: Vec<String>,110}111112impl Cli {113 pub fn node_name() -> String {114 match env::var(NODE_NAME_ENV).ok() {115 Some(name) => name,116 None => {117 if cfg!(feature = "unique-runtime") {118 "Unique"119 } else if cfg!(feature = "quartz-runtime") {120 "Quartz"121 } else {122 "Opal"123 }124 }125 .into(),126 }127 }128}129130#[derive(Debug)]131pub struct RelayChainCli {132 /// The actual relay chain cli object.133 pub base: polkadot_cli::RunCmd,134135 /// Optional chain id that should be passed to the relay chain.136 pub chain_id: Option<String>,137138 /// The base path that should be used by the relay chain.139 pub base_path: Option<PathBuf>,140}141142impl RelayChainCli {143 /// Parse the relay chain CLI parameters using the para chain `Configuration`.144 pub fn new<'a>(145 para_config: &sc_service::Configuration,146 relay_chain_args: impl Iterator<Item = &'a String>,147 ) -> Self {148 let extension = chain_spec::Extensions::try_get(&*para_config.chain_spec);149 let chain_id = extension.map(|e| e.relay_chain.clone());150 let base_path = para_config151 .base_path152 .as_ref()153 .map(|x| x.path().join("polkadot"));154 Self {155 base_path,156 chain_id,157 base: polkadot_cli::RunCmd::parse_from(relay_chain_args),158 }159 }160}1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use crate::chain_spec;18use std::{path::PathBuf, env};19use clap::Parser;2021const NODE_NAME_ENV: &str = "UNIQUE_NODE_NAME";2223/// Sub-commands supported by the collator.24#[derive(Debug, Parser)]25pub enum Subcommand {26 /// Export the genesis state of the parachain.27 #[clap(name = "export-genesis-state")]28 ExportGenesisState(ExportGenesisStateCommand),2930 /// Export the genesis wasm of the parachain.31 #[clap(name = "export-genesis-wasm")]32 ExportGenesisWasm(ExportGenesisWasmCommand),3334 /// Build a chain specification.35 BuildSpec(sc_cli::BuildSpecCmd),3637 /// Validate blocks.38 CheckBlock(sc_cli::CheckBlockCmd),3940 /// Export blocks.41 ExportBlocks(sc_cli::ExportBlocksCmd),4243 /// Export the state of a given block into a chain spec.44 ExportState(sc_cli::ExportStateCmd),4546 /// Import blocks.47 ImportBlocks(sc_cli::ImportBlocksCmd),4849 /// Remove the whole chain.50 PurgeChain(cumulus_client_cli::PurgeChainCmd),5152 /// Revert the chain to a previous state.53 Revert(sc_cli::RevertCmd),5455 /// The custom benchmark subcommmand benchmarking runtime pallets.56 #[structopt(name = "benchmark", about = "Benchmark runtime pallets.")]57 Benchmark(frame_benchmarking_cli::BenchmarkCmd),58}5960/// Command for exporting the genesis state of the parachain61#[derive(Debug, Parser)]62pub struct ExportGenesisStateCommand {63 /// Output file name or stdout if unspecified.64 #[clap(parse(from_os_str))]65 pub output: Option<PathBuf>,6667 /// Id of the parachain this state is for.68 ///69 /// Default: 10070 #[clap(long, conflicts_with = "chain")]71 pub parachain_id: Option<u32>,7273 /// Write output in binary. Default is to write in hex.74 #[clap(short, long)]75 pub raw: bool,7677 /// The name of the chain for that the genesis state should be exported.78 #[clap(long, conflicts_with = "parachain-id")]79 pub chain: Option<String>,80}8182/// Command for exporting the genesis wasm file.83#[derive(Debug, Parser)]84pub struct ExportGenesisWasmCommand {85 /// Output file name or stdout if unspecified.86 #[clap(parse(from_os_str))]87 pub output: Option<PathBuf>,8889 /// Write output in binary. Default is to write in hex.90 #[clap(short, long)]91 pub raw: bool,9293 /// The name of the chain for that the genesis wasm file should be exported.94 #[clap(long)]95 pub chain: Option<String>,96}9798#[derive(Debug, Parser)]99#[clap(args_conflicts_with_subcommands = true, subcommand_negates_reqs = true)]100pub struct Cli {101 #[structopt(subcommand)]102 pub subcommand: Option<Subcommand>,103104 #[structopt(flatten)]105 pub run: cumulus_client_cli::RunCmd,106107 /// When running the node in the `--dev` mode and108 /// there is no transaction in the transaction pool,109 /// an empty block will be sealed automatically110 /// after the `--idle-autoseal-interval` milliseconds.111 ///112 /// The default interval is 500 milliseconds113 #[structopt(default_value = "500", long)]114 pub idle_autoseal_interval: u64,115116 /// Relaychain arguments117 #[structopt(raw = true)]118 pub relaychain_args: Vec<String>,119}120121impl Cli {122 pub fn node_name() -> String {123 match env::var(NODE_NAME_ENV).ok() {124 Some(name) => name,125 None => {126 if cfg!(feature = "unique-runtime") {127 "Unique"128 } else if cfg!(feature = "quartz-runtime") {129 "Quartz"130 } else {131 "Opal"132 }133 }134 .into(),135 }136 }137}138139#[derive(Debug)]140pub struct RelayChainCli {141 /// The actual relay chain cli object.142 pub base: polkadot_cli::RunCmd,143144 /// Optional chain id that should be passed to the relay chain.145 pub chain_id: Option<String>,146147 /// The base path that should be used by the relay chain.148 pub base_path: Option<PathBuf>,149}150151impl RelayChainCli {152 /// Parse the relay chain CLI parameters using the para chain `Configuration`.153 pub fn new<'a>(154 para_config: &sc_service::Configuration,155 relay_chain_args: impl Iterator<Item = &'a String>,156 ) -> Self {157 let extension = chain_spec::Extensions::try_get(&*para_config.chain_spec);158 let chain_id = extension.map(|e| e.relay_chain.clone());159 let base_path = para_config160 .base_path161 .as_ref()162 .map(|x| x.path().join("polkadot"));163 Self {164 base_path,165 chain_id,166 base: polkadot_cli::RunCmd::parse_from(relay_chain_args),167 }168 }169}node/cli/src/command.rsdiffbeforeafterboth--- a/node/cli/src/command.rs
+++ b/node/cli/src/command.rs
@@ -60,7 +60,7 @@
};
use sp_core::hexdisplay::HexDisplay;
use sp_runtime::traits::Block as BlockT;
-use std::{io::Write, net::SocketAddr};
+use std::{io::Write, net::SocketAddr, time::Duration};
use unique_runtime_common::types::Block;
@@ -405,8 +405,10 @@
if is_dev_service {
info!("Running Dev service");
+ let autoseal_interval = Duration::from_millis(cli.idle_autoseal_interval);
+
return start_node_using_chain_runtime! {
- start_dev_node(config).map_err(Into::into)
+ start_dev_node(config, autoseal_interval).map_err(Into::into)
};
};
node/cli/src/service.rsdiffbeforeafterboth--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -21,8 +21,14 @@
use std::sync::Mutex;
use std::collections::BTreeMap;
use std::time::Duration;
+use std::pin::Pin;
use fc_rpc_core::types::FeeHistoryCache;
-use futures::StreamExt;
+use futures::{
+ Stream, StreamExt,
+ stream::select,
+ task::{Context, Poll},
+};
+use tokio::time::Interval;
use unique_rpc::overrides_handle;
@@ -111,6 +117,27 @@
}
}
+pub struct AutosealInterval {
+ interval: Interval,
+}
+
+impl AutosealInterval {
+ pub fn new(config: &Configuration, interval: Duration) -> Self {
+ let _tokio_runtime = config.tokio_handle.enter();
+ let interval = tokio::time::interval(interval);
+
+ Self { interval }
+ }
+}
+
+impl Stream for AutosealInterval {
+ type Item = tokio::time::Instant;
+
+ fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ self.interval.poll_tick(cx).map(Some)
+ }
+}
+
pub fn open_frontier_backend(config: &Configuration) -> Result<Arc<fc_db::Backend<Block>>, String> {
let config_dir = config
.base_path
@@ -712,6 +739,7 @@
/// the parachain inherent
pub fn start_dev_node<Runtime, RuntimeApi, ExecutorDispatch>(
config: Configuration,
+ autoseal_interval: Duration,
) -> sc_service::error::Result<TaskManager>
where
Runtime: RuntimeInstance + Send + Sync + 'static,
@@ -735,7 +763,6 @@
+ sp_consensus_aura::AuraApi<Block, AuraId>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
{
- use futures::Stream;
use sc_consensus_manual_seal::{run_manual_seal, EngineCommand, ManualSealParams};
use fc_consensus::FrontierBlockImport;
use sc_client_api::HeaderBackend;
@@ -799,20 +826,32 @@
telemetry.as_ref().map(|x| x.handle()),
);
- let commands_stream: Box<dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin> =
- Box::new(
- // This bit cribbed from the implementation of instant seal.
- transaction_pool
- .pool()
- .validated_pool()
- .import_notification_stream()
- .map(|_| EngineCommand::SealNewBlock {
- create_empty: true, // was false in Moonbeam
- finalize: false,
- parent_hash: None,
- sender: None,
- }),
- );
+ let transactions_commands_stream: Box<
+ dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin,
+ > = Box::new(
+ transaction_pool
+ .pool()
+ .validated_pool()
+ .import_notification_stream()
+ .map(|_| EngineCommand::SealNewBlock {
+ create_empty: true,
+ finalize: false,
+ parent_hash: None,
+ sender: None,
+ }),
+ );
+
+ let autoseal_interval = Box::pin(AutosealInterval::new(&config, autoseal_interval));
+ let idle_commands_stream: Box<
+ dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin,
+ > = Box::new(autoseal_interval.map(|_| EngineCommand::SealNewBlock {
+ create_empty: true,
+ finalize: false,
+ parent_hash: None,
+ sender: None,
+ }));
+
+ let commands_stream = select(transactions_commands_stream, idle_commands_stream);
let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;
let client_set_aside_for_cidp = client.clone();