Skip to main content

reth_e2e_test_utils/
wait.rs

1//! Helpers for waiting on conditions of test nodes.
2
3use eyre::eyre;
4use std::{fmt::Display, future::Future, time::Duration};
5
6/// Maximum time the wait helpers wait for a condition, e.g. for a node to sync to or commit a
7/// block.
8pub const WAIT_TIMEOUT: Duration = Duration::from_secs(60);
9
10/// Interval at which [`poll_until`] polls and [`NodeTestContext::advance_while`] advances the
11/// chain.
12///
13/// [`NodeTestContext::advance_while`]: crate::node::NodeTestContext::advance_while
14pub const POLL_INTERVAL: Duration = Duration::from_millis(20);
15
16/// Calls `poll` every [`POLL_INTERVAL`] until it returns a value.
17///
18/// Returns an error describing `what` was awaited if the condition is not met within
19/// [`WAIT_TIMEOUT`], or the first error returned by `poll`.
20///
21/// `what` is held across awaits, so it must be `Send` for the returned future to be `Send`. This
22/// rules out `format_args!`, use `format!` instead.
23pub async fn poll_until<T, F, Fut>(what: impl Display + Send, mut poll: F) -> eyre::Result<T>
24where
25    F: FnMut() -> Fut,
26    Fut: Future<Output = eyre::Result<Option<T>>>,
27{
28    let wait = async {
29        loop {
30            if let Some(value) = poll().await? {
31                return Ok(value)
32            }
33            tokio::time::sleep(POLL_INTERVAL).await;
34        }
35    };
36    tokio::time::timeout(WAIT_TIMEOUT, wait)
37        .await
38        .map_err(|_| eyre!("timed out waiting for {what}"))?
39}