mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-02-13 05:11:24 -05:00
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:
parent
f0f7288bb6
commit
b417950f99
@ -1,3 +1,5 @@
|
|||||||
|
mod impl_from_rr_event;
|
||||||
|
|
||||||
pub mod cbor_request_response;
|
pub mod cbor_request_response;
|
||||||
pub mod encrypted_signature;
|
pub mod encrypted_signature;
|
||||||
pub mod quote;
|
pub mod quote;
|
||||||
|
@ -1,20 +1,26 @@
|
|||||||
use crate::network::cbor_request_response::CborCodec;
|
use crate::network::cbor_request_response::CborCodec;
|
||||||
|
use crate::protocol::{alice, bob};
|
||||||
use libp2p::core::ProtocolName;
|
use libp2p::core::ProtocolName;
|
||||||
use libp2p::request_response::{
|
use libp2p::request_response::{
|
||||||
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
|
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
|
||||||
RequestResponseMessage,
|
RequestResponseMessage,
|
||||||
};
|
};
|
||||||
|
use libp2p::PeerId;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub type OutEvent = RequestResponseEvent<Request, ()>;
|
const PROTOCOL: &str = "/comit/xmr/btc/encrypted_signature/1.0.0";
|
||||||
|
type OutEvent = RequestResponseEvent<Request, ()>;
|
||||||
|
type Message = RequestResponseMessage<Request, ()>;
|
||||||
|
|
||||||
|
pub type Behaviour = RequestResponse<CborCodec<EncryptedSignatureProtocol, Request, ()>>;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct EncryptedSignatureProtocol;
|
pub struct EncryptedSignatureProtocol;
|
||||||
|
|
||||||
impl ProtocolName for EncryptedSignatureProtocol {
|
impl ProtocolName for EncryptedSignatureProtocol {
|
||||||
fn protocol_name(&self) -> &[u8] {
|
fn protocol_name(&self) -> &[u8] {
|
||||||
b"/comit/xmr/btc/encrypted_signature/1.0.0"
|
PROTOCOL.as_bytes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,10 +30,6 @@ pub struct Request {
|
|||||||
pub tx_redeem_encsig: crate::bitcoin::EncryptedSignature,
|
pub tx_redeem_encsig: crate::bitcoin::EncryptedSignature,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Behaviour = RequestResponse<CborCodec<EncryptedSignatureProtocol, Request, ()>>;
|
|
||||||
|
|
||||||
pub type Message = RequestResponseMessage<Request, ()>;
|
|
||||||
|
|
||||||
pub fn alice() -> Behaviour {
|
pub fn alice() -> Behaviour {
|
||||||
Behaviour::new(
|
Behaviour::new(
|
||||||
CborCodec::default(),
|
CborCodec::default(),
|
||||||
@ -43,3 +45,31 @@ pub fn bob() -> Behaviour {
|
|||||||
RequestResponseConfig::default(),
|
RequestResponseConfig::default(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<(PeerId, Message)> for alice::OutEvent {
|
||||||
|
fn from((peer, message): (PeerId, Message)) -> Self {
|
||||||
|
match message {
|
||||||
|
Message::Request {
|
||||||
|
request, channel, ..
|
||||||
|
} => Self::EncryptedSignatureReceived {
|
||||||
|
msg: Box::new(request),
|
||||||
|
channel,
|
||||||
|
peer,
|
||||||
|
},
|
||||||
|
Message::Response { .. } => Self::unexpected_response(peer),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::impl_from_rr_event!(OutEvent, alice::OutEvent, PROTOCOL);
|
||||||
|
|
||||||
|
impl From<(PeerId, Message)> for bob::OutEvent {
|
||||||
|
fn from((peer, message): (PeerId, Message)) -> Self {
|
||||||
|
match message {
|
||||||
|
Message::Request { .. } => Self::unexpected_request(peer),
|
||||||
|
Message::Response { request_id, .. } => {
|
||||||
|
Self::EncryptedSignatureAcknowledged { id: request_id }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::impl_from_rr_event!(OutEvent, bob::OutEvent, PROTOCOL);
|
||||||
|
66
swap/src/network/impl_from_rr_event.rs
Normal file
66
swap/src/network/impl_from_rr_event.rs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/// Helper macro to map a [`RequestResponseEvent`] to our [`OutEvent`].
|
||||||
|
///
|
||||||
|
/// This is primarily a macro and not a regular function because we use it for
|
||||||
|
/// Alice and Bob and they have different [`OutEvent`]s that just happen to
|
||||||
|
/// share a couple of variants, like `OutEvent::Failure` and `OutEvent::Other`.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! impl_from_rr_event {
|
||||||
|
($protocol_event:ty, $behaviour_out_event:ty, $protocol:ident) => {
|
||||||
|
impl From<$protocol_event> for $behaviour_out_event {
|
||||||
|
fn from(event: $protocol_event) -> Self {
|
||||||
|
use ::libp2p::request_response::RequestResponseEvent::*;
|
||||||
|
use anyhow::anyhow;
|
||||||
|
|
||||||
|
match event {
|
||||||
|
Message { message, peer, .. } => Self::from((peer, message)),
|
||||||
|
ResponseSent { .. } => Self::Other,
|
||||||
|
InboundFailure { peer, error, .. } => {
|
||||||
|
use libp2p::request_response::InboundFailure::*;
|
||||||
|
|
||||||
|
match error {
|
||||||
|
Timeout => {
|
||||||
|
Self::Failure {
|
||||||
|
error: anyhow!("{} failed because of an inbound timeout", $protocol),
|
||||||
|
peer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ConnectionClosed => {
|
||||||
|
Self::Failure {
|
||||||
|
error: anyhow!("{} failed because the connection was closed before a response could be sent", $protocol),
|
||||||
|
peer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnsupportedProtocols => Self::Other, // TODO: Report this and disconnected / ban the peer?
|
||||||
|
ResponseOmission => Self::Other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OutboundFailure { peer, error, .. } => {
|
||||||
|
use libp2p::request_response::OutboundFailure::*;
|
||||||
|
|
||||||
|
match error {
|
||||||
|
Timeout => {
|
||||||
|
Self::Failure {
|
||||||
|
error: anyhow!("{} failed because we did not receive a response within the configured timeout", $protocol),
|
||||||
|
peer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ConnectionClosed => {
|
||||||
|
Self::Failure {
|
||||||
|
error: anyhow!("{} failed because the connection was closed we received a response", $protocol),
|
||||||
|
peer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnsupportedProtocols => Self::Other, // TODO: Report this and disconnected / ban the peer?
|
||||||
|
DialFailure => {
|
||||||
|
Self::Failure {
|
||||||
|
error: anyhow!("{} failed because we failed to dial", $protocol),
|
||||||
|
peer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,25 +1,29 @@
|
|||||||
use crate::bitcoin;
|
use crate::bitcoin;
|
||||||
use crate::network::cbor_request_response::CborCodec;
|
use crate::network::cbor_request_response::CborCodec;
|
||||||
|
use crate::protocol::{alice, bob};
|
||||||
use libp2p::core::ProtocolName;
|
use libp2p::core::ProtocolName;
|
||||||
use libp2p::request_response::{
|
use libp2p::request_response::{
|
||||||
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
|
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
|
||||||
RequestResponseMessage,
|
RequestResponseMessage,
|
||||||
};
|
};
|
||||||
|
use libp2p::PeerId;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub type OutEvent = RequestResponseEvent<(), BidQuote>;
|
const PROTOCOL: &str = "/comit/xmr/btc/bid-quote/1.0.0";
|
||||||
|
type OutEvent = RequestResponseEvent<(), BidQuote>;
|
||||||
|
type Message = RequestResponseMessage<(), BidQuote>;
|
||||||
|
|
||||||
|
pub type Behaviour = RequestResponse<CborCodec<BidQuoteProtocol, (), BidQuote>>;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct BidQuoteProtocol;
|
pub struct BidQuoteProtocol;
|
||||||
|
|
||||||
impl ProtocolName for BidQuoteProtocol {
|
impl ProtocolName for BidQuoteProtocol {
|
||||||
fn protocol_name(&self) -> &[u8] {
|
fn protocol_name(&self) -> &[u8] {
|
||||||
b"/comit/xmr/btc/bid-quote/1.0.0"
|
PROTOCOL.as_bytes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Message = RequestResponseMessage<(), BidQuote>;
|
|
||||||
|
|
||||||
/// Represents a quote for buying XMR.
|
/// Represents a quote for buying XMR.
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct BidQuote {
|
pub struct BidQuote {
|
||||||
@ -31,8 +35,6 @@ pub struct BidQuote {
|
|||||||
pub max_quantity: bitcoin::Amount,
|
pub max_quantity: bitcoin::Amount,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Behaviour = RequestResponse<CborCodec<BidQuoteProtocol, (), BidQuote>>;
|
|
||||||
|
|
||||||
/// Constructs a new instance of the `quote` behaviour to be used by Alice.
|
/// Constructs a new instance of the `quote` behaviour to be used by Alice.
|
||||||
///
|
///
|
||||||
/// Alice only supports inbound connections, i.e. handing out quotes.
|
/// Alice only supports inbound connections, i.e. handing out quotes.
|
||||||
@ -54,3 +56,29 @@ pub fn bob() -> Behaviour {
|
|||||||
RequestResponseConfig::default(),
|
RequestResponseConfig::default(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<(PeerId, Message)> for alice::OutEvent {
|
||||||
|
fn from((peer, message): (PeerId, Message)) -> Self {
|
||||||
|
match message {
|
||||||
|
Message::Request { channel, .. } => Self::QuoteRequested { channel, peer },
|
||||||
|
Message::Response { .. } => Self::unexpected_response(peer),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::impl_from_rr_event!(OutEvent, alice::OutEvent, PROTOCOL);
|
||||||
|
|
||||||
|
impl From<(PeerId, Message)> for bob::OutEvent {
|
||||||
|
fn from((peer, message): (PeerId, Message)) -> Self {
|
||||||
|
match message {
|
||||||
|
Message::Request { .. } => Self::unexpected_request(peer),
|
||||||
|
Message::Response {
|
||||||
|
response,
|
||||||
|
request_id,
|
||||||
|
} => Self::QuoteReceived {
|
||||||
|
id: request_id,
|
||||||
|
response,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::impl_from_rr_event!(OutEvent, bob::OutEvent, PROTOCOL);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::protocol::bob;
|
||||||
use backoff::backoff::Backoff;
|
use backoff::backoff::Backoff;
|
||||||
use backoff::ExponentialBackoff;
|
use backoff::ExponentialBackoff;
|
||||||
use futures::future::FutureExt;
|
use futures::future::FutureExt;
|
||||||
@ -117,3 +118,13 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<OutEvent> for bob::OutEvent {
|
||||||
|
fn from(event: OutEvent) -> Self {
|
||||||
|
match event {
|
||||||
|
OutEvent::AllAttemptsExhausted { peer } => {
|
||||||
|
bob::OutEvent::AllRedialAttemptsExhausted { peer }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
use crate::network::cbor_request_response::CborCodec;
|
use crate::network::cbor_request_response::CborCodec;
|
||||||
|
use crate::protocol::{alice, bob};
|
||||||
use crate::{bitcoin, monero};
|
use crate::{bitcoin, monero};
|
||||||
use libp2p::core::ProtocolName;
|
use libp2p::core::ProtocolName;
|
||||||
use libp2p::request_response::{
|
use libp2p::request_response::{
|
||||||
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
|
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
|
||||||
RequestResponseMessage,
|
RequestResponseMessage,
|
||||||
};
|
};
|
||||||
|
use libp2p::PeerId;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub type OutEvent = RequestResponseEvent<Request, Response>;
|
const PROTOCOL: &str = "/comit/xmr/btc/spot-price/1.0.0";
|
||||||
|
type OutEvent = RequestResponseEvent<Request, Response>;
|
||||||
|
type Message = RequestResponseMessage<Request, Response>;
|
||||||
|
|
||||||
|
pub type Behaviour = RequestResponse<CborCodec<SpotPriceProtocol, Request, Response>>;
|
||||||
|
|
||||||
/// The spot price protocol allows parties to **initiate** a trade by requesting
|
/// The spot price protocol allows parties to **initiate** a trade by requesting
|
||||||
/// a spot price.
|
/// a spot price.
|
||||||
@ -23,7 +29,7 @@ pub struct SpotPriceProtocol;
|
|||||||
|
|
||||||
impl ProtocolName for SpotPriceProtocol {
|
impl ProtocolName for SpotPriceProtocol {
|
||||||
fn protocol_name(&self) -> &[u8] {
|
fn protocol_name(&self) -> &[u8] {
|
||||||
b"/comit/xmr/btc/spot-price/1.0.0"
|
PROTOCOL.as_bytes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,10 +44,6 @@ pub struct Response {
|
|||||||
pub xmr: monero::Amount,
|
pub xmr: monero::Amount,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Behaviour = RequestResponse<CborCodec<SpotPriceProtocol, Request, Response>>;
|
|
||||||
|
|
||||||
pub type Message = RequestResponseMessage<Request, Response>;
|
|
||||||
|
|
||||||
/// Constructs a new instance of the `spot-price` behaviour to be used by Alice.
|
/// 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
|
/// Alice only supports inbound connections, i.e. providing spot prices for BTC
|
||||||
@ -65,3 +67,35 @@ pub fn bob() -> Behaviour {
|
|||||||
RequestResponseConfig::default(),
|
RequestResponseConfig::default(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<(PeerId, Message)> for alice::OutEvent {
|
||||||
|
fn from((peer, message): (PeerId, Message)) -> Self {
|
||||||
|
match message {
|
||||||
|
Message::Request {
|
||||||
|
request, channel, ..
|
||||||
|
} => Self::SpotPriceRequested {
|
||||||
|
request,
|
||||||
|
channel,
|
||||||
|
peer,
|
||||||
|
},
|
||||||
|
Message::Response { .. } => Self::unexpected_response(peer),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::impl_from_rr_event!(OutEvent, alice::OutEvent, PROTOCOL);
|
||||||
|
|
||||||
|
impl From<(PeerId, Message)> for bob::OutEvent {
|
||||||
|
fn from((peer, message): (PeerId, Message)) -> Self {
|
||||||
|
match message {
|
||||||
|
Message::Request { .. } => Self::unexpected_request(peer),
|
||||||
|
Message::Response {
|
||||||
|
response,
|
||||||
|
request_id,
|
||||||
|
} => Self::SpotPriceReceived {
|
||||||
|
id: request_id,
|
||||||
|
response,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::impl_from_rr_event!(OutEvent, bob::OutEvent, PROTOCOL);
|
||||||
|
@ -1,21 +1,27 @@
|
|||||||
use crate::monero;
|
use crate::monero;
|
||||||
use crate::network::cbor_request_response::CborCodec;
|
use crate::network::cbor_request_response::CborCodec;
|
||||||
|
use crate::protocol::{alice, bob};
|
||||||
use libp2p::core::ProtocolName;
|
use libp2p::core::ProtocolName;
|
||||||
use libp2p::request_response::{
|
use libp2p::request_response::{
|
||||||
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
|
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
|
||||||
RequestResponseMessage,
|
RequestResponseMessage,
|
||||||
};
|
};
|
||||||
|
use libp2p::PeerId;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub type OutEvent = RequestResponseEvent<Request, ()>;
|
const PROTOCOL: &str = "/comit/xmr/btc/transfer_proof/1.0.0";
|
||||||
|
type OutEvent = RequestResponseEvent<Request, ()>;
|
||||||
|
type Message = RequestResponseMessage<Request, ()>;
|
||||||
|
|
||||||
|
pub type Behaviour = RequestResponse<CborCodec<TransferProofProtocol, Request, ()>>;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct TransferProofProtocol;
|
pub struct TransferProofProtocol;
|
||||||
|
|
||||||
impl ProtocolName for TransferProofProtocol {
|
impl ProtocolName for TransferProofProtocol {
|
||||||
fn protocol_name(&self) -> &[u8] {
|
fn protocol_name(&self) -> &[u8] {
|
||||||
b"/comit/xmr/btc/transfer_proof/1.0.0"
|
PROTOCOL.as_bytes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,10 +31,6 @@ pub struct Request {
|
|||||||
pub tx_lock_proof: monero::TransferProof,
|
pub tx_lock_proof: monero::TransferProof,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Behaviour = RequestResponse<CborCodec<TransferProofProtocol, Request, ()>>;
|
|
||||||
|
|
||||||
pub type Message = RequestResponseMessage<Request, ()>;
|
|
||||||
|
|
||||||
pub fn alice() -> Behaviour {
|
pub fn alice() -> Behaviour {
|
||||||
Behaviour::new(
|
Behaviour::new(
|
||||||
CborCodec::default(),
|
CborCodec::default(),
|
||||||
@ -44,3 +46,31 @@ pub fn bob() -> Behaviour {
|
|||||||
RequestResponseConfig::default(),
|
RequestResponseConfig::default(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<(PeerId, Message)> for alice::OutEvent {
|
||||||
|
fn from((peer, message): (PeerId, Message)) -> Self {
|
||||||
|
match message {
|
||||||
|
Message::Request { .. } => Self::unexpected_request(peer),
|
||||||
|
Message::Response { request_id, .. } => Self::TransferProofAcknowledged {
|
||||||
|
peer,
|
||||||
|
id: request_id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::impl_from_rr_event!(OutEvent, alice::OutEvent, PROTOCOL);
|
||||||
|
|
||||||
|
impl From<(PeerId, Message)> for bob::OutEvent {
|
||||||
|
fn from((peer, message): (PeerId, Message)) -> Self {
|
||||||
|
match message {
|
||||||
|
Message::Request {
|
||||||
|
request, channel, ..
|
||||||
|
} => Self::TransferProofReceived {
|
||||||
|
msg: Box::new(request),
|
||||||
|
channel,
|
||||||
|
},
|
||||||
|
Message::Response { .. } => Self::unexpected_response(peer),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::impl_from_rr_event!(OutEvent, bob::OutEvent, PROTOCOL);
|
||||||
|
@ -2,9 +2,7 @@ use crate::network::quote::BidQuote;
|
|||||||
use crate::network::{encrypted_signature, quote, spot_price, transfer_proof};
|
use crate::network::{encrypted_signature, quote, spot_price, transfer_proof};
|
||||||
use crate::protocol::alice::{execution_setup, State3};
|
use crate::protocol::alice::{execution_setup, State3};
|
||||||
use anyhow::{anyhow, Error};
|
use anyhow::{anyhow, Error};
|
||||||
use libp2p::request_response::{
|
use libp2p::request_response::{RequestId, ResponseChannel};
|
||||||
RequestId, RequestResponseEvent, RequestResponseMessage, ResponseChannel,
|
|
||||||
};
|
|
||||||
use libp2p::{NetworkBehaviour, PeerId};
|
use libp2p::{NetworkBehaviour, PeerId};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
@ -33,22 +31,24 @@ pub enum OutEvent {
|
|||||||
channel: ResponseChannel<()>,
|
channel: ResponseChannel<()>,
|
||||||
peer: PeerId,
|
peer: PeerId,
|
||||||
},
|
},
|
||||||
ResponseSent, // Same variant is used for all messages as no processing is done
|
|
||||||
Failure {
|
Failure {
|
||||||
peer: PeerId,
|
peer: PeerId,
|
||||||
error: Error,
|
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 {
|
impl OutEvent {
|
||||||
fn unexpected_request(peer: PeerId) -> OutEvent {
|
pub fn unexpected_request(peer: PeerId) -> OutEvent {
|
||||||
OutEvent::Failure {
|
OutEvent::Failure {
|
||||||
peer,
|
peer,
|
||||||
error: anyhow!("Unexpected request received"),
|
error: anyhow!("Unexpected request received"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unexpected_response(peer: PeerId) -> OutEvent {
|
pub fn unexpected_response(peer: PeerId) -> OutEvent {
|
||||||
OutEvent::Failure {
|
OutEvent::Failure {
|
||||||
peer,
|
peer,
|
||||||
error: anyhow!("Unexpected response received"),
|
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.
|
/// A `NetworkBehaviour` that represents an XMR/BTC swap node as Alice.
|
||||||
#[derive(NetworkBehaviour)]
|
#[derive(NetworkBehaviour)]
|
||||||
#[behaviour(out_event = "OutEvent", event_process = false)]
|
#[behaviour(out_event = "OutEvent", event_process = false)]
|
||||||
|
@ -218,7 +218,6 @@ where
|
|||||||
channel
|
channel
|
||||||
}.boxed());
|
}.boxed());
|
||||||
}
|
}
|
||||||
SwarmEvent::Behaviour(OutEvent::ResponseSent) => {}
|
|
||||||
SwarmEvent::Behaviour(OutEvent::Failure {peer, error}) => {
|
SwarmEvent::Behaviour(OutEvent::Failure {peer, error}) => {
|
||||||
tracing::error!(%peer, "Communication error: {:#}", error);
|
tracing::error!(%peer, "Communication error: {:#}", error);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::network::cbor_request_response::BUF_SIZE;
|
use crate::network::cbor_request_response::BUF_SIZE;
|
||||||
use crate::protocol::alice::{State0, State3};
|
use crate::protocol::alice::{State0, State3};
|
||||||
use crate::protocol::{Message0, Message2, Message4};
|
use crate::protocol::{alice, Message0, Message2, Message4};
|
||||||
use anyhow::{Context, Error};
|
use anyhow::{Context, Error};
|
||||||
use libp2p::PeerId;
|
use libp2p::PeerId;
|
||||||
use libp2p_async_await::BehaviourOutEvent;
|
use libp2p_async_await::BehaviourOutEvent;
|
||||||
@ -86,3 +86,20 @@ impl Behaviour {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<OutEvent> for alice::OutEvent {
|
||||||
|
fn from(event: OutEvent) -> Self {
|
||||||
|
match event {
|
||||||
|
OutEvent::Done {
|
||||||
|
bob_peer_id,
|
||||||
|
state3,
|
||||||
|
swap_id,
|
||||||
|
} => Self::ExecutionSetupDone {
|
||||||
|
bob_peer_id,
|
||||||
|
state3: Box::new(state3),
|
||||||
|
swap_id,
|
||||||
|
},
|
||||||
|
OutEvent::Failure { peer, error } => Self::Failure { peer, error },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,9 +6,7 @@ use crate::protocol::bob;
|
|||||||
use crate::{bitcoin, monero};
|
use crate::{bitcoin, monero};
|
||||||
use anyhow::{anyhow, Error, Result};
|
use anyhow::{anyhow, Error, Result};
|
||||||
use libp2p::core::Multiaddr;
|
use libp2p::core::Multiaddr;
|
||||||
use libp2p::request_response::{
|
use libp2p::request_response::{RequestId, ResponseChannel};
|
||||||
RequestId, RequestResponseEvent, RequestResponseMessage, ResponseChannel,
|
|
||||||
};
|
|
||||||
use libp2p::{NetworkBehaviour, PeerId};
|
use libp2p::{NetworkBehaviour, PeerId};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
@ -128,135 +126,27 @@ pub enum OutEvent {
|
|||||||
AllRedialAttemptsExhausted {
|
AllRedialAttemptsExhausted {
|
||||||
peer: PeerId,
|
peer: PeerId,
|
||||||
},
|
},
|
||||||
ResponseSent, // Same variant is used for all messages as no processing is done
|
Failure {
|
||||||
CommunicationError(Error),
|
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 {
|
impl OutEvent {
|
||||||
fn unexpected_request() -> OutEvent {
|
pub fn unexpected_request(peer: PeerId) -> OutEvent {
|
||||||
OutEvent::CommunicationError(anyhow!("Unexpected request received"))
|
OutEvent::Failure {
|
||||||
}
|
|
||||||
|
|
||||||
fn unexpected_response() -> OutEvent {
|
|
||||||
OutEvent::CommunicationError(anyhow!("Unexpected response received"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<quote::Message> for OutEvent {
|
|
||||||
fn from(message: quote::Message) -> Self {
|
|
||||||
match message {
|
|
||||||
quote::Message::Request { .. } => OutEvent::unexpected_request(),
|
|
||||||
quote::Message::Response {
|
|
||||||
response,
|
|
||||||
request_id,
|
|
||||||
} => OutEvent::QuoteReceived {
|
|
||||||
id: request_id,
|
|
||||||
response,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<spot_price::Message> for OutEvent {
|
|
||||||
fn from(message: spot_price::Message) -> Self {
|
|
||||||
match message {
|
|
||||||
spot_price::Message::Request { .. } => OutEvent::unexpected_request(),
|
|
||||||
spot_price::Message::Response {
|
|
||||||
response,
|
|
||||||
request_id,
|
|
||||||
} => OutEvent::SpotPriceReceived {
|
|
||||||
id: request_id,
|
|
||||||
response,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<transfer_proof::Message> for OutEvent {
|
|
||||||
fn from(message: transfer_proof::Message) -> Self {
|
|
||||||
match message {
|
|
||||||
transfer_proof::Message::Request {
|
|
||||||
request, channel, ..
|
|
||||||
} => OutEvent::TransferProofReceived {
|
|
||||||
msg: Box::new(request),
|
|
||||||
channel,
|
|
||||||
},
|
|
||||||
transfer_proof::Message::Response { .. } => OutEvent::unexpected_response(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<encrypted_signature::Message> for OutEvent {
|
|
||||||
fn from(message: encrypted_signature::Message) -> Self {
|
|
||||||
match message {
|
|
||||||
encrypted_signature::Message::Request { .. } => OutEvent::unexpected_request(),
|
|
||||||
encrypted_signature::Message::Response { request_id, .. } => {
|
|
||||||
OutEvent::EncryptedSignatureAcknowledged { id: request_id }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<redial::OutEvent> for OutEvent {
|
|
||||||
fn from(event: redial::OutEvent) -> Self {
|
|
||||||
match event {
|
|
||||||
redial::OutEvent::AllAttemptsExhausted { peer } => {
|
|
||||||
OutEvent::AllRedialAttemptsExhausted { peer }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn map_rr_event_to_outevent<I, O>(event: RequestResponseEvent<I, O>) -> OutEvent
|
|
||||||
where
|
|
||||||
OutEvent: From<RequestResponseMessage<I, O>>,
|
|
||||||
{
|
|
||||||
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,
|
peer,
|
||||||
error
|
error: anyhow!("Unexpected request received"),
|
||||||
)),
|
}
|
||||||
OutboundFailure { peer, error, .. } => OutEvent::CommunicationError(anyhow!(
|
|
||||||
"protocol with peer {} failed due to {:?}",
|
|
||||||
peer,
|
|
||||||
error
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl From<execution_setup::OutEvent> for OutEvent {
|
pub fn unexpected_response(peer: PeerId) -> OutEvent {
|
||||||
fn from(event: execution_setup::OutEvent) -> Self {
|
OutEvent::Failure {
|
||||||
match event {
|
peer,
|
||||||
execution_setup::OutEvent::Done(res) => OutEvent::ExecutionSetupDone(Box::new(res)),
|
error: anyhow!("Unexpected response received"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,11 +151,8 @@ impl EventLoop {
|
|||||||
tracing::error!("Exhausted all re-dial attempts to Alice");
|
tracing::error!("Exhausted all re-dial attempts to Alice");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SwarmEvent::Behaviour(OutEvent::ResponseSent) => {
|
SwarmEvent::Behaviour(OutEvent::Failure { peer, error }) => {
|
||||||
|
tracing::warn!(%peer, "Communication error: {:#}", error);
|
||||||
}
|
|
||||||
SwarmEvent::Behaviour(OutEvent::CommunicationError(error)) => {
|
|
||||||
tracing::warn!("Communication error: {:#}", error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SwarmEvent::ConnectionEstablished { peer_id, endpoint, .. } if peer_id == self.alice_peer_id => {
|
SwarmEvent::ConnectionEstablished { peer_id, endpoint, .. } if peer_id == self.alice_peer_id => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::network::cbor_request_response::BUF_SIZE;
|
use crate::network::cbor_request_response::BUF_SIZE;
|
||||||
use crate::protocol::bob::{State0, State2};
|
use crate::protocol::bob::{State0, State2};
|
||||||
use crate::protocol::{Message1, Message3};
|
use crate::protocol::{bob, Message1, Message3};
|
||||||
use anyhow::{Context, Error, Result};
|
use anyhow::{Context, Error, Result};
|
||||||
use libp2p::PeerId;
|
use libp2p::PeerId;
|
||||||
use libp2p_async_await::BehaviourOutEvent;
|
use libp2p_async_await::BehaviourOutEvent;
|
||||||
@ -85,3 +85,11 @@ impl Behaviour {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<OutEvent> for bob::OutEvent {
|
||||||
|
fn from(event: OutEvent) -> Self {
|
||||||
|
match event {
|
||||||
|
OutEvent::Done(res) => Self::ExecutionSetupDone(Box::new(res)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user