mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-04-20 07:56:05 -04:00
fix (Bob): Check if Bitcoin redeem transaction was published before transitioning to CancelTimelockExpired
This commit is contained in:
parent
1930540c1f
commit
1f40ee739d
@ -489,6 +489,30 @@ pub struct State4 {
|
||||
}
|
||||
|
||||
impl State4 {
|
||||
pub async fn check_for_tx_redeem(
|
||||
&self,
|
||||
bitcoin_wallet: &bitcoin::Wallet,
|
||||
) -> Result<State5> {
|
||||
let tx_redeem =
|
||||
bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address, self.tx_redeem_fee);
|
||||
let tx_redeem_encsig = self.b.encsign(self.S_a_bitcoin, tx_redeem.digest());
|
||||
|
||||
let tx_redeem_candidate = bitcoin_wallet.get_raw_transaction(tx_redeem.txid()).await?;
|
||||
|
||||
let tx_redeem_sig =
|
||||
tx_redeem.extract_signature_by_key(tx_redeem_candidate, self.b.public())?;
|
||||
let s_a = bitcoin::recover(self.S_a_bitcoin, tx_redeem_sig, tx_redeem_encsig)?;
|
||||
let s_a = monero::private_key_from_secp256k1_scalar(s_a.into());
|
||||
|
||||
Ok(State5 {
|
||||
s_a,
|
||||
s_b: self.s_b,
|
||||
v: self.v,
|
||||
tx_lock: self.tx_lock.clone(),
|
||||
monero_wallet_restore_blockheight: self.monero_wallet_restore_blockheight,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn tx_redeem_encsig(&self) -> bitcoin::EncryptedSignature {
|
||||
let tx_redeem =
|
||||
bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address, self.tx_redeem_fee);
|
||||
|
@ -183,6 +183,13 @@ async fn next_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;
|
||||
|
||||
if let ExpiredTimelocks::None { .. } = state.expired_timelock(bitcoin_wallet).await? {
|
||||
@ -207,6 +214,13 @@ async fn next_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;
|
||||
|
||||
if let ExpiredTimelocks::None { .. } = state.expired_timelock(bitcoin_wallet).await? {
|
||||
|
Loading…
x
Reference in New Issue
Block a user