diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ebe60e3e..b3dbb7ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -135,6 +135,7 @@ jobs: refund_restart_alice_cancelled, refund_restart_alice, bob_refunds_using_cancel_and_refund_command, + bob_refunds_using_cancel_and_refund_command_timelock_not_exired, ] runs-on: ubuntu-latest steps: diff --git a/swap/tests/bob_refunds_using_cancel_and_refund_command_timelock_not_exired.rs b/swap/tests/bob_refunds_using_cancel_and_refund_command_timelock_not_exired.rs new file mode 100644 index 00000000..3540a18c --- /dev/null +++ b/swap/tests/bob_refunds_using_cancel_and_refund_command_timelock_not_exired.rs @@ -0,0 +1,56 @@ +pub mod testutils; + +use bob::cancel::CancelError; +use swap::protocol::{alice, bob, bob::BobState}; +use testutils::{bob_run_until::is_btc_locked, SlowCancelConfig}; + +#[tokio::test] +async fn given_bob_manually_cancels_when_timelock_not_expired_errors() { + testutils::setup_test(SlowCancelConfig, |mut ctx| async move { + let (alice_swap, _) = ctx.new_swap_as_alice().await; + let (bob_swap, bob_join_handle) = ctx.new_swap_as_bob().await; + + let alice_handle = alice::run(alice_swap); + tokio::spawn(alice_handle); + + let bob_state = bob::run_until(bob_swap, is_btc_locked).await.unwrap(); + assert!(matches!(bob_state, BobState::BtcLocked {..})); + + let (bob_swap, bob_join_handle) = ctx.stop_and_resume_bob_from_db(bob_join_handle).await; + assert!(matches!(bob_swap.state, BobState::BtcLocked {..})); + + // Bob manually cancels + let result = bob::cancel( + bob_swap.swap_id, + bob_swap.state, + bob_swap.bitcoin_wallet, + bob_swap.db, + ) + .await + .unwrap() + .err() + .unwrap(); + + assert!(matches!(result, CancelError::CancelTimelockNotExpiredYet)); + + let (bob_swap, bob_join_handle) = ctx.stop_and_resume_bob_from_db(bob_join_handle).await; + assert!(matches!(bob_swap.state, BobState::BtcLocked {..})); + + // Bob manually refunds + bob::refund( + bob_swap.swap_id, + bob_swap.state, + bob_swap.execution_params, + bob_swap.bitcoin_wallet, + bob_swap.db, + ) + .await + .unwrap() + .err() + .unwrap(); + + let (bob_swap, _) = ctx.stop_and_resume_bob_from_db(bob_join_handle).await; + assert!(matches!(bob_swap.state, BobState::BtcLocked {..})); + }) + .await; +}