mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-12-25 07:29:32 -05:00
Save Bob state during swap
This commit is contained in:
parent
7e0a1ffe84
commit
905fc6cf35
@ -1,5 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
bob::{event_loop::EventLoopHandle, execution::negotiate},
|
bob::{event_loop::EventLoopHandle, execution::negotiate},
|
||||||
|
state,
|
||||||
|
state::Bob,
|
||||||
storage::Database,
|
storage::Database,
|
||||||
SwapAmounts,
|
SwapAmounts,
|
||||||
};
|
};
|
||||||
@ -17,6 +19,7 @@ use xmr_btc::{
|
|||||||
|
|
||||||
// The same data structure is used for swap execution and recovery.
|
// The same data structure is used for swap execution and recovery.
|
||||||
// This allows for a seamless transition from a failed swap to recovery.
|
// This allows for a seamless transition from a failed swap to recovery.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub enum BobState {
|
pub enum BobState {
|
||||||
Started {
|
Started {
|
||||||
state0: bob::State0,
|
state0: bob::State0,
|
||||||
@ -53,6 +56,32 @@ impl fmt::Display for BobState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<BobState> for state::Bob {
|
||||||
|
fn from(bob_state: BobState) -> Self {
|
||||||
|
match bob_state {
|
||||||
|
BobState::Started {
|
||||||
|
state0,
|
||||||
|
amounts,
|
||||||
|
addr,
|
||||||
|
} => Bob::Started {
|
||||||
|
state0,
|
||||||
|
amounts,
|
||||||
|
addr,
|
||||||
|
},
|
||||||
|
BobState::Negotiated(state2, peer_id) => Bob::Negotiated { state2, peer_id },
|
||||||
|
BobState::BtcLocked(state3, peer_id) => Bob::BtcLocked { state3, peer_id },
|
||||||
|
BobState::XmrLocked(state4, peer_id) => Bob::XmrLocked { state4, peer_id },
|
||||||
|
BobState::EncSigSent(state4, peer_id) => Bob::EncSigSent { state4, peer_id },
|
||||||
|
BobState::BtcRedeemed(state5) => Bob::BtcRedeemed(state5),
|
||||||
|
BobState::Cancelled(state4) => Bob::BtcCancelled(state4),
|
||||||
|
BobState::BtcRefunded(_)
|
||||||
|
| BobState::XmrRedeemed
|
||||||
|
| BobState::Punished
|
||||||
|
| BobState::SafelyAborted => Bob::SwapComplete,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn swap<R>(
|
pub async fn swap<R>(
|
||||||
state: BobState,
|
state: BobState,
|
||||||
event_loop_handle: EventLoopHandle,
|
event_loop_handle: EventLoopHandle,
|
||||||
@ -131,8 +160,13 @@ where
|
|||||||
bitcoin_wallet.clone(),
|
bitcoin_wallet.clone(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let state = BobState::Negotiated(state2, alice_peer_id);
|
||||||
|
let db_state = state.clone().into();
|
||||||
|
db.insert_latest_state(swap_id, state::Swap::Bob(db_state))
|
||||||
|
.await?;
|
||||||
run_until(
|
run_until(
|
||||||
BobState::Negotiated(state2, alice_peer_id),
|
state,
|
||||||
is_target_state,
|
is_target_state,
|
||||||
event_loop_handle,
|
event_loop_handle,
|
||||||
db,
|
db,
|
||||||
@ -146,9 +180,13 @@ where
|
|||||||
BobState::Negotiated(state2, alice_peer_id) => {
|
BobState::Negotiated(state2, alice_peer_id) => {
|
||||||
// Alice and Bob have exchanged info
|
// Alice and Bob have exchanged info
|
||||||
let state3 = state2.lock_btc(bitcoin_wallet.as_ref()).await?;
|
let state3 = state2.lock_btc(bitcoin_wallet.as_ref()).await?;
|
||||||
// db.insert_latest_state(state);
|
|
||||||
|
let state = BobState::BtcLocked(state3, alice_peer_id);
|
||||||
|
let db_state = state.clone().into();
|
||||||
|
db.insert_latest_state(swap_id, state::Swap::Bob(db_state))
|
||||||
|
.await?;
|
||||||
run_until(
|
run_until(
|
||||||
BobState::BtcLocked(state3, alice_peer_id),
|
state,
|
||||||
is_target_state,
|
is_target_state,
|
||||||
event_loop_handle,
|
event_loop_handle,
|
||||||
db,
|
db,
|
||||||
@ -168,8 +206,12 @@ where
|
|||||||
.watch_for_lock_xmr(monero_wallet.as_ref(), msg2)
|
.watch_for_lock_xmr(monero_wallet.as_ref(), msg2)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let state = BobState::XmrLocked(state4, alice_peer_id);
|
||||||
|
let db_state = state.clone().into();
|
||||||
|
db.insert_latest_state(swap_id, state::Swap::Bob(db_state))
|
||||||
|
.await?;
|
||||||
run_until(
|
run_until(
|
||||||
BobState::XmrLocked(state4, alice_peer_id),
|
state,
|
||||||
is_target_state,
|
is_target_state,
|
||||||
event_loop_handle,
|
event_loop_handle,
|
||||||
db,
|
db,
|
||||||
@ -192,8 +234,12 @@ where
|
|||||||
.send_message3(alice_peer_id.clone(), tx_redeem_encsig)
|
.send_message3(alice_peer_id.clone(), tx_redeem_encsig)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let state = BobState::EncSigSent(state, alice_peer_id);
|
||||||
|
let db_state = state.clone().into();
|
||||||
|
db.insert_latest_state(swap_id, state::Swap::Bob(db_state))
|
||||||
|
.await?;
|
||||||
run_until(
|
run_until(
|
||||||
BobState::EncSigSent(state, alice_peer_id),
|
state,
|
||||||
is_target_state,
|
is_target_state,
|
||||||
event_loop_handle,
|
event_loop_handle,
|
||||||
db,
|
db,
|
||||||
@ -209,10 +255,14 @@ where
|
|||||||
let redeem_watcher = state.watch_for_redeem_btc(bitcoin_wallet.as_ref());
|
let redeem_watcher = state.watch_for_redeem_btc(bitcoin_wallet.as_ref());
|
||||||
let t1_timeout = state.wait_for_t1(bitcoin_wallet.as_ref());
|
let t1_timeout = state.wait_for_t1(bitcoin_wallet.as_ref());
|
||||||
|
|
||||||
|
// TODO(Franck): Check if db save and run_until can be factorized
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
val = redeem_watcher => {
|
val = redeem_watcher => {
|
||||||
|
let state = BobState::BtcRedeemed(val?);
|
||||||
|
let db_state = state.clone().into();
|
||||||
|
db.insert_latest_state(swap_id, state::Swap::Bob(db_state)).await?;
|
||||||
run_until(
|
run_until(
|
||||||
BobState::BtcRedeemed(val?),
|
state,
|
||||||
is_target_state,
|
is_target_state,
|
||||||
event_loop_handle,
|
event_loop_handle,
|
||||||
db,
|
db,
|
||||||
@ -230,15 +280,18 @@ where
|
|||||||
state.submit_tx_cancel(bitcoin_wallet.as_ref()).await?;
|
state.submit_tx_cancel(bitcoin_wallet.as_ref()).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let state = BobState::Cancelled(state);
|
||||||
|
let db_state = state.clone().into();
|
||||||
|
db.insert_latest_state(swap_id, state::Swap::Bob(db_state)).await?;
|
||||||
run_until(
|
run_until(
|
||||||
BobState::Cancelled(state),
|
state,
|
||||||
is_target_state,
|
is_target_state,
|
||||||
event_loop_handle,
|
event_loop_handle,
|
||||||
db,
|
db,
|
||||||
bitcoin_wallet,
|
bitcoin_wallet,
|
||||||
monero_wallet,
|
monero_wallet,
|
||||||
rng,
|
rng,
|
||||||
swap_id
|
swap_id
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|
||||||
@ -248,8 +301,13 @@ where
|
|||||||
BobState::BtcRedeemed(state) => {
|
BobState::BtcRedeemed(state) => {
|
||||||
// Bob redeems XMR using revealed s_a
|
// Bob redeems XMR using revealed s_a
|
||||||
state.claim_xmr(monero_wallet.as_ref()).await?;
|
state.claim_xmr(monero_wallet.as_ref()).await?;
|
||||||
|
|
||||||
|
let state = BobState::XmrRedeemed;
|
||||||
|
let db_state = state.clone().into();
|
||||||
|
db.insert_latest_state(swap_id, state::Swap::Bob(db_state))
|
||||||
|
.await?;
|
||||||
run_until(
|
run_until(
|
||||||
BobState::XmrRedeemed,
|
state,
|
||||||
is_target_state,
|
is_target_state,
|
||||||
event_loop_handle,
|
event_loop_handle,
|
||||||
db,
|
db,
|
||||||
@ -261,37 +319,31 @@ where
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
BobState::Cancelled(state) => {
|
BobState::Cancelled(state) => {
|
||||||
|
// TODO
|
||||||
// Bob has cancelled the swap
|
// Bob has cancelled the swap
|
||||||
match state.current_epoch(bitcoin_wallet.as_ref()).await? {
|
let state = match state.current_epoch(bitcoin_wallet.as_ref()).await? {
|
||||||
Epoch::T0 => panic!("Cancelled before t1??? Something is really wrong"),
|
Epoch::T0 => panic!("Cancelled before t1??? Something is really wrong"),
|
||||||
Epoch::T1 => {
|
Epoch::T1 => {
|
||||||
state.refund_btc(bitcoin_wallet.as_ref()).await?;
|
state.refund_btc(bitcoin_wallet.as_ref()).await?;
|
||||||
run_until(
|
BobState::BtcRefunded(state)
|
||||||
BobState::BtcRefunded(state),
|
|
||||||
is_target_state,
|
|
||||||
event_loop_handle,
|
|
||||||
db,
|
|
||||||
bitcoin_wallet,
|
|
||||||
monero_wallet,
|
|
||||||
rng,
|
|
||||||
swap_id,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
Epoch::T2 => {
|
Epoch::T2 => BobState::Punished,
|
||||||
run_until(
|
};
|
||||||
BobState::Punished,
|
|
||||||
is_target_state,
|
let db_state = state.clone().into();
|
||||||
event_loop_handle,
|
db.insert_latest_state(swap_id, state::Swap::Bob(db_state))
|
||||||
db,
|
.await?;
|
||||||
bitcoin_wallet,
|
run_until(
|
||||||
monero_wallet,
|
state,
|
||||||
rng,
|
is_target_state,
|
||||||
swap_id,
|
event_loop_handle,
|
||||||
)
|
db,
|
||||||
.await
|
bitcoin_wallet,
|
||||||
}
|
monero_wallet,
|
||||||
}
|
rng,
|
||||||
|
swap_id,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
BobState::BtcRefunded(state4) => Ok(BobState::BtcRefunded(state4)),
|
BobState::BtcRefunded(state4) => Ok(BobState::BtcRefunded(state4)),
|
||||||
BobState::Punished => Ok(BobState::Punished),
|
BobState::Punished => Ok(BobState::Punished),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use ::serde::{Deserialize, Serialize};
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
|
|
||||||
pub mod alice;
|
pub mod alice;
|
||||||
@ -10,6 +10,7 @@ pub mod cli;
|
|||||||
pub mod monero;
|
pub mod monero;
|
||||||
pub mod network;
|
pub mod network;
|
||||||
pub mod recover;
|
pub mod recover;
|
||||||
|
pub mod serde;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod storage;
|
pub mod storage;
|
||||||
pub mod tor;
|
pub mod tor;
|
||||||
@ -31,7 +32,7 @@ pub enum Rsp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// XMR/BTC swap amounts.
|
/// XMR/BTC swap amounts.
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
// TODO(Franck): review necessity of this struct
|
// TODO(Franck): review necessity of this struct
|
||||||
pub struct SwapAmounts {
|
pub struct SwapAmounts {
|
||||||
/// Amount of BTC to swap.
|
/// Amount of BTC to swap.
|
||||||
|
@ -24,9 +24,12 @@ use futures::{
|
|||||||
};
|
};
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
use xmr_btc::bitcoin::{
|
use xmr_btc::{
|
||||||
poll_until_block_height_is_gte, BroadcastSignedTransaction, TransactionBlockHeight,
|
bitcoin::{
|
||||||
WatchForRawTransaction,
|
poll_until_block_height_is_gte, BroadcastSignedTransaction, TransactionBlockHeight,
|
||||||
|
WatchForRawTransaction,
|
||||||
|
},
|
||||||
|
bob::{State3, State4},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub async fn recover(
|
pub async fn recover(
|
||||||
@ -366,18 +369,53 @@ pub async fn bob_recover(
|
|||||||
state: Bob,
|
state: Bob,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
match state {
|
match state {
|
||||||
Bob::Handshaken(_) | Bob::SwapComplete => {
|
Bob::Negotiated { .. } | Bob::SwapComplete => {
|
||||||
info!("Nothing to do");
|
info!("Nothing to do");
|
||||||
}
|
}
|
||||||
Bob::BtcLocked(state) | Bob::XmrLocked(state) | Bob::BtcRefundable(state) => {
|
Bob::BtcLocked {
|
||||||
|
state3:
|
||||||
|
State3 {
|
||||||
|
A,
|
||||||
|
b,
|
||||||
|
s_b,
|
||||||
|
refund_timelock,
|
||||||
|
refund_address,
|
||||||
|
tx_lock,
|
||||||
|
tx_cancel_sig_a,
|
||||||
|
tx_refund_encsig,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| Bob::XmrLocked {
|
||||||
|
state4:
|
||||||
|
State4 {
|
||||||
|
A,
|
||||||
|
b,
|
||||||
|
s_b,
|
||||||
|
refund_timelock,
|
||||||
|
refund_address,
|
||||||
|
tx_lock,
|
||||||
|
tx_cancel_sig_a,
|
||||||
|
tx_refund_encsig,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| Bob::BtcCancelled(State4 {
|
||||||
|
A,
|
||||||
|
b,
|
||||||
|
s_b,
|
||||||
|
refund_timelock,
|
||||||
|
refund_address,
|
||||||
|
tx_lock,
|
||||||
|
tx_cancel_sig_a,
|
||||||
|
tx_refund_encsig,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
info!("Bitcoin may still be locked up, attempting to refund");
|
info!("Bitcoin may still be locked up, attempting to refund");
|
||||||
|
|
||||||
let tx_cancel = bitcoin::TxCancel::new(
|
let tx_cancel = bitcoin::TxCancel::new(&tx_lock, refund_timelock, A, b.public());
|
||||||
&state.tx_lock,
|
|
||||||
state.refund_timelock,
|
|
||||||
state.A,
|
|
||||||
state.b.public(),
|
|
||||||
);
|
|
||||||
|
|
||||||
info!("Checking if the Bitcoin cancel transaction has been published");
|
info!("Checking if the Bitcoin cancel transaction has been published");
|
||||||
if bitcoin_wallet
|
if bitcoin_wallet
|
||||||
@ -389,20 +427,17 @@ pub async fn bob_recover(
|
|||||||
info!("Bitcoin cancel transaction not yet published");
|
info!("Bitcoin cancel transaction not yet published");
|
||||||
|
|
||||||
let tx_lock_height = bitcoin_wallet
|
let tx_lock_height = bitcoin_wallet
|
||||||
.transaction_block_height(state.tx_lock.txid())
|
.transaction_block_height(tx_lock.txid())
|
||||||
|
.await;
|
||||||
|
poll_until_block_height_is_gte(&bitcoin_wallet, tx_lock_height + refund_timelock)
|
||||||
.await;
|
.await;
|
||||||
poll_until_block_height_is_gte(
|
|
||||||
&bitcoin_wallet,
|
|
||||||
tx_lock_height + state.refund_timelock,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let sig_a = state.tx_cancel_sig_a.clone();
|
let sig_a = tx_cancel_sig_a.clone();
|
||||||
let sig_b = state.b.sign(tx_cancel.digest());
|
let sig_b = b.sign(tx_cancel.digest());
|
||||||
|
|
||||||
let tx_cancel = tx_cancel
|
let tx_cancel = tx_cancel
|
||||||
.clone()
|
.clone()
|
||||||
.add_signatures(&state.tx_lock, (state.A, sig_a), (state.b.public(), sig_b))
|
.add_signatures(&tx_lock, (A, sig_a), (b.public(), sig_b))
|
||||||
.expect("sig_{a,b} to be valid signatures for tx_cancel");
|
.expect("sig_{a,b} to be valid signatures for tx_cancel");
|
||||||
|
|
||||||
// TODO: We should not fail if the transaction is already on the blockchain
|
// TODO: We should not fail if the transaction is already on the blockchain
|
||||||
@ -413,15 +448,15 @@ pub async fn bob_recover(
|
|||||||
|
|
||||||
info!("Confirmed that Bitcoin cancel transaction is on the blockchain");
|
info!("Confirmed that Bitcoin cancel transaction is on the blockchain");
|
||||||
|
|
||||||
let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &state.refund_address);
|
let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &refund_address);
|
||||||
let signed_tx_refund = {
|
let signed_tx_refund = {
|
||||||
let adaptor = Adaptor::<Sha256, Deterministic<Sha256>>::default();
|
let adaptor = Adaptor::<Sha256, Deterministic<Sha256>>::default();
|
||||||
let sig_a = adaptor
|
let sig_a =
|
||||||
.decrypt_signature(&state.s_b.into_secp256k1(), state.tx_refund_encsig.clone());
|
adaptor.decrypt_signature(&s_b.into_secp256k1(), tx_refund_encsig.clone());
|
||||||
let sig_b = state.b.sign(tx_refund.digest());
|
let sig_b = b.sign(tx_refund.digest());
|
||||||
|
|
||||||
tx_refund
|
tx_refund
|
||||||
.add_signatures(&tx_cancel, (state.A, sig_a), (state.b.public(), sig_b))
|
.add_signatures(&tx_cancel, (A, sig_a), (b.public(), sig_b))
|
||||||
.expect("sig_{a,b} to be valid signatures for tx_refund")
|
.expect("sig_{a,b} to be valid signatures for tx_refund")
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -459,6 +494,8 @@ pub async fn bob_recover(
|
|||||||
.await?;
|
.await?;
|
||||||
info!("Successfully redeemed monero")
|
info!("Successfully redeemed monero")
|
||||||
}
|
}
|
||||||
|
Bob::Started { .. } => todo!(),
|
||||||
|
Bob::EncSigSent { .. } => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
47
swap/src/serde.rs
Normal file
47
swap/src/serde.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
pub mod peer_id {
|
||||||
|
use libp2p::PeerId;
|
||||||
|
use serde::{de::Error, Deserialize, Deserializer, Serializer};
|
||||||
|
|
||||||
|
pub fn serialize<S>(peer_id: &PeerId, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
let string = peer_id.to_string();
|
||||||
|
serializer.serialize_str(&string)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<PeerId, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let string = String::deserialize(deserializer)?;
|
||||||
|
let peer_id = string.parse().map_err(D::Error::custom)?;
|
||||||
|
|
||||||
|
Ok(peer_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use serde::Serialize;
|
||||||
|
use spectral::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct SerializablePeerId(#[serde(with = "super")] PeerId);
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn maker_id_serializes_as_expected() {
|
||||||
|
let peer_id = SerializablePeerId(
|
||||||
|
"QmfUfpC2frwFvcDzpspnfZitHt5wct6n4kpG5jzgRdsxkY"
|
||||||
|
.parse()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let got = serde_json::to_string(&peer_id).expect("failed to serialize peer id");
|
||||||
|
|
||||||
|
assert_that(&got)
|
||||||
|
.is_equal_to(r#""QmfUfpC2frwFvcDzpspnfZitHt5wct6n4kpG5jzgRdsxkY""#.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
use crate::SwapAmounts;
|
||||||
|
use libp2p::{core::Multiaddr, PeerId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use xmr_btc::{alice, bitcoin::EncryptedSignature, bob, monero, serde::monero_private_key};
|
use xmr_btc::{alice, bitcoin::EncryptedSignature, bob, monero, serde::monero_private_key};
|
||||||
@ -37,11 +39,33 @@ pub enum Alice {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
pub enum Bob {
|
pub enum Bob {
|
||||||
Handshaken(bob::State2),
|
Started {
|
||||||
BtcLocked(bob::State2),
|
state0: bob::State0,
|
||||||
XmrLocked(bob::State2),
|
amounts: SwapAmounts,
|
||||||
BtcRedeemed(bob::State2),
|
addr: Multiaddr,
|
||||||
BtcRefundable(bob::State2),
|
},
|
||||||
|
Negotiated {
|
||||||
|
state2: bob::State2,
|
||||||
|
#[serde(with = "crate::serde::peer_id")]
|
||||||
|
peer_id: PeerId,
|
||||||
|
},
|
||||||
|
BtcLocked {
|
||||||
|
state3: bob::State3,
|
||||||
|
#[serde(with = "crate::serde::peer_id")]
|
||||||
|
peer_id: PeerId,
|
||||||
|
},
|
||||||
|
XmrLocked {
|
||||||
|
state4: bob::State4,
|
||||||
|
#[serde(with = "crate::serde::peer_id")]
|
||||||
|
peer_id: PeerId,
|
||||||
|
},
|
||||||
|
EncSigSent {
|
||||||
|
state4: bob::State4,
|
||||||
|
#[serde(with = "crate::serde::peer_id")]
|
||||||
|
peer_id: PeerId,
|
||||||
|
},
|
||||||
|
BtcRedeemed(bob::State5),
|
||||||
|
BtcCancelled(bob::State4),
|
||||||
SwapComplete,
|
SwapComplete,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,12 +109,14 @@ impl Display for Alice {
|
|||||||
impl Display for Bob {
|
impl Display for Bob {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Bob::Handshaken(_) => f.write_str("Handshake complete"),
|
Bob::Negotiated { .. } => f.write_str("Handshake complete"),
|
||||||
Bob::BtcLocked(_) | Bob::XmrLocked(_) | Bob::BtcRefundable(_) => {
|
Bob::BtcLocked { .. } | Bob::XmrLocked { .. } | Bob::BtcCancelled(_) => {
|
||||||
f.write_str("Bitcoin refundable")
|
f.write_str("Bitcoin refundable")
|
||||||
}
|
}
|
||||||
Bob::BtcRedeemed(_) => f.write_str("Monero redeemable"),
|
Bob::BtcRedeemed(_) => f.write_str("Monero redeemable"),
|
||||||
Bob::SwapComplete => f.write_str("Swap complete"),
|
Bob::SwapComplete => f.write_str("Swap complete"),
|
||||||
|
Bob::Started { .. } => f.write_str("Swap started"),
|
||||||
|
Bob::EncSigSent { .. } => f.write_str("Encrypted signature sent"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -346,7 +346,7 @@ impl_from_child_enum!(State3, State);
|
|||||||
impl_from_child_enum!(State4, State);
|
impl_from_child_enum!(State4, State);
|
||||||
impl_from_child_enum!(State5, State);
|
impl_from_child_enum!(State5, State);
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
pub struct State0 {
|
pub struct State0 {
|
||||||
b: bitcoin::SecretKey,
|
b: bitcoin::SecretKey,
|
||||||
s_b: cross_curve_dleq::Scalar,
|
s_b: cross_curve_dleq::Scalar,
|
||||||
@ -560,25 +560,25 @@ impl State2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct State3 {
|
pub struct State3 {
|
||||||
A: bitcoin::PublicKey,
|
pub A: bitcoin::PublicKey,
|
||||||
b: bitcoin::SecretKey,
|
pub b: bitcoin::SecretKey,
|
||||||
s_b: cross_curve_dleq::Scalar,
|
pub s_b: cross_curve_dleq::Scalar,
|
||||||
S_a_monero: monero::PublicKey,
|
S_a_monero: monero::PublicKey,
|
||||||
S_a_bitcoin: bitcoin::PublicKey,
|
S_a_bitcoin: bitcoin::PublicKey,
|
||||||
v: monero::PrivateViewKey,
|
v: monero::PrivateViewKey,
|
||||||
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
||||||
btc: bitcoin::Amount,
|
btc: bitcoin::Amount,
|
||||||
xmr: monero::Amount,
|
xmr: monero::Amount,
|
||||||
refund_timelock: u32,
|
pub refund_timelock: u32,
|
||||||
punish_timelock: u32,
|
punish_timelock: u32,
|
||||||
refund_address: bitcoin::Address,
|
pub refund_address: bitcoin::Address,
|
||||||
redeem_address: bitcoin::Address,
|
redeem_address: bitcoin::Address,
|
||||||
punish_address: bitcoin::Address,
|
punish_address: bitcoin::Address,
|
||||||
tx_lock: bitcoin::TxLock,
|
pub tx_lock: bitcoin::TxLock,
|
||||||
tx_cancel_sig_a: Signature,
|
pub tx_cancel_sig_a: Signature,
|
||||||
tx_refund_encsig: EncryptedSignature,
|
pub tx_refund_encsig: EncryptedSignature,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State3 {
|
impl State3 {
|
||||||
@ -626,11 +626,11 @@ impl State3 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||||
pub struct State4 {
|
pub struct State4 {
|
||||||
pub A: bitcoin::PublicKey,
|
pub A: bitcoin::PublicKey,
|
||||||
pub b: bitcoin::SecretKey,
|
pub b: bitcoin::SecretKey,
|
||||||
s_b: cross_curve_dleq::Scalar,
|
pub s_b: cross_curve_dleq::Scalar,
|
||||||
S_a_monero: monero::PublicKey,
|
S_a_monero: monero::PublicKey,
|
||||||
pub S_a_bitcoin: bitcoin::PublicKey,
|
pub S_a_bitcoin: bitcoin::PublicKey,
|
||||||
v: monero::PrivateViewKey,
|
v: monero::PrivateViewKey,
|
||||||
@ -639,12 +639,12 @@ pub struct State4 {
|
|||||||
xmr: monero::Amount,
|
xmr: monero::Amount,
|
||||||
pub refund_timelock: u32,
|
pub refund_timelock: u32,
|
||||||
punish_timelock: u32,
|
punish_timelock: u32,
|
||||||
refund_address: bitcoin::Address,
|
pub refund_address: bitcoin::Address,
|
||||||
pub redeem_address: bitcoin::Address,
|
pub redeem_address: bitcoin::Address,
|
||||||
punish_address: bitcoin::Address,
|
punish_address: bitcoin::Address,
|
||||||
pub tx_lock: bitcoin::TxLock,
|
pub tx_lock: bitcoin::TxLock,
|
||||||
tx_cancel_sig_a: Signature,
|
pub tx_cancel_sig_a: Signature,
|
||||||
tx_refund_encsig: EncryptedSignature,
|
pub tx_refund_encsig: EncryptedSignature,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State4 {
|
impl State4 {
|
||||||
@ -823,25 +823,25 @@ impl State4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||||
pub struct State5 {
|
pub struct State5 {
|
||||||
A: bitcoin::PublicKey,
|
A: bitcoin::PublicKey,
|
||||||
b: bitcoin::SecretKey,
|
pub b: bitcoin::SecretKey,
|
||||||
#[serde(with = "monero_private_key")]
|
#[serde(with = "monero_private_key")]
|
||||||
s_a: monero::PrivateKey,
|
s_a: monero::PrivateKey,
|
||||||
s_b: cross_curve_dleq::Scalar,
|
pub s_b: cross_curve_dleq::Scalar,
|
||||||
S_a_monero: monero::PublicKey,
|
S_a_monero: monero::PublicKey,
|
||||||
S_a_bitcoin: bitcoin::PublicKey,
|
pub S_a_bitcoin: bitcoin::PublicKey,
|
||||||
v: monero::PrivateViewKey,
|
pub v: monero::PrivateViewKey,
|
||||||
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
||||||
btc: bitcoin::Amount,
|
btc: bitcoin::Amount,
|
||||||
xmr: monero::Amount,
|
xmr: monero::Amount,
|
||||||
refund_timelock: u32,
|
refund_timelock: u32,
|
||||||
punish_timelock: u32,
|
punish_timelock: u32,
|
||||||
refund_address: bitcoin::Address,
|
refund_address: bitcoin::Address,
|
||||||
redeem_address: bitcoin::Address,
|
pub redeem_address: bitcoin::Address,
|
||||||
punish_address: bitcoin::Address,
|
punish_address: bitcoin::Address,
|
||||||
tx_lock: bitcoin::TxLock,
|
pub tx_lock: bitcoin::TxLock,
|
||||||
tx_refund_encsig: EncryptedSignature,
|
tx_refund_encsig: EncryptedSignature,
|
||||||
tx_cancel_sig: Signature,
|
tx_cancel_sig: Signature,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user