From a2fc93e582fc10b786b26bdbb382c33b3bb37255 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 21 Dec 2020 16:02:49 +1100 Subject: [PATCH] Avoid code duplication and nested returns --- swap/src/alice/swap.rs | 15 ++------------- swap/src/bitcoin.rs | 27 +++++++++++++++++++++++---- swap/src/bob/swap.rs | 16 ++-------------- swap/src/lib.rs | 2 -- 4 files changed, 27 insertions(+), 33 deletions(-) diff --git a/swap/src/alice/swap.rs b/swap/src/alice/swap.rs index 4ca86671..34cb093d 100644 --- a/swap/src/alice/swap.rs +++ b/swap/src/alice/swap.rs @@ -16,11 +16,10 @@ use crate::{ state, state::{Alice, Swap}, storage::Database, - SwapAmounts, TRANSACTION_ALREADY_IN_BLOCKCHAIN_ERROR_CODE, + SwapAmounts, }; use anyhow::{bail, Result}; use async_recursion::async_recursion; -use bitcoin_harness::bitcoind_rpc::jsonrpc_client::JsonRpcError; use futures::{ future::{select, Either}, pin_mut, @@ -474,17 +473,7 @@ pub async fn run_until( .await } AliceState::T1Expired { state3 } => { - if let Err(error) = state3.submit_tx_cancel(bitcoin_wallet.as_ref()).await { - if let Some(json_rpc_err) = error.downcast_ref::() { - if json_rpc_err.code == TRANSACTION_ALREADY_IN_BLOCKCHAIN_ERROR_CODE { - info!("Failed to send cancel transaction, assuming that is was already included by the other party..."); - } else { - return Err(error); - } - } else { - return Err(error); - } - }; + state3.submit_tx_cancel(bitcoin_wallet.as_ref()).await?; let state = AliceState::BtcCancelled { state3 }; let db_state = (&state).into(); diff --git a/swap/src/bitcoin.rs b/swap/src/bitcoin.rs index 5dfc8edd..5febb47e 100644 --- a/swap/src/bitcoin.rs +++ b/swap/src/bitcoin.rs @@ -2,7 +2,11 @@ use anyhow::{Context, Result}; use async_trait::async_trait; use backoff::{backoff::Constant as ConstantBackoff, future::FutureOperation as _}; use bitcoin::util::psbt::PartiallySignedTransaction; -use bitcoin_harness::{bitcoind_rpc::PsbtBase64, BitcoindRpcApi}; +use bitcoin_harness::{ + bitcoind_rpc, + bitcoind_rpc::{jsonrpc_client, jsonrpc_client::JsonRpcError, PsbtBase64}, + BitcoindRpcApi, +}; use reqwest::Url; use std::time::Duration; use tokio::time::interval; @@ -18,6 +22,7 @@ pub use ::bitcoin::{Address, Transaction}; pub use xmr_btc::bitcoin::*; pub const TX_LOCK_MINE_TIMEOUT: u64 = 3600; +const TRANSACTION_ALREADY_IN_BLOCKCHAIN_ERROR_CODE: i64 = -27; #[derive(Debug)] pub struct Wallet { @@ -105,9 +110,23 @@ impl SignTxLock for Wallet { #[async_trait] impl BroadcastSignedTransaction for Wallet { async fn broadcast_signed_transaction(&self, transaction: Transaction) -> Result { - let txid = self.inner.send_raw_transaction(transaction).await?; - tracing::debug!("Bitcoin tx broadcasted! TXID = {}", txid); - Ok(txid) + let txid = transaction.txid(); + match self.inner.send_raw_transaction(transaction).await { + Err(bitcoind_rpc::Error::JsonRpcClient(jsonrpc_client::Error::JsonRpc( + JsonRpcError { + code: TRANSACTION_ALREADY_IN_BLOCKCHAIN_ERROR_CODE, + .. + }, + ))) => { + tracing::info!("Cancel transaction is already confirmed."); + Ok(txid) + } + Err(err) => Err(err.into()), + Ok(txid) => { + tracing::debug!("Bitcoin tx broadcasted! TXID = {}", txid); + Ok(txid) + } + } } } diff --git a/swap/src/bob/swap.rs b/swap/src/bob/swap.rs index 556f15c4..c38dda06 100644 --- a/swap/src/bob/swap.rs +++ b/swap/src/bob/swap.rs @@ -3,11 +3,10 @@ use crate::{ state, state::{Bob, Swap}, storage::Database, - SwapAmounts, TRANSACTION_ALREADY_IN_BLOCKCHAIN_ERROR_CODE, + SwapAmounts, }; use anyhow::{bail, Result}; use async_recursion::async_recursion; -use bitcoin_harness::bitcoind_rpc::jsonrpc_client::JsonRpcError; use libp2p::{core::Multiaddr, PeerId}; use rand::{CryptoRng, RngCore}; use std::{convert::TryFrom, fmt, sync::Arc}; @@ -345,18 +344,7 @@ where .await } BobState::T1Expired(state4) => { - let result = state4.submit_tx_cancel(bitcoin_wallet.as_ref()).await; - if let Err(error) = result { - if let Some(json_rpc_err) = error.downcast_ref::() { - if json_rpc_err.code == TRANSACTION_ALREADY_IN_BLOCKCHAIN_ERROR_CODE { - info!("Failed to send cancel transaction, assuming that is was already included by the other party..."); - } else { - return Err(error); - } - } else { - return Err(error); - } - }; + state4.submit_tx_cancel(bitcoin_wallet.as_ref()).await?; let state = BobState::Cancelled(state4); db.insert_latest_state(swap_id, state::Swap::Bob(state.clone().into())) diff --git a/swap/src/lib.rs b/swap/src/lib.rs index 7b95a0d4..b71d005f 100644 --- a/swap/src/lib.rs +++ b/swap/src/lib.rs @@ -15,8 +15,6 @@ pub mod trace; pub type Never = std::convert::Infallible; -const TRANSACTION_ALREADY_IN_BLOCKCHAIN_ERROR_CODE: i64 = -27; - /// Commands sent from Bob to the main task. #[derive(Clone, Copy, Debug)] pub enum Cmd {