1pub mod abi;
5pub mod action_executor;
6pub mod client;
7pub mod config;
8pub mod crypto;
9pub mod encoding;
10pub mod error;
11pub mod eth_client;
12pub mod eth_syncer;
13pub mod eth_transaction_builder;
14pub mod events;
15pub mod metered_eth_provider;
16pub mod metrics;
17pub mod monitor;
18pub mod node;
19pub mod orchestrator;
20pub mod server;
21pub mod storage;
22pub mod sui_bridge_watchdog;
23pub mod sui_client;
24pub mod sui_syncer;
25pub mod sui_transaction_builder;
26pub mod types;
27pub mod utils;
28
29#[cfg(any(feature = "test-utils", test))]
30pub(crate) mod eth_mock_provider;
31
32#[cfg(test)]
33pub(crate) mod sui_mock_client;
34
35#[cfg(any(feature = "test-utils", test))]
36pub mod test_utils;
37
38pub const BRIDGE_ENABLE_PROTOCOL_VERSION: u64 = 45;
39
40#[cfg(any(feature = "test-utils", test))]
41pub mod e2e_tests;
42
43#[macro_export]
44macro_rules! retry_with_max_elapsed_time {
45    ($func:expr, $max_elapsed_time:expr) => {{
46        let backoff = backoff::ExponentialBackoff {
49            initial_interval: Duration::from_millis(400),
50            randomization_factor: 0.1,
51            multiplier: 2.0,
52            max_interval: Duration::from_secs(120),
53            max_elapsed_time: Some($max_elapsed_time),
54            ..Default::default()
55        };
56        backoff::future::retry(backoff, || {
57            let fut = async {
58                let result = $func.await;
59                match result {
60                    Ok(_) => {
61                        return Ok(result);
62                    }
63                    Err(e) => {
64                        tracing::debug!("Retrying due to error: {:?}", e);
66                        return Err(backoff::Error::transient(e));
67                    }
68                }
69            };
70            std::boxed::Box::pin(fut)
71        })
72        .await
73    }};
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79    use std::time::Duration;
80
81    async fn example_func_ok() -> anyhow::Result<()> {
82        Ok(())
83    }
84
85    async fn example_func_err() -> anyhow::Result<()> {
86        tracing::info!("example_func_err");
87        Err(anyhow::anyhow!(""))
88    }
89
90    #[tokio::test]
91    async fn test_retry_with_max_elapsed_time() {
92        telemetry_subscribers::init_for_testing();
93        let max_elapsed_time = Duration::from_millis(20);
96        retry_with_max_elapsed_time!(example_func_ok(), max_elapsed_time)
97            .unwrap()
98            .unwrap();
99
100        let max_elapsed_time = Duration::from_secs(10);
102        let instant = std::time::Instant::now();
103        retry_with_max_elapsed_time!(example_func_err(), max_elapsed_time).unwrap_err();
104        assert!(instant.elapsed() < max_elapsed_time);
105    }
106}