From ae8134f04ed5de8521c2f1b332f625d911887c24 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 14 Jan 2021 13:23:03 +1100 Subject: [PATCH] Replace amounts messages with swap res/req --- swap/src/database/alice.rs | 5 +- swap/src/database/bob.rs | 5 +- swap/src/network/request_response.rs | 16 ++--- swap/src/protocol/alice.rs | 49 ++++++++------- swap/src/protocol/alice/event_loop.rs | 36 ++++++----- swap/src/protocol/alice/steps.rs | 21 +++---- swap/src/protocol/alice/swap.rs | 2 +- .../alice/{amounts.rs => swap_response.rs} | 39 +++++++----- swap/src/protocol/bob.rs | 51 ++++++++-------- swap/src/protocol/bob/event_loop.rs | 60 ++++++++++++------- swap/src/protocol/bob/swap.rs | 12 +++- .../bob/{amounts.rs => swap_request.rs} | 48 ++++++++------- 12 files changed, 192 insertions(+), 152 deletions(-) rename swap/src/protocol/alice/{amounts.rs => swap_response.rs} (72%) rename swap/src/protocol/bob/{amounts.rs => swap_request.rs} (67%) diff --git a/swap/src/database/alice.rs b/swap/src/database/alice.rs index 8b26c014..0562b299 100644 --- a/swap/src/database/alice.rs +++ b/swap/src/database/alice.rs @@ -1,6 +1,3 @@ -use ::bitcoin::hashes::core::fmt::Display; -use serde::{Deserialize, Serialize}; - use crate::{ bitcoin::{EncryptedSignature, TxCancel, TxRefund}, monero, @@ -8,6 +5,8 @@ use crate::{ protocol::{alice, alice::AliceState}, SwapAmounts, }; +use ::bitcoin::hashes::core::fmt::Display; +use serde::{Deserialize, Serialize}; // Large enum variant is fine because this is only used for database // and is dropped once written in DB. diff --git a/swap/src/database/bob.rs b/swap/src/database/bob.rs index d6309154..6eaf159a 100644 --- a/swap/src/database/bob.rs +++ b/swap/src/database/bob.rs @@ -1,10 +1,9 @@ -use ::bitcoin::hashes::core::fmt::Display; -use serde::{Deserialize, Serialize}; - use crate::{ protocol::{bob, bob::BobState}, SwapAmounts, }; +use ::bitcoin::hashes::core::fmt::Display; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] pub enum Bob { diff --git a/swap/src/network/request_response.rs b/swap/src/network/request_response.rs index cadd0a8d..a58be87f 100644 --- a/swap/src/network/request_response.rs +++ b/swap/src/network/request_response.rs @@ -8,10 +8,7 @@ use serde::{Deserialize, Serialize}; use std::{fmt::Debug, io, marker::PhantomData}; use tracing::debug; -use crate::{ - protocol::{alice, bob}, - SwapAmounts, -}; +use crate::protocol::{alice, bob}; /// Time to wait for a response back once we send a request. pub const TIMEOUT: u64 = 3600; // One hour. @@ -25,8 +22,7 @@ const BUF_SIZE: usize = 1024 * 1024; /// Messages Bob sends to Alice. #[derive(Clone, Debug, Serialize, Deserialize)] pub enum BobToAlice { - #[serde(with = "::bitcoin::util::amount::serde::as_sat")] - AmountsFromBtc(::bitcoin::Amount), + SwapRequest(bob::SwapRequest), Message0(Box), Message1(bob::Message1), Message2(bob::Message2), @@ -36,7 +32,7 @@ pub enum BobToAlice { /// Messages Alice sends to Bob. #[derive(Clone, Debug, Serialize, Deserialize)] pub enum AliceToBob { - Amounts(SwapAmounts), + SwapResponse(alice::SwapResponse), Message0(Box), Message1(Box), Message2(alice::Message2), @@ -44,7 +40,7 @@ pub enum AliceToBob { } #[derive(Debug, Clone, Copy, Default)] -pub struct AmountsProtocol; +pub struct Swap; #[derive(Debug, Clone, Copy, Default)] pub struct Message0Protocol; @@ -58,9 +54,9 @@ pub struct Message2Protocol; #[derive(Debug, Clone, Copy, Default)] pub struct Message3Protocol; -impl ProtocolName for AmountsProtocol { +impl ProtocolName for Swap { fn protocol_name(&self) -> &[u8] { - b"/xmr/btc/amounts/1.0.0" + b"/xmr/btc/swap/1.0.0" } } diff --git a/swap/src/protocol/alice.rs b/swap/src/protocol/alice.rs index dba570d8..e15d55a7 100644 --- a/swap/src/protocol/alice.rs +++ b/swap/src/protocol/alice.rs @@ -1,36 +1,40 @@ //! Run an XMR/BTC swap in the role of Alice. //! Alice holds XMR and wishes receive BTC. -use anyhow::{bail, Result}; -use libp2p::{request_response::ResponseChannel, NetworkBehaviour, PeerId}; -use tracing::{debug, info}; - use crate::{ - bitcoin, database, monero, + bitcoin, + config::Config, + database, + database::Database, + monero, network::{ peer_tracker::{self, PeerTracker}, request_response::AliceToBob, + transport::build, Seed as NetworkSeed, }, protocol::bob, + seed::Seed, SwapAmounts, }; +use anyhow::{bail, Result}; +use libp2p::{ + core::Multiaddr, identity::Keypair, request_response::ResponseChannel, NetworkBehaviour, PeerId, +}; +use rand::rngs::OsRng; +use std::{path::PathBuf, sync::Arc}; +use tracing::{debug, info}; +use uuid::Uuid; pub use self::{ - amounts::*, event_loop::{EventLoop, EventLoopHandle}, message0::Message0, message1::Message1, message2::Message2, state::*, swap::{run, run_until}, + swap_response::*, }; -use crate::{config::Config, database::Database, network::transport::build, seed::Seed}; -use libp2p::{core::Multiaddr, identity::Keypair}; -use rand::rngs::OsRng; -use std::{path::PathBuf, sync::Arc}; -use uuid::Uuid; -mod amounts; pub mod event_loop; mod message0; mod message1; @@ -39,6 +43,7 @@ mod message3; pub mod state; mod steps; pub mod swap; +mod swap_response; pub struct Swap { pub state: AliceState, @@ -217,8 +222,9 @@ pub enum OutEvent { ConnectionEstablished(PeerId), // TODO (Franck): Change this to get both amounts so parties can verify the amounts are // expected early on. - Request(Box), /* Not-uniform with Bob on purpose, ready for adding Xmr - * event. */ + Request(Box), /* Not-uniform with Bob on purpose, ready for adding + * Xmr + * event. */ Message0 { msg: Box, channel: ResponseChannel, @@ -244,8 +250,8 @@ impl From for OutEvent { } } -impl From for OutEvent { - fn from(event: amounts::OutEvent) -> Self { +impl From for OutEvent { + fn from(event: swap_response::OutEvent) -> Self { OutEvent::Request(Box::new(event)) } } @@ -291,7 +297,7 @@ impl From for OutEvent { #[allow(missing_debug_implementations)] pub struct Behaviour { pt: PeerTracker, - amounts: Amounts, + amounts: swap_response::Behaviour, message0: message0::Behaviour, message1: message1::Behaviour, message2: message2::Behaviour, @@ -300,9 +306,12 @@ pub struct Behaviour { impl Behaviour { /// Alice always sends her messages as a response to a request from Bob. - pub fn send_amounts(&mut self, channel: ResponseChannel, amounts: SwapAmounts) { - let msg = AliceToBob::Amounts(amounts); - self.amounts.send(channel, msg); + pub fn send_swap_response( + &mut self, + channel: ResponseChannel, + swap_response: SwapResponse, + ) { + self.amounts.send(channel, swap_response); info!("Sent amounts response"); } diff --git a/swap/src/protocol/alice/event_loop.rs b/swap/src/protocol/alice/event_loop.rs index db5eb67f..6a643c63 100644 --- a/swap/src/protocol/alice/event_loop.rs +++ b/swap/src/protocol/alice/event_loop.rs @@ -9,10 +9,9 @@ use crate::{ network::{request_response::AliceToBob, transport::SwapTransport, TokioExecutor}, protocol::{ alice, - alice::{Behaviour, OutEvent}, + alice::{Behaviour, OutEvent, SwapResponse}, bob, }, - SwapAmounts, }; #[allow(missing_debug_implementations)] @@ -40,9 +39,9 @@ pub struct EventLoopHandle { msg1: Receiver<(bob::Message1, ResponseChannel)>, msg2: Receiver<(bob::Message2, ResponseChannel)>, msg3: Receiver, - request: Receiver, + request: Receiver, conn_established: Receiver, - send_amounts: Sender<(ResponseChannel, SwapAmounts)>, + send_swap_response: Sender<(ResponseChannel, SwapResponse)>, send_msg0: Sender<(ResponseChannel, alice::Message0)>, send_msg1: Sender<(ResponseChannel, alice::Message1)>, send_msg2: Sender<(ResponseChannel, alice::Message2)>, @@ -84,19 +83,24 @@ impl EventLoopHandle { .ok_or_else(|| anyhow!("Failed to receive Bitcoin encrypted signature from Bob")) } - pub async fn recv_request(&mut self) -> Result { + pub async fn recv_request( + &mut self, + ) -> Result { self.request .recv() .await .ok_or_else(|| anyhow!("Failed to receive amounts request from Bob")) } - pub async fn send_amounts( + pub async fn send_swap_response( &mut self, channel: ResponseChannel, - amounts: SwapAmounts, + swap_response: SwapResponse, ) -> Result<()> { - let _ = self.send_amounts.send((channel, amounts)).await?; + let _ = self + .send_swap_response + .send((channel, swap_response)) + .await?; Ok(()) } @@ -135,9 +139,9 @@ pub struct EventLoop { msg1: Sender<(bob::Message1, ResponseChannel)>, msg2: Sender<(bob::Message2, ResponseChannel)>, msg3: Sender, - request: Sender, + request: Sender, conn_established: Sender, - send_amounts: Receiver<(ResponseChannel, SwapAmounts)>, + send_swap_response: Receiver<(ResponseChannel, SwapResponse)>, send_msg0: Receiver<(ResponseChannel, alice::Message0)>, send_msg1: Receiver<(ResponseChannel, alice::Message1)>, send_msg2: Receiver<(ResponseChannel, alice::Message2)>, @@ -165,7 +169,7 @@ impl EventLoop { let msg3 = Channels::new(); let request = Channels::new(); let conn_established = Channels::new(); - let send_amounts = Channels::new(); + let send_swap_response = Channels::new(); let send_msg0 = Channels::new(); let send_msg1 = Channels::new(); let send_msg2 = Channels::new(); @@ -178,7 +182,7 @@ impl EventLoop { msg3: msg3.sender, request: request.sender, conn_established: conn_established.sender, - send_amounts: send_amounts.receiver, + send_swap_response: send_swap_response.receiver, send_msg0: send_msg0.receiver, send_msg1: send_msg1.receiver, send_msg2: send_msg2.receiver, @@ -191,7 +195,7 @@ impl EventLoop { msg3: msg3.receiver, request: request.receiver, conn_established: conn_established.receiver, - send_amounts: send_amounts.sender, + send_swap_response: send_swap_response.sender, send_msg0: send_msg0.sender, send_msg1: send_msg1.sender, send_msg2: send_msg2.sender, @@ -225,9 +229,9 @@ impl EventLoop { } } }, - amounts = self.send_amounts.next().fuse() => { - if let Some((channel, amounts)) = amounts { - self.swarm.send_amounts(channel, amounts); + swap_response = self.send_swap_response.next().fuse() => { + if let Some((channel, swap_response)) = swap_response { + self.swarm.send_swap_response(channel, swap_response); } }, msg0 = self.send_msg0.next().fuse() => { diff --git a/swap/src/protocol/alice/steps.rs b/swap/src/protocol/alice/steps.rs index 09cf3cec..eba754e2 100644 --- a/swap/src/protocol/alice/steps.rs +++ b/swap/src/protocol/alice/steps.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result}; use ecdsa_fun::{adaptor::Adaptor, nonce::Deterministic}; use futures::{ future::{select, Either}, @@ -24,13 +24,16 @@ use crate::{ monero, monero::Transfer, network::request_response::AliceToBob, - protocol::{alice, alice::event_loop::EventLoopHandle}, + protocol::{ + alice, + alice::{event_loop::EventLoopHandle, SwapResponse}, + }, SwapAmounts, }; pub async fn negotiate( state0: alice::State0, - amounts: SwapAmounts, + xmr_amount: monero::Amount, event_loop_handle: &mut EventLoopHandle, config: Config, ) -> Result<(ResponseChannel, alice::State3)> { @@ -46,18 +49,10 @@ pub async fn negotiate( let event = timeout(config.bob_time_to_act, event_loop_handle.recv_request()) .await - .context("Failed to receive amounts from Bob")??; - - if event.btc != amounts.btc { - bail!( - "Bob proposed a different amount; got {}, expected: {}", - event.btc, - amounts.btc - ); - } + .context("Failed to receive swap request from Bob")??; event_loop_handle - .send_amounts(event.channel, amounts) + .send_swap_response(event.channel, SwapResponse { xmr_amount }) .await?; let (bob_message0, channel) = diff --git a/swap/src/protocol/alice/swap.rs b/swap/src/protocol/alice/swap.rs index 2ed2eb2f..791f2713 100644 --- a/swap/src/protocol/alice/swap.rs +++ b/swap/src/protocol/alice/swap.rs @@ -105,7 +105,7 @@ async fn run_until_internal( match state { AliceState::Started { amounts, state0 } => { let (channel, state3) = - negotiate(state0, amounts, &mut event_loop_handle, config).await?; + negotiate(state0, amounts.xmr, &mut event_loop_handle, config).await?; let state = AliceState::Negotiated { channel: Some(channel), diff --git a/swap/src/protocol/alice/amounts.rs b/swap/src/protocol/alice/swap_response.rs similarity index 72% rename from swap/src/protocol/alice/amounts.rs rename to swap/src/protocol/alice/swap_response.rs index a3079352..47f6ceab 100644 --- a/swap/src/protocol/alice/amounts.rs +++ b/swap/src/protocol/alice/swap_response.rs @@ -6,6 +6,7 @@ use libp2p::{ swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters}, NetworkBehaviour, }; +use serde::{Deserialize, Serialize}; use std::{ collections::VecDeque, task::{Context, Poll}, @@ -14,29 +15,37 @@ use std::{ use tracing::{debug, error}; use crate::{ - network::request_response::{AliceToBob, AmountsProtocol, BobToAlice, Codec, TIMEOUT}, - protocol::alice::amounts, + monero, + network::request_response::{AliceToBob, BobToAlice, Codec, Swap, TIMEOUT}, + protocol::bob, }; #[derive(Debug)] pub struct OutEvent { - pub btc: ::bitcoin::Amount, + pub msg: bob::SwapRequest, pub channel: ResponseChannel, } -/// A `NetworkBehaviour` that represents getting the amounts of an XMR/BTC swap. +#[derive(Copy, Clone, Debug, Serialize, Deserialize)] +pub struct SwapResponse { + pub xmr_amount: monero::Amount, +} + +/// A `NetworkBehaviour` that represents negotiate a swap using Swap +/// request/response. #[derive(NetworkBehaviour)] #[behaviour(out_event = "OutEvent", poll_method = "poll")] #[allow(missing_debug_implementations)] -pub struct Amounts { - rr: RequestResponse>, +pub struct Behaviour { + rr: RequestResponse>, #[behaviour(ignore)] events: VecDeque, } -impl Amounts { +impl Behaviour { /// Alice always sends her messages as a response to a request from Bob. - pub fn send(&mut self, channel: ResponseChannel, msg: AliceToBob) { + pub fn send(&mut self, channel: ResponseChannel, msg: SwapResponse) { + let msg = AliceToBob::SwapResponse(msg); self.rr.send_response(channel, msg); } @@ -44,7 +53,7 @@ impl Amounts { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>, OutEvent>> { + ) -> Poll>, OutEvent>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)); } @@ -53,7 +62,7 @@ impl Amounts { } } -impl Default for Amounts { +impl Default for Behaviour { fn default() -> Self { let timeout = Duration::from_secs(TIMEOUT); @@ -63,7 +72,7 @@ impl Default for Amounts { Self { rr: RequestResponse::new( Codec::default(), - vec![(AmountsProtocol, ProtocolSupport::Full)], + vec![(Swap, ProtocolSupport::Full)], config, ), events: Default::default(), @@ -71,7 +80,7 @@ impl Default for Amounts { } } -impl NetworkBehaviourEventProcess> for Amounts { +impl NetworkBehaviourEventProcess> for Behaviour { fn inject_event(&mut self, event: RequestResponseEvent) { match event { RequestResponseEvent::Message { @@ -81,9 +90,9 @@ impl NetworkBehaviourEventProcess> }, .. } => { - if let BobToAlice::AmountsFromBtc(btc) = request { - debug!("Received amounts request"); - self.events.push_back(amounts::OutEvent { btc, channel }) + if let BobToAlice::SwapRequest(msg) = request { + debug!("Received swap request"); + self.events.push_back(OutEvent { msg, channel }) } } RequestResponseEvent::Message { diff --git a/swap/src/protocol/bob.rs b/swap/src/protocol/bob.rs index 173f49eb..fa4b53f4 100644 --- a/swap/src/protocol/bob.rs +++ b/swap/src/protocol/bob.rs @@ -1,20 +1,28 @@ //! Run an XMR/BTC swap in the role of Bob. //! Bob holds BTC and wishes receive XMR. -use anyhow::{bail, Result}; -use libp2p::{core::Multiaddr, NetworkBehaviour, PeerId}; -use tracing::{debug, info}; - use crate::{ bitcoin, bitcoin::EncryptedSignature, - database, monero, network, - network::peer_tracker::{self, PeerTracker}, + config::Config, + database, + database::Database, + monero, network, + network::{ + peer_tracker::{self, PeerTracker}, + transport::build, + }, protocol::{alice, bob}, + seed::Seed, SwapAmounts, }; +use anyhow::{bail, Result}; +use libp2p::{core::Multiaddr, identity::Keypair, NetworkBehaviour, PeerId}; +use rand::rngs::OsRng; +use std::{path::PathBuf, sync::Arc}; +use tracing::{debug, info}; +use uuid::Uuid; pub use self::{ - amounts::*, event_loop::{EventLoop, EventLoopHandle}, message0::Message0, message1::Message1, @@ -22,14 +30,9 @@ pub use self::{ message3::Message3, state::*, swap::{run, run_until}, + swap_request::*, }; -use crate::{config::Config, database::Database, network::transport::build, seed::Seed}; -use libp2p::identity::Keypair; -use rand::rngs::OsRng; -use std::{path::PathBuf, sync::Arc}; -use uuid::Uuid; -mod amounts; pub mod event_loop; mod message0; mod message1; @@ -37,6 +40,7 @@ mod message2; mod message3; pub mod state; pub mod swap; +mod swap_request; pub struct Swap { pub state: BobState, @@ -204,7 +208,7 @@ impl Builder { #[derive(Debug, Clone)] pub enum OutEvent { ConnectionEstablished(PeerId), - Amounts(SwapAmounts), + SwapResponse(alice::SwapResponse), Message0(Box), Message1(Box), Message2(alice::Message2), @@ -221,11 +225,9 @@ impl From for OutEvent { } } -impl From for OutEvent { - fn from(event: amounts::OutEvent) -> Self { - match event { - amounts::OutEvent::Amounts(amounts) => OutEvent::Amounts(amounts), - } +impl From for OutEvent { + fn from(event: swap_request::OutEvent) -> Self { + OutEvent::SwapResponse(event.swap_response) } } @@ -267,7 +269,7 @@ impl From for OutEvent { #[allow(missing_debug_implementations)] pub struct Behaviour { pt: PeerTracker, - amounts: Amounts, + swap_request: swap_request::Behaviour, message0: message0::Behaviour, message1: message1::Behaviour, message2: message2::Behaviour, @@ -275,11 +277,10 @@ pub struct Behaviour { } impl Behaviour { - /// Sends a message to Alice to get current amounts based on `btc`. - pub fn request_amounts(&mut self, alice: PeerId, btc: u64) { - let btc = ::bitcoin::Amount::from_sat(btc); - let _id = self.amounts.request_amounts(alice.clone(), btc); - info!("Requesting amounts from: {}", alice); + /// Sends a swap request to Alice to negotiate the swap. + pub fn send_swap_request(&mut self, alice: PeerId, swap_request: SwapRequest) { + let _id = self.swap_request.send(alice.clone(), swap_request); + info!("Requesting swap from: {}", alice); } /// Sends Bob's first message to Alice. diff --git a/swap/src/protocol/bob/event_loop.rs b/swap/src/protocol/bob/event_loop.rs index 5e95356a..99130973 100644 --- a/swap/src/protocol/bob/event_loop.rs +++ b/swap/src/protocol/bob/event_loop.rs @@ -1,3 +1,12 @@ +use crate::{ + bitcoin::EncryptedSignature, + network::{transport::SwapTransport, TokioExecutor}, + protocol::{ + alice, + alice::SwapResponse, + bob::{self, Behaviour, OutEvent, SwapRequest}, + }, +}; use anyhow::{anyhow, Result}; use futures::FutureExt; use libp2p::{core::Multiaddr, PeerId}; @@ -7,15 +16,6 @@ use tokio::{ }; use tracing::{debug, error, info}; -use crate::{ - bitcoin::EncryptedSignature, - network::{transport::SwapTransport, TokioExecutor}, - protocol::{ - alice, - bob::{self, Behaviour, OutEvent}, - }, -}; - #[derive(Debug)] pub struct Channels { sender: Sender, @@ -37,12 +37,13 @@ impl Default for Channels { #[derive(Debug)] pub struct EventLoopHandle { + swap_response: Receiver, msg0: Receiver, msg1: Receiver, msg2: Receiver, - request_amounts: Sender<::bitcoin::Amount>, conn_established: Receiver, dial_alice: Sender<()>, + send_swap_request: Sender, send_msg0: Sender, send_msg1: Sender, send_msg2: Sender, @@ -50,25 +51,32 @@ pub struct EventLoopHandle { } impl EventLoopHandle { + pub async fn recv_swap_response(&mut self) -> Result { + self.swap_response + .recv() + .await + .ok_or_else(|| anyhow!("Failed to receive swap response from Alice")) + } + pub async fn recv_message0(&mut self) -> Result { self.msg0 .recv() .await - .ok_or_else(|| anyhow!("Failed to receive message 0 from Bob")) + .ok_or_else(|| anyhow!("Failed to receive message 0 from Alice")) } pub async fn recv_message1(&mut self) -> Result { self.msg1 .recv() .await - .ok_or_else(|| anyhow!("Failed to receive message 1 from Bob")) + .ok_or_else(|| anyhow!("Failed to receive message 1 from Alice")) } pub async fn recv_message2(&mut self) -> Result { self.msg2 .recv() .await - .ok_or_else(|| anyhow!("Failed o receive message 2 from Bob")) + .ok_or_else(|| anyhow!("Failed o receive message 2 from Alice")) } /// Dials other party and wait for the connection to be established. @@ -85,8 +93,8 @@ impl EventLoopHandle { Ok(()) } - pub async fn request_amounts(&mut self, btc_amount: ::bitcoin::Amount) -> Result<()> { - let _ = self.request_amounts.send(btc_amount).await?; + pub async fn send_swap_request(&mut self, swap_request: SwapRequest) -> Result<()> { + let _ = self.send_swap_request.send(swap_request).await?; Ok(()) } @@ -115,12 +123,13 @@ impl EventLoopHandle { pub struct EventLoop { swarm: libp2p::Swarm, alice_peer_id: PeerId, + swap_response: Sender, msg0: Sender, msg1: Sender, msg2: Sender, conn_established: Sender, - request_amounts: Receiver<::bitcoin::Amount>, dial_alice: Receiver<()>, + send_swap_request: Receiver, send_msg0: Receiver, send_msg1: Receiver, send_msg2: Receiver, @@ -143,12 +152,13 @@ impl EventLoop { swarm.add_address(alice_peer_id.clone(), alice_addr); - let amounts = Channels::new(); + let swap_response = Channels::new(); let msg0 = Channels::new(); let msg1 = Channels::new(); let msg2 = Channels::new(); let conn_established = Channels::new(); let dial_alice = Channels::new(); + let send_swap_request = Channels::new(); let send_msg0 = Channels::new(); let send_msg1 = Channels::new(); let send_msg2 = Channels::new(); @@ -157,12 +167,13 @@ impl EventLoop { let event_loop = EventLoop { swarm, alice_peer_id, - request_amounts: amounts.receiver, + swap_response: swap_response.sender, msg0: msg0.sender, msg1: msg1.sender, msg2: msg2.sender, conn_established: conn_established.sender, dial_alice: dial_alice.receiver, + send_swap_request: send_swap_request.receiver, send_msg0: send_msg0.receiver, send_msg1: send_msg1.receiver, send_msg2: send_msg2.receiver, @@ -170,12 +181,13 @@ impl EventLoop { }; let handle = EventLoopHandle { - request_amounts: amounts.sender, + swap_response: swap_response.receiver, msg0: msg0.receiver, msg1: msg1.receiver, msg2: msg2.receiver, conn_established: conn_established.receiver, dial_alice: dial_alice.sender, + send_swap_request: send_swap_request.sender, send_msg0: send_msg0.sender, send_msg1: send_msg1.sender, send_msg2: send_msg2.sender, @@ -193,7 +205,9 @@ impl EventLoop { OutEvent::ConnectionEstablished(peer_id) => { let _ = self.conn_established.send(peer_id).await; } - OutEvent::Amounts(_amounts) => info!("Amounts received from Alice"), + OutEvent::SwapResponse(msg) => { + let _ = self.swap_response.send(msg).await; + }, OutEvent::Message0(msg) => { let _ = self.msg0.send(*msg).await; } @@ -222,9 +236,9 @@ impl EventLoop { } } }, - amounts = self.request_amounts.next().fuse() => { - if let Some(btc_amount) = amounts { - self.swarm.request_amounts(self.alice_peer_id.clone(), btc_amount.as_sat()); + swap_request = self.send_swap_request.next().fuse() => { + if let Some(swap_request) = swap_request { + self.swarm.send_swap_request(self.alice_peer_id.clone(), swap_request); } }, diff --git a/swap/src/protocol/bob/swap.rs b/swap/src/protocol/bob/swap.rs index 07e0be2e..208c978c 100644 --- a/swap/src/protocol/bob/swap.rs +++ b/swap/src/protocol/bob/swap.rs @@ -11,7 +11,7 @@ use crate::{ config::Config, database::{Database, Swap}, monero, - protocol::bob::{self, event_loop::EventLoopHandle, state::*}, + protocol::bob::{self, event_loop::EventLoopHandle, state::*, SwapRequest}, ExpiredTimelocks, SwapAmounts, }; @@ -373,7 +373,15 @@ where R: RngCore + CryptoRng + Send, { tracing::trace!("Starting negotiate"); - swarm.request_amounts(amounts.btc).await?; + swarm + .send_swap_request(SwapRequest { + btc_amount: amounts.btc, + }) + .await?; + + // TODO: Use this once Bob's CLI is modified to only pass xmr amount in + // argument. + let _swap_response = swarm.recv_swap_response().await?; swarm.send_message0(state0.next_message(&mut rng)).await?; let msg0 = swarm.recv_message0().await?; diff --git a/swap/src/protocol/bob/amounts.rs b/swap/src/protocol/bob/swap_request.rs similarity index 67% rename from swap/src/protocol/bob/amounts.rs rename to swap/src/protocol/bob/swap_request.rs index 6350467c..157a1faa 100644 --- a/swap/src/protocol/bob/amounts.rs +++ b/swap/src/protocol/bob/swap_request.rs @@ -1,3 +1,7 @@ +use crate::{ + network::request_response::{AliceToBob, BobToAlice, Codec, Swap, TIMEOUT}, + protocol::alice::SwapResponse, +}; use anyhow::Result; use libp2p::{ request_response::{ @@ -7,6 +11,7 @@ use libp2p::{ swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters}, NetworkBehaviour, PeerId, }; +use serde::{Deserialize, Serialize}; use std::{ collections::VecDeque, task::{Context, Poll}, @@ -14,29 +19,30 @@ use std::{ }; use tracing::{debug, error}; -use crate::{ - network::request_response::{AliceToBob, AmountsProtocol, BobToAlice, Codec, TIMEOUT}, - SwapAmounts, -}; - -#[derive(Copy, Clone, Debug)] -pub enum OutEvent { - Amounts(SwapAmounts), +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct SwapRequest { + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] + pub btc_amount: bitcoin::Amount, } -/// A `NetworkBehaviour` that represents getting the amounts of an XMR/BTC swap. +#[derive(Copy, Clone, Debug)] +pub struct OutEvent { + pub swap_response: SwapResponse, +} + +/// A `NetworkBehaviour` that represents doing the negotiation of a swap. #[derive(NetworkBehaviour)] #[behaviour(out_event = "OutEvent", poll_method = "poll")] #[allow(missing_debug_implementations)] -pub struct Amounts { - rr: RequestResponse>, +pub struct Behaviour { + rr: RequestResponse>, #[behaviour(ignore)] events: VecDeque, } -impl Amounts { - pub fn request_amounts(&mut self, alice: PeerId, btc: ::bitcoin::Amount) -> Result { - let msg = BobToAlice::AmountsFromBtc(btc); +impl Behaviour { + pub fn send(&mut self, alice: PeerId, swap_request: SwapRequest) -> Result { + let msg = BobToAlice::SwapRequest(swap_request); let id = self.rr.send_request(&alice, msg); Ok(id) @@ -46,7 +52,7 @@ impl Amounts { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>, OutEvent>> { + ) -> Poll>, OutEvent>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)); } @@ -55,7 +61,7 @@ impl Amounts { } } -impl Default for Amounts { +impl Default for Behaviour { fn default() -> Self { let timeout = Duration::from_secs(TIMEOUT); @@ -65,7 +71,7 @@ impl Default for Amounts { Self { rr: RequestResponse::new( Codec::default(), - vec![(AmountsProtocol, ProtocolSupport::Full)], + vec![(Swap, ProtocolSupport::Full)], config, ), events: Default::default(), @@ -73,7 +79,7 @@ impl Default for Amounts { } } -impl NetworkBehaviourEventProcess> for Amounts { +impl NetworkBehaviourEventProcess> for Behaviour { fn inject_event(&mut self, event: RequestResponseEvent) { match event { RequestResponseEvent::Message { @@ -84,9 +90,9 @@ impl NetworkBehaviourEventProcess> message: RequestResponseMessage::Response { response, .. }, .. } => { - if let AliceToBob::Amounts(p) = response { - debug!("Received amounts response"); - self.events.push_back(OutEvent::Amounts(p)); + if let AliceToBob::SwapResponse(swap_response) = response { + debug!("Received swap response"); + self.events.push_back(OutEvent { swap_response }); } } RequestResponseEvent::InboundFailure { error, .. } => {