From 18faa786d6e7fe85e33c97682454327964ec9acc Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Mon, 30 Aug 2021 12:07:01 +1000 Subject: [PATCH 1/3] Fail if something goes wrong when checking tx lock status Probably a failure when interacting with the electrum node to get script status updates --- CHANGELOG.md | 3 +++ swap/src/protocol/alice/swap.rs | 3 ++- swap/src/protocol/bob/swap.rs | 11 +++++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8992f81c..b96e9cfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - An issue where the ASB was unable to use the Monero wallet in case `monero-wallet-rpc` has been restarted. In case no wallet is loaded when we try to interact with the `monero-wallet-rpc` daemon, we now load the correct wallet on-demand. See issue https://github.com/comit-network/xmr-btc-swap/issues/652. +- An issue where swap protocol was getting stuck trying to submit the cancel transaction. + We were not handling the error when TxCancel submission fails. + See issues: https://github.com/comit-network/xmr-btc-swap/issues/709, https://github.com/comit-network/xmr-btc-swap/issues/688, https://github.com/comit-network/xmr-btc-swap/issues/701. ## [0.8.1] - 2021-08-16 diff --git a/swap/src/protocol/alice/swap.rs b/swap/src/protocol/alice/swap.rs index b09658f0..c3808103 100644 --- a/swap/src/protocol/alice/swap.rs +++ b/swap/src/protocol/alice/swap.rs @@ -195,7 +195,8 @@ where select! { biased; // make sure the cancel timelock expiry future is polled first - _ = tx_lock_status.wait_until_confirmed_with(state3.cancel_timelock) => { + result = tx_lock_status.wait_until_confirmed_with(state3.cancel_timelock) => { + let _ = result?; AliceState::CancelTimelockExpired { monero_wallet_restore_blockheight, transfer_proof, diff --git a/swap/src/protocol/bob/swap.rs b/swap/src/protocol/bob/swap.rs index 0ebab92b..c1987e20 100644 --- a/swap/src/protocol/bob/swap.rs +++ b/swap/src/protocol/bob/swap.rs @@ -128,7 +128,7 @@ async fn next_state( let state4 = state3.cancel(); BobState::CancelTimelockExpired(state4) - } + }, } } else { let state4 = state3.cancel(); @@ -159,7 +159,8 @@ async fn next_state( }, } } - _ = tx_lock_status.wait_until_confirmed_with(state.cancel_timelock) => { + result = tx_lock_status.wait_until_confirmed_with(state.cancel_timelock) => { + let _ = result?; BobState::CancelTimelockExpired(state.cancel()) } } @@ -178,7 +179,8 @@ async fn next_state( _ = event_loop_handle.send_encrypted_signature(state.tx_redeem_encsig()) => { BobState::EncSigSent(state) }, - _ = tx_lock_status.wait_until_confirmed_with(state.cancel_timelock) => { + result = tx_lock_status.wait_until_confirmed_with(state.cancel_timelock) => { + let _ = result?; BobState::CancelTimelockExpired(state.cancel()) } } @@ -194,7 +196,8 @@ async fn next_state( state5 = state.watch_for_redeem_btc(bitcoin_wallet) => { BobState::BtcRedeemed(state5?) }, - _ = tx_lock_status.wait_until_confirmed_with(state.cancel_timelock) => { + result = tx_lock_status.wait_until_confirmed_with(state.cancel_timelock) => { + let _ = result?; BobState::CancelTimelockExpired(state.cancel()) } } From 8598bcade11ee5ae8b0cb61d8dbf267f17882cd8 Mon Sep 17 00:00:00 2001 From: rishflab Date: Mon, 30 Aug 2021 14:43:53 +1000 Subject: [PATCH 2/3] Configure electrum client to retry 5 times --- CHANGELOG.md | 3 ++- swap/src/bitcoin/wallet.rs | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b96e9cfe..89ae41d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 See issue https://github.com/comit-network/xmr-btc-swap/issues/652. - An issue where swap protocol was getting stuck trying to submit the cancel transaction. We were not handling the error when TxCancel submission fails. - See issues: https://github.com/comit-network/xmr-btc-swap/issues/709, https://github.com/comit-network/xmr-btc-swap/issues/688, https://github.com/comit-network/xmr-btc-swap/issues/701. + We also configured the electrum client to retry 5 times in order to help with this problem. + See issues: https://github.com/comit-network/xmr-btc-swap/issues/709 https://github.com/comit-network/xmr-btc-swap/issues/688, https://github.com/comit-network/xmr-btc-swap/issues/701. ## [0.8.1] - 2021-08-16 diff --git a/swap/src/bitcoin/wallet.rs b/swap/src/bitcoin/wallet.rs index b2554e80..4bdc6388 100644 --- a/swap/src/bitcoin/wallet.rs +++ b/swap/src/bitcoin/wallet.rs @@ -48,7 +48,10 @@ impl Wallet { env_config: env::Config, target_block: usize, ) -> Result { - let client = bdk::electrum_client::Client::new(electrum_rpc_url.as_str()) + let config = bdk::electrum_client::ConfigBuilder::default() + .retry(5) + .build(); + let client = bdk::electrum_client::Client::from_config(electrum_rpc_url.as_str(), config) .context("Failed to initialize Electrum RPC client")?; let db = bdk::sled::open(wallet_dir)?.open_tree(SLED_TREE_NAME)?; From af50c655ae0e73bf1a90282a22f26468089a0f36 Mon Sep 17 00:00:00 2001 From: rishflab Date: Tue, 31 Aug 2021 15:21:44 +1000 Subject: [PATCH 3/3] Remove timeout on send encrypted signature Bob was timing out if the encrypted signature could not be sent in 60 seconds. This behaviour is unnecessary because we are racing against the cancel timelock anyway. By timing out before this, we remove the opportunity for bob and alice to re-establish a connection. --- swap/src/cli/event_loop.rs | 4 ++-- swap/src/protocol/bob/swap.rs | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/swap/src/cli/event_loop.rs b/swap/src/cli/event_loop.rs index 2ed37b26..d8c0d453 100644 --- a/swap/src/cli/event_loop.rs +++ b/swap/src/cli/event_loop.rs @@ -54,7 +54,7 @@ impl EventLoop { ) -> Result<(Self, EventLoopHandle)> { let execution_setup = bmrng::channel_with_timeout(1, Duration::from_secs(60)); let transfer_proof = bmrng::channel_with_timeout(1, Duration::from_secs(60)); - let encrypted_signature = bmrng::channel_with_timeout(1, Duration::from_secs(60)); + let encrypted_signature = bmrng::channel(1); let quote = bmrng::channel_with_timeout(1, Duration::from_secs(60)); let event_loop = EventLoop { @@ -248,7 +248,7 @@ impl EventLoopHandle { pub async fn send_encrypted_signature( &mut self, tx_redeem_encsig: EncryptedSignature, - ) -> Result<()> { + ) -> Result<(), bmrng::error::RequestError> { Ok(self .encrypted_signature .send_receive(tx_redeem_encsig) diff --git a/swap/src/protocol/bob/swap.rs b/swap/src/protocol/bob/swap.rs index c1987e20..45c5a3b1 100644 --- a/swap/src/protocol/bob/swap.rs +++ b/swap/src/protocol/bob/swap.rs @@ -176,8 +176,12 @@ async fn next_state( // Bob sends Alice his key select! { - _ = event_loop_handle.send_encrypted_signature(state.tx_redeem_encsig()) => { - BobState::EncSigSent(state) + result = event_loop_handle.send_encrypted_signature(state.tx_redeem_encsig()) => { + match result { + Ok(_) => BobState::EncSigSent(state), + Err(bmrng::error::RequestError::RecvError | bmrng::error::RequestError::SendError(_)) => bail!("Failed to communicate encrypted signature through event loop channel"), + Err(bmrng::error::RequestError::RecvTimeoutError) => unreachable!("We construct the channel with no timeout"), + } }, result = tx_lock_status.wait_until_confirmed_with(state.cancel_timelock) => { let _ = result?;