200: Wait for refund if insufficient Monero is locked up r=da-kami a=da-kami

In a scenario where Alice does not lock up sufficient funds Bob should properly transition to refunds. At the moment the CLI just panics. 
I noticed this when Alice accidentally had a different amount set than Bob. In the future this should not happen, because Alice provides the amount for Bob. However, in case Alice is malicious Bob should still transition correctly. 

Co-authored-by: Daniel Karzel <daniel@comit.network>
This commit is contained in:
bors[bot] 2021-02-17 05:00:39 +00:00 committed by GitHub
commit b3f49cf83e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 7 deletions

View File

@ -7,7 +7,7 @@ use crate::{
}, },
execution_params::ExecutionParams, execution_params::ExecutionParams,
monero, monero,
monero::{monero_private_key, TransferProof}, monero::{monero_private_key, InsufficientFunds, TransferProof},
protocol::{ protocol::{
alice::{Message1, Message3}, alice::{Message1, Message3},
bob::{EncryptedSignature, Message0, Message2, Message4}, bob::{EncryptedSignature, Message0, Message2, Message4},
@ -310,7 +310,7 @@ impl State3 {
xmr_wallet: &W, xmr_wallet: &W,
transfer_proof: TransferProof, transfer_proof: TransferProof,
monero_wallet_restore_blockheight: u32, monero_wallet_restore_blockheight: u32,
) -> Result<State4> ) -> Result<Result<State4, InsufficientFunds>>
where where
W: monero::WatchForTransfer, W: monero::WatchForTransfer,
{ {
@ -319,7 +319,7 @@ impl State3 {
)); ));
let S = self.S_a_monero + S_b_monero; let S = self.S_a_monero + S_b_monero;
xmr_wallet if let Err(e) = xmr_wallet
.watch_for_transfer( .watch_for_transfer(
S, S,
self.v.public(), self.v.public(),
@ -327,9 +327,12 @@ impl State3 {
self.xmr, self.xmr,
self.min_monero_confirmations, self.min_monero_confirmations,
) )
.await?; .await
{
return Ok(Err(e));
}
Ok(State4 { Ok(Ok(State4 {
A: self.A, A: self.A,
b: self.b, b: self.b,
s_b: self.s_b, s_b: self.s_b,
@ -343,7 +346,7 @@ impl State3 {
tx_cancel_sig_a: self.tx_cancel_sig_a, tx_cancel_sig_a: self.tx_cancel_sig_a,
tx_refund_encsig: self.tx_refund_encsig, tx_refund_encsig: self.tx_refund_encsig,
monero_wallet_restore_blockheight, monero_wallet_restore_blockheight,
}) }))
} }
pub async fn wait_for_cancel_timelock_to_expire<W>(&self, bitcoin_wallet: &W) -> Result<()> pub async fn wait_for_cancel_timelock_to_expire<W>(&self, bitcoin_wallet: &W) -> Result<()>

View File

@ -4,6 +4,7 @@ use crate::{
database::{Database, Swap}, database::{Database, Swap},
execution_params::ExecutionParams, execution_params::ExecutionParams,
monero, monero,
monero::InsufficientFunds,
protocol::bob::{self, event_loop::EventLoopHandle, state::*, QuoteRequest}, protocol::bob::{self, event_loop::EventLoopHandle, state::*, QuoteRequest},
}; };
use anyhow::{bail, Result}; use anyhow::{bail, Result};
@ -186,7 +187,15 @@ async fn run_until_internal(
select! { select! {
state4 = xmr_lock_watcher => { state4 = xmr_lock_watcher => {
BobState::XmrLocked(state4?) match state4? {
Ok(state4) => BobState::XmrLocked(state4),
Err(InsufficientFunds {..}) => {
info!("The other party has locked insufficient Monero funds! Waiting for refund...");
state.wait_for_cancel_timelock_to_expire(bitcoin_wallet.as_ref()).await?;
let state4 = state.state4();
BobState::CancelTimelockExpired(state4)
},
}
}, },
_ = cancel_timelock_expires => { _ = cancel_timelock_expires => {
let state4 = state.state4(); let state4 = state.state4();