diff --git a/swap/Cargo.toml b/swap/Cargo.toml index 2c217182..7bfb32ea 100644 --- a/swap/Cargo.toml +++ b/swap/Cargo.toml @@ -32,5 +32,6 @@ tracing-core = "0.1" tracing-futures = { version = "0.2", features = ["std-future", "futures-03"] } tracing-log = "0.1" tracing-subscriber = { version = "0.2", default-features = false, features = ["fmt", "ansi", "env-filter"] } +url = "2.1" void = "1" xmr-btc = { path = "../xmr-btc" } \ No newline at end of file diff --git a/swap/src/alice.rs b/swap/src/alice.rs index 734cbed5..ac46a8ba 100644 --- a/swap/src/alice.rs +++ b/swap/src/alice.rs @@ -32,7 +32,7 @@ pub async fn swap( redeem_address: ::bitcoin::Address, punish_address: ::bitcoin::Address, ) -> Result<()> { - let mut message0: Option = None; + let message0: Option = None; let mut last_amounts: Option = None; let mut swarm = new_swarm(listen)?; @@ -48,13 +48,12 @@ pub async fn swap( last_amounts = Some(p); swarm.send(channel, AliceToBob::Amounts(p)); } - OutEvent::Message0(msg) => { + OutEvent::Message0 => { debug!("Got message0 from Bob"); // TODO: Do this in a more Rusty/functional way. - message0 = Some(msg); + // message0 = Some(msg); break; } - other => panic!("unexpected event: {:?}", other), }; } @@ -78,9 +77,9 @@ pub async fn swap( ); swarm.set_state0(state0.clone()); - let state1 = match message0 { + let _state1 = match message0 { Some(msg) => state0.receive(msg), - None => unreachable!("should have msg by here"), + None => todo!("implement serde on Message0"), }; tracing::warn!("parking thread ..."); @@ -117,7 +116,8 @@ fn new_swarm(listen: Multiaddr) -> Result { pub enum OutEvent { ConnectionEstablished(PeerId), Request(amounts::OutEvent), - Message0(bob::Message0), + // Message0(bob::Message0), + Message0, } impl From for OutEvent { @@ -139,7 +139,8 @@ impl From for OutEvent { impl From for OutEvent { fn from(event: message0::OutEvent) -> Self { match event { - message0::OutEvent::Msg(msg) => OutEvent::Message0(msg), + // message0::OutEvent::Msg(msg) => OutEvent::Message0(msg), + message0::OutEvent::Msg => OutEvent::Message0, } } } @@ -171,7 +172,7 @@ impl Alice { } pub fn set_state0(&mut self, state: State0) { - self.message0.set_state(state); + let _ = self.message0.set_state(state); } } diff --git a/swap/src/alice/message0.rs b/swap/src/alice/message0.rs index c1631bb9..699a7114 100644 --- a/swap/src/alice/message0.rs +++ b/swap/src/alice/message0.rs @@ -7,7 +7,6 @@ use libp2p::{ swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters}, NetworkBehaviour, }; -use rand::rngs::OsRng; use std::{ collections::VecDeque, task::{Context, Poll}, @@ -16,11 +15,12 @@ use std::{ use tracing::error; use crate::network::request_response::{AliceToBob, BobToAlice, Codec, Protocol}; -use xmr_btc::{alice::State0, bob}; +use xmr_btc::alice::State0; #[derive(Debug)] pub enum OutEvent { - Msg(bob::Message0), + // Msg(bob::Message0), + Msg, } /// A `NetworkBehaviour` that represents getting the amounts of an XMR/BTC swap. @@ -85,16 +85,18 @@ impl NetworkBehaviourEventProcess> channel, }, } => match request { - BobToAlice::Message0(msg) => { - let response = match self.state { + BobToAlice::Message0 => { + let response = match &self.state { None => panic!("No state, did you forget to set it?"), - Some(state) => { + Some(_state) => { // TODO: Get OsRng from somewhere? - AliceToBob::Message0(state.next_message(&mut OsRng)) + // AliceToBob::Message0(state.next_message(&mut OsRng)) + AliceToBob::Message0 } }; self.rr.send_response(channel, response); - self.events.push_back(OutEvent::Msg(msg)); + + self.events.push_back(OutEvent::Msg); } _ => panic!("unexpected request"), }, diff --git a/swap/src/bob.rs b/swap/src/bob.rs index 41db2b36..4504b3c9 100644 --- a/swap/src/bob.rs +++ b/swap/src/bob.rs @@ -6,7 +6,7 @@ use futures::{ StreamExt, }; use libp2p::{core::identity::Keypair, Multiaddr, NetworkBehaviour, PeerId}; -use rand::{CryptoRng, RngCore}; +use rand::rngs::OsRng; use std::{process, thread, time::Duration}; use tracing::{debug, info, warn}; @@ -23,23 +23,20 @@ use crate::{ Cmd, Rsp, PUNISH_TIMELOCK, REFUND_TIMELOCK, }; use xmr_btc::{ - alice, bitcoin::BuildTxLockPsbt, bob::{self, State0}, }; -pub async fn swap( +pub async fn swap( btc: u64, addr: Multiaddr, mut cmd_tx: Sender, mut rsp_rx: Receiver, - rng: &mut R, refund_address: ::bitcoin::Address, - wallet: &W, + _wallet: W, ) -> Result<()> where - W: BuildTxLockPsbt, - R: RngCore + CryptoRng, + W: BuildTxLockPsbt + Send + Sync + 'static, { let mut swarm = new_swarm()?; @@ -73,6 +70,7 @@ where let xmr = xmr_btc::monero::Amount::from_piconero(xmr.as_piconero()); let btc = ::bitcoin::Amount::from_sat(btc.as_sat()); + let rng = &mut OsRng; let state0 = State0::new( rng, btc, @@ -82,9 +80,11 @@ where refund_address, ); swarm.send_message0(alice.clone(), state0.next_message(rng)); - let state1 = match swarm.next().await { - OutEvent::Message0(msg) => { - state0.receive(wallet, msg) // TODO: More graceful error handling. + let _state1 = match swarm.next().await { + OutEvent::Message0 => { + // state0.receive(wallet, msg) // TODO: More graceful error + // handling. + println!("TODO: receive after serde is done for Message0") } other => panic!("unexpected event: {:?}", other), }; @@ -120,7 +120,8 @@ fn new_swarm() -> Result { pub enum OutEvent { ConnectionEstablished(PeerId), Amounts(amounts::OutEvent), - Message0(alice::Message0), + // Message0(alice::Message0), + Message0, } impl From for OutEvent { @@ -142,7 +143,8 @@ impl From for OutEvent { impl From for OutEvent { fn from(event: message0::OutEvent) -> Self { match event { - message0::OutEvent::Msg(msg) => OutEvent::Message0(msg), + // message0::OutEvent::Msg(msg) => OutEvent::Message0(msg), + message0::OutEvent::Msg => OutEvent::Message0, } } } diff --git a/swap/src/bob/amounts.rs b/swap/src/bob/amounts.rs index 6a329a00..18071985 100644 --- a/swap/src/bob/amounts.rs +++ b/swap/src/bob/amounts.rs @@ -85,6 +85,7 @@ impl NetworkBehaviourEventProcess> }, } => match response { AliceToBob::Amounts(p) => self.events.push_back(OutEvent::Amounts(p)), + AliceToBob::Message0 => panic!("shouldn't get message0 here"), }, RequestResponseEvent::InboundFailure { .. } => { diff --git a/swap/src/bob/message0.rs b/swap/src/bob/message0.rs index e5d3d215..7aba6f23 100644 --- a/swap/src/bob/message0.rs +++ b/swap/src/bob/message0.rs @@ -14,11 +14,12 @@ use std::{ use tracing::error; use crate::network::request_response::{AliceToBob, BobToAlice, Codec, Protocol}; -use xmr_btc::{alice, bob}; +use xmr_btc::bob; #[derive(Debug)] pub enum OutEvent { - Msg(alice::Message0), + // Msg(alice::Message0), + Msg, } /// A `NetworkBehaviour` that represents send/recv of message 0. @@ -46,8 +47,9 @@ impl Message0 { } } - pub fn send(&mut self, alice: PeerId, msg: bob::Message0) { - let msg = BobToAlice::Message0(msg); + pub fn send(&mut self, alice: PeerId, _msg: bob::Message0) { + // let msg = BobToAlice::Message0(msg); + let msg = BobToAlice::Message0; let _id = self.rr.send_request(&alice, msg); } @@ -79,7 +81,9 @@ impl NetworkBehaviourEventProcess> request_id: _, }, } => match response { - AliceToBob::Message0(msg) => self.events.push_back(OutEvent::Msg(msg)), + // AliceToBob::Message0(msg) => self.events.push_back(OutEvent::Msg(msg)), + AliceToBob::Message0 => self.events.push_back(OutEvent::Msg), + AliceToBob::Amounts(_) => panic!("shouldn't get amounts here"), }, RequestResponseEvent::InboundFailure { .. } => { diff --git a/swap/src/main.rs b/swap/src/main.rs index f796cb75..f5b60f42 100644 --- a/swap/src/main.rs +++ b/swap/src/main.rs @@ -20,17 +20,20 @@ use rand::rngs::OsRng; use std::{io, io::Write, process}; use structopt::StructOpt; use tracing::info; +use url::Url; + mod cli; mod trace; use cli::Options; -use swap::{alice, bob, Cmd, Rsp, SwapParams}; - +use swap::{alice, bitcoin::Wallet, bob, Cmd, Rsp, SwapParams}; +use xmr_btc::bitcoin::BuildTxLockPsbt; // TODO: Add root seed file instead of generating new seed each run. // Alice's address and port until we have a config file. pub const PORT: u16 = 9876; // Arbitrarily chosen. pub const ADDR: &str = "127.0.0.1"; +pub const BITCOIND_JSON_RPC_URL: &str = "127.0.0.1:8332"; #[tokio::main] async fn main() -> Result<()> { @@ -48,23 +51,40 @@ async fn main() -> Result<()> { bail!("Alice cannot set the amount to swap via the cli"); } - // TODO: Get these addresses from command line - let redeem = bitcoin::Address::default(); - let punish = bitcoin::Address::default(); - - swap_as_alice(alice, redeem, refund).await?; + let url = Url::parse(BITCOIND_JSON_RPC_URL).expect("failed to parse url"); + let bitcoin_wallet = Wallet::new("alice", &url) + .await + .expect("failed to create bitcoin wallet"); + + let redeem = bitcoin_wallet + .new_address() + .await + .expect("failed to get new redeem address"); + let punish = bitcoin_wallet + .new_address() + .await + .expect("failed to get new punish address"); + + swap_as_alice(alice.clone(), redeem, punish).await?; } else { info!("running swap node as Bob ..."); - // TODO: Get refund address from command line - let refund = bitcoin::Address::default(); + let url = Url::parse(BITCOIND_JSON_RPC_URL).expect("failed to parse url"); + let bitcoin_wallet = Wallet::new("bob", &url) + .await + .expect("failed to create bitcoin wallet"); + + let refund = bitcoin_wallet + .new_address() + .await + .expect("failed to get new address"); match (opt.piconeros, opt.satoshis) { (Some(_), Some(_)) => bail!("Please supply only a single amount to swap"), (None, None) => bail!("Please supply an amount to swap"), (Some(_picos), _) => todo!("support starting with picos"), (None, Some(sats)) => { - swap_as_bob(sats, alice_addr, refund).await?; + swap_as_bob(sats, alice, refund, bitcoin_wallet).await?; } }; } @@ -74,16 +94,24 @@ async fn main() -> Result<()> { async fn swap_as_alice( addr: Multiaddr, - redeem: bitcoin::Address::default(), - punish: bitcoin::Address::default(), + redeem: bitcoin::Address, + punish: bitcoin::Address, ) -> Result<()> { - alice::swap(addr, OsRng, redeem, punish).await + alice::swap(addr, &mut OsRng, redeem, punish).await } -async fn swap_as_bob(sats: u64, addr: Multiaddr, refund: bitcoin::Address) -> Result<()> { +async fn swap_as_bob( + sats: u64, + addr: Multiaddr, + refund: bitcoin::Address, + wallet: W, +) -> Result<()> +where + W: BuildTxLockPsbt + Send + Sync + 'static, +{ let (cmd_tx, mut cmd_rx) = mpsc::channel(1); let (mut rsp_tx, rsp_rx) = mpsc::channel(1); - tokio::spawn(bob::swap(sats, addr, cmd_tx, rsp_rx, OsRng, refund)); + tokio::spawn(bob::swap(sats, addr, cmd_tx, rsp_rx, refund, wallet)); loop { let read = cmd_rx.next().await; match read { diff --git a/swap/src/network/request_response.rs b/swap/src/network/request_response.rs index 4af3a222..86420bee 100644 --- a/swap/src/network/request_response.rs +++ b/swap/src/network/request_response.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use std::{fmt::Debug, io}; use crate::SwapParams; -use xmr_btc::{alice, bob, monero}; +use xmr_btc::monero; /// Time to wait for a response back once we send a request. pub const TIMEOUT: u64 = 3600; // One hour. @@ -19,14 +19,16 @@ pub enum BobToAlice { #[serde(with = "::bitcoin::util::amount::serde::as_sat")] AmountsFromBtc(::bitcoin::Amount), AmountsFromXmr(monero::Amount), - Message0(bob::Message0), + Message0, + // Message0(bob::Message0), } /// Messages Alice sends to Bob. #[derive(Clone, Debug, Serialize, Deserialize)] pub enum AliceToBob { Amounts(SwapParams), - Message0(alice::Message0), + Message0, + // Message0(alice::Message0), } #[derive(Debug, Clone, Copy, Default)]