Save state for Bob at specific points in the swap

This commit is contained in:
rishflab 2020-11-02 16:00:10 +11:00
parent 5cb2f451d0
commit ea08778b2f
6 changed files with 82 additions and 7 deletions

View File

@ -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-tokio-socks5 = "0.4"
log = { version = "0.4", features = ["serde"] }
monero = "0.9"
monero = { version = "0.9", features = ["serde_support"] }
monero-harness = { path = "../monero-harness" }
rand = "0.7"
reqwest = { version = "0.10", default-features = false, features = ["socks"] }

View File

@ -31,6 +31,7 @@ use crate::{
transport::SwapTransport,
TokioExecutor,
},
storage::Database,
SwapAmounts, PUNISH_TIMELOCK, REFUND_TIMELOCK,
};
use xmr_btc::{
@ -43,6 +44,7 @@ use xmr_btc::{
pub async fn swap(
bitcoin_wallet: Arc<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>,
_db: Database<crate::storage::Alice>,
listen: Multiaddr,
transport: SwapTransport,
behaviour: Alice,

View File

@ -22,14 +22,14 @@ mod message3;
use self::{amounts::*, message0::*, message1::*, message2::*, message3::*};
use crate::{
bitcoin,
bitcoin::TX_LOCK_MINE_TIMEOUT,
bitcoin::{self, TX_LOCK_MINE_TIMEOUT},
monero,
network::{
peer_tracker::{self, PeerTracker},
transport::SwapTransport,
TokioExecutor,
},
storage::{self, Database},
Cmd, Rsp, SwapAmounts, PUNISH_TIMELOCK, REFUND_TIMELOCK,
};
use xmr_btc::{
@ -43,6 +43,7 @@ use xmr_btc::{
pub async fn swap(
bitcoin_wallet: Arc<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>,
db: Database<storage::Bob>,
btc: u64,
addr: Multiaddr,
mut cmd_tx: Sender<Cmd>,
@ -141,6 +142,9 @@ pub async fn swap(
other => panic!("unexpected event: {:?}", other),
};
db.insert_latest_state(&storage::Bob::Handshaken(state2.clone()))
.await?;
swarm.send_message2(alice.clone(), state2.next_message());
info!("Handshake complete");
@ -151,7 +155,7 @@ pub async fn swap(
network.clone(),
monero_wallet.clone(),
bitcoin_wallet.clone(),
state2,
state2.clone(),
TX_LOCK_MINE_TIMEOUT,
);
@ -166,8 +170,17 @@ pub async fn swap(
let _ = bitcoin_wallet
.broadcast_signed_transaction(signed_tx_lock)
.await?;
db.insert_latest_state(&storage::Bob::BtcLocked(state2.clone()))
.await?;
}
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;
guard.0.send_message3(alice.clone(), tx_redeem_encsig);
info!("Sent Bitcoin redeem encsig");
@ -185,21 +198,41 @@ pub async fn swap(
spend_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
.create_and_load_wallet_for_output(spend_key, view_key)
.await?;
}
GeneratorState::Yielded(bob::Action::CancelBtc(tx_cancel)) => {
db.insert_latest_state(&storage::Bob::BtcRefundable(state2.clone()))
.await?;
let _ = bitcoin_wallet
.broadcast_signed_transaction(tx_cancel)
.await?;
db.insert_latest_state(&storage::Bob::BtcRefundable(state2.clone()))
.await?;
}
GeneratorState::Yielded(bob::Action::RefundBtc(tx_refund)) => {
db.insert_latest_state(&storage::Bob::BtcRefundable(state2.clone()))
.await?;
let _ = bitcoin_wallet
.broadcast_signed_transaction(tx_refund)
.await?;
}
GeneratorState::Complete(()) => return Ok(()),
GeneratorState::Complete(()) => {
db.insert_latest_state(&storage::Bob::SwapComplete).await?;
return Ok(());
}
}
}
}

View File

@ -27,6 +27,7 @@ use swap::{
network::transport::{build, build_tor, SwapTransport},
Cmd, Rsp, SwapAmounts,
};
use tempfile::tempdir;
use tracing::info;
mod cli;
@ -80,9 +81,12 @@ async fn main() -> Result<()> {
let monero_wallet = Arc::new(monero::Wallet::new(monerod_url));
let db = Database::open(db_dir.path()).unwrap();
swap_as_alice(
bitcoin_wallet,
monero_wallet,
db
listen_addr,
transport,
behaviour,
@ -113,9 +117,12 @@ async fn main() -> Result<()> {
let monero_wallet = Arc::new(monero::Wallet::new(monerod_url));
let db = Database::open(db_dir.path()).unwrap();
swap_as_bob(
bitcoin_wallet,
monero_wallet,
db
satoshis,
alice_addr,
transport,
@ -149,6 +156,7 @@ async fn create_tor_service(
async fn swap_as_alice(
bitcoin_wallet: Arc<swap::bitcoin::Wallet>,
monero_wallet: Arc<swap::monero::Wallet>,
db: Database<storage::Alice>,
addr: Multiaddr,
transport: SwapTransport,
behaviour: Alice,
@ -159,6 +167,7 @@ async fn swap_as_alice(
async fn swap_as_bob(
bitcoin_wallet: Arc<swap::bitcoin::Wallet>,
monero_wallet: Arc<swap::monero::Wallet>,
db: Database<storage::Bob>,
sats: u64,
alice: Multiaddr,
transport: SwapTransport,
@ -169,6 +178,7 @@ async fn swap_as_bob(
tokio::spawn(bob::swap(
bitcoin_wallet,
monero_wallet,
db,
sats,
alice,
cmd_tx,

View File

@ -1,6 +1,36 @@
use anyhow::{anyhow, Context, Result};
use serde::{de::DeserializeOwned, Serialize};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
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>
where

View File

@ -495,7 +495,7 @@ impl State1 {
}
}
#[derive(Debug, Deserialize, Serialize)]
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct State2 {
pub A: bitcoin::PublicKey,
pub b: bitcoin::SecretKey,