diff --git a/swap/src/protocol/alice/behaviour.rs b/swap/src/protocol/alice/behaviour.rs index 29465067..0669c918 100644 --- a/swap/src/protocol/alice/behaviour.rs +++ b/swap/src/protocol/alice/behaviour.rs @@ -1,13 +1,9 @@ -use crate::env::Config; use crate::network::quote::BidQuote; use crate::network::{encrypted_signature, quote, spot_price, transfer_proof}; -use crate::protocol::alice::{execution_setup, State0, State3}; -use crate::{bitcoin, monero}; -use anyhow::{anyhow, Error, Result}; +use crate::protocol::alice::{execution_setup, State3}; +use anyhow::{anyhow, Error}; use libp2p::request_response::{RequestResponseEvent, RequestResponseMessage, ResponseChannel}; use libp2p::{NetworkBehaviour, PeerId}; -use rand::{CryptoRng, RngCore}; -use tracing::debug; #[derive(Debug)] pub enum OutEvent { @@ -166,11 +162,11 @@ impl From for OutEvent { #[behaviour(out_event = "OutEvent", event_process = false)] #[allow(missing_debug_implementations)] pub struct Behaviour { - quote: quote::Behaviour, - spot_price: spot_price::Behaviour, - execution_setup: execution_setup::Behaviour, - transfer_proof: transfer_proof::Behaviour, - encrypted_signature: encrypted_signature::Behaviour, + pub quote: quote::Behaviour, + pub spot_price: spot_price::Behaviour, + pub execution_setup: execution_setup::Behaviour, + pub transfer_proof: transfer_proof::Behaviour, + pub encrypted_signature: encrypted_signature::Behaviour, } impl Default for Behaviour { @@ -184,74 +180,3 @@ impl Default for Behaviour { } } } - -impl Behaviour { - pub fn send_quote( - &mut self, - channel: ResponseChannel, - response: BidQuote, - ) -> Result<()> { - self.quote - .send_response(channel, response) - .map_err(|_| anyhow!("Failed to respond with quote"))?; - - Ok(()) - } - - pub fn send_spot_price( - &mut self, - channel: ResponseChannel, - response: spot_price::Response, - ) -> Result<()> { - self.spot_price - .send_response(channel, response) - .map_err(|_| anyhow!("Failed to respond with spot price"))?; - - Ok(()) - } - - pub async fn start_execution_setup( - &mut self, - peer: PeerId, - btc: bitcoin::Amount, - xmr: monero::Amount, - env_config: Config, - bitcoin_wallet: &bitcoin::Wallet, - rng: &mut (impl RngCore + CryptoRng), - ) -> Result<()> { - let state0 = State0::new(btc, xmr, env_config, bitcoin_wallet, rng).await?; - - tracing::info!( - %peer, - "Starting execution setup to sell {} for {}", - xmr, btc, - ); - - self.execution_setup.run(peer, state0); - - Ok(()) - } - - /// Send Transfer Proof to Bob. - /// - /// Fails and returns the transfer proof if we are currently not connected - /// to this peer. - pub fn send_transfer_proof( - &mut self, - bob: PeerId, - msg: transfer_proof::Request, - ) -> Result<(), transfer_proof::Request> { - if !self.transfer_proof.is_connected(&bob) { - return Err(msg); - } - self.transfer_proof.send_request(&bob, msg); - - debug!("Sending Transfer Proof"); - - Ok(()) - } - - pub fn send_encrypted_signature_ack(&mut self, channel: ResponseChannel<()>) { - let _ = self.encrypted_signature.send_response(channel, ()); - } -} diff --git a/swap/src/protocol/alice/event_loop.rs b/swap/src/protocol/alice/event_loop.rs index 2ed686fe..60537f6e 100644 --- a/swap/src/protocol/alice/event_loop.rs +++ b/swap/src/protocol/alice/event_loop.rs @@ -4,7 +4,7 @@ use crate::env::Config; use crate::monero::BalanceTooLow; use crate::network::quote::BidQuote; use crate::network::{encrypted_signature, spot_price, transfer_proof}; -use crate::protocol::alice::{AliceState, Behaviour, OutEvent, State3, Swap}; +use crate::protocol::alice::{AliceState, Behaviour, OutEvent, State0, State3, Swap}; use crate::{bitcoin, kraken, monero}; use anyhow::{bail, Context, Result}; use futures::future; @@ -135,21 +135,24 @@ where } }; - match self.swarm.send_spot_price(channel, spot_price::Response { xmr }) { + match self.swarm.spot_price.send_response(channel, spot_price::Response { xmr }) { Ok(_) => {}, - Err(e) => { + Err(_) => { // if we can't respond, the peer probably just disconnected so it is not a huge deal, only log this on debug - debug!(%peer, "failed to respond with spot price: {:#}", e); + debug!(%peer, "failed to respond with spot price"); continue; } } - match self.swarm.start_execution_setup(peer, btc, xmr, self.env_config, self.bitcoin_wallet.as_ref(), &mut OsRng).await { - Ok(_) => {}, + let state0 = match State0::new(btc, xmr, self.env_config, self.bitcoin_wallet.as_ref(), &mut OsRng).await { + Ok(state) => state, Err(e) => { - tracing::warn!(%peer, "failed to start execution setup: {:#}", e); + tracing::warn!(%peer, "failed to make State0 for execution setup: {:#}", e); + continue; } - } + }; + + self.swarm.execution_setup.run(peer, state0); } SwarmEvent::Behaviour(OutEvent::QuoteRequested { channel, peer }) => { let quote = match self.make_quote(self.max_buy).await { @@ -160,13 +163,8 @@ where } }; - match self.swarm.send_quote(channel, quote) { - Ok(_) => {}, - Err(e) => { - // if we can't respond, the peer probably just disconnected so it is not a huge deal, only log this on debug - debug!(%peer, "failed to respond with quote: {:#}", e); - continue; - } + if self.swarm.quote.send_response(channel, quote).is_err() { + debug!(%peer, "failed to respond with quote"); } } SwarmEvent::Behaviour(OutEvent::ExecutionSetupDone{bob_peer_id, state3}) => { @@ -186,7 +184,7 @@ where } } - self.swarm.send_encrypted_signature_ack(channel); + let _ = self.swarm.encrypted_signature.send_response(channel, ()); } SwarmEvent::Behaviour(OutEvent::ResponseSent) => {} SwarmEvent::Behaviour(OutEvent::Failure {peer, error}) => { @@ -198,9 +196,7 @@ where if let Some(transfer_proof) = self.buffered_transfer_proofs.remove(&peer) { tracing::debug!(%peer, "Found buffered transfer proof for peer"); - self.swarm - .send_transfer_proof(peer, transfer_proof) - .expect("must be able to send transfer proof after connection was established"); + self.swarm.transfer_proof.send_request(&peer, transfer_proof); } } SwarmEvent::IncomingConnectionError { send_back_addr: address, error, .. } => { @@ -222,12 +218,13 @@ where next_transfer_proof = self.send_transfer_proof.next() => { match next_transfer_proof { Some(Ok((peer, transfer_proof))) => { - let result = self.swarm.send_transfer_proof(peer, transfer_proof); - - if let Err(transfer_proof) = result { + if !self.swarm.transfer_proof.is_connected(&peer) { tracing::warn!(%peer, "No active connection to peer, buffering transfer proof"); self.buffered_transfer_proofs.insert(peer, transfer_proof); + continue; } + + self.swarm.transfer_proof.send_request(&peer, transfer_proof); }, Some(Err(_)) => { tracing::debug!("A swap stopped without sending a transfer proof"); diff --git a/swap/src/protocol/bob.rs b/swap/src/protocol/bob.rs index 3a87b8db..f9ea8142 100644 --- a/swap/src/protocol/bob.rs +++ b/swap/src/protocol/bob.rs @@ -8,7 +8,6 @@ use libp2p::core::Multiaddr; use libp2p::request_response::{RequestResponseEvent, RequestResponseMessage, ResponseChannel}; use libp2p::{NetworkBehaviour, PeerId}; use std::sync::Arc; -use tracing::debug; use uuid::Uuid; pub use self::cancel::cancel; @@ -232,11 +231,11 @@ impl From for OutEvent { #[behaviour(out_event = "OutEvent", event_process = false)] #[allow(missing_debug_implementations)] pub struct Behaviour { - quote: quote::Behaviour, - spot_price: spot_price::Behaviour, - execution_setup: execution_setup::Behaviour, - transfer_proof: transfer_proof::Behaviour, - encrypted_signature: encrypted_signature::Behaviour, + pub quote: quote::Behaviour, + pub spot_price: spot_price::Behaviour, + pub execution_setup: execution_setup::Behaviour, + pub transfer_proof: transfer_proof::Behaviour, + pub encrypted_signature: encrypted_signature::Behaviour, } impl Default for Behaviour { @@ -252,34 +251,6 @@ impl Default for Behaviour { } impl Behaviour { - pub fn request_quote(&mut self, alice: PeerId) { - let _ = self.quote.send_request(&alice, ()); - } - - pub fn request_spot_price(&mut self, alice: PeerId, request: spot_price::Request) { - let _ = self.spot_price.send_request(&alice, request); - } - - pub fn start_execution_setup( - &mut self, - alice_peer_id: PeerId, - state0: State0, - bitcoin_wallet: Arc, - ) { - self.execution_setup - .run(alice_peer_id, state0, bitcoin_wallet); - } - - pub fn send_encrypted_signature( - &mut self, - alice: PeerId, - tx_redeem_encsig: bitcoin::EncryptedSignature, - ) { - let msg = encrypted_signature::Request { tx_redeem_encsig }; - self.encrypted_signature.send_request(&alice, msg); - debug!("Encrypted signature sent"); - } - /// Add a known address for the given peer pub fn add_address(&mut self, peer_id: PeerId, address: Multiaddr) { self.quote.add_address(&peer_id, address.clone()); diff --git a/swap/src/protocol/bob/event_loop.rs b/swap/src/protocol/bob/event_loop.rs index ed6d60cb..b6e71a64 100644 --- a/swap/src/protocol/bob/event_loop.rs +++ b/swap/src/protocol/bob/event_loop.rs @@ -1,6 +1,6 @@ use crate::bitcoin::EncryptedSignature; use crate::network::quote::BidQuote; -use crate::network::{spot_price, transfer_proof}; +use crate::network::{encrypted_signature, spot_price, transfer_proof}; use crate::protocol::bob::{Behaviour, OutEvent, State0, State2}; use crate::{bitcoin, monero}; use anyhow::{anyhow, Result}; @@ -21,7 +21,7 @@ pub struct EventLoop { start_execution_setup: Receiver, done_execution_setup: Sender>, recv_transfer_proof: Sender, - send_encrypted_signature: Receiver, + send_encrypted_signature: Receiver, request_quote: Receiver<()>, recv_quote: Sender, } @@ -135,24 +135,24 @@ impl EventLoop { }, spot_price_request = self.request_spot_price.recv().fuse() => { if let Some(request) = spot_price_request { - self.swarm.request_spot_price(self.alice_peer_id, request); + self.swarm.spot_price.send_request(&self.alice_peer_id, request); } }, quote_request = self.request_quote.recv().fuse() => { if quote_request.is_some() { - self.swarm.request_quote(self.alice_peer_id); + self.swarm.quote.send_request(&self.alice_peer_id, ()); } }, option = self.start_execution_setup.recv().fuse() => { if let Some(state0) = option { let _ = self .swarm - .start_execution_setup(self.alice_peer_id, state0, self.bitcoin_wallet.clone()); + .execution_setup.run(self.alice_peer_id, state0, self.bitcoin_wallet.clone()); } }, encrypted_signature = self.send_encrypted_signature.recv().fuse() => { if let Some(tx_redeem_encsig) = encrypted_signature { - self.swarm.send_encrypted_signature(self.alice_peer_id, tx_redeem_encsig); + self.swarm.encrypted_signature.send_request(&self.alice_peer_id, tx_redeem_encsig); } } } @@ -165,7 +165,7 @@ pub struct EventLoopHandle { start_execution_setup: Sender, done_execution_setup: Receiver>, recv_transfer_proof: Receiver, - send_encrypted_signature: Sender, + send_encrypted_signature: Sender, request_spot_price: Sender, recv_spot_price: Receiver, request_quote: Sender<()>, @@ -220,7 +220,9 @@ impl EventLoopHandle { &mut self, tx_redeem_encsig: EncryptedSignature, ) -> Result<()> { - self.send_encrypted_signature.send(tx_redeem_encsig).await?; + self.send_encrypted_signature + .send(encrypted_signature::Request { tx_redeem_encsig }) + .await?; Ok(()) }