Improve error reporting of failed protocols

Instead of forwarding every error, we deliberately ignore certain
variants that are not worth being printed to the log. In particular,
this concerns "UnsupportedProtocols" and "ResponseOmission".

To make this less verbose we introduce a macro for mapping a
`RequestResponseEvent` to `{alice,bob}::OutEvent`. We use a macro
because those `OutEvent`s are different types and the only other
way of abstracting over them would be to introduce traits that we
implement on both of them.

To make the macro easier to use, we move all the `From` implementations
that convert between the protocol and the more high-level behaviour
into the actual protocol module.
This commit is contained in:
Thomas Eizinger 2021-03-26 16:40:48 +11:00
parent f0f7288bb6
commit b417950f99
No known key found for this signature in database
GPG key ID: 651AC83A6C6C8B96
13 changed files with 276 additions and 279 deletions

View file

@ -2,9 +2,7 @@ use crate::network::quote::BidQuote;
use crate::network::{encrypted_signature, quote, spot_price, transfer_proof};
use crate::protocol::alice::{execution_setup, State3};
use anyhow::{anyhow, Error};
use libp2p::request_response::{
RequestId, RequestResponseEvent, RequestResponseMessage, ResponseChannel,
};
use libp2p::request_response::{RequestId, ResponseChannel};
use libp2p::{NetworkBehaviour, PeerId};
use uuid::Uuid;
@ -33,22 +31,24 @@ pub enum OutEvent {
channel: ResponseChannel<()>,
peer: PeerId,
},
ResponseSent, // Same variant is used for all messages as no processing is done
Failure {
peer: PeerId,
error: Error,
},
/// "Fallback" variant that allows the event mapping code to swallow certain
/// events that we don't want the caller to deal with.
Other,
}
impl OutEvent {
fn unexpected_request(peer: PeerId) -> OutEvent {
pub fn unexpected_request(peer: PeerId) -> OutEvent {
OutEvent::Failure {
peer,
error: anyhow!("Unexpected request received"),
}
}
fn unexpected_response(peer: PeerId) -> OutEvent {
pub fn unexpected_response(peer: PeerId) -> OutEvent {
OutEvent::Failure {
peer,
error: anyhow!("Unexpected response received"),
@ -56,121 +56,6 @@ impl OutEvent {
}
}
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<(PeerId, transfer_proof::Message)> for OutEvent {
fn from((peer, message): (PeerId, transfer_proof::Message)) -> Self {
match message {
transfer_proof::Message::Request { .. } => OutEvent::unexpected_request(peer),
transfer_proof::Message::Response { request_id, .. } => {
OutEvent::TransferProofAcknowledged {
peer,
id: request_id,
}
}
}
}
}
impl From<(PeerId, encrypted_signature::Message)> for OutEvent {
fn from((peer, message): (PeerId, encrypted_signature::Message)) -> Self {
match message {
encrypted_signature::Message::Request {
request, channel, ..
} => OutEvent::EncryptedSignatureReceived {
msg: Box::new(request),
channel,
peer,
},
encrypted_signature::Message::Response { .. } => OutEvent::unexpected_response(peer),
}
}
}
impl From<spot_price::OutEvent> for OutEvent {
fn from(event: spot_price::OutEvent) -> Self {
map_rr_event_to_outevent(event)
}
}
impl From<quote::OutEvent> for OutEvent {
fn from(event: quote::OutEvent) -> Self {
map_rr_event_to_outevent(event)
}
}
impl From<transfer_proof::OutEvent> for OutEvent {
fn from(event: transfer_proof::OutEvent) -> Self {
map_rr_event_to_outevent(event)
}
}
impl From<encrypted_signature::OutEvent> for OutEvent {
fn from(event: encrypted_signature::OutEvent) -> Self {
map_rr_event_to_outevent(event)
}
}
fn map_rr_event_to_outevent<I, O>(event: RequestResponseEvent<I, O>) -> OutEvent
where
OutEvent: From<(PeerId, RequestResponseMessage<I, O>)>,
{
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,
},
}
}
impl From<execution_setup::OutEvent> for OutEvent {
fn from(event: execution_setup::OutEvent) -> Self {
use crate::protocol::alice::execution_setup::OutEvent::*;
match event {
Done {
bob_peer_id,
swap_id,
state3,
} => OutEvent::ExecutionSetupDone {
bob_peer_id,
swap_id,
state3: Box::new(state3),
},
Failure { peer, error } => OutEvent::Failure { peer, error },
}
}
}
/// A `NetworkBehaviour` that represents an XMR/BTC swap node as Alice.
#[derive(NetworkBehaviour)]
#[behaviour(out_event = "OutEvent", event_process = false)]