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
10pub(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}