408: Improve error reporting of failed protocols r=thomaseizinger a=thomaseizinger

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.

417: Bump curve25519-dalek from 3.0.2 to 3.1.0 r=thomaseizinger a=dependabot[bot]

Bumps [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek) from 3.0.2 to 3.1.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/dalek-cryptography/curve25519-dalek/blob/main/CHANGELOG.md">curve25519-dalek's changelog</a>.</em></p>
<blockquote>
<h3>3.1.0</h3>
<ul>
<li>Add support for the Elligator2 encoding for Edwards points.</li>
<li>Add two optional formally-verified field arithmetic backends which
use the Fiat Crypto project's Rust code, which is generated from
proofs of functional correctness checked by the Coq theorem proving
system.</li>
<li>Add support for additional sizes of precomputed tables for basepoint
scalar multiplication.</li>
<li>Fix an unused import.</li>
<li>Add support for using the <code>zeroize</code> traits with all point types.
Note that points are not automatically zeroized on Drop, but that
consumers of <code>curve25519-dalek</code> should call these methods manually
when needed.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="2ea17d554a"><code>2ea17d5</code></a> Update CHANGELOG and README; bump to 3.1.0.</li>
<li><a href="5eca140010"><code>5eca140</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/dalek-cryptography/curve25519-dalek/issues/351">#351</a> from isislovecruft/fix/cleanup-elligator</li>
<li><a href="cecc821f40"><code>cecc821</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/dalek-cryptography/curve25519-dalek/issues/342">#342</a> from huitseeker/fiat4_with_u32</li>
<li><a href="35d4eab431"><code>35d4eab</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/dalek-cryptography/curve25519-dalek/issues/349">#349</a> from huitseeker/modernize_benchmarks</li>
<li><a href="b05feec7aa"><code>b05feec</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/dalek-cryptography/curve25519-dalek/issues/350">#350</a> from isislovecruft/develop</li>
<li><a href="0da8f08d65"><code>0da8f08</code></a> Maintain legacy 3.x support for lookup tables.</li>
<li><a href="ee90202a58"><code>ee90202</code></a> Trivial cleanups to Elligator2 encoding.</li>
<li><a href="d130b5f17e"><code>d130b5f</code></a> [benchmarks-only] Updates the benchmarks</li>
<li><a href="cc0c444fae"><code>cc0c444</code></a> Merge branch 'feature/dynamic-table-sizes' into develop</li>
<li><a href="1491f0db36"><code>1491f0d</code></a> Update copyright years.</li>
<li>Additional commits viewable in <a href="https://github.com/dalek-cryptography/curve25519-dalek/compare/3.0.2...3.1.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=curve25519-dalek&package-manager=cargo&previous-version=3.0.2&new-version=3.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
pull/422/head
bors[bot] 3 years ago committed by GitHub
commit 2e3f052417
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

4
Cargo.lock generated

@ -817,9 +817,9 @@ dependencies = [
[[package]]
name = "curve25519-dalek"
version = "3.0.2"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f627126b946c25a4638eec0ea634fc52506dea98db118aae985118ce7c3d723f"
checksum = "639891fde0dbea823fc3d798a0fdf9d2f9440a42d64a78ab3488b0ca025117b3"
dependencies = [
"byteorder",
"digest 0.9.0",

@ -1,3 +1,5 @@
mod impl_from_rr_event;
pub mod cbor_request_response;
pub mod encrypted_signature;
pub mod quote;

@ -1,20 +1,26 @@
use crate::network::cbor_request_response::CborCodec;
use crate::protocol::{alice, bob};
use libp2p::core::ProtocolName;
use libp2p::request_response::{
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
RequestResponseMessage,
};
use libp2p::PeerId;
use serde::{Deserialize, Serialize};
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)]
pub struct EncryptedSignatureProtocol;
impl ProtocolName for EncryptedSignatureProtocol {
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 type Behaviour = RequestResponse<CborCodec<EncryptedSignatureProtocol, Request, ()>>;
pub type Message = RequestResponseMessage<Request, ()>;
pub fn alice() -> Behaviour {
Behaviour::new(
CborCodec::default(),
@ -43,3 +45,31 @@ pub fn bob() -> Behaviour {
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);

@ -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::network::cbor_request_response::CborCodec;
use crate::protocol::{alice, bob};
use libp2p::core::ProtocolName;
use libp2p::request_response::{
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
RequestResponseMessage,
};
use libp2p::PeerId;
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)]
pub struct BidQuoteProtocol;
impl ProtocolName for BidQuoteProtocol {
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.
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BidQuote {
@ -31,8 +35,6 @@ pub struct BidQuote {
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.
///
/// Alice only supports inbound connections, i.e. handing out quotes.
@ -54,3 +56,29 @@ pub fn bob() -> Behaviour {
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::ExponentialBackoff;
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::protocol::{alice, bob};
use crate::{bitcoin, monero};
use libp2p::core::ProtocolName;
use libp2p::request_response::{
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
RequestResponseMessage,
};
use libp2p::PeerId;
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
/// a spot price.
@ -23,7 +29,7 @@ pub struct SpotPriceProtocol;
impl ProtocolName for SpotPriceProtocol {
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 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.
///
/// Alice only supports inbound connections, i.e. providing spot prices for BTC
@ -65,3 +67,35 @@ pub fn bob() -> Behaviour {
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::network::cbor_request_response::CborCodec;
use crate::protocol::{alice, bob};
use libp2p::core::ProtocolName;
use libp2p::request_response::{
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
RequestResponseMessage,
};
use libp2p::PeerId;
use serde::{Deserialize, Serialize};
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)]
pub struct TransferProofProtocol;
impl ProtocolName for TransferProofProtocol {
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 type Behaviour = RequestResponse<CborCodec<TransferProofProtocol, Request, ()>>;
pub type Message = RequestResponseMessage<Request, ()>;
pub fn alice() -> Behaviour {
Behaviour::new(
CborCodec::default(),
@ -44,3 +46,31 @@ pub fn bob() -> Behaviour {
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::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)]

@ -218,7 +218,6 @@ where
channel
}.boxed());
}
SwarmEvent::Behaviour(OutEvent::ResponseSent) => {}
SwarmEvent::Behaviour(OutEvent::Failure {peer, error}) => {
tracing::error!(%peer, "Communication error: {:#}", error);
}

@ -1,6 +1,6 @@
use crate::network::cbor_request_response::BUF_SIZE;
use crate::protocol::alice::{State0, State3};
use crate::protocol::{Message0, Message2, Message4};
use crate::protocol::{alice, Message0, Message2, Message4};
use anyhow::{Context, Error};
use libp2p::PeerId;
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 anyhow::{anyhow, Error, Result};
use libp2p::core::Multiaddr;
use libp2p::request_response::{
RequestId, RequestResponseEvent, RequestResponseMessage, ResponseChannel,
};
use libp2p::request_response::{RequestId, ResponseChannel};
use libp2p::{NetworkBehaviour, PeerId};
use std::sync::Arc;
use uuid::Uuid;
@ -128,135 +126,27 @@ pub enum OutEvent {
AllRedialAttemptsExhausted {
peer: PeerId,
},
ResponseSent, // Same variant is used for all messages as no processing is done
CommunicationError(Error),
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() -> OutEvent {
OutEvent::CommunicationError(anyhow!("Unexpected request received"))
}
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 }
}
pub fn unexpected_request(peer: PeerId) -> OutEvent {
OutEvent::Failure {
peer,
error: anyhow!("Unexpected request received"),
}
}
}
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,
error
)),
OutboundFailure { peer, error, .. } => OutEvent::CommunicationError(anyhow!(
"protocol with peer {} failed due to {:?}",
pub fn unexpected_response(peer: PeerId) -> OutEvent {
OutEvent::Failure {
peer,
error
)),
}
}
impl From<execution_setup::OutEvent> for OutEvent {
fn from(event: execution_setup::OutEvent) -> Self {
match event {
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");
return;
}
SwarmEvent::Behaviour(OutEvent::ResponseSent) => {
}
SwarmEvent::Behaviour(OutEvent::CommunicationError(error)) => {
tracing::warn!("Communication error: {:#}", error);
SwarmEvent::Behaviour(OutEvent::Failure { peer, error }) => {
tracing::warn!(%peer, "Communication error: {:#}", error);
return;
}
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::protocol::bob::{State0, State2};
use crate::protocol::{Message1, Message3};
use crate::protocol::{bob, Message1, Message3};
use anyhow::{Context, Error, Result};
use libp2p::PeerId;
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…
Cancel
Save