mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-10-01 01:45:40 -04:00
Await 10 confirmations of lock tx in refund
Awaiting the confirmations in an earlier state can cause trouble with resuming swaps with short cancel expiries (test scenarios). Since it is the responsibility of the refund state to ensure that the XMR can be sweeped, we now ensure that the lock transaction has 10 confirmations before refunding the XMR using generate_from_keys.
This commit is contained in:
parent
1c129d58c4
commit
bc442bcad3
@ -30,27 +30,33 @@ pub enum Alice {
|
||||
},
|
||||
XmrLockTransferProofSent {
|
||||
monero_wallet_restore_blockheight: BlockHeight,
|
||||
transfer_proof: TransferProof,
|
||||
state3: alice::State3,
|
||||
},
|
||||
EncSigLearned {
|
||||
monero_wallet_restore_blockheight: BlockHeight,
|
||||
transfer_proof: TransferProof,
|
||||
encrypted_signature: EncryptedSignature,
|
||||
state3: alice::State3,
|
||||
},
|
||||
CancelTimelockExpired {
|
||||
monero_wallet_restore_blockheight: BlockHeight,
|
||||
transfer_proof: TransferProof,
|
||||
state3: alice::State3,
|
||||
},
|
||||
BtcCancelled {
|
||||
monero_wallet_restore_blockheight: BlockHeight,
|
||||
transfer_proof: TransferProof,
|
||||
state3: alice::State3,
|
||||
},
|
||||
BtcPunishable {
|
||||
monero_wallet_restore_blockheight: BlockHeight,
|
||||
transfer_proof: TransferProof,
|
||||
state3: alice::State3,
|
||||
},
|
||||
BtcRefunded {
|
||||
monero_wallet_restore_blockheight: BlockHeight,
|
||||
transfer_proof: TransferProof,
|
||||
state3: alice::State3,
|
||||
#[serde(with = "monero_private_key")]
|
||||
spend_key: monero::PrivateKey,
|
||||
@ -95,52 +101,62 @@ impl From<&AliceState> for Alice {
|
||||
},
|
||||
AliceState::XmrLockTransferProofSent {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
} => Alice::XmrLockTransferProofSent {
|
||||
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight,
|
||||
transfer_proof: transfer_proof.clone(),
|
||||
state3: state3.as_ref().clone(),
|
||||
},
|
||||
AliceState::EncSigLearned {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
encrypted_signature,
|
||||
} => Alice::EncSigLearned {
|
||||
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight,
|
||||
transfer_proof: transfer_proof.clone(),
|
||||
state3: state3.as_ref().clone(),
|
||||
encrypted_signature: *encrypted_signature.clone(),
|
||||
},
|
||||
AliceState::BtcRedeemed => Alice::Done(AliceEndState::BtcRedeemed),
|
||||
AliceState::BtcCancelled {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
..
|
||||
} => Alice::BtcCancelled {
|
||||
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight,
|
||||
transfer_proof: transfer_proof.clone(),
|
||||
state3: state3.as_ref().clone(),
|
||||
},
|
||||
AliceState::BtcRefunded {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
spend_key,
|
||||
state3,
|
||||
} => Alice::BtcRefunded {
|
||||
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight,
|
||||
transfer_proof: transfer_proof.clone(),
|
||||
spend_key: *spend_key,
|
||||
state3: state3.as_ref().clone(),
|
||||
},
|
||||
AliceState::BtcPunishable {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
..
|
||||
} => Alice::BtcPunishable {
|
||||
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight,
|
||||
transfer_proof: transfer_proof.clone(),
|
||||
state3: state3.as_ref().clone(),
|
||||
},
|
||||
AliceState::XmrRefunded => Alice::Done(AliceEndState::XmrRefunded),
|
||||
AliceState::CancelTimelockExpired {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
} => Alice::CancelTimelockExpired {
|
||||
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight,
|
||||
transfer_proof: transfer_proof.clone(),
|
||||
state3: state3.as_ref().clone(),
|
||||
},
|
||||
AliceState::BtcPunished => Alice::Done(AliceEndState::BtcPunished),
|
||||
@ -178,48 +194,60 @@ impl From<Alice> for AliceState {
|
||||
},
|
||||
Alice::XmrLockTransferProofSent {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
} => AliceState::XmrLockTransferProofSent {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3: Box::new(state3),
|
||||
},
|
||||
Alice::EncSigLearned {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3: state,
|
||||
encrypted_signature,
|
||||
} => AliceState::EncSigLearned {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3: Box::new(state),
|
||||
encrypted_signature: Box::new(encrypted_signature),
|
||||
},
|
||||
Alice::CancelTimelockExpired {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
} => AliceState::CancelTimelockExpired {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3: Box::new(state3),
|
||||
},
|
||||
Alice::BtcCancelled {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
} => AliceState::BtcCancelled {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3: Box::new(state3),
|
||||
},
|
||||
|
||||
Alice::BtcPunishable {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
} => AliceState::BtcPunishable {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3: Box::new(state3),
|
||||
},
|
||||
Alice::BtcRefunded {
|
||||
monero_wallet_restore_blockheight,
|
||||
state3,
|
||||
transfer_proof,
|
||||
spend_key,
|
||||
state3,
|
||||
} => AliceState::BtcRefunded {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
spend_key,
|
||||
state3: Box::new(state3),
|
||||
},
|
||||
|
@ -34,30 +34,36 @@ pub enum AliceState {
|
||||
},
|
||||
XmrLockTransferProofSent {
|
||||
monero_wallet_restore_blockheight: BlockHeight,
|
||||
transfer_proof: TransferProof,
|
||||
state3: Box<State3>,
|
||||
},
|
||||
EncSigLearned {
|
||||
monero_wallet_restore_blockheight: BlockHeight,
|
||||
transfer_proof: TransferProof,
|
||||
encrypted_signature: Box<bitcoin::EncryptedSignature>,
|
||||
state3: Box<State3>,
|
||||
},
|
||||
BtcRedeemed,
|
||||
BtcCancelled {
|
||||
monero_wallet_restore_blockheight: BlockHeight,
|
||||
transfer_proof: TransferProof,
|
||||
state3: Box<State3>,
|
||||
},
|
||||
BtcRefunded {
|
||||
monero_wallet_restore_blockheight: BlockHeight,
|
||||
transfer_proof: TransferProof,
|
||||
spend_key: monero::PrivateKey,
|
||||
state3: Box<State3>,
|
||||
},
|
||||
BtcPunishable {
|
||||
monero_wallet_restore_blockheight: BlockHeight,
|
||||
transfer_proof: TransferProof,
|
||||
state3: Box<State3>,
|
||||
},
|
||||
XmrRefunded,
|
||||
CancelTimelockExpired {
|
||||
monero_wallet_restore_blockheight: BlockHeight,
|
||||
transfer_proof: TransferProof,
|
||||
state3: Box<State3>,
|
||||
},
|
||||
BtcPunished,
|
||||
|
@ -101,9 +101,9 @@ async fn next_state(
|
||||
.await?;
|
||||
|
||||
AliceState::XmrLockTransactionSent {
|
||||
state3,
|
||||
transfer_proof,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
}
|
||||
}
|
||||
_ => AliceState::SafelyAborted,
|
||||
@ -120,47 +120,44 @@ async fn next_state(
|
||||
.await?;
|
||||
|
||||
AliceState::XmrLocked {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
}
|
||||
}
|
||||
_ => AliceState::CancelTimelockExpired {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
},
|
||||
},
|
||||
|
||||
AliceState::XmrLocked {
|
||||
state3,
|
||||
transfer_proof,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
} => match state3.expired_timelocks(bitcoin_wallet).await? {
|
||||
ExpiredTimelocks::None => {
|
||||
event_loop_handle
|
||||
.send_transfer_proof(transfer_proof.clone())
|
||||
.await?;
|
||||
|
||||
// TODO: Handle this upon refund instead.
|
||||
// Make sure that the balance of the created wallet is unlocked instead of
|
||||
// watching for transfer.
|
||||
monero_wallet
|
||||
.watch_for_transfer(state3.lock_xmr_watch_request(transfer_proof, 10))
|
||||
.await?;
|
||||
|
||||
XmrLockTransferProofSent {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
}
|
||||
}
|
||||
_ => AliceState::CancelTimelockExpired {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
},
|
||||
},
|
||||
AliceState::XmrLockTransferProofSent {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
} => {
|
||||
let tx_lock_status = bitcoin_wallet.subscribe_to(state3.tx_lock.clone()).await;
|
||||
|
||||
@ -168,32 +165,36 @@ async fn next_state(
|
||||
ExpiredTimelocks::None => {
|
||||
select! {
|
||||
_ = tx_lock_status.wait_until_confirmed_with(state3.cancel_timelock) => {
|
||||
AliceState::CancelTimelockExpired {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
AliceState::CancelTimelockExpired {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
}
|
||||
}
|
||||
enc_sig = event_loop_handle.recv_encrypted_signature() => {
|
||||
tracing::info!("Received encrypted signature");
|
||||
|
||||
AliceState::EncSigLearned {
|
||||
state3,
|
||||
encrypted_signature: Box::new(enc_sig?),
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
encrypted_signature: Box::new(enc_sig?),
|
||||
state3,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => AliceState::CancelTimelockExpired {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
},
|
||||
}
|
||||
}
|
||||
AliceState::EncSigLearned {
|
||||
state3,
|
||||
encrypted_signature,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
encrypted_signature,
|
||||
state3,
|
||||
} => match state3.expired_timelocks(bitcoin_wallet).await? {
|
||||
ExpiredTimelocks::None => {
|
||||
let tx_lock_status = bitcoin_wallet.subscribe_to(state3.tx_lock.clone()).await;
|
||||
@ -212,8 +213,9 @@ async fn next_state(
|
||||
.await?;
|
||||
|
||||
AliceState::CancelTimelockExpired {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -224,20 +226,23 @@ async fn next_state(
|
||||
.await?;
|
||||
|
||||
AliceState::CancelTimelockExpired {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => AliceState::CancelTimelockExpired {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
},
|
||||
},
|
||||
AliceState::CancelTimelockExpired {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
} => {
|
||||
let transaction = state3.signed_cancel_transaction()?;
|
||||
|
||||
@ -259,13 +264,15 @@ async fn next_state(
|
||||
}
|
||||
|
||||
AliceState::BtcCancelled {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
}
|
||||
}
|
||||
AliceState::BtcCancelled {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
} => {
|
||||
let tx_refund_status = bitcoin_wallet.subscribe_to(state3.tx_refund()).await;
|
||||
let tx_cancel_status = bitcoin_wallet.subscribe_to(state3.tx_cancel()).await;
|
||||
@ -278,26 +285,35 @@ async fn next_state(
|
||||
let spend_key = state3.extract_monero_private_key(published_refund_tx)?;
|
||||
|
||||
AliceState::BtcRefunded {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
spend_key,
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
}
|
||||
}
|
||||
_ = tx_cancel_status.wait_until_confirmed_with(state3.punish_timelock) => {
|
||||
AliceState::BtcPunishable {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AliceState::BtcRefunded {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
spend_key,
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
} => {
|
||||
let view_key = state3.v;
|
||||
|
||||
// Ensure that the XMR to be refunded are spendable by awaiting 10 confirmations
|
||||
// on the lock transaction
|
||||
monero_wallet
|
||||
.watch_for_transfer(state3.lock_xmr_watch_request(transfer_proof, 10))
|
||||
.await?;
|
||||
|
||||
monero_wallet
|
||||
.create_from(spend_key, view_key, monero_wallet_restore_blockheight)
|
||||
.await?;
|
||||
@ -305,8 +321,9 @@ async fn next_state(
|
||||
AliceState::XmrRefunded
|
||||
}
|
||||
AliceState::BtcPunishable {
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
state3,
|
||||
} => {
|
||||
let signed_tx_punish = state3.signed_punish_transaction()?;
|
||||
|
||||
@ -341,9 +358,10 @@ async fn next_state(
|
||||
let spend_key = state3.extract_monero_private_key(published_refund_tx)?;
|
||||
|
||||
AliceState::BtcRefunded {
|
||||
monero_wallet_restore_blockheight,
|
||||
transfer_proof,
|
||||
spend_key,
|
||||
state3,
|
||||
monero_wallet_restore_blockheight,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user