mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-01-25 14:56:23 -05:00
bc442bcad3
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.
283 lines
11 KiB
Rust
283 lines
11 KiB
Rust
use crate::bitcoin::EncryptedSignature;
|
|
use crate::monero;
|
|
use crate::monero::{monero_private_key, TransferProof};
|
|
use crate::protocol::alice;
|
|
use crate::protocol::alice::AliceState;
|
|
use ::bitcoin::hashes::core::fmt::Display;
|
|
use monero_rpc::wallet::BlockHeight;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
// Large enum variant is fine because this is only used for database
|
|
// and is dropped once written in DB.
|
|
#[allow(clippy::large_enum_variant)]
|
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
|
pub enum Alice {
|
|
Started {
|
|
state3: alice::State3,
|
|
},
|
|
BtcLocked {
|
|
state3: alice::State3,
|
|
},
|
|
XmrLockTransactionSent {
|
|
monero_wallet_restore_blockheight: BlockHeight,
|
|
transfer_proof: TransferProof,
|
|
state3: alice::State3,
|
|
},
|
|
XmrLocked {
|
|
monero_wallet_restore_blockheight: BlockHeight,
|
|
transfer_proof: TransferProof,
|
|
state3: alice::State3,
|
|
},
|
|
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,
|
|
},
|
|
Done(AliceEndState),
|
|
}
|
|
|
|
#[derive(Copy, Clone, strum::Display, Debug, Deserialize, Serialize, PartialEq)]
|
|
pub enum AliceEndState {
|
|
SafelyAborted,
|
|
BtcRedeemed,
|
|
XmrRefunded,
|
|
BtcPunished,
|
|
}
|
|
|
|
impl From<&AliceState> for Alice {
|
|
fn from(alice_state: &AliceState) -> Self {
|
|
match alice_state {
|
|
AliceState::Started { state3 } => Alice::Started {
|
|
state3: state3.as_ref().clone(),
|
|
},
|
|
AliceState::BtcLocked { state3 } => Alice::BtcLocked {
|
|
state3: state3.as_ref().clone(),
|
|
},
|
|
AliceState::XmrLockTransactionSent {
|
|
monero_wallet_restore_blockheight,
|
|
transfer_proof,
|
|
state3,
|
|
} => Alice::XmrLockTransactionSent {
|
|
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight,
|
|
transfer_proof: transfer_proof.clone(),
|
|
state3: state3.as_ref().clone(),
|
|
},
|
|
AliceState::XmrLocked {
|
|
monero_wallet_restore_blockheight,
|
|
transfer_proof,
|
|
state3,
|
|
} => Alice::XmrLocked {
|
|
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight,
|
|
transfer_proof: transfer_proof.clone(),
|
|
state3: state3.as_ref().clone(),
|
|
},
|
|
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),
|
|
AliceState::SafelyAborted => Alice::Done(AliceEndState::SafelyAborted),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<Alice> for AliceState {
|
|
fn from(db_state: Alice) -> Self {
|
|
match db_state {
|
|
Alice::Started { state3 } => AliceState::Started {
|
|
state3: Box::new(state3),
|
|
},
|
|
Alice::BtcLocked { state3 } => AliceState::BtcLocked {
|
|
state3: Box::new(state3),
|
|
},
|
|
Alice::XmrLockTransactionSent {
|
|
monero_wallet_restore_blockheight,
|
|
transfer_proof,
|
|
state3,
|
|
} => AliceState::XmrLockTransactionSent {
|
|
monero_wallet_restore_blockheight,
|
|
transfer_proof,
|
|
state3: Box::new(state3),
|
|
},
|
|
Alice::XmrLocked {
|
|
monero_wallet_restore_blockheight,
|
|
transfer_proof,
|
|
state3,
|
|
} => AliceState::XmrLocked {
|
|
monero_wallet_restore_blockheight,
|
|
transfer_proof,
|
|
state3: Box::new(state3),
|
|
},
|
|
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,
|
|
transfer_proof,
|
|
spend_key,
|
|
state3,
|
|
} => AliceState::BtcRefunded {
|
|
monero_wallet_restore_blockheight,
|
|
transfer_proof,
|
|
spend_key,
|
|
state3: Box::new(state3),
|
|
},
|
|
Alice::Done(end_state) => match end_state {
|
|
AliceEndState::SafelyAborted => AliceState::SafelyAborted,
|
|
AliceEndState::BtcRedeemed => AliceState::BtcRedeemed,
|
|
AliceEndState::XmrRefunded => AliceState::XmrRefunded,
|
|
AliceEndState::BtcPunished => AliceState::BtcPunished,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Display for Alice {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Alice::Started { .. } => write!(f, "Started"),
|
|
Alice::BtcLocked { .. } => f.write_str("Bitcoin locked"),
|
|
Alice::XmrLockTransactionSent { .. } => f.write_str("Monero lock transaction sent"),
|
|
Alice::XmrLocked { .. } => f.write_str("Monero locked"),
|
|
Alice::XmrLockTransferProofSent { .. } => {
|
|
f.write_str("Monero lock transfer proof sent")
|
|
}
|
|
Alice::CancelTimelockExpired { .. } => f.write_str("Cancel timelock is expired"),
|
|
Alice::BtcCancelled { .. } => f.write_str("Bitcoin cancel transaction published"),
|
|
Alice::BtcPunishable { .. } => f.write_str("Bitcoin punishable"),
|
|
Alice::BtcRefunded { .. } => f.write_str("Monero refundable"),
|
|
Alice::Done(end_state) => write!(f, "Done: {}", end_state),
|
|
Alice::EncSigLearned { .. } => f.write_str("Encrypted signature learned"),
|
|
}
|
|
}
|
|
}
|