From 4f8907a4b0cebf81b5c29260ce2d97f442520d0c Mon Sep 17 00:00:00 2001 From: patrini32 <171664803+patrini32@users.noreply.github.com> Date: Tue, 4 Jun 2024 19:08:58 +0300 Subject: [PATCH] prettify error, when bob tries to cancel and refund after disconnecting --- swap/src/cli/cancel_and_refund.rs | 42 +++++++++++++++++++------------ swap/src/protocol/bob/state.rs | 16 ++++++------ 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/swap/src/cli/cancel_and_refund.rs b/swap/src/cli/cancel_and_refund.rs index d542b7ed..bf3a6fc4 100644 --- a/swap/src/cli/cancel_and_refund.rs +++ b/swap/src/cli/cancel_and_refund.rs @@ -1,4 +1,3 @@ -use crate::bitcoin::wallet::Subscription; use crate::bitcoin::{parse_rpc_error_code, RpcErrorCode, Wallet}; use crate::protocol::bob::BobState; use crate::protocol::Database; @@ -12,8 +11,15 @@ pub async fn cancel_and_refund( bitcoin_wallet: Arc, db: Arc, ) -> Result { - if let Err(err) = cancel(swap_id, bitcoin_wallet.clone(), db.clone()).await { - tracing::info!(%err, "Could not submit cancel transaction"); + match cancel(swap_id, bitcoin_wallet.clone(), db.clone()).await { + Ok((_, state)) => { + if matches!(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 { @@ -29,7 +35,7 @@ pub async fn cancel( swap_id: Uuid, bitcoin_wallet: Arc, db: Arc, -) -> Result<(Txid, Subscription, BobState)> { +) -> Result<(Txid, BobState)> { let state = db.get_state(swap_id).await?.try_into()?; let state6 = match state { @@ -55,26 +61,30 @@ pub async fn cancel( tracing::info!(%swap_id, "Manually cancelling swap"); - let (txid, subscription) = match state6.submit_tx_cancel(bitcoin_wallet.as_ref()).await { - Ok(txid) => txid, + match state6.submit_tx_cancel(bitcoin_wallet.as_ref()).await { + Ok((txid, _)) => { + let state = BobState::BtcCancelled(state6); + db.insert_latest_state(swap_id, state.clone().into()) + .await?; + return Ok((txid, state)); + } Err(err) => { if let Ok(error_code) = parse_rpc_error_code(&err) { tracing::debug!(%error_code, "parse rpc error"); - if error_code == i64::from(RpcErrorCode::RpcVerifyAlreadyInChain) { - tracing::info!("Cancel transaction has already been confirmed on chain"); - } else if error_code == i64::from(RpcErrorCode::RpcVerifyError) { - tracing::info!("General error trying to submit cancel transaction"); + if error_code == i64::from(RpcErrorCode::RpcVerifyAlreadyInChain) + || error_code == i64::from(RpcErrorCode::RpcVerifyError) + { + let txid = state6.construct_tx_cancel().unwrap().txid(); + let state = BobState::BtcCancelled(state6); + db.insert_latest_state(swap_id, state.clone().into()) + .await?; + tracing::info!("Cancel transaction has already been confirmed on chain. The swap has therefore already been cancelled by Alice"); + return Ok((txid, state)); } } bail!(err); } }; - - let state = BobState::BtcCancelled(state6); - db.insert_latest_state(swap_id, state.clone().into()) - .await?; - - Ok((txid, subscription, state)) } pub async fn refund( diff --git a/swap/src/protocol/bob/state.rs b/swap/src/protocol/bob/state.rs index 58c1d723..a1fd750a 100644 --- a/swap/src/protocol/bob/state.rs +++ b/swap/src/protocol/bob/state.rs @@ -663,12 +663,8 @@ impl State6 { Ok(tx) } - - pub async fn submit_tx_cancel( - &self, - bitcoin_wallet: &bitcoin::Wallet, - ) -> Result<(Txid, Subscription)> { - let transaction = bitcoin::TxCancel::new( + pub fn construct_tx_cancel(&self) -> Result { + bitcoin::TxCancel::new( &self.tx_lock, self.cancel_timelock, self.A, @@ -676,7 +672,13 @@ impl State6 { self.tx_cancel_fee, )? .complete_as_bob(self.A, self.b.clone(), self.tx_cancel_sig_a.clone()) - .context("Failed to complete Bitcoin cancel transaction")?; + .context("Failed to complete Bitcoin cancel transaction") + } + pub async fn submit_tx_cancel( + &self, + bitcoin_wallet: &bitcoin::Wallet, + ) -> Result<(Txid, Subscription)> { + let transaction = self.construct_tx_cancel()?; let (tx_id, subscription) = bitcoin_wallet.broadcast(transaction, "cancel").await?;