Skip to main content

hopr_lib/
helpers.rs

1use std::time::Duration;
2
3use hopr_api::{
4    chain::ChainValues,
5    types::primitive::prelude::{Address, XDai, XDaiBalance},
6};
7
8use crate::errors::HoprLibError;
9
10/// Waits until the given address is funded.
11///
12/// This is done by querying the RPC provider for balance with backoff until `max_delay` argument.
13pub(crate) async fn wait_for_funds<R: ChainValues>(
14    min_balance: XDaiBalance,
15    suggested_balance: XDaiBalance,
16    max_delay: Duration,
17    account: Address,
18    resolver: &R,
19) -> Result<(), HoprLibError> {
20    tracing::info!(
21        suggested_minimum_balance = %suggested_balance,
22        "node about to start, checking for funds",
23    );
24
25    let multiplier = 1.05;
26    let mut current_delay = Duration::from_secs(2).min(max_delay);
27
28    while current_delay <= max_delay {
29        match resolver.balance::<XDai, _>(account).await {
30            Ok(current_balance) => {
31                tracing::info!(balance = %current_balance, "balance status");
32                if current_balance.ge(&min_balance) {
33                    tracing::info!("node is funded");
34                    return Ok(());
35                } else {
36                    tracing::warn!("still unfunded, trying again soon");
37                }
38            }
39            Err(error) => tracing::error!(%error, "failed to fetch balance from the chain"),
40        }
41
42        hopr_async_runtime::prelude::sleep(current_delay).await;
43        current_delay = current_delay.mul_f64(multiplier);
44    }
45
46    Err(HoprLibError::InsufficientFunds(format!(
47        "failed to fund the node within {} seconds",
48        max_delay.as_secs()
49    )))
50}