pub async fn run(mut self) -> anyhow::Result<()> {
        if self.is_sync {
            tracing::info!("Starting synchronous L2 block sealer");
        } else if let Some(sender) = self.commands_sender.upgrade() {
            tracing::info!(
                "Starting async L2 block sealer with queue capacity {}",
                sender.max_capacity()
            );
        } else {
            tracing::warn!("L2 block sealer not started, since its handle is already dropped");
        }

        let mut l2_block_seal_delta: Option<Instant> = None;
        // Commands must be processed sequentially: a later L2 block cannot be saved before
        // an earlier one.
        while let Some(completable) = self.next_command().await {
            completable.command.seal(self.pool.clone()).await?;
            if let Some(delta) = l2_block_seal_delta {
                L2_BLOCK_METRICS.seal_delta.observe(delta.elapsed());
            }
            l2_block_seal_delta = Some(Instant::now());

            completable.completion_sender.send(()).ok();
            // ^ We don't care whether anyone listens to the processing progress
        }
        Ok(())
    }
Seals L2 blocks as they are received from the [`StateKeeperPersistence`]. This should be run
on a separate Tokio task.
core/node/state_keeper/src/io/persistence.rs