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