From c251d887f7cef2a6279ce708b052780ca744266b Mon Sep 17 00:00:00 2001 From: binarybaron <86064887+binarybaron@users.noreply.github.com> Date: Wed, 5 Jun 2024 16:13:23 +0200 Subject: [PATCH] tests tests: Create integration test for Bob transfer proof buffer --- ...t_swap_while_alice_sends_transfer_proof.rs | 80 +++++++++++++++++++ swap/tests/harness/mod.rs | 22 ++++- 2 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 swap/tests/happy_path_bob_runs_different_swap_while_alice_sends_transfer_proof.rs diff --git a/swap/tests/happy_path_bob_runs_different_swap_while_alice_sends_transfer_proof.rs b/swap/tests/happy_path_bob_runs_different_swap_while_alice_sends_transfer_proof.rs new file mode 100644 index 00000000..04349a87 --- /dev/null +++ b/swap/tests/happy_path_bob_runs_different_swap_while_alice_sends_transfer_proof.rs @@ -0,0 +1,80 @@ +use futures::{select, FutureExt}; +use harness::{ + alice_run_until::{is_btc_locked, is_transfer_proof_sent}, + bob_run_until, SlowCancelConfig, +}; +use swap::{ + asb::FixedRate, + protocol::{alice, bob}, +}; +use tokio::{join, task}; + +pub mod harness; + +#[tokio::test] +async fn given_bob_is_running_a_different_swap_while_alice_sends_transfer_proof_swap_completes() { + harness::setup_test(SlowCancelConfig, |mut ctx| async move { + // Start a swap with bob, wait until btc is locked + println!("Starting swap with bob, waiting until btc is locked"); + let (bob_swap, bob_join_handle) = ctx.bob_swap().await; + let bob_swap_id = bob_swap.id; + + let bob_swap = tokio::spawn(bob::run_until(bob_swap, bob_run_until::is_btc_locked)); + + let alice_swap = ctx.alice_next_swap().await; + let alice_swap = tokio::spawn(alice::run_until( + alice_swap, + is_btc_locked, + FixedRate::default(), + )); + + let (bob_state, alice_state) = join!(bob_swap, alice_swap); + + let _ = bob_state??; + let _ = alice_state??; + + // Start bob but with a different swap. Alice will send the transfer proof while bob is running the new swap + println!("Starting a different swap with bob while alice sends transfer proof"); + let (bob_swap2, bob_join_handle2) = ctx.bob_swap().await; + let bob_state2 = bob::run(bob_swap2); + + ctx.restart_alice_resume_only(true).await; + let alice_swap = ctx.alice_next_swap().await; + let alice_state = + alice::run_until(alice_swap, is_transfer_proof_sent, FixedRate::default()).fuse(); + let mut alice_state = Box::pin(alice_state); + + let mut bob_handle = task::spawn(bob_state2).fuse(); + + // TODO: Fix this + let result = select! { + alice_state = alice_state => { + drop(bob_handle); // Explicitly drop the handle to cancel bob_state2 + () + }, + // This should ideally never be reached. + _ = &mut bob_handle => { + () + }, + }; + + // Resume the original swap for bob and alice + println!("Resuming the original swap for bob and alice"); + let (bob_swap, _) = ctx + .stop_and_resume_bob_from_db(bob_join_handle2, bob_swap_id) + .await; + let bob_state = bob::run(bob_swap); + + ctx.restart_alice_resume_only(true).await; + let alice_swap = ctx.alice_next_swap().await; + let alice_state = alice::run(alice_swap, FixedRate::default()); + + let (bob_state, alice_state) = join!(bob_state, alice_state); + + ctx.assert_bob_redeemed(bob_state?).await; + ctx.assert_alice_redeemed(alice_state?).await; + + Ok(()) + }) + .await; +} diff --git a/swap/tests/harness/mod.rs b/swap/tests/harness/mod.rs index 119dd096..f5937147 100644 --- a/swap/tests/harness/mod.rs +++ b/swap/tests/harness/mod.rs @@ -89,6 +89,7 @@ where env_config, alice_bitcoin_wallet.clone(), alice_monero_wallet.clone(), + false ) .await; @@ -224,6 +225,7 @@ async fn start_alice( env_config: Config, bitcoin_wallet: Arc, monero_wallet: Arc, + resume_only: bool, ) -> (AliceApplicationHandle, Receiver) { if let Some(parent_dir) = db_path.parent() { ensure_directory_exists(parent_dir).unwrap(); @@ -236,7 +238,6 @@ async fn start_alice( let min_buy = bitcoin::Amount::from_sat(u64::MIN); let max_buy = bitcoin::Amount::from_sat(u64::MAX); let latest_rate = FixedRate::default(); - let resume_only = false; let mut swarm = swarm::asb( seed, @@ -435,7 +436,7 @@ impl BobParams { } let db = Arc::new(SqliteDatabase::open(&self.db_path).await?); - let (event_loop, handle) = self.new_eventloop(swap_id, db).await?; + let (event_loop, handle) = self.new_eventloop(swap_id, db.clone()).await?; let swap = bob::Swap::from_db( db, @@ -504,7 +505,7 @@ impl BobParams { .behaviour_mut() .add_address(self.alice_peer_id, self.alice_address.clone()); - cli::EventLoop::new(swap_id, swarm, self.alice_peer_id, db.clone()); + cli::EventLoop::new(swap_id, swarm, self.alice_peer_id, db) } } @@ -561,7 +562,7 @@ impl TestContext { .await } - pub async fn restart_alice(&mut self) { + pub async fn restart_alice_resume_only(&mut self, resume_only: bool) { self.alice_handle.abort(); let (alice_handle, alice_swap_handle) = start_alice( @@ -571,6 +572,7 @@ impl TestContext { self.env_config, self.alice_bitcoin_wallet.clone(), self.alice_monero_wallet.clone(), + resume_only, ) .await; @@ -578,6 +580,10 @@ impl TestContext { self.alice_swap_handle = alice_swap_handle; } + pub async fn restart_alice(&mut self) { + self.restart_alice_resume_only(true).await; + } + pub async fn alice_next_swap(&mut self) -> alice::Swap { timeout(Duration::from_secs(20), self.alice_swap_handle.recv()) .await @@ -997,6 +1003,14 @@ pub mod alice_run_until { pub fn is_encsig_learned(state: &AliceState) -> bool { matches!(state, AliceState::EncSigLearned { .. }) } + + pub fn is_transfer_proof_sent(state: &AliceState) -> bool { + matches!(state, AliceState::XmrLockTransferProofSent { .. }) + } + + pub fn is_btc_locked(state: &AliceState) -> bool { + matches!(state, AliceState::BtcLocked { .. }) + } } pub mod bob_run_until {