difftreelog
Autoseal after idle n seconds
in: master
4 files changed
node/cli/Cargo.tomldiffbeforeafterboth--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -294,6 +294,7 @@
[dependencies]
futures = '0.3.17'
+futures-timer = '3.0.2'
log = '0.4.14'
flexi_logger = "0.15.7"
parking_lot = '0.11.2'
node/cli/src/cli.rsdiffbeforeafterboth104 #[structopt(flatten)]104 #[structopt(flatten)]105 pub run: cumulus_client_cli::RunCmd,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 /// Default interval is 500 milliseconds113 #[structopt(default_value = "500", long)]114 pub idle_autoseal_interval: u64,106115107 /// Relaychain arguments116 /// Relaychain arguments108 #[structopt(raw = true)]117 #[structopt(raw = true)]node/cli/src/command.rsdiffbeforeafterboth--- a/node/cli/src/command.rs
+++ b/node/cli/src/command.rs
@@ -35,7 +35,7 @@
use crate::{
chain_spec::{self, RuntimeId, RuntimeIdentification, ServiceId, ServiceIdentification},
cli::{Cli, RelayChainCli, Subcommand},
- service::{new_partial, start_node, start_dev_node},
+ service::{new_partial, start_node, start_dev_node, AutosealInterval},
};
#[cfg(feature = "unique-runtime")]
@@ -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,12 @@
if is_dev_service {
info!("Running Dev service");
+ let autoseal_interval = AutosealInterval::new(
+ 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,11 @@
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::Future;
+use futures::{Stream, StreamExt, stream::select, task::{Context, Poll}};
+use futures_timer::Delay;
use unique_rpc::overrides_handle;
@@ -111,6 +114,40 @@
}
}
+pub struct AutosealInterval {
+ duration: Duration,
+ delay_handle: Pin<Box<Delay>>
+}
+
+impl AutosealInterval {
+ pub fn new(duration: Duration) -> Result<Self, String> {
+ if duration.is_zero() {
+ return Err("Invalid autoseal interval: 0 seconds".into());
+ }
+
+ Ok(Self {
+ duration,
+ delay_handle: Box::pin(Delay::new(duration))
+ })
+ }
+}
+
+impl Stream for AutosealInterval {
+ type Item = ();
+
+ fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ match self.delay_handle.as_mut().poll(cx) {
+ Poll::Ready(_) => {
+ let duration = self.duration;
+ self.delay_handle.reset(duration);
+
+ Poll::Ready(Some(()))
+ }
+ Poll::Pending => Poll::Pending
+ }
+ }
+}
+
pub fn open_frontier_backend(config: &Configuration) -> Result<Arc<fc_db::Backend<Block>>, String> {
let config_dir = config
.base_path
@@ -712,6 +749,7 @@
/// the parachain inherent
pub fn start_dev_node<Runtime, RuntimeApi, ExecutorDispatch>(
config: Configuration,
+ autoseal_interval: AutosealInterval,
) -> sc_service::error::Result<TaskManager>
where
Runtime: RuntimeInstance + Send + Sync + 'static,
@@ -735,7 +773,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,21 +836,36 @@
telemetry.as_ref().map(|x| x.handle()),
);
- let commands_stream: Box<dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin> =
+ let transactions_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
+ create_empty: true,
finalize: false,
parent_hash: None,
sender: None,
}),
);
+ let autoseal_interval = Box::pin(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();