From 8e4fd2cc3b360151ff4d7a3af740d2415378c978 Mon Sep 17 00:00:00 2001 From: patrini32 <171664803+patrini32@users.noreply.github.com> Date: Tue, 4 Jun 2024 19:46:42 +0300 Subject: [PATCH] Add test and rustify code --- swap/src/cli/cancel_and_refund.rs | 7 +- ...punishes_after_bob_dead_and_bob_cancels.rs | 83 +++++++++++++++++++ 2 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 swap/tests/alice_manually_punishes_after_bob_dead_and_bob_cancels.rs diff --git a/swap/src/cli/cancel_and_refund.rs b/swap/src/cli/cancel_and_refund.rs index bf3a6fc4..b1c0f2aa 100644 --- a/swap/src/cli/cancel_and_refund.rs +++ b/swap/src/cli/cancel_and_refund.rs @@ -12,14 +12,13 @@ pub async fn cancel_and_refund( db: Arc, ) -> Result { match cancel(swap_id, bitcoin_wallet.clone(), db.clone()).await { - Ok((_, state)) => { - if matches!(state, BobState::BtcCancelled { .. }) { - return Ok(state); - } + Ok((_, state @ BobState::BtcCancelled {..})) => { + return Ok(state); } Err(err) => { tracing::info!(%err, "Could not submit cancel transaction"); } + _ => {} }; let state = match refund(swap_id, bitcoin_wallet, db).await { diff --git a/swap/tests/alice_manually_punishes_after_bob_dead_and_bob_cancels.rs b/swap/tests/alice_manually_punishes_after_bob_dead_and_bob_cancels.rs new file mode 100644 index 00000000..de0ba4e7 --- /dev/null +++ b/swap/tests/alice_manually_punishes_after_bob_dead_and_bob_cancels.rs @@ -0,0 +1,83 @@ +pub mod harness; + +use harness::alice_run_until::is_xmr_lock_transaction_sent; +use harness::bob_run_until::is_btc_locked; +use harness::FastPunishConfig; +use swap::asb; +use swap::asb::FixedRate; +use swap::cli; +use swap::protocol::alice::AliceState; +use swap::protocol::bob::BobState; +use swap::protocol::{alice, bob}; +/// Bob locks Btc and Alice locks Xmr. Bob does not act; he fails to send Alice +/// the encsig and fail to refund or redeem. Alice punishes using the cancel and +/// punish command. Then Bob tries to refund. +#[tokio::test] +async fn alice_manually_punishes_after_bob_dead_and_bob_cancels() { + harness::setup_test(FastPunishConfig, |mut ctx| async move { + 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, is_btc_locked)); + + let alice_swap = ctx.alice_next_swap().await; + let alice_bitcoin_wallet = alice_swap.bitcoin_wallet.clone(); + + let alice_swap = tokio::spawn(alice::run_until( + alice_swap, + is_xmr_lock_transaction_sent, + FixedRate::default(), + )); + + let bob_state = bob_swap.await??; + assert!(matches!(bob_state, BobState::BtcLocked { .. })); + + let alice_state = alice_swap.await??; + + // Ensure cancel timelock is expired + if let AliceState::XmrLockTransactionSent { state3, .. } = alice_state { + alice_bitcoin_wallet + .subscribe_to(state3.tx_lock) + .await + .wait_until_confirmed_with(state3.cancel_timelock) + .await?; + } else { + panic!("Alice in unexpected state {}", alice_state); + } + + // manual cancel (required to be able to punish) + + ctx.restart_alice().await; + let alice_swap = ctx.alice_next_swap().await; + let (_, alice_state) = + asb::cancel(alice_swap.swap_id, alice_swap.bitcoin_wallet, alice_swap.db).await?; + + // Ensure punish timelock is expired + if let AliceState::BtcCancelled { state3, .. } = alice_state { + alice_bitcoin_wallet + .subscribe_to(state3.tx_cancel()) + .await + .wait_until_confirmed_with(state3.punish_timelock) + .await?; + } else { + panic!("Alice in unexpected state {}", alice_state); + } + + // manual punish + + ctx.restart_alice().await; + let alice_swap = ctx.alice_next_swap().await; + let (_, alice_state) = + asb::punish(alice_swap.swap_id, alice_swap.bitcoin_wallet, alice_swap.db).await?; + ctx.assert_alice_punished(alice_state).await; + + let (bob_swap, _) = ctx + .stop_and_resume_bob_from_db(bob_join_handle, bob_swap_id) + .await; + + let state = + cli::cancel_and_refund(bob_swap_id, bob_swap.bitcoin_wallet, bob_swap.db).await?; + assert!(matches!(state, BobState::BtcCancelled { .. })); + Ok(()) + }) + .await; +}