mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-02-21 07:09:51 -05:00
Move common stuff to network::swap_setup
This commit is contained in:
parent
981f9fd704
commit
fd23884d74
@ -1,3 +1,10 @@
|
|||||||
|
use libp2p::core::upgrade;
|
||||||
|
use libp2p::swarm::NegotiatedSubstream;
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub const BUF_SIZE: usize = 1024 * 1024;
|
||||||
|
|
||||||
pub mod protocol {
|
pub mod protocol {
|
||||||
use futures::future;
|
use futures::future;
|
||||||
use libp2p::core::upgrade::{from_fn, FromFnUpgrade};
|
use libp2p::core::upgrade::{from_fn, FromFnUpgrade};
|
||||||
@ -24,3 +31,76 @@ pub mod protocol {
|
|||||||
>,
|
>,
|
||||||
>;
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
|
||||||
|
pub struct BlockchainNetwork {
|
||||||
|
#[serde(with = "crate::bitcoin::network")]
|
||||||
|
pub bitcoin: bitcoin::Network,
|
||||||
|
#[serde(with = "crate::monero::network")]
|
||||||
|
pub monero: monero::Network,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct SpotPriceRequest {
|
||||||
|
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
||||||
|
pub btc: bitcoin::Amount,
|
||||||
|
pub blockchain_network: BlockchainNetwork,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub enum SpotPriceResponse {
|
||||||
|
Xmr(crate::monero::Amount),
|
||||||
|
Error(SpotPriceError),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub enum SpotPriceError {
|
||||||
|
NoSwapsAccepted,
|
||||||
|
AmountBelowMinimum {
|
||||||
|
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
||||||
|
min: bitcoin::Amount,
|
||||||
|
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
||||||
|
buy: bitcoin::Amount,
|
||||||
|
},
|
||||||
|
AmountAboveMaximum {
|
||||||
|
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
||||||
|
max: bitcoin::Amount,
|
||||||
|
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
||||||
|
buy: bitcoin::Amount,
|
||||||
|
},
|
||||||
|
BalanceTooLow {
|
||||||
|
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
||||||
|
buy: bitcoin::Amount,
|
||||||
|
},
|
||||||
|
BlockchainNetworkMismatch {
|
||||||
|
cli: BlockchainNetwork,
|
||||||
|
asb: BlockchainNetwork,
|
||||||
|
},
|
||||||
|
/// To be used for errors that cannot be explained on the CLI side (e.g.
|
||||||
|
/// rate update problems on the seller side)
|
||||||
|
Other,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn read_cbor_message<T>(substream: &mut NegotiatedSubstream) -> anyhow::Result<T>
|
||||||
|
where
|
||||||
|
T: DeserializeOwned,
|
||||||
|
{
|
||||||
|
let bytes = upgrade::read_one(substream, BUF_SIZE).await?;
|
||||||
|
let mut de = serde_cbor::Deserializer::from_slice(&bytes);
|
||||||
|
let message = T::deserialize(&mut de)?;
|
||||||
|
|
||||||
|
Ok(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn write_cbor_message<T>(
|
||||||
|
substream: &mut NegotiatedSubstream,
|
||||||
|
message: T,
|
||||||
|
) -> anyhow::Result<()>
|
||||||
|
where
|
||||||
|
T: Serialize,
|
||||||
|
{
|
||||||
|
let bytes = serde_cbor::to_vec(&message)?;
|
||||||
|
upgrade::write_one(substream, &bytes).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::network::swap_setup::protocol;
|
use std::collections::VecDeque;
|
||||||
use crate::protocol::alice::event_loop::LatestRate;
|
use std::fmt::Debug;
|
||||||
use crate::protocol::alice::{State0, State3};
|
use std::task::{Context, Poll};
|
||||||
use crate::protocol::{alice, Message0, Message2, Message4};
|
use std::time::Duration;
|
||||||
use crate::{bitcoin, env, monero};
|
|
||||||
use anyhow::{anyhow, Context as _, Result};
|
use anyhow::{anyhow, Context as _, Result};
|
||||||
use futures::future::{BoxFuture, OptionFuture};
|
use futures::future::{BoxFuture, OptionFuture};
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
@ -13,15 +13,18 @@ use libp2p::swarm::{
|
|||||||
ProtocolsHandler, ProtocolsHandlerEvent, ProtocolsHandlerUpgrErr, SubstreamProtocol,
|
ProtocolsHandler, ProtocolsHandlerEvent, ProtocolsHandlerUpgrErr, SubstreamProtocol,
|
||||||
};
|
};
|
||||||
use libp2p::{Multiaddr, PeerId};
|
use libp2p::{Multiaddr, PeerId};
|
||||||
use serde::de::DeserializeOwned;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::collections::VecDeque;
|
|
||||||
use std::fmt::Debug;
|
|
||||||
use std::task::{Context, Poll};
|
|
||||||
use std::time::Duration;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use void::Void;
|
use void::Void;
|
||||||
|
|
||||||
|
use crate::network::swap_setup;
|
||||||
|
use crate::network::swap_setup::{
|
||||||
|
protocol, BlockchainNetwork, SpotPriceError, SpotPriceRequest, SpotPriceResponse,
|
||||||
|
};
|
||||||
|
use crate::protocol::alice::event_loop::LatestRate;
|
||||||
|
use crate::protocol::alice::{State0, State3};
|
||||||
|
use crate::protocol::{alice, Message0, Message2, Message4};
|
||||||
|
use crate::{bitcoin, env, monero};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum OutEvent {
|
pub enum OutEvent {
|
||||||
Initiated {
|
Initiated {
|
||||||
@ -104,14 +107,6 @@ impl From<OutEvent> for alice::OutEvent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
|
|
||||||
pub struct BlockchainNetwork {
|
|
||||||
#[serde(with = "crate::bitcoin::network")]
|
|
||||||
pub bitcoin: bitcoin::Network,
|
|
||||||
#[serde(with = "crate::monero::network")]
|
|
||||||
pub monero: monero::Network,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct Behaviour<LR> {
|
pub struct Behaviour<LR> {
|
||||||
events: VecDeque<OutEvent>,
|
events: VecDeque<OutEvent>,
|
||||||
@ -204,47 +199,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
||||||
pub struct SpotPriceRequest {
|
|
||||||
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
|
||||||
pub btc: bitcoin::Amount,
|
|
||||||
pub blockchain_network: BlockchainNetwork,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
||||||
pub enum SpotPriceResponse {
|
|
||||||
Xmr(monero::Amount),
|
|
||||||
Error(SpotPriceError),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
||||||
pub enum SpotPriceError {
|
|
||||||
NoSwapsAccepted,
|
|
||||||
AmountBelowMinimum {
|
|
||||||
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
|
||||||
min: bitcoin::Amount,
|
|
||||||
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
|
||||||
buy: bitcoin::Amount,
|
|
||||||
},
|
|
||||||
AmountAboveMaximum {
|
|
||||||
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
|
||||||
max: bitcoin::Amount,
|
|
||||||
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
|
||||||
buy: bitcoin::Amount,
|
|
||||||
},
|
|
||||||
BalanceTooLow {
|
|
||||||
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
|
||||||
buy: bitcoin::Amount,
|
|
||||||
},
|
|
||||||
BlockchainNetworkMismatch {
|
|
||||||
cli: BlockchainNetwork,
|
|
||||||
asb: BlockchainNetwork,
|
|
||||||
},
|
|
||||||
/// To be used for errors that cannot be explained on the CLI side (e.g.
|
|
||||||
/// rate update problems on the seller side)
|
|
||||||
Other,
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: This is bob only.
|
// TODO: This is bob only.
|
||||||
// enum OutboundState {
|
// enum OutboundState {
|
||||||
// PendingOpen(
|
// PendingOpen(
|
||||||
@ -298,8 +252,6 @@ pub enum HandlerOutEvent {
|
|||||||
|
|
||||||
pub enum HandlerInEvent {}
|
pub enum HandlerInEvent {}
|
||||||
|
|
||||||
pub const BUF_SIZE: usize = 1024 * 1024;
|
|
||||||
|
|
||||||
impl<LR> ProtocolsHandler for Handler<LR>
|
impl<LR> ProtocolsHandler for Handler<LR>
|
||||||
where
|
where
|
||||||
LR: LatestRate + Send + 'static,
|
LR: LatestRate + Send + 'static,
|
||||||
@ -332,7 +284,7 @@ where
|
|||||||
let env_config = self.env_config;
|
let env_config = self.env_config;
|
||||||
|
|
||||||
let protocol = tokio::time::timeout(self.timeout, async move {
|
let protocol = tokio::time::timeout(self.timeout, async move {
|
||||||
let request = read_cbor_message::<SpotPriceRequest>(&mut substream)
|
let request = swap_setup::read_cbor_message::<SpotPriceRequest>(&mut substream)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::Io(e))?;
|
.map_err(|e| Error::Io(e))?;
|
||||||
let wallet_snapshot = sender
|
let wallet_snapshot = sender
|
||||||
@ -392,14 +344,14 @@ where
|
|||||||
|
|
||||||
let xmr = match validate.await {
|
let xmr = match validate.await {
|
||||||
Ok(xmr) => {
|
Ok(xmr) => {
|
||||||
write_cbor_message(&mut substream, SpotPriceResponse::Xmr(xmr))
|
swap_setup::write_cbor_message(&mut substream, SpotPriceResponse::Xmr(xmr))
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::Io(e))?;
|
.map_err(|e| Error::Io(e))?;
|
||||||
|
|
||||||
xmr
|
xmr
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
write_cbor_message(
|
swap_setup::write_cbor_message(
|
||||||
&mut substream,
|
&mut substream,
|
||||||
SpotPriceResponse::Error(e.to_error_response()),
|
SpotPriceResponse::Error(e.to_error_response()),
|
||||||
)
|
)
|
||||||
@ -420,17 +372,17 @@ where
|
|||||||
&mut rand::thread_rng(),
|
&mut rand::thread_rng(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let message0 = read_cbor_message::<Message0>(&mut substream)
|
let message0 = swap_setup::read_cbor_message::<Message0>(&mut substream)
|
||||||
.await
|
.await
|
||||||
.context("Failed to deserialize message0")
|
.context("Failed to deserialize message0")
|
||||||
.map_err(|e| Error::Io(e))?;
|
.map_err(|e| Error::Io(e))?;
|
||||||
let (swap_id, state1) = state0.receive(message0).map_err(|e| Error::Io(e))?;
|
let (swap_id, state1) = state0.receive(message0).map_err(|e| Error::Io(e))?;
|
||||||
|
|
||||||
write_cbor_message(&mut substream, state1.next_message())
|
swap_setup::write_cbor_message(&mut substream, state1.next_message())
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::Io(e))?;
|
.map_err(|e| Error::Io(e))?;
|
||||||
|
|
||||||
let message2 = read_cbor_message::<Message2>(&mut substream)
|
let message2 = swap_setup::read_cbor_message::<Message2>(&mut substream)
|
||||||
.await
|
.await
|
||||||
.context("Failed to deserialize message2")
|
.context("Failed to deserialize message2")
|
||||||
.map_err(|e| Error::Io(e))?;
|
.map_err(|e| Error::Io(e))?;
|
||||||
@ -439,11 +391,11 @@ where
|
|||||||
.context("Failed to receive Message2")
|
.context("Failed to receive Message2")
|
||||||
.map_err(|e| Error::Io(e))?;
|
.map_err(|e| Error::Io(e))?;
|
||||||
|
|
||||||
write_cbor_message(&mut substream, state2.next_message())
|
swap_setup::write_cbor_message(&mut substream, state2.next_message())
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::Io(e))?;
|
.map_err(|e| Error::Io(e))?;
|
||||||
|
|
||||||
let message4 = read_cbor_message::<Message4>(&mut substream)
|
let message4 = swap_setup::read_cbor_message::<Message4>(&mut substream)
|
||||||
.await
|
.await
|
||||||
.context("Failed to deserialize message4")
|
.context("Failed to deserialize message4")
|
||||||
.map_err(|e| Error::Io(e))?;
|
.map_err(|e| Error::Io(e))?;
|
||||||
@ -509,27 +461,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn read_cbor_message<T>(substream: &mut NegotiatedSubstream) -> Result<T>
|
|
||||||
where
|
|
||||||
T: DeserializeOwned,
|
|
||||||
{
|
|
||||||
let bytes = upgrade::read_one(substream, BUF_SIZE).await?;
|
|
||||||
let mut de = serde_cbor::Deserializer::from_slice(&bytes);
|
|
||||||
let message = T::deserialize(&mut de)?;
|
|
||||||
|
|
||||||
Ok(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn write_cbor_message<T>(substream: &mut NegotiatedSubstream, message: T) -> Result<()>
|
|
||||||
where
|
|
||||||
T: Serialize,
|
|
||||||
{
|
|
||||||
let bytes = serde_cbor::to_vec(&message)?;
|
|
||||||
upgrade::write_one(substream, &bytes).await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Differentiate between errors that we send back and shit that happens on
|
// TODO: Differentiate between errors that we send back and shit that happens on
|
||||||
// our side (IO, timeout)
|
// our side (IO, timeout)
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user