mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-12-29 01:16:24 -05:00
Ensure that Bob can cancel correctly if T1 expired and Alice did not move
Bob has to check for the possibility to cancel in every state after he locked the BTC. Otherwise Bob will try to perform actions that don't have any point.
This commit is contained in:
parent
8296490764
commit
83ce6f2c85
@ -429,6 +429,10 @@ pub async fn run_until(
|
||||
state3,
|
||||
encrypted_signature,
|
||||
} => {
|
||||
// TODO: Evaluate if it is correct for Alice to Redeem no matter what.
|
||||
// If T1 expired she should potentially not try redeem. (The implementation
|
||||
// gives her an advantage.)
|
||||
|
||||
let signed_tx_redeem = match build_bitcoin_redeem_transaction(
|
||||
encrypted_signature,
|
||||
&state3.tx_lock,
|
||||
|
@ -223,16 +223,21 @@ where
|
||||
// Bob has locked Btc
|
||||
// Watch for Alice to Lock Xmr or for t1 to elapse
|
||||
BobState::BtcLocked(state3) => {
|
||||
// TODO(Franck): Refund if cannot connect to Alice.
|
||||
event_loop_handle.dial().await?;
|
||||
let state = if let Epoch::T0 = state3.current_epoch(bitcoin_wallet.as_ref()).await?
|
||||
{
|
||||
event_loop_handle.dial().await?;
|
||||
|
||||
// todo: watch until t1, not indefinitely
|
||||
let msg2 = event_loop_handle.recv_message2().await?;
|
||||
let state4 = state3
|
||||
.watch_for_lock_xmr(monero_wallet.as_ref(), msg2)
|
||||
.await?;
|
||||
// todo: watch until t1, not indefinitely
|
||||
let msg2 = event_loop_handle.recv_message2().await?;
|
||||
let state4 = state3
|
||||
.watch_for_lock_xmr(monero_wallet.as_ref(), msg2)
|
||||
.await?;
|
||||
|
||||
let state = BobState::XmrLocked(state4);
|
||||
BobState::XmrLocked(state4)
|
||||
} else {
|
||||
let state4 = state3.t1_expired();
|
||||
BobState::T1Expired(state4)
|
||||
};
|
||||
let db_state = state.clone().into();
|
||||
db.insert_latest_state(swap_id, state::Swap::Bob(db_state))
|
||||
.await?;
|
||||
@ -249,10 +254,8 @@ where
|
||||
.await
|
||||
}
|
||||
BobState::XmrLocked(state) => {
|
||||
// TODO(Franck): Refund if cannot connect to Alice.
|
||||
event_loop_handle.dial().await?;
|
||||
|
||||
let state = if let Epoch::T0 = state.current_epoch(bitcoin_wallet.as_ref()).await? {
|
||||
event_loop_handle.dial().await?;
|
||||
// Alice has locked Xmr
|
||||
// Bob sends Alice his key
|
||||
let tx_redeem_encsig = state.tx_redeem_encsig();
|
||||
|
@ -697,18 +697,13 @@ impl State3 {
|
||||
where
|
||||
W: WatchForRawTransaction + TransactionBlockHeight + BlockHeight,
|
||||
{
|
||||
let current_block_height = bitcoin_wallet.block_height().await;
|
||||
let t0 = bitcoin_wallet
|
||||
.transaction_block_height(self.tx_lock.txid())
|
||||
.await;
|
||||
let t1 = t0 + self.refund_timelock;
|
||||
let t2 = t1 + self.punish_timelock;
|
||||
|
||||
match (current_block_height < t1, current_block_height < t2) {
|
||||
(true, _) => Ok(Epoch::T0),
|
||||
(false, true) => Ok(Epoch::T1),
|
||||
(false, false) => Ok(Epoch::T2),
|
||||
}
|
||||
crate::current_epoch(
|
||||
bitcoin_wallet,
|
||||
self.refund_timelock,
|
||||
self.punish_timelock,
|
||||
self.tx_lock.txid(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -621,9 +621,43 @@ impl State3 {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn t1_expired(&self) -> State4 {
|
||||
State4 {
|
||||
A: self.A,
|
||||
b: self.b.clone(),
|
||||
s_b: self.s_b,
|
||||
S_a_monero: self.S_a_monero,
|
||||
S_a_bitcoin: self.S_a_bitcoin,
|
||||
v: self.v,
|
||||
btc: self.btc,
|
||||
xmr: self.xmr,
|
||||
refund_timelock: self.refund_timelock,
|
||||
punish_timelock: self.punish_timelock,
|
||||
refund_address: self.refund_address.clone(),
|
||||
redeem_address: self.redeem_address.clone(),
|
||||
punish_address: self.punish_address.clone(),
|
||||
tx_lock: self.tx_lock.clone(),
|
||||
tx_cancel_sig_a: self.tx_cancel_sig_a.clone(),
|
||||
tx_refund_encsig: self.tx_refund_encsig.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tx_lock_id(&self) -> bitcoin::Txid {
|
||||
self.tx_lock.txid()
|
||||
}
|
||||
|
||||
pub async fn current_epoch<W>(&self, bitcoin_wallet: &W) -> Result<Epoch>
|
||||
where
|
||||
W: WatchForRawTransaction + TransactionBlockHeight + BlockHeight,
|
||||
{
|
||||
crate::current_epoch(
|
||||
bitcoin_wallet,
|
||||
self.refund_timelock,
|
||||
self.punish_timelock,
|
||||
self.tx_lock.txid(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||
@ -761,18 +795,13 @@ impl State4 {
|
||||
where
|
||||
W: WatchForRawTransaction + TransactionBlockHeight + BlockHeight,
|
||||
{
|
||||
let current_block_height = bitcoin_wallet.block_height().await;
|
||||
let t0 = bitcoin_wallet
|
||||
.transaction_block_height(self.tx_lock.txid())
|
||||
.await;
|
||||
let t1 = t0 + self.refund_timelock;
|
||||
let t2 = t1 + self.punish_timelock;
|
||||
|
||||
match (current_block_height < t1, current_block_height < t2) {
|
||||
(true, _) => Ok(Epoch::T0),
|
||||
(false, true) => Ok(Epoch::T1),
|
||||
(false, false) => Ok(Epoch::T2),
|
||||
}
|
||||
crate::current_epoch(
|
||||
bitcoin_wallet,
|
||||
self.refund_timelock,
|
||||
self.punish_timelock,
|
||||
self.tx_lock.txid(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn refund_btc<W: bitcoin::BroadcastSignedTransaction>(
|
||||
|
@ -60,4 +60,26 @@ pub mod monero;
|
||||
pub mod serde;
|
||||
pub mod transport;
|
||||
|
||||
use crate::bitcoin::{BlockHeight, TransactionBlockHeight, WatchForRawTransaction};
|
||||
pub use cross_curve_dleq;
|
||||
|
||||
pub async fn current_epoch<W>(
|
||||
bitcoin_wallet: &W,
|
||||
refund_timelock: u32,
|
||||
punish_timelock: u32,
|
||||
lock_tx_id: ::bitcoin::Txid,
|
||||
) -> anyhow::Result<Epoch>
|
||||
where
|
||||
W: WatchForRawTransaction + TransactionBlockHeight + BlockHeight,
|
||||
{
|
||||
let current_block_height = bitcoin_wallet.block_height().await;
|
||||
let t0 = bitcoin_wallet.transaction_block_height(lock_tx_id).await;
|
||||
let t1 = t0 + refund_timelock;
|
||||
let t2 = t1 + punish_timelock;
|
||||
|
||||
match (current_block_height < t1, current_block_height < t2) {
|
||||
(true, _) => Ok(Epoch::T0),
|
||||
(false, true) => Ok(Epoch::T1),
|
||||
(false, false) => Ok(Epoch::T2),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user