improve usability of refund

pull/1571/head
nhnn 2 months ago
parent 81fabdd451
commit d52db29e64
No known key found for this signature in database

@ -1,6 +1,6 @@
use crate::bitcoin::wallet::Subscription;
use crate::bitcoin::{parse_rpc_error_code, RpcErrorCode, Wallet};
use crate::protocol::bob::BobState;
use crate::protocol::bob::{BobState, BtcPunishedWhileRefundError};
use crate::protocol::Database;
use anyhow::{bail, Result};
use bitcoin::Txid;
@ -105,7 +105,23 @@ pub async fn refund(
};
tracing::info!(%swap_id, "Manually refunding swap");
state6.publish_refund_btc(bitcoin_wallet.as_ref()).await?;
match state6.publish_refund_btc(bitcoin_wallet.as_ref()).await {
Ok(_) => (),
Err(refund_error) => {
if let Some(refund_error) = refund_error.downcast_ref::<BtcPunishedWhileRefundError>() {
let state = BobState::BtcPunished {
tx_lock_id: state6.tx_lock_id(),
};
db.insert_latest_state(swap_id, state.clone().into())
.await?;
println!("{}", refund_error);
return Ok(state);
}
}
}
let state = BobState::BtcRefunded(state6);
db.insert_latest_state(swap_id, state.clone().into())

@ -10,6 +10,7 @@ use crate::monero_ext::ScalarExt;
use crate::protocol::{Message0, Message1, Message2, Message3, Message4, CROSS_CURVE_PROOF_SYSTEM};
use anyhow::{anyhow, bail, Context, Result};
use bdk::database::BatchDatabase;
use bdk::electrum_client::Error as BdkError;
use ecdsa_fun::adaptor::{Adaptor, HashTranscript};
use ecdsa_fun::nonce::Deterministic;
use ecdsa_fun::Signature;
@ -21,6 +22,14 @@ use sigma_fun::ext::dl_secp256k1_ed25519_eq::CrossCurveDLEQProof;
use std::fmt;
use uuid::Uuid;
#[derive(Debug)]
pub struct BtcPunishedWhileRefundError;
impl std::fmt::Display for BtcPunishedWhileRefundError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Cannot refund because BTC is punished.")
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum BobState {
Started {
@ -662,9 +671,23 @@ impl State6 {
pub async fn publish_refund_btc(&self, bitcoin_wallet: &bitcoin::Wallet) -> Result<()> {
let signed_tx_refund = self.signed_refund_transaction()?;
bitcoin_wallet.broadcast(signed_tx_refund, "refund").await?;
Ok(())
let transaction_broadcast = bitcoin_wallet.broadcast(signed_tx_refund, "refund").await;
match transaction_broadcast {
Ok(_) => Ok(()),
Err(anyhow_error) => match anyhow_error.downcast_ref::<BdkError>() {
Some(&BdkError::Protocol(serde_json::Value::String(ref protocol_error)))
// UTXO is already spent, swap timeout.
if protocol_error.contains("bad-txns-inputs-missingorspent") =>
{
// Correct the state and show friendly error.
// Set state to CancelTimelockExpired
Err(anyhow!(BtcPunishedWhileRefundError))
}
_ => Err(anyhow_error),
},
}
}
pub fn signed_refund_transaction(&self) -> Result<Transaction> {

Loading…
Cancel
Save