diff --git a/swap/src/bitcoin/wallet.rs b/swap/src/bitcoin/wallet.rs index 17d7ace5..db1df5c2 100644 --- a/swap/src/bitcoin/wallet.rs +++ b/swap/src/bitcoin/wallet.rs @@ -147,14 +147,20 @@ impl Wallet { self.inner.lock().await.network() } - pub async fn broadcast(&self, transaction: Transaction) -> Result { + /// Broadcast the given transaction to the network and emit a log statement + /// if done so successfully. + pub async fn broadcast(&self, transaction: Transaction, kind: &str) -> Result { let txid = transaction.txid(); self.inner .lock() .await .broadcast(transaction) - .with_context(|| format!("failed to broadcast transaction {}", txid))?; + .with_context(|| { + format!("failed to broadcast Bitcoin {} transaction {}", kind, txid) + })?; + + tracing::info!("Published Bitcoin {} transaction as {}", txid, kind); Ok(txid) } diff --git a/swap/src/protocol/alice/steps.rs b/swap/src/protocol/alice/steps.rs index cdb447ac..e65567d1 100644 --- a/swap/src/protocol/alice/steps.rs +++ b/swap/src/protocol/alice/steps.rs @@ -25,7 +25,6 @@ use libp2p::PeerId; use sha2::Sha256; use std::sync::Arc; use tokio::time::timeout; -use tracing::info; // TODO(Franck): Use helper functions from xmr-btc instead of re-writing them // here @@ -125,16 +124,6 @@ pub fn build_bitcoin_redeem_transaction( Ok(tx) } -pub async fn publish_bitcoin_redeem_transaction( - redeem_tx: bitcoin::Transaction, - bitcoin_wallet: Arc, -) -> Result<::bitcoin::Txid> { - info!("Attempting to publish bitcoin redeem txn"); - let txid = bitcoin_wallet.broadcast(redeem_tx).await?; - - Ok(txid) -} - pub async fn publish_cancel_transaction( tx_lock: TxLock, a: bitcoin::SecretKey, @@ -170,7 +159,7 @@ pub async fn publish_cancel_transaction( .expect("sig_{a,b} to be valid signatures for tx_cancel"); // TODO(Franck): Error handling is delicate, why can't we broadcast? - bitcoin_wallet.broadcast(tx_cancel).await?; + bitcoin_wallet.broadcast(tx_cancel, "cancel").await?; // TODO(Franck): Wait until transaction is mined and returned mined // block height @@ -248,17 +237,3 @@ pub fn build_bitcoin_punish_transaction( Ok(signed_tx_punish) } - -pub async fn publish_bitcoin_punish_transaction( - punish_tx: bitcoin::Transaction, - bitcoin_wallet: Arc, - execution_params: ExecutionParams, -) -> Result { - let txid = bitcoin_wallet.broadcast(punish_tx).await?; - - bitcoin_wallet - .wait_for_transaction_finality(txid, execution_params) - .await?; - - Ok(txid) -} diff --git a/swap/src/protocol/alice/swap.rs b/swap/src/protocol/alice/swap.rs index 59185617..addde0a4 100644 --- a/swap/src/protocol/alice/swap.rs +++ b/swap/src/protocol/alice/swap.rs @@ -15,8 +15,7 @@ use crate::{ event_loop::EventLoopHandle, steps::{ build_bitcoin_punish_transaction, build_bitcoin_redeem_transaction, - extract_monero_private_key, lock_xmr, publish_bitcoin_punish_transaction, - publish_bitcoin_redeem_transaction, publish_cancel_transaction, + extract_monero_private_key, lock_xmr, publish_cancel_transaction, wait_for_bitcoin_encrypted_signature, wait_for_bitcoin_refund, wait_for_locked_bitcoin, }, @@ -219,37 +218,31 @@ async fn run_until_internal( state3.B, &state3.redeem_address, ) { - Ok(tx) => { - match publish_bitcoin_redeem_transaction(tx, bitcoin_wallet.clone()) - .await - { - Ok(txid) => { - let publishded_redeem_tx = bitcoin_wallet - .wait_for_transaction_finality(txid, execution_params) - .await; + Ok(tx) => match bitcoin_wallet.broadcast(tx, "redeem").await { + Ok(txid) => { + let publishded_redeem_tx = bitcoin_wallet + .wait_for_transaction_finality(txid, execution_params) + .await; - match publishded_redeem_tx { - Ok(_) => AliceState::BtcRedeemed, - Err(e) => { - bail!("Waiting for Bitcoin transaction finality failed with {}! The redeem transaction was published, but it is not ensured that the transaction was included! You're screwed.", e) - } + match publishded_redeem_tx { + Ok(_) => AliceState::BtcRedeemed, + Err(e) => { + bail!("Waiting for Bitcoin transaction finality failed with {}! The redeem transaction was published, but it is not ensured that the transaction was included! You're screwed.", e) } } - Err(e) => { - error!("Publishing the redeem transaction failed with {}, attempting to wait for cancellation now. If you restart the application before the timelock is expired publishing the redeem transaction will be retried.", e); - state3 - .wait_for_cancel_timelock_to_expire( - bitcoin_wallet.as_ref(), - ) - .await?; + } + Err(e) => { + error!("Publishing the redeem transaction failed with {}, attempting to wait for cancellation now. If you restart the application before the timelock is expired publishing the redeem transaction will be retried.", e); + state3 + .wait_for_cancel_timelock_to_expire(bitcoin_wallet.as_ref()) + .await?; - AliceState::CancelTimelockExpired { - state3, - monero_wallet_restore_blockheight, - } + AliceState::CancelTimelockExpired { + state3, + monero_wallet_restore_blockheight, } } - } + }, Err(e) => { error!("Constructing the redeem transaction failed with {}, attempting to wait for cancellation now.", e); state3 @@ -427,11 +420,15 @@ async fn run_until_internal( state3.B, )?; - let punish_tx_finalised = publish_bitcoin_punish_transaction( - signed_tx_punish, - bitcoin_wallet.clone(), - execution_params, - ); + let punish_tx_finalised = async { + let txid = bitcoin_wallet.broadcast(signed_tx_punish, "punish").await?; + + bitcoin_wallet + .wait_for_transaction_finality(txid, execution_params) + .await?; + + Result::<_, anyhow::Error>::Ok(txid) + }; let refund_tx_seen = bitcoin_wallet.watch_for_raw_transaction(tx_refund.txid()); diff --git a/swap/src/protocol/bob/state.rs b/swap/src/protocol/bob/state.rs index 584fcee0..f057d41c 100644 --- a/swap/src/protocol/bob/state.rs +++ b/swap/src/protocol/bob/state.rs @@ -271,8 +271,7 @@ impl State2 { pub async fn lock_btc(self, bitcoin_wallet: &bitcoin::Wallet) -> Result { let signed_tx_lock = bitcoin_wallet.sign_tx_lock(self.tx_lock.clone()).await?; - tracing::debug!("locking BTC in transaction {}", self.tx_lock.txid()); - let _ = bitcoin_wallet.broadcast(signed_tx_lock).await?; + let _ = bitcoin_wallet.broadcast(signed_tx_lock, "lock").await?; Ok(State3 { A: self.A, @@ -475,7 +474,8 @@ impl State4 { tx_cancel", ); - let tx_id = bitcoin_wallet.broadcast(tx_cancel).await?; + let tx_id = bitcoin_wallet.broadcast(tx_cancel, "cancel").await?; + Ok(tx_id) } @@ -544,7 +544,7 @@ impl State4 { let signed_tx_refund = tx_refund.add_signatures((self.A, sig_a), (self.b.public(), sig_b))?; - let txid = bitcoin_wallet.broadcast(signed_tx_refund).await?; + let txid = bitcoin_wallet.broadcast(signed_tx_refund, "refund").await?; bitcoin_wallet .wait_for_transaction_finality(txid, execution_params)