Repository: paritytech/substrate
File: client/consensus/manual-seal/src/lib.rs (Rust)

Code before:
		create_empty: false,
		finalize: true,
		parent_hash: None,
		sender: None,
	});

	run_manual_seal(ManualSealParams {
		block_import,
		env,
		client,
		pool,
		commands_stream,
		select_chain,
		consensus_data_provider,
		create_inherent_data_providers,
	})
	.await
}

/// Runs the background finalization task for the manual/instant seal engines.
/// delayed-finalize finalizes blocks configured seconds after blocks are imported.
///
/// This task is intended to be ran along with a block sealing task, but expects blocks are not
/// finalized when they're sealed. Specifically, `finalize` in `SealNewBlock` command should be set
/// to `false` when it is sent to `commands_stream`. That is, `run_delayed_finalize` is incompatible
/// with `run_instant_seal_and_finalize` due to re-finalize attemption.
pub async fn run_delayed_finalize<B, CB, C, S>(
	DelayedFinalizeParams { client, spawn_handle, delay_sec }: DelayedFinalizeParams<C, S>,
) where
	B: BlockT + 'static,
	CB: ClientBackend<B> + 'static,
	C: HeaderBackend<B> + Finalizer<B, CB> + ProvideRuntimeApi<B> + BlockchainEvents<B> + 'static,
	S: SpawnNamed,
{
	let mut block_import_stream = client.import_notification_stream();

	while let Some(notification) = block_import_stream.next().await {
		let delay = Delay::new(Duration::from_secs(delay_sec));
		let cloned_client = client.clone();
		spawn_handle.spawn(
			"delayed-finalize",
			None,
			Box::pin(async move {
				delay.await;
				finalize_block(FinalizeBlockParams {
					hash: notification.hash,
					sender: None,
					justification: None,
					finalizer: cloned_client,
					_phantom: PhantomData,
				})

Review comment (suggestion):
```suggestion
/// Creates a future for delayed finalization of manual sealed blocks.
///
/// The future needs to be spawned in the background alongside the [`run_manual_seal`]/[`run_instant_seal`] future. 
/// It is required that [`EngineCommand::SealNewBlock`] is send with `finalize = false` to not finalize blocks directly after building them. This also means that delayed finality can not be used with [`run_instant_seal_and_finalize`].
```

Code after:
	// into the transaction pool.
	let commands_stream = pool.import_notification_stream().map(|_| EngineCommand::SealNewBlock {
		create_empty: false,
		finalize: true,
		parent_hash: None,
		sender: None,
	});

	run_manual_seal(ManualSealParams {
		block_import,
		env,
		client,
		pool,
		commands_stream,
		select_chain,
		consensus_data_provider,
		create_inherent_data_providers,
	})
	.await
}

/// Creates a future for delayed finalization of manual sealed blocks.
///
/// The future needs to be spawned in the background alongside the
/// [`run_manual_seal`]/[`run_instant_seal`] future. It is required that
/// [`EngineCommand::SealNewBlock`] is send with `finalize = false` to not finalize blocks directly
/// after building them. This also means that delayed finality can not be used with
/// [`run_instant_seal_and_finalize`].
pub async fn run_delayed_finalize<B, CB, C, S>(
	DelayedFinalizeParams { client, spawn_handle, delay_sec }: DelayedFinalizeParams<C, S>,
) where
	B: BlockT + 'static,
	CB: ClientBackend<B> + 'static,
	C: HeaderBackend<B> + Finalizer<B, CB> + ProvideRuntimeApi<B> + BlockchainEvents<B> + 'static,
	S: SpawnNamed,
{
	let mut block_import_stream = client.import_notification_stream();

	while let Some(notification) = block_import_stream.next().await {
		let delay = Delay::new(Duration::from_secs(delay_sec));
		let cloned_client = client.clone();
		spawn_handle.spawn(
			"delayed-finalize",
			None,
			Box::pin(async move {
				delay.await;
				finalize_block(FinalizeBlockParams {
					hash: notification.hash,
					sender: None,
					justification: None,
					finalizer: cloned_client,