Unify encrypted-signature protocol to a single one

This commit is contained in:
Thomas Eizinger 2021-03-18 17:24:06 +11:00
parent 9979cc9f1f
commit 1de0b39b32
No known key found for this signature in database
GPG Key ID: 651AC83A6C6C8B96
10 changed files with 99 additions and 241 deletions

View File

@ -1,3 +1,4 @@
pub mod encrypted_signature;
pub mod peer_tracker; pub mod peer_tracker;
pub mod quote; pub mod quote;
pub mod request_response; pub mod request_response;

View File

@ -0,0 +1,43 @@
use crate::network::request_response::CborCodec;
use libp2p::core::ProtocolName;
use libp2p::request_response::{
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
RequestResponseMessage,
};
use serde::{Deserialize, Serialize};
pub type OutEvent = RequestResponseEvent<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"
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
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(),
vec![(EncryptedSignatureProtocol, ProtocolSupport::Inbound)],
RequestResponseConfig::default(),
)
}
pub fn bob() -> Behaviour {
Behaviour::new(
CborCodec::default(),
vec![(EncryptedSignatureProtocol, ProtocolSupport::Outbound)],
RequestResponseConfig::default(),
)
}

View File

@ -9,21 +9,9 @@ use std::fmt::Debug;
use std::io; use std::io;
use std::marker::PhantomData; use std::marker::PhantomData;
/// Time to wait for a response back once we send a request.
pub const TIMEOUT: u64 = 3600; // One hour.
/// Message receive buffer. /// Message receive buffer.
pub const BUF_SIZE: usize = 1024 * 1024; pub const BUF_SIZE: usize = 1024 * 1024;
#[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"
}
}
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct CborCodec<P, Req, Res> { pub struct CborCodec<P, Req, Res> {
phantom: PhantomData<(P, Req, Res)>, phantom: PhantomData<(P, Req, Res)>,

View File

@ -14,7 +14,6 @@ pub use self::swap::{run, run_until};
pub use execution_setup::Message3; pub use execution_setup::Message3;
mod behaviour; mod behaviour;
mod encrypted_signature;
pub mod event_loop; pub mod event_loop;
mod execution_setup; mod execution_setup;
pub mod state; pub mod state;

View File

@ -1,8 +1,7 @@
use crate::env::Config; use crate::env::Config;
use crate::network::quote::BidQuote; use crate::network::quote::BidQuote;
use crate::network::{peer_tracker, quote, spot_price, transfer_proof}; use crate::network::{encrypted_signature, peer_tracker, quote, spot_price, transfer_proof};
use crate::protocol::alice::{encrypted_signature, execution_setup, State0, State3}; use crate::protocol::alice::{execution_setup, State0, State3};
use crate::protocol::bob::EncryptedSignature;
use crate::{bitcoin, monero}; use crate::{bitcoin, monero};
use anyhow::{anyhow, Error, Result}; use anyhow::{anyhow, Error, Result};
use libp2p::request_response::{RequestResponseEvent, RequestResponseMessage, ResponseChannel}; use libp2p::request_response::{RequestResponseEvent, RequestResponseMessage, ResponseChannel};
@ -27,8 +26,8 @@ pub enum OutEvent {
state3: Box<State3>, state3: Box<State3>,
}, },
TransferProofAcknowledged(PeerId), TransferProofAcknowledged(PeerId),
EncryptedSignature { EncryptedSignatureReceived {
msg: Box<EncryptedSignature>, msg: Box<encrypted_signature::Request>,
channel: ResponseChannel<()>, channel: ResponseChannel<()>,
peer: PeerId, peer: PeerId,
}, },
@ -98,6 +97,21 @@ impl From<(PeerId, transfer_proof::Message)> for OutEvent {
} }
} }
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 { impl From<spot_price::OutEvent> for OutEvent {
fn from(event: spot_price::OutEvent) -> Self { fn from(event: spot_price::OutEvent) -> Self {
map_rr_event_to_outevent(event) map_rr_event_to_outevent(event)
@ -116,6 +130,12 @@ impl From<transfer_proof::OutEvent> for OutEvent {
} }
} }
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 fn map_rr_event_to_outevent<I, O>(event: RequestResponseEvent<I, O>) -> OutEvent
where where
OutEvent: From<(PeerId, RequestResponseMessage<I, O>)>, OutEvent: From<(PeerId, RequestResponseMessage<I, O>)>,
@ -152,24 +172,6 @@ impl From<execution_setup::OutEvent> for OutEvent {
} }
} }
impl From<encrypted_signature::OutEvent> for OutEvent {
fn from(event: encrypted_signature::OutEvent) -> Self {
use crate::protocol::alice::encrypted_signature::OutEvent::*;
match event {
MsgReceived { msg, channel, peer } => OutEvent::EncryptedSignature {
msg: Box::new(msg),
channel,
peer,
},
AckSent => OutEvent::ResponseSent,
Failure { peer, error } => OutEvent::Failure {
peer,
error: error.context("Failure with Encrypted Signature"),
},
}
}
}
/// 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)]
@ -191,7 +193,7 @@ impl Default for Behaviour {
spot_price: spot_price::alice(), spot_price: spot_price::alice(),
execution_setup: Default::default(), execution_setup: Default::default(),
transfer_proof: transfer_proof::alice(), transfer_proof: transfer_proof::alice(),
encrypted_signature: Default::default(), encrypted_signature: encrypted_signature::alice(),
} }
} }
} }
@ -249,7 +251,7 @@ impl Behaviour {
debug!("Sent Transfer Proof"); debug!("Sent Transfer Proof");
} }
pub fn send_encrypted_signature_ack(&mut self, channel: ResponseChannel<()>) -> Result<()> { pub fn send_encrypted_signature_ack(&mut self, channel: ResponseChannel<()>) {
self.encrypted_signature.send_ack(channel) let _ = self.encrypted_signature.send_response(channel, ());
} }
} }

View File

@ -1,95 +0,0 @@
use crate::network::request_response::{CborCodec, EncryptedSignatureProtocol, TIMEOUT};
use crate::protocol::bob::EncryptedSignature;
use anyhow::{anyhow, Error, Result};
use libp2p::request_response::{
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
RequestResponseMessage, ResponseChannel,
};
use libp2p::{NetworkBehaviour, PeerId};
use std::time::Duration;
use tracing::debug;
#[derive(Debug)]
pub enum OutEvent {
MsgReceived {
msg: EncryptedSignature,
channel: ResponseChannel<()>,
peer: PeerId,
},
AckSent,
Failure {
peer: PeerId,
error: Error,
},
}
/// A `NetworkBehaviour` that represents receiving the Bitcoin encrypted
/// signature from Bob.
#[derive(NetworkBehaviour)]
#[behaviour(out_event = "OutEvent", event_process = false)]
#[allow(missing_debug_implementations)]
pub struct Behaviour {
rr: RequestResponse<CborCodec<EncryptedSignatureProtocol, EncryptedSignature, ()>>,
}
impl Behaviour {
pub fn send_ack(&mut self, channel: ResponseChannel<()>) -> Result<()> {
self.rr
.send_response(channel, ())
.map_err(|err| anyhow!("Failed to ack encrypted signature: {:?}", err))
}
}
impl Default for Behaviour {
fn default() -> Self {
let timeout = Duration::from_secs(TIMEOUT);
let mut config = RequestResponseConfig::default();
config.set_request_timeout(timeout);
Self {
rr: RequestResponse::new(
CborCodec::default(),
vec![(EncryptedSignatureProtocol, ProtocolSupport::Inbound)],
config,
),
}
}
}
impl From<RequestResponseEvent<EncryptedSignature, ()>> for OutEvent {
fn from(event: RequestResponseEvent<EncryptedSignature, ()>) -> Self {
match event {
RequestResponseEvent::Message {
peer,
message:
RequestResponseMessage::Request {
request, channel, ..
},
..
} => {
debug!("Received encrypted signature from {}", peer);
OutEvent::MsgReceived {
msg: request,
channel,
peer,
}
}
RequestResponseEvent::Message {
message: RequestResponseMessage::Response { .. },
peer,
} => OutEvent::Failure {
peer,
error: anyhow!("Alice should not get a Response"),
},
RequestResponseEvent::InboundFailure { error, peer, .. } => OutEvent::Failure {
peer,
error: anyhow!("Inbound failure: {:?}", error),
},
RequestResponseEvent::OutboundFailure { error, peer, .. } => OutEvent::Failure {
peer,
error: anyhow!("Outbound failure: {:?}", error),
},
RequestResponseEvent::ResponseSent { .. } => OutEvent::AckSent,
}
}
}

View File

@ -3,9 +3,8 @@ use crate::database::Database;
use crate::env::Config; use crate::env::Config;
use crate::monero::BalanceTooLow; use crate::monero::BalanceTooLow;
use crate::network::quote::BidQuote; use crate::network::quote::BidQuote;
use crate::network::{spot_price, transfer_proof, transport, TokioExecutor}; use crate::network::{encrypted_signature, spot_price, transfer_proof, transport, TokioExecutor};
use crate::protocol::alice::{AliceState, Behaviour, OutEvent, State3, Swap}; use crate::protocol::alice::{AliceState, Behaviour, OutEvent, State3, Swap};
use crate::protocol::bob::EncryptedSignature;
use crate::seed::Seed; use crate::seed::Seed;
use crate::{bitcoin, kraken, monero}; use crate::{bitcoin, kraken, monero};
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
@ -34,7 +33,7 @@ pub struct EventLoop<RS> {
max_buy: bitcoin::Amount, max_buy: bitcoin::Amount,
/// Stores a sender per peer for incoming [`EncryptedSignature`]s. /// Stores a sender per peer for incoming [`EncryptedSignature`]s.
recv_encrypted_signature: HashMap<PeerId, oneshot::Sender<EncryptedSignature>>, recv_encrypted_signature: HashMap<PeerId, oneshot::Sender<encrypted_signature::Request>>,
/// Stores a list of futures, waiting for transfer proof which will be sent /// Stores a list of futures, waiting for transfer proof which will be sent
/// to the given peer. /// to the given peer.
send_transfer_proof: send_transfer_proof:
@ -156,7 +155,7 @@ where
OutEvent::TransferProofAcknowledged(peer) => { OutEvent::TransferProofAcknowledged(peer) => {
trace!(%peer, "Bob acknowledged transfer proof"); trace!(%peer, "Bob acknowledged transfer proof");
} }
OutEvent::EncryptedSignature{ msg, channel, peer } => { OutEvent::EncryptedSignatureReceived{ msg, channel, peer } => {
match self.recv_encrypted_signature.remove(&peer) { match self.recv_encrypted_signature.remove(&peer) {
Some(sender) => { Some(sender) => {
// this failing just means the receiver is no longer interested ... // this failing just means the receiver is no longer interested ...
@ -167,9 +166,7 @@ where
} }
} }
if let Err(error) = self.swarm.send_encrypted_signature_ack(channel) { self.swarm.send_encrypted_signature_ack(channel);
error!("Failed to send Encrypted Signature ack: {:?}", error);
}
} }
OutEvent::ResponseSent => {} OutEvent::ResponseSent => {}
OutEvent::Failure {peer, error} => { OutEvent::Failure {peer, error} => {
@ -307,7 +304,7 @@ impl LatestRate for kraken::RateUpdateStream {
#[derive(Debug)] #[derive(Debug)]
pub struct EventLoopHandle { pub struct EventLoopHandle {
recv_encrypted_signature: Option<oneshot::Receiver<EncryptedSignature>>, recv_encrypted_signature: Option<oneshot::Receiver<encrypted_signature::Request>>,
send_transfer_proof: Option<oneshot::Sender<transfer_proof::Request>>, send_transfer_proof: Option<oneshot::Sender<transfer_proof::Request>>,
} }

View File

@ -1,6 +1,6 @@
use crate::database::Database; use crate::database::Database;
use crate::env::Config; use crate::env::Config;
use crate::network::{peer_tracker, spot_price}; use crate::network::{encrypted_signature, peer_tracker, spot_price};
use crate::protocol::bob; use crate::protocol::bob;
use crate::{bitcoin, monero}; use crate::{bitcoin, monero};
use anyhow::{anyhow, Error, Result}; use anyhow::{anyhow, Error, Result};
@ -13,7 +13,6 @@ use tracing::debug;
use uuid::Uuid; use uuid::Uuid;
pub use self::cancel::cancel; pub use self::cancel::cancel;
pub use self::encrypted_signature::EncryptedSignature;
pub use self::event_loop::{EventLoop, EventLoopHandle}; pub use self::event_loop::{EventLoop, EventLoopHandle};
pub use self::refund::refund; pub use self::refund::refund;
pub use self::state::*; pub use self::state::*;
@ -22,7 +21,6 @@ use crate::network::quote::BidQuote;
use crate::network::{quote, transfer_proof}; use crate::network::{quote, transfer_proof};
pub mod cancel; pub mod cancel;
mod encrypted_signature;
pub mod event_loop; pub mod event_loop;
mod execution_setup; mod execution_setup;
pub mod refund; pub mod refund;
@ -166,6 +164,17 @@ impl From<transfer_proof::Message> for OutEvent {
} }
} }
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 { .. } => {
OutEvent::EncryptedSignatureAcknowledged
}
}
}
}
impl From<peer_tracker::OutEvent> for OutEvent { impl From<peer_tracker::OutEvent> for OutEvent {
fn from(event: peer_tracker::OutEvent) -> Self { fn from(event: peer_tracker::OutEvent) -> Self {
match event { match event {
@ -194,6 +203,12 @@ impl From<transfer_proof::OutEvent> for OutEvent {
} }
} }
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 fn map_rr_event_to_outevent<I, O>(event: RequestResponseEvent<I, O>) -> OutEvent
where where
OutEvent: From<RequestResponseMessage<I, O>>, OutEvent: From<RequestResponseMessage<I, O>>,
@ -224,18 +239,6 @@ impl From<execution_setup::OutEvent> for OutEvent {
} }
} }
impl From<encrypted_signature::OutEvent> for OutEvent {
fn from(event: encrypted_signature::OutEvent) -> Self {
use encrypted_signature::OutEvent::*;
match event {
Acknowledged => OutEvent::EncryptedSignatureAcknowledged,
Failure(err) => {
OutEvent::CommunicationError(err.context("Failure with Encrypted Signature"))
}
}
}
}
/// A `NetworkBehaviour` that represents an XMR/BTC swap node as Bob. /// A `NetworkBehaviour` that represents an XMR/BTC swap node as Bob.
#[derive(NetworkBehaviour)] #[derive(NetworkBehaviour)]
#[behaviour(out_event = "OutEvent", event_process = false)] #[behaviour(out_event = "OutEvent", event_process = false)]
@ -257,7 +260,7 @@ impl Default for Behaviour {
spot_price: spot_price::bob(), spot_price: spot_price::bob(),
execution_setup: Default::default(), execution_setup: Default::default(),
transfer_proof: transfer_proof::bob(), transfer_proof: transfer_proof::bob(),
encrypted_signature: Default::default(), encrypted_signature: encrypted_signature::bob(),
} }
} }
} }
@ -286,8 +289,8 @@ impl Behaviour {
alice: PeerId, alice: PeerId,
tx_redeem_encsig: bitcoin::EncryptedSignature, tx_redeem_encsig: bitcoin::EncryptedSignature,
) { ) {
let msg = EncryptedSignature { tx_redeem_encsig }; let msg = encrypted_signature::Request { tx_redeem_encsig };
self.encrypted_signature.send(alice, msg); self.encrypted_signature.send_request(&alice, msg);
debug!("Encrypted signature sent"); debug!("Encrypted signature sent");
} }

View File

@ -1,74 +0,0 @@
use crate::network::request_response::{CborCodec, EncryptedSignatureProtocol, TIMEOUT};
use anyhow::{anyhow, Error};
use libp2p::request_response::{
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
RequestResponseMessage,
};
use libp2p::{NetworkBehaviour, PeerId};
use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct EncryptedSignature {
pub tx_redeem_encsig: crate::bitcoin::EncryptedSignature,
}
#[derive(Debug)]
pub enum OutEvent {
Acknowledged,
Failure(Error),
}
/// A `NetworkBehaviour` that represents sending encrypted signature to Alice.
#[derive(NetworkBehaviour)]
#[behaviour(out_event = "OutEvent", event_process = false)]
#[allow(missing_debug_implementations)]
pub struct Behaviour {
rr: RequestResponse<CborCodec<EncryptedSignatureProtocol, EncryptedSignature, ()>>,
}
impl Behaviour {
pub fn send(&mut self, alice: PeerId, msg: EncryptedSignature) {
let _id = self.rr.send_request(&alice, msg);
}
}
impl Default for Behaviour {
fn default() -> Self {
let timeout = Duration::from_secs(TIMEOUT);
let mut config = RequestResponseConfig::default();
config.set_request_timeout(timeout);
Self {
rr: RequestResponse::new(
CborCodec::default(),
vec![(EncryptedSignatureProtocol, ProtocolSupport::Outbound)],
config,
),
}
}
}
impl From<RequestResponseEvent<EncryptedSignature, ()>> for OutEvent {
fn from(event: RequestResponseEvent<EncryptedSignature, ()>) -> Self {
match event {
RequestResponseEvent::Message {
message: RequestResponseMessage::Request { .. },
..
} => OutEvent::Failure(anyhow!("Bob should never get a request from Alice")),
RequestResponseEvent::Message {
message: RequestResponseMessage::Response { .. },
..
} => OutEvent::Acknowledged,
RequestResponseEvent::InboundFailure { error, .. } => {
OutEvent::Failure(anyhow!("Inbound failure: {:?}", error))
}
RequestResponseEvent::OutboundFailure { error, .. } => {
OutEvent::Failure(anyhow!("Outbound failure: {:?}", error))
}
RequestResponseEvent::ResponseSent { .. } => OutEvent::Failure(anyhow!(
"Bob does not send the encrypted signature response to Alice"
)),
}
}
}

View File

@ -7,7 +7,7 @@ use crate::monero::wallet::WatchRequest;
use crate::monero::{monero_private_key, TransferProof}; use crate::monero::{monero_private_key, TransferProof};
use crate::monero_ext::ScalarExt; use crate::monero_ext::ScalarExt;
use crate::protocol::alice::{Message1, Message3}; use crate::protocol::alice::{Message1, Message3};
use crate::protocol::bob::{EncryptedSignature, Message0, Message2, Message4}; use crate::protocol::bob::{Message0, Message2, Message4};
use crate::protocol::CROSS_CURVE_PROOF_SYSTEM; use crate::protocol::CROSS_CURVE_PROOF_SYSTEM;
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, bail, Context, Result};
use ecdsa_fun::adaptor::{Adaptor, HashTranscript}; use ecdsa_fun::adaptor::{Adaptor, HashTranscript};
@ -404,12 +404,6 @@ pub struct State4 {
} }
impl State4 { impl State4 {
pub fn next_message(&self) -> EncryptedSignature {
EncryptedSignature {
tx_redeem_encsig: self.tx_redeem_encsig(),
}
}
pub fn tx_redeem_encsig(&self) -> bitcoin::EncryptedSignature { pub fn tx_redeem_encsig(&self) -> bitcoin::EncryptedSignature {
let tx_redeem = bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address); let tx_redeem = bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address);
self.b.encsign(self.S_a_bitcoin, tx_redeem.digest()) self.b.encsign(self.S_a_bitcoin, tx_redeem.digest())