From 9f1bf72c7b5619d2baa9e6f8278949c9b6754275 Mon Sep 17 00:00:00 2001 From: Lucas Soriano del Pino Date: Fri, 16 Oct 2020 11:18:02 +1100 Subject: [PATCH] Only generate refund action after Bitcoin lock --- xmr-btc/src/lib.rs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/xmr-btc/src/lib.rs b/xmr-btc/src/lib.rs index fc0cbb35..f1412366 100644 --- a/xmr-btc/src/lib.rs +++ b/xmr-btc/src/lib.rs @@ -118,7 +118,12 @@ where B: MedianTime + bitcoin::WatchForRawTransaction + Send + Sync, { enum SwapFailed { - TimelockReached, + BeforeBtcLock, + AfterBtcLock(Reason), + } + + enum Reason { + BtcExpired, InsufficientXMR(monero::InsufficientFunds), } @@ -142,7 +147,7 @@ where let btc_has_expired = bitcoin_time_is_gte(bitcoin_ledger, refund_timelock).shared(); if btc_has_expired.clone().await { - return Err(SwapFailed::TimelockReached); + return Err(SwapFailed::BeforeBtcLock); } co.yield_(Action::LockBitcoin(tx_lock.clone())).await; @@ -150,8 +155,6 @@ where let poll_until_btc_has_expired = poll_until(btc_has_expired).shared(); futures::pin_mut!(poll_until_btc_has_expired); - // the source of this could be the database, this layer doesn't care - let transfer_proof = match select( network.receive_transfer_proof(), poll_until_btc_has_expired.clone(), @@ -159,7 +162,7 @@ where .await { Either::Left((proof, _)) => proof, - Either::Right(_) => return Err(SwapFailed::TimelockReached), + Either::Right(_) => return Err(SwapFailed::AfterBtcLock(Reason::BtcExpired)), }; let S_b_monero = monero::PublicKey::from_private_key(&monero::PrivateKey::from_scalar( @@ -179,8 +182,10 @@ where ) .await { - Either::Left((Err(e), _)) => return Err(SwapFailed::InsufficientXMR(e)), - Either::Right(_) => return Err(SwapFailed::TimelockReached), + Either::Left((Err(e), _)) => { + return Err(SwapFailed::AfterBtcLock(Reason::InsufficientXMR(e))) + } + Either::Right(_) => return Err(SwapFailed::AfterBtcLock(Reason::BtcExpired)), _ => {} } @@ -197,7 +202,7 @@ where .await { Either::Left((tx, _)) => tx, - Either::Right(_) => return Err(SwapFailed::TimelockReached), + Either::Right(_) => return Err(SwapFailed::AfterBtcLock(Reason::BtcExpired)), }; // NOTE: If any of this fails, Bob will never be able to take the monero. @@ -226,7 +231,7 @@ where } .await; - if swap_result.is_err() { + if let Err(SwapFailed::AfterBtcLock(_)) = swap_result { let tx_cancel = bitcoin::TxCancel::new(&tx_lock, refund_timelock, A.clone(), b.public()); let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &refund_address);