diff --git a/swap/tests/happy_path_restart_bob_after_comm.rs b/swap/tests/happy_path_restart_bob_after_comm.rs index 3b83d4b9..7c1618b0 100644 --- a/swap/tests/happy_path_restart_bob_after_comm.rs +++ b/swap/tests/happy_path_restart_bob_after_comm.rs @@ -1,168 +1,59 @@ -use crate::testutils::{init_alice, init_bob}; -use get_port::get_port; -use libp2p::Multiaddr; use rand::rngs::OsRng; -use swap::{ - bitcoin, - config::Config, - database::Database, - monero, - protocol::{alice, bob, bob::BobState}, - seed::Seed, -}; -use tempfile::tempdir; -use testcontainers::clients::Cli; -use testutils::init_tracing; -use uuid::Uuid; +use swap::protocol::{alice, bob, bob::BobState}; pub mod testutils; #[tokio::test] async fn given_bob_restarts_after_encsig_is_sent_resume_swap() { - let _guard = init_tracing(); + testutils::test(|alice_harness, bob_harness| async move { + let alice = alice_harness.new_alice().await; + let bob = bob_harness.new_bob().await; - let cli = Cli::default(); - let ( - monero, - testutils::Containers { - bitcoind, - monerods: _monerods, - }, - ) = testutils::init_containers(&cli).await; + let alice_swap = alice::swap( + alice.state, + alice.event_loop_handle, + alice.bitcoin_wallet.clone(), + alice.monero_wallet.clone(), + alice.config, + alice.swap_id, + alice.db, + ); + let alice_swap_handle = tokio::spawn(alice_swap); - let btc_to_swap = bitcoin::Amount::from_sat(1_000_000); - let xmr_to_swap = monero::Amount::from_piconero(1_000_000_000_000); - - let bob_btc_starting_balance = btc_to_swap * 10; - let alice_xmr_starting_balance = xmr_to_swap * 10; - - let port = get_port().expect("Failed to find a free port"); - let alice_multiaddr: Multiaddr = format!("/ip4/127.0.0.1/tcp/{}", port) - .parse() - .expect("failed to parse Alice's address"); - - let config = Config::regtest(); - - let ( - alice_state, - mut alice_event_loop, - alice_event_loop_handle, - alice_btc_wallet, - alice_xmr_wallet, - alice_db, - ) = init_alice( - &bitcoind, - &monero, - btc_to_swap, - xmr_to_swap, - alice_xmr_starting_balance, - alice_multiaddr.clone(), - config, - Seed::random().unwrap(), - ) - .await; - - let alice_peer_id = alice_event_loop.peer_id(); - let (bob_state, bob_event_loop, bob_event_loop_handle, bob_btc_wallet, bob_xmr_wallet, _) = - init_bob( - alice_multiaddr.clone(), - alice_peer_id.clone(), - &bitcoind, - &monero, - btc_to_swap, - bob_btc_starting_balance, - xmr_to_swap, - config, + let bob_state = bob::run_until( + bob.state, + bob::swap::is_encsig_sent, + bob.event_loop_handle, + bob.db, + bob.bitcoin_wallet.clone(), + bob.monero_wallet.clone(), + OsRng, + bob.swap_id, ) - .await; + .await + .unwrap(); - // TODO: we are making a clone of Alices's wallets here to keep them in scope - // after Alices's wallets are moved into an async task. - let alice_btc_wallet_clone = alice_btc_wallet.clone(); - let alice_xmr_wallet_clone = alice_xmr_wallet.clone(); + assert!(matches!(bob_state, BobState::EncSigSent {..})); - // TODO: we are making a clone of Bob's wallets here to keep them in scope after - // Bob's wallets are moved into an async task. - let bob_btc_wallet_clone = bob_btc_wallet.clone(); - let bob_xmr_wallet_clone = bob_xmr_wallet.clone(); + let bob = bob_harness.recover_bob_from_db().await; + assert!(matches!(bob.state, BobState::EncSigSent {..})); - let alice_swap_handle = tokio::spawn(alice::swap::swap( - alice_state, - alice_event_loop_handle, - alice_btc_wallet.clone(), - alice_xmr_wallet.clone(), - config, - Uuid::new_v4(), - alice_db, - )); + let bob_state = bob::swap( + bob.state, + bob.event_loop_handle, + bob.db, + bob.bitcoin_wallet.clone(), + bob.monero_wallet.clone(), + OsRng, + bob.swap_id, + ) + .await + .unwrap(); - tokio::spawn(async move { alice_event_loop.run().await }); + bob_harness.assert_redeemed(bob_state).await; - tokio::spawn(bob_event_loop.run()); - - let bob_swap_id = Uuid::new_v4(); - let bob_db_datadir = tempdir().unwrap(); - let bob_db = Database::open(bob_db_datadir.path()).unwrap(); - - let bob_state = bob::swap::run_until( - bob_state, - bob::swap::is_encsig_sent, - bob_event_loop_handle, - bob_db, - bob_btc_wallet.clone(), - bob_xmr_wallet.clone(), - OsRng, - bob_swap_id, - ) - .await - .unwrap(); - - assert!(matches!(bob_state, BobState::EncSigSent {..})); - - let bob_db = Database::open(bob_db_datadir.path()).unwrap(); - - let resume_state = - if let swap::database::Swap::Bob(state) = bob_db.get_state(bob_swap_id).unwrap() { - assert!(matches!(state, swap::database::Bob::EncSigSent {..})); - state.into() - } else { - unreachable!() - }; - - let (event_loop_after_restart, event_loop_handle_after_restart) = - testutils::init_bob_event_loop(alice_peer_id, alice_multiaddr); - tokio::spawn(event_loop_after_restart.run()); - - let bob_state = bob::swap::swap( - resume_state, - event_loop_handle_after_restart, - bob_db, - bob_btc_wallet, - bob_xmr_wallet, - OsRng, - bob_swap_id, - ) - .await - .unwrap(); - - // Wait for Alice to finish too - alice_swap_handle.await.unwrap().unwrap(); - - assert!(matches!(bob_state, BobState::XmrRedeemed {..})); - - let btc_alice_final = alice_btc_wallet_clone.as_ref().balance().await.unwrap(); - let btc_bob_final = bob_btc_wallet_clone.as_ref().balance().await.unwrap(); - - assert_eq!( - btc_alice_final, - btc_to_swap - bitcoin::Amount::from_sat(bitcoin::TX_FEE) - ); - assert!(btc_bob_final <= bob_btc_starting_balance - btc_to_swap); - - let xmr_alice_final = alice_xmr_wallet_clone.as_ref().get_balance().await.unwrap(); - bob_xmr_wallet_clone.as_ref().inner.refresh().await.unwrap(); - let xmr_bob_final = bob_xmr_wallet_clone.as_ref().get_balance().await.unwrap(); - - assert!(xmr_alice_final <= alice_xmr_starting_balance - xmr_to_swap); - assert_eq!(xmr_bob_final, xmr_to_swap); + let alice_state = alice_swap_handle.await.unwrap(); + alice_harness.assert_redeemed(alice_state.unwrap()).await; + }) + .await; } diff --git a/swap/tests/happy_path_restart_bob_before_comm.rs b/swap/tests/happy_path_restart_bob_before_comm.rs index a3c5216e..c206e2fd 100644 --- a/swap/tests/happy_path_restart_bob_before_comm.rs +++ b/swap/tests/happy_path_restart_bob_before_comm.rs @@ -1,159 +1,59 @@ -use crate::testutils::{init_alice, init_bob}; -use get_port::get_port; -use libp2p::Multiaddr; use rand::rngs::OsRng; -use swap::{ - bitcoin, - config::Config, - database::Database, - monero, - protocol::{alice, alice::AliceState, bob, bob::BobState}, - seed::Seed, -}; -use tempfile::tempdir; -use testcontainers::clients::Cli; -use testutils::init_tracing; -use tokio::select; -use uuid::Uuid; +use swap::protocol::{alice, bob, bob::BobState}; pub mod testutils; #[tokio::test] async fn given_bob_restarts_after_xmr_is_locked_resume_swap() { - let _guard = init_tracing(); + testutils::test(|alice_harness, bob_harness| async move { + let alice = alice_harness.new_alice().await; + let bob = bob_harness.new_bob().await; - let cli = Cli::default(); - let ( - monero, - testutils::Containers { - bitcoind, - monerods: _monerods, - }, - ) = testutils::init_containers(&cli).await; + let alice_swap = alice::swap( + alice.state, + alice.event_loop_handle, + alice.bitcoin_wallet.clone(), + alice.monero_wallet.clone(), + alice.config, + alice.swap_id, + alice.db, + ); + let alice_swap_handle = tokio::spawn(alice_swap); - let btc_to_swap = bitcoin::Amount::from_sat(1_000_000); - let xmr_to_swap = monero::Amount::from_piconero(1_000_000_000_000); - - let bob_btc_starting_balance = btc_to_swap * 10; - let bob_xmr_starting_balance = monero::Amount::from_piconero(0); - - let alice_btc_starting_balance = bitcoin::Amount::ZERO; - let alice_xmr_starting_balance = xmr_to_swap * 10; - - let port = get_port().expect("Failed to find a free port"); - let alice_multiaddr: Multiaddr = format!("/ip4/127.0.0.1/tcp/{}", port) - .parse() - .expect("failed to parse Alice's address"); - - let ( - alice_state, - mut alice_event_loop, - alice_event_loop_handle, - alice_btc_wallet, - alice_xmr_wallet, - alice_db, - ) = init_alice( - &bitcoind, - &monero, - btc_to_swap, - xmr_to_swap, - alice_xmr_starting_balance, - alice_multiaddr.clone(), - Config::regtest(), - Seed::random().unwrap(), - ) - .await; - - let alice_peer_id = alice_event_loop.peer_id(); - let (bob_state, bob_event_loop_1, bob_event_loop_handle_1, bob_btc_wallet, bob_xmr_wallet, _) = - init_bob( - alice_multiaddr.clone(), - alice_peer_id.clone(), - &bitcoind, - &monero, - btc_to_swap, - bob_btc_starting_balance, - xmr_to_swap, - Config::regtest(), - ) - .await; - - let alice_fut = alice::swap::swap( - alice_state, - alice_event_loop_handle, - alice_btc_wallet.clone(), - alice_xmr_wallet.clone(), - Config::regtest(), - Uuid::new_v4(), - alice_db, - ); - - let bob_swap_id = Uuid::new_v4(); - let bob_db_datadir = tempdir().unwrap(); - - let bob_xmr_locked_fut = { - let bob_db = Database::open(bob_db_datadir.path()).unwrap(); - bob::swap::run_until( - bob_state, + let bob_state = bob::run_until( + bob.state, bob::swap::is_xmr_locked, - bob_event_loop_handle_1, - bob_db, - bob_btc_wallet.clone(), - bob_xmr_wallet.clone(), + bob.event_loop_handle, + bob.db, + bob.bitcoin_wallet.clone(), + bob.monero_wallet.clone(), OsRng, - bob_swap_id, + bob.swap_id, ) - }; + .await + .unwrap(); - tokio::spawn(async move { alice_event_loop.run().await }); + assert!(matches!(bob_state, BobState::XmrLocked {..})); - let alice_fut_handle = tokio::spawn(alice_fut); + let bob = bob_harness.recover_bob_from_db().await; + assert!(matches!(bob.state, BobState::XmrLocked {..})); - // We are selecting with bob_event_loop_1 so that we stop polling on it once - // bob reaches `xmr locked` state. - let bob_restart_state = select! { - res = bob_xmr_locked_fut => res.unwrap(), - _ = bob_event_loop_1.run() => panic!("The event loop should never finish") - }; + let bob_state = bob::swap( + bob.state, + bob.event_loop_handle, + bob.db, + bob.bitcoin_wallet.clone(), + bob.monero_wallet.clone(), + OsRng, + bob.swap_id, + ) + .await + .unwrap(); - let (bob_event_loop_2, bob_event_loop_handle_2) = - testutils::init_bob_event_loop(alice_peer_id, alice_multiaddr); + bob_harness.assert_redeemed(bob_state).await; - let bob_fut = bob::swap::swap( - bob_restart_state, - bob_event_loop_handle_2, - Database::open(bob_db_datadir.path()).unwrap(), - bob_btc_wallet.clone(), - bob_xmr_wallet.clone(), - OsRng, - bob_swap_id, - ); - - let bob_final_state = select! { - bob_final_state = bob_fut => bob_final_state.unwrap(), - _ = bob_event_loop_2.run() => panic!("Event loop is not expected to stop") - }; - - assert!(matches!(bob_final_state, BobState::XmrRedeemed)); - - // Wait for Alice to finish too. - let alice_final_state = alice_fut_handle.await.unwrap().unwrap(); - assert!(matches!(alice_final_state, AliceState::BtcRedeemed)); - - let btc_alice_final = alice_btc_wallet.as_ref().balance().await.unwrap(); - let btc_bob_final = bob_btc_wallet.as_ref().balance().await.unwrap(); - - let xmr_alice_final = alice_xmr_wallet.as_ref().get_balance().await.unwrap(); - - bob_xmr_wallet.as_ref().inner.refresh().await.unwrap(); - let xmr_bob_final = bob_xmr_wallet.as_ref().get_balance().await.unwrap(); - - assert_eq!( - btc_alice_final, - alice_btc_starting_balance + btc_to_swap - bitcoin::Amount::from_sat(bitcoin::TX_FEE) - ); - assert!(btc_bob_final <= bob_btc_starting_balance - btc_to_swap); - - assert!(xmr_alice_final <= alice_xmr_starting_balance - xmr_to_swap); - assert_eq!(xmr_bob_final, bob_xmr_starting_balance + xmr_to_swap); + let alice_state = alice_swap_handle.await.unwrap(); + alice_harness.assert_redeemed(alice_state.unwrap()).await; + }) + .await; }