fix (Bob): Check if Bitcoin redeem transaction was published before transitioning to CancelTimelockExpired

This commit is contained in:
binarybaron 2024-06-03 23:31:16 +02:00
parent c9f379a108
commit e6686b7aa1
2 changed files with 21 additions and 10 deletions

View File

@ -489,12 +489,6 @@ pub struct State4 {
} }
impl State4 { impl State4 {
pub fn tx_redeem_encsig(&self) -> bitcoin::EncryptedSignature {
let tx_redeem =
bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address, self.tx_redeem_fee);
self.b.encsign(self.S_a_bitcoin, tx_redeem.digest())
}
pub async fn check_for_tx_redeem( pub async fn check_for_tx_redeem(
&self, &self,
bitcoin_wallet: &bitcoin::Wallet, bitcoin_wallet: &bitcoin::Wallet,
@ -519,6 +513,12 @@ impl State4 {
}) })
} }
pub fn tx_redeem_encsig(&self) -> bitcoin::EncryptedSignature {
let tx_redeem =
bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address, self.tx_redeem_fee);
self.b.encsign(self.S_a_bitcoin, tx_redeem.digest())
}
pub async fn watch_for_redeem_btc(&self, bitcoin_wallet: &bitcoin::Wallet) -> Result<State5> { pub async fn watch_for_redeem_btc(&self, bitcoin_wallet: &bitcoin::Wallet) -> Result<State5> {
let tx_redeem = let tx_redeem =
bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address, self.tx_redeem_fee); bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address, self.tx_redeem_fee);

View File

@ -183,12 +183,16 @@ async fn next_state(
} }
} }
BobState::XmrLocked(state) => { BobState::XmrLocked(state) => {
// In case we send the encrypted signature to Alice, but she doesn't give us a confirmation
// We need to check if she still published the Bitcoin redeem transaction
// Otherwise we risk staying stuck in "XmrLocked"
if let Ok(state5) = state.check_for_tx_redeem(bitcoin_wallet).await {
return Ok(BobState::BtcRedeemed(state5));
}
let tx_lock_status = bitcoin_wallet.subscribe_to(state.tx_lock.clone()).await; let tx_lock_status = bitcoin_wallet.subscribe_to(state.tx_lock.clone()).await;
if let Ok(state5) = state.check_for_tx_redeem(bitcoin_wallet).await { if let ExpiredTimelocks::None = state.expired_timelock(bitcoin_wallet).await? {
// this is in case we send the encrypted signature to alice, but we don't get confirmation that she received it. alice would be able to redeem the btc, but we would be stuck in xmrlocked, never being able to redeem the xmr.
BobState::BtcRedeemed(state5)
} else if let ExpiredTimelocks::None { .. } = state.expired_timelock(bitcoin_wallet).await? {
// Alice has locked Xmr // Alice has locked Xmr
// Bob sends Alice his key // Bob sends Alice his key
@ -210,6 +214,13 @@ async fn next_state(
} }
} }
BobState::EncSigSent(state) => { BobState::EncSigSent(state) => {
// We need to make sure that Alice did not publish the redeem transaction while we were offline
// Even if the cancel timelock expired, if Alice published the redeem transaction while we were away we cannot miss it
// If we do we cannot refund and will never be able to leave the "CancelTimelockExpired" state
if let Ok(state5) = state.check_for_tx_redeem(bitcoin_wallet).await {
return Ok(BobState::BtcRedeemed(state5));
}
let tx_lock_status = bitcoin_wallet.subscribe_to(state.tx_lock.clone()).await; let tx_lock_status = bitcoin_wallet.subscribe_to(state.tx_lock.clone()).await;
if let ExpiredTimelocks::None { .. } = state.expired_timelock(bitcoin_wallet).await? { if let ExpiredTimelocks::None { .. } = state.expired_timelock(bitcoin_wallet).await? {