pub(crate) async fn ensure_consistency(
        &mut self,
        delay_interval: Duration,
        pool: &ConnectionPool<Core>,
        stop_receiver: &mut watch::Receiver<bool>,
    ) -> Result<(), OrStopped> {
        let earliest_l1_batch = wait_for_l1_batch(pool, delay_interval, stop_receiver).await?;
        let mut storage = pool.connection_tagged("tree_updater").await?;

        self.ensure_genesis(&mut storage, earliest_l1_batch).await?;
        let next_l1_batch_to_process = self.next_l1_batch_number().await?;

        let current_db_batch = storage
            .blocks_dal()
            .get_sealed_l1_batch_number()
            .await?
            .unwrap_or_default();
        let last_l1_batch_with_tree_data = storage
            .blocks_dal()
            .get_last_l1_batch_number_with_tree_data()
            .await?;
        drop(storage);

        tracing::info!(
            "Next L1 batch for Merkle tree: {next_l1_batch_to_process}, current Postgres L1 batch: {current_db_batch:?}, \
             last L1 batch with metadata: {last_l1_batch_with_tree_data:?}"
        );

        // It may be the case that we don't have any L1 batches with metadata in Postgres, e.g. after
        // recovering from a snapshot. We cannot wait for such a batch to appear (*this* is the component
        // responsible for their appearance!), but fortunately most of the updater doesn't depend on it.
        if let Some(last_l1_batch_with_tree_data) = last_l1_batch_with_tree_data {
            let backup_lag =
                (last_l1_batch_with_tree_data.0 + 1).saturating_sub(next_l1_batch_to_process.0);
            METRICS.backup_lag.set(backup_lag.into());

            if next_l1_batch_to_process > last_l1_batch_with_tree_data + 1 {
                tracing::warn!(
                    "Next L1 batch of the tree ({next_l1_batch_to_process}) is greater than last L1 batch with metadata in Postgres \
                     ({last_l1_batch_with_tree_data}); this may be a result of restoring Postgres from a snapshot. \
                     Truncating Merkle tree versions so that this mismatch is fixed..."
                );
                self.roll_back_logs(last_l1_batch_with_tree_data).await?;
                self.save().await?;
                tracing::info!("Truncated Merkle tree to L1 batch #{next_l1_batch_to_process}");
            }

            self.ensure_no_l1_batch_divergence(pool).await?;
        }
        Ok(())
    }
Ensures that the tree is consistent with Postgres, truncating the tree if necessary.
This will wait for at least one L1 batch to appear in Postgres if necessary.
core/node/zk_os_tree_manager/src/updater.rs