Only generate refund action after Bitcoin lock

This commit is contained in:
Lucas Soriano del Pino 2020-10-16 11:18:02 +11:00
parent c1f6adc8ed
commit 9f1bf72c7b

View File

@ -118,7 +118,12 @@ where
B: MedianTime + bitcoin::WatchForRawTransaction + Send + Sync,
{
enum SwapFailed {
TimelockReached,
BeforeBtcLock,
AfterBtcLock(Reason),
}
enum Reason {
BtcExpired,
InsufficientXMR(monero::InsufficientFunds),
}
@ -142,7 +147,7 @@ where
let btc_has_expired = bitcoin_time_is_gte(bitcoin_ledger, refund_timelock).shared();
if btc_has_expired.clone().await {
return Err(SwapFailed::TimelockReached);
return Err(SwapFailed::BeforeBtcLock);
}
co.yield_(Action::LockBitcoin(tx_lock.clone())).await;
@ -150,8 +155,6 @@ where
let poll_until_btc_has_expired = poll_until(btc_has_expired).shared();
futures::pin_mut!(poll_until_btc_has_expired);
// the source of this could be the database, this layer doesn't care
let transfer_proof = match select(
network.receive_transfer_proof(),
poll_until_btc_has_expired.clone(),
@ -159,7 +162,7 @@ where
.await
{
Either::Left((proof, _)) => proof,
Either::Right(_) => return Err(SwapFailed::TimelockReached),
Either::Right(_) => return Err(SwapFailed::AfterBtcLock(Reason::BtcExpired)),
};
let S_b_monero = monero::PublicKey::from_private_key(&monero::PrivateKey::from_scalar(
@ -179,8 +182,10 @@ where
)
.await
{
Either::Left((Err(e), _)) => return Err(SwapFailed::InsufficientXMR(e)),
Either::Right(_) => return Err(SwapFailed::TimelockReached),
Either::Left((Err(e), _)) => {
return Err(SwapFailed::AfterBtcLock(Reason::InsufficientXMR(e)))
}
Either::Right(_) => return Err(SwapFailed::AfterBtcLock(Reason::BtcExpired)),
_ => {}
}
@ -197,7 +202,7 @@ where
.await
{
Either::Left((tx, _)) => tx,
Either::Right(_) => return Err(SwapFailed::TimelockReached),
Either::Right(_) => return Err(SwapFailed::AfterBtcLock(Reason::BtcExpired)),
};
// NOTE: If any of this fails, Bob will never be able to take the monero.
@ -226,7 +231,7 @@ where
}
.await;
if swap_result.is_err() {
if let Err(SwapFailed::AfterBtcLock(_)) = swap_result {
let tx_cancel =
bitcoin::TxCancel::new(&tx_lock, refund_timelock, A.clone(), b.public());
let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &refund_address);