mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-11-09 19:10:36 +00:00
Replace amounts messages with swap res/req
This commit is contained in:
parent
9fa900dce8
commit
ae8134f04e
@ -1,6 +1,3 @@
|
||||
use ::bitcoin::hashes::core::fmt::Display;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
bitcoin::{EncryptedSignature, TxCancel, TxRefund},
|
||||
monero,
|
||||
@ -8,6 +5,8 @@ use crate::{
|
||||
protocol::{alice, alice::AliceState},
|
||||
SwapAmounts,
|
||||
};
|
||||
use ::bitcoin::hashes::core::fmt::Display;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// Large enum variant is fine because this is only used for database
|
||||
// and is dropped once written in DB.
|
||||
|
@ -1,10 +1,9 @@
|
||||
use ::bitcoin::hashes::core::fmt::Display;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
protocol::{bob, bob::BobState},
|
||||
SwapAmounts,
|
||||
};
|
||||
use ::bitcoin::hashes::core::fmt::Display;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||
pub enum Bob {
|
||||
|
@ -8,10 +8,7 @@ use serde::{Deserialize, Serialize};
|
||||
use std::{fmt::Debug, io, marker::PhantomData};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::{
|
||||
protocol::{alice, bob},
|
||||
SwapAmounts,
|
||||
};
|
||||
use crate::protocol::{alice, bob};
|
||||
|
||||
/// Time to wait for a response back once we send a request.
|
||||
pub const TIMEOUT: u64 = 3600; // One hour.
|
||||
@ -25,8 +22,7 @@ const BUF_SIZE: usize = 1024 * 1024;
|
||||
/// Messages Bob sends to Alice.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum BobToAlice {
|
||||
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
||||
AmountsFromBtc(::bitcoin::Amount),
|
||||
SwapRequest(bob::SwapRequest),
|
||||
Message0(Box<bob::Message0>),
|
||||
Message1(bob::Message1),
|
||||
Message2(bob::Message2),
|
||||
@ -36,7 +32,7 @@ pub enum BobToAlice {
|
||||
/// Messages Alice sends to Bob.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum AliceToBob {
|
||||
Amounts(SwapAmounts),
|
||||
SwapResponse(alice::SwapResponse),
|
||||
Message0(Box<alice::Message0>),
|
||||
Message1(Box<alice::Message1>),
|
||||
Message2(alice::Message2),
|
||||
@ -44,7 +40,7 @@ pub enum AliceToBob {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct AmountsProtocol;
|
||||
pub struct Swap;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct Message0Protocol;
|
||||
@ -58,9 +54,9 @@ pub struct Message2Protocol;
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct Message3Protocol;
|
||||
|
||||
impl ProtocolName for AmountsProtocol {
|
||||
impl ProtocolName for Swap {
|
||||
fn protocol_name(&self) -> &[u8] {
|
||||
b"/xmr/btc/amounts/1.0.0"
|
||||
b"/xmr/btc/swap/1.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,36 +1,40 @@
|
||||
//! Run an XMR/BTC swap in the role of Alice.
|
||||
//! Alice holds XMR and wishes receive BTC.
|
||||
use anyhow::{bail, Result};
|
||||
use libp2p::{request_response::ResponseChannel, NetworkBehaviour, PeerId};
|
||||
use tracing::{debug, info};
|
||||
|
||||
use crate::{
|
||||
bitcoin, database, monero,
|
||||
bitcoin,
|
||||
config::Config,
|
||||
database,
|
||||
database::Database,
|
||||
monero,
|
||||
network::{
|
||||
peer_tracker::{self, PeerTracker},
|
||||
request_response::AliceToBob,
|
||||
transport::build,
|
||||
Seed as NetworkSeed,
|
||||
},
|
||||
protocol::bob,
|
||||
seed::Seed,
|
||||
SwapAmounts,
|
||||
};
|
||||
use anyhow::{bail, Result};
|
||||
use libp2p::{
|
||||
core::Multiaddr, identity::Keypair, request_response::ResponseChannel, NetworkBehaviour, PeerId,
|
||||
};
|
||||
use rand::rngs::OsRng;
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
use tracing::{debug, info};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub use self::{
|
||||
amounts::*,
|
||||
event_loop::{EventLoop, EventLoopHandle},
|
||||
message0::Message0,
|
||||
message1::Message1,
|
||||
message2::Message2,
|
||||
state::*,
|
||||
swap::{run, run_until},
|
||||
swap_response::*,
|
||||
};
|
||||
use crate::{config::Config, database::Database, network::transport::build, seed::Seed};
|
||||
use libp2p::{core::Multiaddr, identity::Keypair};
|
||||
use rand::rngs::OsRng;
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
use uuid::Uuid;
|
||||
|
||||
mod amounts;
|
||||
pub mod event_loop;
|
||||
mod message0;
|
||||
mod message1;
|
||||
@ -39,6 +43,7 @@ mod message3;
|
||||
pub mod state;
|
||||
mod steps;
|
||||
pub mod swap;
|
||||
mod swap_response;
|
||||
|
||||
pub struct Swap {
|
||||
pub state: AliceState,
|
||||
@ -217,7 +222,8 @@ pub enum OutEvent {
|
||||
ConnectionEstablished(PeerId),
|
||||
// TODO (Franck): Change this to get both amounts so parties can verify the amounts are
|
||||
// expected early on.
|
||||
Request(Box<amounts::OutEvent>), /* Not-uniform with Bob on purpose, ready for adding Xmr
|
||||
Request(Box<swap_response::OutEvent>), /* Not-uniform with Bob on purpose, ready for adding
|
||||
* Xmr
|
||||
* event. */
|
||||
Message0 {
|
||||
msg: Box<bob::Message0>,
|
||||
@ -244,8 +250,8 @@ impl From<peer_tracker::OutEvent> for OutEvent {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<amounts::OutEvent> for OutEvent {
|
||||
fn from(event: amounts::OutEvent) -> Self {
|
||||
impl From<swap_response::OutEvent> for OutEvent {
|
||||
fn from(event: swap_response::OutEvent) -> Self {
|
||||
OutEvent::Request(Box::new(event))
|
||||
}
|
||||
}
|
||||
@ -291,7 +297,7 @@ impl From<message3::OutEvent> for OutEvent {
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Behaviour {
|
||||
pt: PeerTracker,
|
||||
amounts: Amounts,
|
||||
amounts: swap_response::Behaviour,
|
||||
message0: message0::Behaviour,
|
||||
message1: message1::Behaviour,
|
||||
message2: message2::Behaviour,
|
||||
@ -300,9 +306,12 @@ pub struct Behaviour {
|
||||
|
||||
impl Behaviour {
|
||||
/// Alice always sends her messages as a response to a request from Bob.
|
||||
pub fn send_amounts(&mut self, channel: ResponseChannel<AliceToBob>, amounts: SwapAmounts) {
|
||||
let msg = AliceToBob::Amounts(amounts);
|
||||
self.amounts.send(channel, msg);
|
||||
pub fn send_swap_response(
|
||||
&mut self,
|
||||
channel: ResponseChannel<AliceToBob>,
|
||||
swap_response: SwapResponse,
|
||||
) {
|
||||
self.amounts.send(channel, swap_response);
|
||||
info!("Sent amounts response");
|
||||
}
|
||||
|
||||
|
@ -9,10 +9,9 @@ use crate::{
|
||||
network::{request_response::AliceToBob, transport::SwapTransport, TokioExecutor},
|
||||
protocol::{
|
||||
alice,
|
||||
alice::{Behaviour, OutEvent},
|
||||
alice::{Behaviour, OutEvent, SwapResponse},
|
||||
bob,
|
||||
},
|
||||
SwapAmounts,
|
||||
};
|
||||
|
||||
#[allow(missing_debug_implementations)]
|
||||
@ -40,9 +39,9 @@ pub struct EventLoopHandle {
|
||||
msg1: Receiver<(bob::Message1, ResponseChannel<AliceToBob>)>,
|
||||
msg2: Receiver<(bob::Message2, ResponseChannel<AliceToBob>)>,
|
||||
msg3: Receiver<bob::Message3>,
|
||||
request: Receiver<crate::protocol::alice::amounts::OutEvent>,
|
||||
request: Receiver<crate::protocol::alice::swap_response::OutEvent>,
|
||||
conn_established: Receiver<PeerId>,
|
||||
send_amounts: Sender<(ResponseChannel<AliceToBob>, SwapAmounts)>,
|
||||
send_swap_response: Sender<(ResponseChannel<AliceToBob>, SwapResponse)>,
|
||||
send_msg0: Sender<(ResponseChannel<AliceToBob>, alice::Message0)>,
|
||||
send_msg1: Sender<(ResponseChannel<AliceToBob>, alice::Message1)>,
|
||||
send_msg2: Sender<(ResponseChannel<AliceToBob>, alice::Message2)>,
|
||||
@ -84,19 +83,24 @@ impl EventLoopHandle {
|
||||
.ok_or_else(|| anyhow!("Failed to receive Bitcoin encrypted signature from Bob"))
|
||||
}
|
||||
|
||||
pub async fn recv_request(&mut self) -> Result<crate::protocol::alice::amounts::OutEvent> {
|
||||
pub async fn recv_request(
|
||||
&mut self,
|
||||
) -> Result<crate::protocol::alice::swap_response::OutEvent> {
|
||||
self.request
|
||||
.recv()
|
||||
.await
|
||||
.ok_or_else(|| anyhow!("Failed to receive amounts request from Bob"))
|
||||
}
|
||||
|
||||
pub async fn send_amounts(
|
||||
pub async fn send_swap_response(
|
||||
&mut self,
|
||||
channel: ResponseChannel<AliceToBob>,
|
||||
amounts: SwapAmounts,
|
||||
swap_response: SwapResponse,
|
||||
) -> Result<()> {
|
||||
let _ = self.send_amounts.send((channel, amounts)).await?;
|
||||
let _ = self
|
||||
.send_swap_response
|
||||
.send((channel, swap_response))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -135,9 +139,9 @@ pub struct EventLoop {
|
||||
msg1: Sender<(bob::Message1, ResponseChannel<AliceToBob>)>,
|
||||
msg2: Sender<(bob::Message2, ResponseChannel<AliceToBob>)>,
|
||||
msg3: Sender<bob::Message3>,
|
||||
request: Sender<crate::protocol::alice::amounts::OutEvent>,
|
||||
request: Sender<crate::protocol::alice::swap_response::OutEvent>,
|
||||
conn_established: Sender<PeerId>,
|
||||
send_amounts: Receiver<(ResponseChannel<AliceToBob>, SwapAmounts)>,
|
||||
send_swap_response: Receiver<(ResponseChannel<AliceToBob>, SwapResponse)>,
|
||||
send_msg0: Receiver<(ResponseChannel<AliceToBob>, alice::Message0)>,
|
||||
send_msg1: Receiver<(ResponseChannel<AliceToBob>, alice::Message1)>,
|
||||
send_msg2: Receiver<(ResponseChannel<AliceToBob>, alice::Message2)>,
|
||||
@ -165,7 +169,7 @@ impl EventLoop {
|
||||
let msg3 = Channels::new();
|
||||
let request = Channels::new();
|
||||
let conn_established = Channels::new();
|
||||
let send_amounts = Channels::new();
|
||||
let send_swap_response = Channels::new();
|
||||
let send_msg0 = Channels::new();
|
||||
let send_msg1 = Channels::new();
|
||||
let send_msg2 = Channels::new();
|
||||
@ -178,7 +182,7 @@ impl EventLoop {
|
||||
msg3: msg3.sender,
|
||||
request: request.sender,
|
||||
conn_established: conn_established.sender,
|
||||
send_amounts: send_amounts.receiver,
|
||||
send_swap_response: send_swap_response.receiver,
|
||||
send_msg0: send_msg0.receiver,
|
||||
send_msg1: send_msg1.receiver,
|
||||
send_msg2: send_msg2.receiver,
|
||||
@ -191,7 +195,7 @@ impl EventLoop {
|
||||
msg3: msg3.receiver,
|
||||
request: request.receiver,
|
||||
conn_established: conn_established.receiver,
|
||||
send_amounts: send_amounts.sender,
|
||||
send_swap_response: send_swap_response.sender,
|
||||
send_msg0: send_msg0.sender,
|
||||
send_msg1: send_msg1.sender,
|
||||
send_msg2: send_msg2.sender,
|
||||
@ -225,9 +229,9 @@ impl EventLoop {
|
||||
}
|
||||
}
|
||||
},
|
||||
amounts = self.send_amounts.next().fuse() => {
|
||||
if let Some((channel, amounts)) = amounts {
|
||||
self.swarm.send_amounts(channel, amounts);
|
||||
swap_response = self.send_swap_response.next().fuse() => {
|
||||
if let Some((channel, swap_response)) = swap_response {
|
||||
self.swarm.send_swap_response(channel, swap_response);
|
||||
}
|
||||
},
|
||||
msg0 = self.send_msg0.next().fuse() => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use anyhow::{bail, Context, Result};
|
||||
use anyhow::{Context, Result};
|
||||
use ecdsa_fun::{adaptor::Adaptor, nonce::Deterministic};
|
||||
use futures::{
|
||||
future::{select, Either},
|
||||
@ -24,13 +24,16 @@ use crate::{
|
||||
monero,
|
||||
monero::Transfer,
|
||||
network::request_response::AliceToBob,
|
||||
protocol::{alice, alice::event_loop::EventLoopHandle},
|
||||
protocol::{
|
||||
alice,
|
||||
alice::{event_loop::EventLoopHandle, SwapResponse},
|
||||
},
|
||||
SwapAmounts,
|
||||
};
|
||||
|
||||
pub async fn negotiate(
|
||||
state0: alice::State0,
|
||||
amounts: SwapAmounts,
|
||||
xmr_amount: monero::Amount,
|
||||
event_loop_handle: &mut EventLoopHandle,
|
||||
config: Config,
|
||||
) -> Result<(ResponseChannel<AliceToBob>, alice::State3)> {
|
||||
@ -46,18 +49,10 @@ pub async fn negotiate(
|
||||
|
||||
let event = timeout(config.bob_time_to_act, event_loop_handle.recv_request())
|
||||
.await
|
||||
.context("Failed to receive amounts from Bob")??;
|
||||
|
||||
if event.btc != amounts.btc {
|
||||
bail!(
|
||||
"Bob proposed a different amount; got {}, expected: {}",
|
||||
event.btc,
|
||||
amounts.btc
|
||||
);
|
||||
}
|
||||
.context("Failed to receive swap request from Bob")??;
|
||||
|
||||
event_loop_handle
|
||||
.send_amounts(event.channel, amounts)
|
||||
.send_swap_response(event.channel, SwapResponse { xmr_amount })
|
||||
.await?;
|
||||
|
||||
let (bob_message0, channel) =
|
||||
|
@ -105,7 +105,7 @@ async fn run_until_internal(
|
||||
match state {
|
||||
AliceState::Started { amounts, state0 } => {
|
||||
let (channel, state3) =
|
||||
negotiate(state0, amounts, &mut event_loop_handle, config).await?;
|
||||
negotiate(state0, amounts.xmr, &mut event_loop_handle, config).await?;
|
||||
|
||||
let state = AliceState::Negotiated {
|
||||
channel: Some(channel),
|
||||
|
@ -6,6 +6,7 @@ use libp2p::{
|
||||
swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters},
|
||||
NetworkBehaviour,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
task::{Context, Poll},
|
||||
@ -14,29 +15,37 @@ use std::{
|
||||
use tracing::{debug, error};
|
||||
|
||||
use crate::{
|
||||
network::request_response::{AliceToBob, AmountsProtocol, BobToAlice, Codec, TIMEOUT},
|
||||
protocol::alice::amounts,
|
||||
monero,
|
||||
network::request_response::{AliceToBob, BobToAlice, Codec, Swap, TIMEOUT},
|
||||
protocol::bob,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OutEvent {
|
||||
pub btc: ::bitcoin::Amount,
|
||||
pub msg: bob::SwapRequest,
|
||||
pub channel: ResponseChannel<AliceToBob>,
|
||||
}
|
||||
|
||||
/// A `NetworkBehaviour` that represents getting the amounts of an XMR/BTC swap.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SwapResponse {
|
||||
pub xmr_amount: monero::Amount,
|
||||
}
|
||||
|
||||
/// A `NetworkBehaviour` that represents negotiate a swap using Swap
|
||||
/// request/response.
|
||||
#[derive(NetworkBehaviour)]
|
||||
#[behaviour(out_event = "OutEvent", poll_method = "poll")]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Amounts {
|
||||
rr: RequestResponse<Codec<AmountsProtocol>>,
|
||||
pub struct Behaviour {
|
||||
rr: RequestResponse<Codec<Swap>>,
|
||||
#[behaviour(ignore)]
|
||||
events: VecDeque<OutEvent>,
|
||||
}
|
||||
|
||||
impl Amounts {
|
||||
impl Behaviour {
|
||||
/// Alice always sends her messages as a response to a request from Bob.
|
||||
pub fn send(&mut self, channel: ResponseChannel<AliceToBob>, msg: AliceToBob) {
|
||||
pub fn send(&mut self, channel: ResponseChannel<AliceToBob>, msg: SwapResponse) {
|
||||
let msg = AliceToBob::SwapResponse(msg);
|
||||
self.rr.send_response(channel, msg);
|
||||
}
|
||||
|
||||
@ -44,7 +53,7 @@ impl Amounts {
|
||||
&mut self,
|
||||
_: &mut Context<'_>,
|
||||
_: &mut impl PollParameters,
|
||||
) -> Poll<NetworkBehaviourAction<RequestProtocol<Codec<AmountsProtocol>>, OutEvent>> {
|
||||
) -> Poll<NetworkBehaviourAction<RequestProtocol<Codec<Swap>>, OutEvent>> {
|
||||
if let Some(event) = self.events.pop_front() {
|
||||
return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event));
|
||||
}
|
||||
@ -53,7 +62,7 @@ impl Amounts {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Amounts {
|
||||
impl Default for Behaviour {
|
||||
fn default() -> Self {
|
||||
let timeout = Duration::from_secs(TIMEOUT);
|
||||
|
||||
@ -63,7 +72,7 @@ impl Default for Amounts {
|
||||
Self {
|
||||
rr: RequestResponse::new(
|
||||
Codec::default(),
|
||||
vec![(AmountsProtocol, ProtocolSupport::Full)],
|
||||
vec![(Swap, ProtocolSupport::Full)],
|
||||
config,
|
||||
),
|
||||
events: Default::default(),
|
||||
@ -71,7 +80,7 @@ impl Default for Amounts {
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkBehaviourEventProcess<RequestResponseEvent<BobToAlice, AliceToBob>> for Amounts {
|
||||
impl NetworkBehaviourEventProcess<RequestResponseEvent<BobToAlice, AliceToBob>> for Behaviour {
|
||||
fn inject_event(&mut self, event: RequestResponseEvent<BobToAlice, AliceToBob>) {
|
||||
match event {
|
||||
RequestResponseEvent::Message {
|
||||
@ -81,9 +90,9 @@ impl NetworkBehaviourEventProcess<RequestResponseEvent<BobToAlice, AliceToBob>>
|
||||
},
|
||||
..
|
||||
} => {
|
||||
if let BobToAlice::AmountsFromBtc(btc) = request {
|
||||
debug!("Received amounts request");
|
||||
self.events.push_back(amounts::OutEvent { btc, channel })
|
||||
if let BobToAlice::SwapRequest(msg) = request {
|
||||
debug!("Received swap request");
|
||||
self.events.push_back(OutEvent { msg, channel })
|
||||
}
|
||||
}
|
||||
RequestResponseEvent::Message {
|
@ -1,20 +1,28 @@
|
||||
//! Run an XMR/BTC swap in the role of Bob.
|
||||
//! Bob holds BTC and wishes receive XMR.
|
||||
use anyhow::{bail, Result};
|
||||
use libp2p::{core::Multiaddr, NetworkBehaviour, PeerId};
|
||||
use tracing::{debug, info};
|
||||
|
||||
use crate::{
|
||||
bitcoin,
|
||||
bitcoin::EncryptedSignature,
|
||||
database, monero, network,
|
||||
network::peer_tracker::{self, PeerTracker},
|
||||
config::Config,
|
||||
database,
|
||||
database::Database,
|
||||
monero, network,
|
||||
network::{
|
||||
peer_tracker::{self, PeerTracker},
|
||||
transport::build,
|
||||
},
|
||||
protocol::{alice, bob},
|
||||
seed::Seed,
|
||||
SwapAmounts,
|
||||
};
|
||||
use anyhow::{bail, Result};
|
||||
use libp2p::{core::Multiaddr, identity::Keypair, NetworkBehaviour, PeerId};
|
||||
use rand::rngs::OsRng;
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
use tracing::{debug, info};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub use self::{
|
||||
amounts::*,
|
||||
event_loop::{EventLoop, EventLoopHandle},
|
||||
message0::Message0,
|
||||
message1::Message1,
|
||||
@ -22,14 +30,9 @@ pub use self::{
|
||||
message3::Message3,
|
||||
state::*,
|
||||
swap::{run, run_until},
|
||||
swap_request::*,
|
||||
};
|
||||
use crate::{config::Config, database::Database, network::transport::build, seed::Seed};
|
||||
use libp2p::identity::Keypair;
|
||||
use rand::rngs::OsRng;
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
use uuid::Uuid;
|
||||
|
||||
mod amounts;
|
||||
pub mod event_loop;
|
||||
mod message0;
|
||||
mod message1;
|
||||
@ -37,6 +40,7 @@ mod message2;
|
||||
mod message3;
|
||||
pub mod state;
|
||||
pub mod swap;
|
||||
mod swap_request;
|
||||
|
||||
pub struct Swap {
|
||||
pub state: BobState,
|
||||
@ -204,7 +208,7 @@ impl Builder {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum OutEvent {
|
||||
ConnectionEstablished(PeerId),
|
||||
Amounts(SwapAmounts),
|
||||
SwapResponse(alice::SwapResponse),
|
||||
Message0(Box<alice::Message0>),
|
||||
Message1(Box<alice::Message1>),
|
||||
Message2(alice::Message2),
|
||||
@ -221,11 +225,9 @@ impl From<peer_tracker::OutEvent> for OutEvent {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<amounts::OutEvent> for OutEvent {
|
||||
fn from(event: amounts::OutEvent) -> Self {
|
||||
match event {
|
||||
amounts::OutEvent::Amounts(amounts) => OutEvent::Amounts(amounts),
|
||||
}
|
||||
impl From<swap_request::OutEvent> for OutEvent {
|
||||
fn from(event: swap_request::OutEvent) -> Self {
|
||||
OutEvent::SwapResponse(event.swap_response)
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,7 +269,7 @@ impl From<message3::OutEvent> for OutEvent {
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Behaviour {
|
||||
pt: PeerTracker,
|
||||
amounts: Amounts,
|
||||
swap_request: swap_request::Behaviour,
|
||||
message0: message0::Behaviour,
|
||||
message1: message1::Behaviour,
|
||||
message2: message2::Behaviour,
|
||||
@ -275,11 +277,10 @@ pub struct Behaviour {
|
||||
}
|
||||
|
||||
impl Behaviour {
|
||||
/// Sends a message to Alice to get current amounts based on `btc`.
|
||||
pub fn request_amounts(&mut self, alice: PeerId, btc: u64) {
|
||||
let btc = ::bitcoin::Amount::from_sat(btc);
|
||||
let _id = self.amounts.request_amounts(alice.clone(), btc);
|
||||
info!("Requesting amounts from: {}", alice);
|
||||
/// Sends a swap request to Alice to negotiate the swap.
|
||||
pub fn send_swap_request(&mut self, alice: PeerId, swap_request: SwapRequest) {
|
||||
let _id = self.swap_request.send(alice.clone(), swap_request);
|
||||
info!("Requesting swap from: {}", alice);
|
||||
}
|
||||
|
||||
/// Sends Bob's first message to Alice.
|
||||
|
@ -1,3 +1,12 @@
|
||||
use crate::{
|
||||
bitcoin::EncryptedSignature,
|
||||
network::{transport::SwapTransport, TokioExecutor},
|
||||
protocol::{
|
||||
alice,
|
||||
alice::SwapResponse,
|
||||
bob::{self, Behaviour, OutEvent, SwapRequest},
|
||||
},
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use futures::FutureExt;
|
||||
use libp2p::{core::Multiaddr, PeerId};
|
||||
@ -7,15 +16,6 @@ use tokio::{
|
||||
};
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
use crate::{
|
||||
bitcoin::EncryptedSignature,
|
||||
network::{transport::SwapTransport, TokioExecutor},
|
||||
protocol::{
|
||||
alice,
|
||||
bob::{self, Behaviour, OutEvent},
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Channels<T> {
|
||||
sender: Sender<T>,
|
||||
@ -37,12 +37,13 @@ impl<T> Default for Channels<T> {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EventLoopHandle {
|
||||
swap_response: Receiver<SwapResponse>,
|
||||
msg0: Receiver<alice::Message0>,
|
||||
msg1: Receiver<alice::Message1>,
|
||||
msg2: Receiver<alice::Message2>,
|
||||
request_amounts: Sender<::bitcoin::Amount>,
|
||||
conn_established: Receiver<PeerId>,
|
||||
dial_alice: Sender<()>,
|
||||
send_swap_request: Sender<SwapRequest>,
|
||||
send_msg0: Sender<bob::Message0>,
|
||||
send_msg1: Sender<bob::Message1>,
|
||||
send_msg2: Sender<bob::Message2>,
|
||||
@ -50,25 +51,32 @@ pub struct EventLoopHandle {
|
||||
}
|
||||
|
||||
impl EventLoopHandle {
|
||||
pub async fn recv_swap_response(&mut self) -> Result<SwapResponse> {
|
||||
self.swap_response
|
||||
.recv()
|
||||
.await
|
||||
.ok_or_else(|| anyhow!("Failed to receive swap response from Alice"))
|
||||
}
|
||||
|
||||
pub async fn recv_message0(&mut self) -> Result<alice::Message0> {
|
||||
self.msg0
|
||||
.recv()
|
||||
.await
|
||||
.ok_or_else(|| anyhow!("Failed to receive message 0 from Bob"))
|
||||
.ok_or_else(|| anyhow!("Failed to receive message 0 from Alice"))
|
||||
}
|
||||
|
||||
pub async fn recv_message1(&mut self) -> Result<alice::Message1> {
|
||||
self.msg1
|
||||
.recv()
|
||||
.await
|
||||
.ok_or_else(|| anyhow!("Failed to receive message 1 from Bob"))
|
||||
.ok_or_else(|| anyhow!("Failed to receive message 1 from Alice"))
|
||||
}
|
||||
|
||||
pub async fn recv_message2(&mut self) -> Result<alice::Message2> {
|
||||
self.msg2
|
||||
.recv()
|
||||
.await
|
||||
.ok_or_else(|| anyhow!("Failed o receive message 2 from Bob"))
|
||||
.ok_or_else(|| anyhow!("Failed o receive message 2 from Alice"))
|
||||
}
|
||||
|
||||
/// Dials other party and wait for the connection to be established.
|
||||
@ -85,8 +93,8 @@ impl EventLoopHandle {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn request_amounts(&mut self, btc_amount: ::bitcoin::Amount) -> Result<()> {
|
||||
let _ = self.request_amounts.send(btc_amount).await?;
|
||||
pub async fn send_swap_request(&mut self, swap_request: SwapRequest) -> Result<()> {
|
||||
let _ = self.send_swap_request.send(swap_request).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -115,12 +123,13 @@ impl EventLoopHandle {
|
||||
pub struct EventLoop {
|
||||
swarm: libp2p::Swarm<Behaviour>,
|
||||
alice_peer_id: PeerId,
|
||||
swap_response: Sender<SwapResponse>,
|
||||
msg0: Sender<alice::Message0>,
|
||||
msg1: Sender<alice::Message1>,
|
||||
msg2: Sender<alice::Message2>,
|
||||
conn_established: Sender<PeerId>,
|
||||
request_amounts: Receiver<::bitcoin::Amount>,
|
||||
dial_alice: Receiver<()>,
|
||||
send_swap_request: Receiver<SwapRequest>,
|
||||
send_msg0: Receiver<bob::Message0>,
|
||||
send_msg1: Receiver<bob::Message1>,
|
||||
send_msg2: Receiver<bob::Message2>,
|
||||
@ -143,12 +152,13 @@ impl EventLoop {
|
||||
|
||||
swarm.add_address(alice_peer_id.clone(), alice_addr);
|
||||
|
||||
let amounts = Channels::new();
|
||||
let swap_response = Channels::new();
|
||||
let msg0 = Channels::new();
|
||||
let msg1 = Channels::new();
|
||||
let msg2 = Channels::new();
|
||||
let conn_established = Channels::new();
|
||||
let dial_alice = Channels::new();
|
||||
let send_swap_request = Channels::new();
|
||||
let send_msg0 = Channels::new();
|
||||
let send_msg1 = Channels::new();
|
||||
let send_msg2 = Channels::new();
|
||||
@ -157,12 +167,13 @@ impl EventLoop {
|
||||
let event_loop = EventLoop {
|
||||
swarm,
|
||||
alice_peer_id,
|
||||
request_amounts: amounts.receiver,
|
||||
swap_response: swap_response.sender,
|
||||
msg0: msg0.sender,
|
||||
msg1: msg1.sender,
|
||||
msg2: msg2.sender,
|
||||
conn_established: conn_established.sender,
|
||||
dial_alice: dial_alice.receiver,
|
||||
send_swap_request: send_swap_request.receiver,
|
||||
send_msg0: send_msg0.receiver,
|
||||
send_msg1: send_msg1.receiver,
|
||||
send_msg2: send_msg2.receiver,
|
||||
@ -170,12 +181,13 @@ impl EventLoop {
|
||||
};
|
||||
|
||||
let handle = EventLoopHandle {
|
||||
request_amounts: amounts.sender,
|
||||
swap_response: swap_response.receiver,
|
||||
msg0: msg0.receiver,
|
||||
msg1: msg1.receiver,
|
||||
msg2: msg2.receiver,
|
||||
conn_established: conn_established.receiver,
|
||||
dial_alice: dial_alice.sender,
|
||||
send_swap_request: send_swap_request.sender,
|
||||
send_msg0: send_msg0.sender,
|
||||
send_msg1: send_msg1.sender,
|
||||
send_msg2: send_msg2.sender,
|
||||
@ -193,7 +205,9 @@ impl EventLoop {
|
||||
OutEvent::ConnectionEstablished(peer_id) => {
|
||||
let _ = self.conn_established.send(peer_id).await;
|
||||
}
|
||||
OutEvent::Amounts(_amounts) => info!("Amounts received from Alice"),
|
||||
OutEvent::SwapResponse(msg) => {
|
||||
let _ = self.swap_response.send(msg).await;
|
||||
},
|
||||
OutEvent::Message0(msg) => {
|
||||
let _ = self.msg0.send(*msg).await;
|
||||
}
|
||||
@ -222,9 +236,9 @@ impl EventLoop {
|
||||
}
|
||||
}
|
||||
},
|
||||
amounts = self.request_amounts.next().fuse() => {
|
||||
if let Some(btc_amount) = amounts {
|
||||
self.swarm.request_amounts(self.alice_peer_id.clone(), btc_amount.as_sat());
|
||||
swap_request = self.send_swap_request.next().fuse() => {
|
||||
if let Some(swap_request) = swap_request {
|
||||
self.swarm.send_swap_request(self.alice_peer_id.clone(), swap_request);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -11,7 +11,7 @@ use crate::{
|
||||
config::Config,
|
||||
database::{Database, Swap},
|
||||
monero,
|
||||
protocol::bob::{self, event_loop::EventLoopHandle, state::*},
|
||||
protocol::bob::{self, event_loop::EventLoopHandle, state::*, SwapRequest},
|
||||
ExpiredTimelocks, SwapAmounts,
|
||||
};
|
||||
|
||||
@ -373,7 +373,15 @@ where
|
||||
R: RngCore + CryptoRng + Send,
|
||||
{
|
||||
tracing::trace!("Starting negotiate");
|
||||
swarm.request_amounts(amounts.btc).await?;
|
||||
swarm
|
||||
.send_swap_request(SwapRequest {
|
||||
btc_amount: amounts.btc,
|
||||
})
|
||||
.await?;
|
||||
|
||||
// TODO: Use this once Bob's CLI is modified to only pass xmr amount in
|
||||
// argument.
|
||||
let _swap_response = swarm.recv_swap_response().await?;
|
||||
|
||||
swarm.send_message0(state0.next_message(&mut rng)).await?;
|
||||
let msg0 = swarm.recv_message0().await?;
|
||||
|
@ -1,3 +1,7 @@
|
||||
use crate::{
|
||||
network::request_response::{AliceToBob, BobToAlice, Codec, Swap, TIMEOUT},
|
||||
protocol::alice::SwapResponse,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use libp2p::{
|
||||
request_response::{
|
||||
@ -7,6 +11,7 @@ use libp2p::{
|
||||
swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters},
|
||||
NetworkBehaviour, PeerId,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
task::{Context, Poll},
|
||||
@ -14,29 +19,30 @@ use std::{
|
||||
};
|
||||
use tracing::{debug, error};
|
||||
|
||||
use crate::{
|
||||
network::request_response::{AliceToBob, AmountsProtocol, BobToAlice, Codec, TIMEOUT},
|
||||
SwapAmounts,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum OutEvent {
|
||||
Amounts(SwapAmounts),
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SwapRequest {
|
||||
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
||||
pub btc_amount: bitcoin::Amount,
|
||||
}
|
||||
|
||||
/// A `NetworkBehaviour` that represents getting the amounts of an XMR/BTC swap.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct OutEvent {
|
||||
pub swap_response: SwapResponse,
|
||||
}
|
||||
|
||||
/// A `NetworkBehaviour` that represents doing the negotiation of a swap.
|
||||
#[derive(NetworkBehaviour)]
|
||||
#[behaviour(out_event = "OutEvent", poll_method = "poll")]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Amounts {
|
||||
rr: RequestResponse<Codec<AmountsProtocol>>,
|
||||
pub struct Behaviour {
|
||||
rr: RequestResponse<Codec<Swap>>,
|
||||
#[behaviour(ignore)]
|
||||
events: VecDeque<OutEvent>,
|
||||
}
|
||||
|
||||
impl Amounts {
|
||||
pub fn request_amounts(&mut self, alice: PeerId, btc: ::bitcoin::Amount) -> Result<RequestId> {
|
||||
let msg = BobToAlice::AmountsFromBtc(btc);
|
||||
impl Behaviour {
|
||||
pub fn send(&mut self, alice: PeerId, swap_request: SwapRequest) -> Result<RequestId> {
|
||||
let msg = BobToAlice::SwapRequest(swap_request);
|
||||
let id = self.rr.send_request(&alice, msg);
|
||||
|
||||
Ok(id)
|
||||
@ -46,7 +52,7 @@ impl Amounts {
|
||||
&mut self,
|
||||
_: &mut Context<'_>,
|
||||
_: &mut impl PollParameters,
|
||||
) -> Poll<NetworkBehaviourAction<RequestProtocol<Codec<AmountsProtocol>>, OutEvent>> {
|
||||
) -> Poll<NetworkBehaviourAction<RequestProtocol<Codec<Swap>>, OutEvent>> {
|
||||
if let Some(event) = self.events.pop_front() {
|
||||
return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event));
|
||||
}
|
||||
@ -55,7 +61,7 @@ impl Amounts {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Amounts {
|
||||
impl Default for Behaviour {
|
||||
fn default() -> Self {
|
||||
let timeout = Duration::from_secs(TIMEOUT);
|
||||
|
||||
@ -65,7 +71,7 @@ impl Default for Amounts {
|
||||
Self {
|
||||
rr: RequestResponse::new(
|
||||
Codec::default(),
|
||||
vec![(AmountsProtocol, ProtocolSupport::Full)],
|
||||
vec![(Swap, ProtocolSupport::Full)],
|
||||
config,
|
||||
),
|
||||
events: Default::default(),
|
||||
@ -73,7 +79,7 @@ impl Default for Amounts {
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkBehaviourEventProcess<RequestResponseEvent<BobToAlice, AliceToBob>> for Amounts {
|
||||
impl NetworkBehaviourEventProcess<RequestResponseEvent<BobToAlice, AliceToBob>> for Behaviour {
|
||||
fn inject_event(&mut self, event: RequestResponseEvent<BobToAlice, AliceToBob>) {
|
||||
match event {
|
||||
RequestResponseEvent::Message {
|
||||
@ -84,9 +90,9 @@ impl NetworkBehaviourEventProcess<RequestResponseEvent<BobToAlice, AliceToBob>>
|
||||
message: RequestResponseMessage::Response { response, .. },
|
||||
..
|
||||
} => {
|
||||
if let AliceToBob::Amounts(p) = response {
|
||||
debug!("Received amounts response");
|
||||
self.events.push_back(OutEvent::Amounts(p));
|
||||
if let AliceToBob::SwapResponse(swap_response) = response {
|
||||
debug!("Received swap response");
|
||||
self.events.push_back(OutEvent { swap_response });
|
||||
}
|
||||
}
|
||||
RequestResponseEvent::InboundFailure { error, .. } => {
|
Loading…
Reference in New Issue
Block a user