mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-01-12 07:59:33 -05:00
Save state for Bob at specific points in the swap
This commit is contained in:
parent
5cb2f451d0
commit
ea08778b2f
@ -19,7 +19,7 @@ genawaiter = "0.99.1"
|
|||||||
libp2p = { version = "0.29", default-features = false, features = ["tcp-tokio", "yamux", "mplex", "dns", "noise", "request-response"] }
|
libp2p = { version = "0.29", default-features = false, features = ["tcp-tokio", "yamux", "mplex", "dns", "noise", "request-response"] }
|
||||||
libp2p-tokio-socks5 = "0.4"
|
libp2p-tokio-socks5 = "0.4"
|
||||||
log = { version = "0.4", features = ["serde"] }
|
log = { version = "0.4", features = ["serde"] }
|
||||||
monero = "0.9"
|
monero = { version = "0.9", features = ["serde_support"] }
|
||||||
monero-harness = { path = "../monero-harness" }
|
monero-harness = { path = "../monero-harness" }
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
reqwest = { version = "0.10", default-features = false, features = ["socks"] }
|
reqwest = { version = "0.10", default-features = false, features = ["socks"] }
|
||||||
|
@ -31,6 +31,7 @@ use crate::{
|
|||||||
transport::SwapTransport,
|
transport::SwapTransport,
|
||||||
TokioExecutor,
|
TokioExecutor,
|
||||||
},
|
},
|
||||||
|
storage::Database,
|
||||||
SwapAmounts, PUNISH_TIMELOCK, REFUND_TIMELOCK,
|
SwapAmounts, PUNISH_TIMELOCK, REFUND_TIMELOCK,
|
||||||
};
|
};
|
||||||
use xmr_btc::{
|
use xmr_btc::{
|
||||||
@ -43,6 +44,7 @@ use xmr_btc::{
|
|||||||
pub async fn swap(
|
pub async fn swap(
|
||||||
bitcoin_wallet: Arc<bitcoin::Wallet>,
|
bitcoin_wallet: Arc<bitcoin::Wallet>,
|
||||||
monero_wallet: Arc<monero::Wallet>,
|
monero_wallet: Arc<monero::Wallet>,
|
||||||
|
_db: Database<crate::storage::Alice>,
|
||||||
listen: Multiaddr,
|
listen: Multiaddr,
|
||||||
transport: SwapTransport,
|
transport: SwapTransport,
|
||||||
behaviour: Alice,
|
behaviour: Alice,
|
||||||
|
@ -22,14 +22,14 @@ mod message3;
|
|||||||
|
|
||||||
use self::{amounts::*, message0::*, message1::*, message2::*, message3::*};
|
use self::{amounts::*, message0::*, message1::*, message2::*, message3::*};
|
||||||
use crate::{
|
use crate::{
|
||||||
bitcoin,
|
bitcoin::{self, TX_LOCK_MINE_TIMEOUT},
|
||||||
bitcoin::TX_LOCK_MINE_TIMEOUT,
|
|
||||||
monero,
|
monero,
|
||||||
network::{
|
network::{
|
||||||
peer_tracker::{self, PeerTracker},
|
peer_tracker::{self, PeerTracker},
|
||||||
transport::SwapTransport,
|
transport::SwapTransport,
|
||||||
TokioExecutor,
|
TokioExecutor,
|
||||||
},
|
},
|
||||||
|
storage::{self, Database},
|
||||||
Cmd, Rsp, SwapAmounts, PUNISH_TIMELOCK, REFUND_TIMELOCK,
|
Cmd, Rsp, SwapAmounts, PUNISH_TIMELOCK, REFUND_TIMELOCK,
|
||||||
};
|
};
|
||||||
use xmr_btc::{
|
use xmr_btc::{
|
||||||
@ -43,6 +43,7 @@ use xmr_btc::{
|
|||||||
pub async fn swap(
|
pub async fn swap(
|
||||||
bitcoin_wallet: Arc<bitcoin::Wallet>,
|
bitcoin_wallet: Arc<bitcoin::Wallet>,
|
||||||
monero_wallet: Arc<monero::Wallet>,
|
monero_wallet: Arc<monero::Wallet>,
|
||||||
|
db: Database<storage::Bob>,
|
||||||
btc: u64,
|
btc: u64,
|
||||||
addr: Multiaddr,
|
addr: Multiaddr,
|
||||||
mut cmd_tx: Sender<Cmd>,
|
mut cmd_tx: Sender<Cmd>,
|
||||||
@ -141,6 +142,9 @@ pub async fn swap(
|
|||||||
other => panic!("unexpected event: {:?}", other),
|
other => panic!("unexpected event: {:?}", other),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
db.insert_latest_state(&storage::Bob::Handshaken(state2.clone()))
|
||||||
|
.await?;
|
||||||
|
|
||||||
swarm.send_message2(alice.clone(), state2.next_message());
|
swarm.send_message2(alice.clone(), state2.next_message());
|
||||||
|
|
||||||
info!("Handshake complete");
|
info!("Handshake complete");
|
||||||
@ -151,7 +155,7 @@ pub async fn swap(
|
|||||||
network.clone(),
|
network.clone(),
|
||||||
monero_wallet.clone(),
|
monero_wallet.clone(),
|
||||||
bitcoin_wallet.clone(),
|
bitcoin_wallet.clone(),
|
||||||
state2,
|
state2.clone(),
|
||||||
TX_LOCK_MINE_TIMEOUT,
|
TX_LOCK_MINE_TIMEOUT,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -166,8 +170,17 @@ pub async fn swap(
|
|||||||
let _ = bitcoin_wallet
|
let _ = bitcoin_wallet
|
||||||
.broadcast_signed_transaction(signed_tx_lock)
|
.broadcast_signed_transaction(signed_tx_lock)
|
||||||
.await?;
|
.await?;
|
||||||
|
db.insert_latest_state(&storage::Bob::BtcLocked(state2.clone()))
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
GeneratorState::Yielded(bob::Action::SendBtcRedeemEncsig(tx_redeem_encsig)) => {
|
GeneratorState::Yielded(bob::Action::SendBtcRedeemEncsig(tx_redeem_encsig)) => {
|
||||||
|
// FIXME: We _know_ that this action is only yielded if the monero has been
|
||||||
|
// locked. This only works because we know that this is the case, but it may be
|
||||||
|
// cleaner to save the state inside an implementation of `watch_for_transfer` or
|
||||||
|
// modify the library code to make this easier
|
||||||
|
db.insert_latest_state(&storage::Bob::XmrLocked(state2.clone()))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let mut guard = network.as_ref().lock().await;
|
let mut guard = network.as_ref().lock().await;
|
||||||
guard.0.send_message3(alice.clone(), tx_redeem_encsig);
|
guard.0.send_message3(alice.clone(), tx_redeem_encsig);
|
||||||
info!("Sent Bitcoin redeem encsig");
|
info!("Sent Bitcoin redeem encsig");
|
||||||
@ -185,21 +198,41 @@ pub async fn swap(
|
|||||||
spend_key,
|
spend_key,
|
||||||
view_key,
|
view_key,
|
||||||
}) => {
|
}) => {
|
||||||
|
// FIXME: We _know_ that this action is only yielded if the bitcoin has been
|
||||||
|
// redeemed. This only works because we know that this is the case, but it may
|
||||||
|
// be cleaner to save the state inside an implementation of `watch_for_transfer`
|
||||||
|
// or modify the library code to make this easier
|
||||||
|
db.insert_latest_state(&storage::Bob::BtcRedeemed(state2.clone()))
|
||||||
|
.await?;
|
||||||
|
|
||||||
monero_wallet
|
monero_wallet
|
||||||
.create_and_load_wallet_for_output(spend_key, view_key)
|
.create_and_load_wallet_for_output(spend_key, view_key)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
GeneratorState::Yielded(bob::Action::CancelBtc(tx_cancel)) => {
|
GeneratorState::Yielded(bob::Action::CancelBtc(tx_cancel)) => {
|
||||||
|
db.insert_latest_state(&storage::Bob::BtcRefundable(state2.clone()))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let _ = bitcoin_wallet
|
let _ = bitcoin_wallet
|
||||||
.broadcast_signed_transaction(tx_cancel)
|
.broadcast_signed_transaction(tx_cancel)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
db.insert_latest_state(&storage::Bob::BtcRefundable(state2.clone()))
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
GeneratorState::Yielded(bob::Action::RefundBtc(tx_refund)) => {
|
GeneratorState::Yielded(bob::Action::RefundBtc(tx_refund)) => {
|
||||||
|
db.insert_latest_state(&storage::Bob::BtcRefundable(state2.clone()))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let _ = bitcoin_wallet
|
let _ = bitcoin_wallet
|
||||||
.broadcast_signed_transaction(tx_refund)
|
.broadcast_signed_transaction(tx_refund)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
GeneratorState::Complete(()) => return Ok(()),
|
GeneratorState::Complete(()) => {
|
||||||
|
db.insert_latest_state(&storage::Bob::SwapComplete).await?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ use swap::{
|
|||||||
network::transport::{build, build_tor, SwapTransport},
|
network::transport::{build, build_tor, SwapTransport},
|
||||||
Cmd, Rsp, SwapAmounts,
|
Cmd, Rsp, SwapAmounts,
|
||||||
};
|
};
|
||||||
|
use tempfile::tempdir;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
mod cli;
|
mod cli;
|
||||||
@ -80,9 +81,12 @@ async fn main() -> Result<()> {
|
|||||||
|
|
||||||
let monero_wallet = Arc::new(monero::Wallet::new(monerod_url));
|
let monero_wallet = Arc::new(monero::Wallet::new(monerod_url));
|
||||||
|
|
||||||
|
let db = Database::open(db_dir.path()).unwrap();
|
||||||
|
|
||||||
swap_as_alice(
|
swap_as_alice(
|
||||||
bitcoin_wallet,
|
bitcoin_wallet,
|
||||||
monero_wallet,
|
monero_wallet,
|
||||||
|
db
|
||||||
listen_addr,
|
listen_addr,
|
||||||
transport,
|
transport,
|
||||||
behaviour,
|
behaviour,
|
||||||
@ -113,9 +117,12 @@ async fn main() -> Result<()> {
|
|||||||
|
|
||||||
let monero_wallet = Arc::new(monero::Wallet::new(monerod_url));
|
let monero_wallet = Arc::new(monero::Wallet::new(monerod_url));
|
||||||
|
|
||||||
|
let db = Database::open(db_dir.path()).unwrap();
|
||||||
|
|
||||||
swap_as_bob(
|
swap_as_bob(
|
||||||
bitcoin_wallet,
|
bitcoin_wallet,
|
||||||
monero_wallet,
|
monero_wallet,
|
||||||
|
db
|
||||||
satoshis,
|
satoshis,
|
||||||
alice_addr,
|
alice_addr,
|
||||||
transport,
|
transport,
|
||||||
@ -149,6 +156,7 @@ async fn create_tor_service(
|
|||||||
async fn swap_as_alice(
|
async fn swap_as_alice(
|
||||||
bitcoin_wallet: Arc<swap::bitcoin::Wallet>,
|
bitcoin_wallet: Arc<swap::bitcoin::Wallet>,
|
||||||
monero_wallet: Arc<swap::monero::Wallet>,
|
monero_wallet: Arc<swap::monero::Wallet>,
|
||||||
|
db: Database<storage::Alice>,
|
||||||
addr: Multiaddr,
|
addr: Multiaddr,
|
||||||
transport: SwapTransport,
|
transport: SwapTransport,
|
||||||
behaviour: Alice,
|
behaviour: Alice,
|
||||||
@ -159,6 +167,7 @@ async fn swap_as_alice(
|
|||||||
async fn swap_as_bob(
|
async fn swap_as_bob(
|
||||||
bitcoin_wallet: Arc<swap::bitcoin::Wallet>,
|
bitcoin_wallet: Arc<swap::bitcoin::Wallet>,
|
||||||
monero_wallet: Arc<swap::monero::Wallet>,
|
monero_wallet: Arc<swap::monero::Wallet>,
|
||||||
|
db: Database<storage::Bob>,
|
||||||
sats: u64,
|
sats: u64,
|
||||||
alice: Multiaddr,
|
alice: Multiaddr,
|
||||||
transport: SwapTransport,
|
transport: SwapTransport,
|
||||||
@ -169,6 +178,7 @@ async fn swap_as_bob(
|
|||||||
tokio::spawn(bob::swap(
|
tokio::spawn(bob::swap(
|
||||||
bitcoin_wallet,
|
bitcoin_wallet,
|
||||||
monero_wallet,
|
monero_wallet,
|
||||||
|
db,
|
||||||
sats,
|
sats,
|
||||||
alice,
|
alice,
|
||||||
cmd_tx,
|
cmd_tx,
|
||||||
|
@ -1,6 +1,36 @@
|
|||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use xmr_btc::{alice, bitcoin::EncryptedSignature, bob, serde::monero_private_key};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub enum Bob {
|
||||||
|
Handshaken(bob::State2),
|
||||||
|
BtcLocked(bob::State2),
|
||||||
|
XmrLocked(bob::State2),
|
||||||
|
BtcRedeemed(bob::State2),
|
||||||
|
BtcRefundable(bob::State2),
|
||||||
|
SwapComplete,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub enum Alice {
|
||||||
|
Handshaken(alice::State3),
|
||||||
|
BtcLocked(alice::State3),
|
||||||
|
XmrLocked(alice::State3),
|
||||||
|
ReceivedEncSig {
|
||||||
|
state: alice::State3,
|
||||||
|
enc_sig: EncryptedSignature,
|
||||||
|
},
|
||||||
|
BtcCancelled(alice::State3),
|
||||||
|
BtcRefunded {
|
||||||
|
state: alice::State3,
|
||||||
|
#[serde(with = "monero_private_key")]
|
||||||
|
s_b: monero::PrivateKey,
|
||||||
|
},
|
||||||
|
SwapComplete,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Database<T>
|
pub struct Database<T>
|
||||||
where
|
where
|
||||||
|
@ -495,7 +495,7 @@ impl State1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
pub struct State2 {
|
pub struct State2 {
|
||||||
pub A: bitcoin::PublicKey,
|
pub A: bitcoin::PublicKey,
|
||||||
pub b: bitcoin::SecretKey,
|
pub b: bitcoin::SecretKey,
|
||||||
|
Loading…
Reference in New Issue
Block a user