async fn confirm_submission(
        &self,
        client: &mut TxClient<Channel>,
        hex_encoded_tx_hash: String,
    ) -> u64 {
        // The min seconds to sleep after receiving a GetTx response and sending the next request.
        const MIN_POLL_INTERVAL_SECS: u64 = 1;
        // The max seconds to sleep after receiving a GetTx response and sending the next request.
        const MAX_POLL_INTERVAL_SECS: u64 = 12;
        // How long to wait after starting `confirm_submission` before starting to log errors.
        const START_LOGGING_DELAY: Duration = Duration::from_secs(12);
        // The minimum duration between logging errors.
        const LOG_ERROR_INTERVAL: Duration = Duration::from_secs(5);

        let start = Instant::now();
        let mut logged_at = start;

        let mut log_if_due = |maybe_error: Option<anyhow::Error>| {
            if start.elapsed() <= START_LOGGING_DELAY || logged_at.elapsed() <= LOG_ERROR_INTERVAL {
                return;
            }
            let reason = maybe_error
                .map_or(anyhow::anyhow!("transaction still pending"), |error| {
                    anyhow::anyhow!("transaction still pending, error: {}", error)
                });
            tracing::warn!(
                %reason,
                tx_hash = %hex_encoded_tx_hash,
                elapsed_seconds = start.elapsed().as_secs_f32(),
                "waiting to confirm blob submission"
            );
            logged_at = Instant::now();
        };

        let mut sleep_secs = MIN_POLL_INTERVAL_SECS;
        loop {
            tokio::time::sleep(Duration::from_secs(sleep_secs)).await;
            let res = self
                .clone()
                .get_tx(client, hex_encoded_tx_hash.clone())
                .await;
            match res {
                Ok(Some(height)) => return height,
                Ok(None) => {
                    sleep_secs = MIN_POLL_INTERVAL_SECS;
                    log_if_due(None);
                }
                Err(error) => {
                    sleep_secs =
                        std::cmp::min(sleep_secs.saturating_mul(2), MAX_POLL_INTERVAL_SECS);
                    log_if_due(Some(error));
                }
            }
        }
    }
Waits for the transaction to be included in a block and returns the height of that block.
core/node/da_clients/src/celestia/sdk.rs