async fn recover_key_chunk(
        tree: &Mutex<AsyncTreeRecovery>,
        snapshot_l2_block: L2BlockNumber,
        key_chunk: ops::RangeInclusive<H256>,
        pool: &ConnectionPool<Core>,
        stop_receiver: &watch::Receiver<bool>,
    ) -> anyhow::Result<bool> {
        let acquire_connection_latency =
            RECOVERY_METRICS.chunk_latency[&ChunkRecoveryStage::AcquireConnection].start();
        let mut storage = pool.connection_tagged("metadata_calculator").await?;
        acquire_connection_latency.observe();

        if *stop_receiver.borrow() {
            return Ok(false);
        }

        let entries_latency =
            RECOVERY_METRICS.chunk_latency[&ChunkRecoveryStage::LoadEntries].start();
        let all_entries = storage
            .storage_logs_dal()
            .get_tree_entries_for_l2_block(snapshot_l2_block, key_chunk.clone())
            .await?;
        Self::check_pruning_info(&mut storage, snapshot_l2_block).await?;
        drop(storage);

        let entries_latency = entries_latency.observe();
        tracing::debug!(
            "Loaded {} entries for chunk {key_chunk:?} in {entries_latency:?}",
            all_entries.len()
        );

        if *stop_receiver.borrow() {
            return Ok(false);
        }

        // Sanity check: all entry keys must be distinct. Otherwise, we may end up writing non-final values
        // to the tree, since we don't enforce any ordering on entries besides by the hashed key.
        for window in all_entries.windows(2) {
            let [prev_entry, next_entry] = window else {
                unreachable!();
            };
            anyhow::ensure!(
                prev_entry.key != next_entry.key,
                "node snapshot in Postgres is corrupted: entries {prev_entry:?} and {next_entry:?} \
                 have same hashed_key"
            );
        }

        let all_entries = all_entries
            .into_iter()
            .map(|entry| TreeEntry {
                key: entry.tree_key(),
                value: entry.value,
                leaf_index: entry.leaf_index,
            })
            .collect();
        let lock_tree_latency =
            RECOVERY_METRICS.chunk_latency[&ChunkRecoveryStage::LockTree].start();
        let mut tree = tree.lock().await;
        lock_tree_latency.observe();

        if *stop_receiver.borrow() {
            return Ok(false);
        }

        let extend_tree_latency =
            RECOVERY_METRICS.chunk_latency[&ChunkRecoveryStage::ExtendTree].start();
        tree.extend(all_entries).await?;
        let extend_tree_latency = extend_tree_latency.observe();
        tracing::debug!(
            "Extended Merkle tree with entries for chunk {key_chunk:?} in {extend_tree_latency:?}"
        );
        Ok(true)
    }
Returns `Ok(true)` if the chunk was recovered, `Ok(false)` if the recovery process was interrupted.
core/node/metadata_calculator/src/recovery/mod.rs