From 9d0b9abde06a67e623520974101b6ad42f874c31 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 18 Mar 2021 16:59:51 +1100 Subject: [PATCH] Introduce helper function for mapping RequestResponseEvent Decomposing a RequestResponseEvent is quite verbose. We can introduce a helper function that does the matching for us and delegates to specific `From` implementations for the protocol specific bits. --- swap/src/network/quote.rs | 3 + swap/src/network/spot_price.rs | 3 + swap/src/protocol/alice/behaviour.rs | 108 ++++++++++++++------------ swap/src/protocol/alice/event_loop.rs | 4 +- swap/src/protocol/bob.rs | 104 ++++++++++++------------- 5 files changed, 114 insertions(+), 108 deletions(-) diff --git a/swap/src/network/quote.rs b/swap/src/network/quote.rs index 4e536a0b..ee938a8a 100644 --- a/swap/src/network/quote.rs +++ b/swap/src/network/quote.rs @@ -3,6 +3,7 @@ use crate::network::request_response::CborCodec; use libp2p::core::ProtocolName; use libp2p::request_response::{ ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent, + RequestResponseMessage, }; use serde::{Deserialize, Serialize}; @@ -17,6 +18,8 @@ impl ProtocolName for BidQuoteProtocol { } } +pub type Message = RequestResponseMessage<(), BidQuote>; + /// Represents a quote for buying XMR. #[derive(Serialize, Deserialize, Debug, Clone)] pub struct BidQuote { diff --git a/swap/src/network/spot_price.rs b/swap/src/network/spot_price.rs index 3fcd9373..1b5aa617 100644 --- a/swap/src/network/spot_price.rs +++ b/swap/src/network/spot_price.rs @@ -3,6 +3,7 @@ use crate::{bitcoin, monero}; use libp2p::core::ProtocolName; use libp2p::request_response::{ ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent, + RequestResponseMessage, }; use serde::{Deserialize, Serialize}; @@ -39,6 +40,8 @@ pub struct Response { pub type Behaviour = RequestResponse>; +pub type Message = RequestResponseMessage; + /// Constructs a new instance of the `spot-price` behaviour to be used by Alice. /// /// Alice only supports inbound connections, i.e. providing spot prices for BTC diff --git a/swap/src/protocol/alice/behaviour.rs b/swap/src/protocol/alice/behaviour.rs index a7825678..63aca002 100644 --- a/swap/src/protocol/alice/behaviour.rs +++ b/swap/src/protocol/alice/behaviour.rs @@ -7,7 +7,7 @@ use crate::protocol::alice::{ use crate::protocol::bob::EncryptedSignature; use crate::{bitcoin, monero}; use anyhow::{anyhow, Error, Result}; -use libp2p::request_response::{RequestResponseMessage, ResponseChannel}; +use libp2p::request_response::{RequestResponseEvent, RequestResponseMessage, ResponseChannel}; use libp2p::{NetworkBehaviour, PeerId}; use rand::{CryptoRng, RngCore}; use tracing::debug; @@ -16,7 +16,7 @@ use tracing::debug; pub enum OutEvent { ConnectionEstablished(PeerId), SpotPriceRequested { - msg: spot_price::Request, + request: spot_price::Request, channel: ResponseChannel, peer: PeerId, }, @@ -51,62 +51,68 @@ impl From for OutEvent { } } +impl OutEvent { + fn unexpected_response(peer: PeerId) -> OutEvent { + OutEvent::Failure { + peer, + error: anyhow!("Unexpected response received"), + } + } +} + +impl From<(PeerId, quote::Message)> for OutEvent { + fn from((peer, message): (PeerId, quote::Message)) -> Self { + match message { + quote::Message::Request { channel, .. } => OutEvent::QuoteRequested { channel, peer }, + quote::Message::Response { .. } => OutEvent::unexpected_response(peer), + } + } +} + +impl From<(PeerId, spot_price::Message)> for OutEvent { + fn from((peer, message): (PeerId, spot_price::Message)) -> Self { + match message { + spot_price::Message::Request { + request, channel, .. + } => OutEvent::SpotPriceRequested { + request, + channel, + peer, + }, + spot_price::Message::Response { .. } => OutEvent::unexpected_response(peer), + } + } +} + impl From for OutEvent { fn from(event: spot_price::OutEvent) -> Self { - match event { - spot_price::OutEvent::Message { - peer, - message: - RequestResponseMessage::Request { - channel, - request: msg, - .. - }, - } => OutEvent::SpotPriceRequested { msg, channel, peer }, - spot_price::OutEvent::Message { - message: RequestResponseMessage::Response { .. }, - peer, - } => OutEvent::Failure { - error: anyhow!("Alice is only meant to hand out spot prices, not receive them"), - peer, - }, - spot_price::OutEvent::ResponseSent { .. } => OutEvent::ResponseSent, - spot_price::OutEvent::InboundFailure { peer, error, .. } => OutEvent::Failure { - error: anyhow!("spot_price protocol failed due to {:?}", error), - peer, - }, - spot_price::OutEvent::OutboundFailure { peer, error, .. } => OutEvent::Failure { - error: anyhow!("spot_price protocol failed due to {:?}", error), - peer, - }, - } + map_rr_event_to_outevent(event) } } impl From for OutEvent { fn from(event: quote::OutEvent) -> Self { - match event { - quote::OutEvent::Message { - peer, - message: RequestResponseMessage::Request { channel, .. }, - } => OutEvent::QuoteRequested { channel, peer }, - quote::OutEvent::Message { - message: RequestResponseMessage::Response { .. }, - peer, - } => OutEvent::Failure { - error: anyhow!("Alice is only meant to hand out quotes, not receive them"), - peer, - }, - quote::OutEvent::ResponseSent { .. } => OutEvent::ResponseSent, - quote::OutEvent::InboundFailure { peer, error, .. } => OutEvent::Failure { - error: anyhow!("quote protocol failed due to {:?}", error), - peer, - }, - quote::OutEvent::OutboundFailure { peer, error, .. } => OutEvent::Failure { - error: anyhow!("quote protocol failed due to {:?}", error), - peer, - }, - } + map_rr_event_to_outevent(event) + } +} + +fn map_rr_event_to_outevent(event: RequestResponseEvent) -> OutEvent +where + OutEvent: From<(PeerId, RequestResponseMessage)>, +{ + use RequestResponseEvent::*; + + match event { + Message { message, peer, .. } => OutEvent::from((peer, message)), + ResponseSent { .. } => OutEvent::ResponseSent, + InboundFailure { peer, error, .. } => OutEvent::Failure { + error: anyhow!("protocol failed due to {:?}", error), + peer, + }, + OutboundFailure { peer, error, .. } => OutEvent::Failure { + error: anyhow!("protocol failed due to {:?}", error), + peer, + }, } } diff --git a/swap/src/protocol/alice/event_loop.rs b/swap/src/protocol/alice/event_loop.rs index c04dbdb8..c5f993dc 100644 --- a/swap/src/protocol/alice/event_loop.rs +++ b/swap/src/protocol/alice/event_loop.rs @@ -105,8 +105,8 @@ where OutEvent::ConnectionEstablished(alice) => { debug!("Connection Established with {}", alice); } - OutEvent::SpotPriceRequested { msg, channel, peer } => { - let btc = msg.btc; + OutEvent::SpotPriceRequested { request, channel, peer } => { + let btc = request.btc; let xmr = match self.handle_spot_price_request(btc, self.monero_wallet.clone()).await { Ok(xmr) => xmr, Err(e) => { diff --git a/swap/src/protocol/bob.rs b/swap/src/protocol/bob.rs index 62103aea..363d4573 100644 --- a/swap/src/protocol/bob.rs +++ b/swap/src/protocol/bob.rs @@ -7,7 +7,7 @@ use crate::{bitcoin, monero}; use anyhow::{anyhow, Error, Result}; pub use execution_setup::{Message0, Message2, Message4}; use libp2p::core::Multiaddr; -use libp2p::request_response::{RequestResponseMessage, ResponseChannel}; +use libp2p::request_response::{RequestResponseEvent, RequestResponseMessage, ResponseChannel}; use libp2p::{NetworkBehaviour, PeerId}; use std::sync::Arc; use tracing::debug; @@ -126,6 +126,30 @@ pub enum OutEvent { CommunicationError(Error), } +impl OutEvent { + fn unexpected_request() -> OutEvent { + OutEvent::CommunicationError(anyhow!("Unexpected request received")) + } +} + +impl From for OutEvent { + fn from(message: quote::Message) -> Self { + match message { + quote::Message::Request { .. } => OutEvent::unexpected_request(), + quote::Message::Response { response, .. } => OutEvent::QuoteReceived(response), + } + } +} + +impl From for OutEvent { + fn from(message: spot_price::Message) -> Self { + match message { + spot_price::Message::Request { .. } => OutEvent::unexpected_request(), + spot_price::Message::Response { response, .. } => OutEvent::SpotPriceReceived(response), + } + } +} + impl From for OutEvent { fn from(event: peer_tracker::OutEvent) -> Self { match event { @@ -138,65 +162,35 @@ impl From for OutEvent { impl From for OutEvent { fn from(event: spot_price::OutEvent) -> Self { - match event { - spot_price::OutEvent::Message { - message: RequestResponseMessage::Response { response, .. }, - .. - } => OutEvent::SpotPriceReceived(response), - spot_price::OutEvent::Message { - message: RequestResponseMessage::Request { .. }, - .. - } => OutEvent::CommunicationError(anyhow!( - "Bob is only meant to receive spot prices, not hand them out" - )), - spot_price::OutEvent::ResponseSent { .. } => OutEvent::ResponseSent, - spot_price::OutEvent::InboundFailure { peer, error, .. } => { - OutEvent::CommunicationError(anyhow!( - "spot_price protocol with peer {} failed due to {:?}", - peer, - error - )) - } - spot_price::OutEvent::OutboundFailure { peer, error, .. } => { - OutEvent::CommunicationError(anyhow!( - "spot_price protocol with peer {} failed due to {:?}", - peer, - error - )) - } - } + map_rr_event_to_outevent(event) } } impl From for OutEvent { fn from(event: quote::OutEvent) -> Self { - match event { - quote::OutEvent::Message { - message: RequestResponseMessage::Response { response, .. }, - .. - } => OutEvent::QuoteReceived(response), - quote::OutEvent::Message { - message: RequestResponseMessage::Request { .. }, - .. - } => OutEvent::CommunicationError(anyhow!( - "Bob is only meant to receive quotes, not hand them out" - )), - quote::OutEvent::ResponseSent { .. } => OutEvent::ResponseSent, - quote::OutEvent::InboundFailure { peer, error, .. } => { - OutEvent::CommunicationError(anyhow!( - "quote protocol with peer {} failed due to {:?}", - peer, - error - )) - } - quote::OutEvent::OutboundFailure { peer, error, .. } => { - OutEvent::CommunicationError(anyhow!( - "quote protocol with peer {} failed due to {:?}", - peer, - error - )) - } - } + map_rr_event_to_outevent(event) + } +} + +fn map_rr_event_to_outevent(event: RequestResponseEvent) -> OutEvent +where + OutEvent: From>, +{ + use RequestResponseEvent::*; + + match event { + Message { message, .. } => OutEvent::from(message), + ResponseSent { .. } => OutEvent::ResponseSent, + InboundFailure { peer, error, .. } => OutEvent::CommunicationError(anyhow!( + "protocol with peer {} failed due to {:?}", + peer, + error + )), + OutboundFailure { peer, error, .. } => OutEvent::CommunicationError(anyhow!( + "protocol with peer {} failed due to {:?}", + peer, + error + )), } }