comit-network/xmr-btc-swap

Retry locking of Monero if fails on first try

Closed this issue · 0 comments

Users are experiencing an issue where the asb is not locking their funds. I contacted one of the asb providers and he provided me with these (incomplete) logs:

2024-07-22T22:03:38.716628669Z  INFO swap{id=b7d26ad0-371b-4e58-99fa-ace7622f5223}: Waiting for Bitcoin transaction finality txid=63cfc5f77864e30ab4adcf9d32a41622b0e721a5e399e2166a3877f45f21b6bc seen_confirmations=1 needed_confirmations=1
2024-07-22T22:03:38.731170301Z  INFO swap{id=b7d26ad0-371b-4e58-99fa-ace7622f5223}: Advancing state state=btc is locked rate=0.002384 BTC
2024-07-22T22:03:39.348100081Z ERROR swap{id=b7d26ad0-371b-4e58-99fa-ace7622f5223}: error=JSON-RPC request failed with code -4: failed to get output distribution
2024-07-22T22:03:39.348196883Z ERROR Swap failed: JSON-RPC request failed with code -4: failed to get output distribution: JSON-RPC request failed with code -4: failed to get output distribution swap_id=b7d26ad0-371b-4e58-99fa-ace7622f5223
...
2024-07-23T20:37:53.044695858Z DEBUG Swap completed swap_id=b7d26ad0-371b-4e58-99fa-ace7622f5223 final_state=safely aborted
2024-07-23T20:37:53.045118503Z DEBUG A swap stopped without sending a transfer proof: request channel closed

The failed to get output distribution error is unexpected. This might be due to an outdated monerod / monero-wallet-rpc node. I have asked the provider about that but they haven't responded yet.

What is happening here is the following:

  1. Bob locks their Bitcoin.
  2. Alice sees the confirmations on the Bitcoin lock transaction
  3. Alice tries to lock their Monero but fails due to the failed to get output distribution error
  4. Bob has to wait 12 hours to refund their funds

We should implement a feature to retry locking the Monero if it fails on the first try.

This is the relevant code where we should implement the retry mechanism.

AliceState::BtcLocked { state3 } => {
match state3.expired_timelocks(bitcoin_wallet).await? {
ExpiredTimelocks::None { .. } => {
// Record the current monero wallet block height so we don't have to scan from
// block 0 for scenarios where we create a refund wallet.
let monero_wallet_restore_blockheight = monero_wallet.block_height().await?;
let transfer_proof = monero_wallet
.transfer(state3.lock_xmr_transfer_request())
.await?;
AliceState::XmrLockTransactionSent {
monero_wallet_restore_blockheight,
transfer_proof,
state3,
}
}
_ => AliceState::SafelyAborted,
}
}