Send offer duration from ASB to CLI

On the ASB side this is max_swap_timeout, and may eventually be
configurable, or dynamic. On the CLI side this is just received as
valid_duration, an Optional Duration.

Signed-off-by: Ian McKenzie <sirreal.ian@gmail.com>
This commit is contained in:
Ian McKenzie 2024-06-29 13:41:52 -07:00
parent 23a27680a4
commit c6004052dd
10 changed files with 36 additions and 5 deletions

View File

@ -18,6 +18,7 @@ use std::collections::HashMap;
use std::convert::{Infallible, TryInto}; use std::convert::{Infallible, TryInto};
use std::fmt::Debug; use std::fmt::Debug;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use uuid::Uuid; use uuid::Uuid;
@ -44,6 +45,7 @@ where
latest_rate: LR, latest_rate: LR,
min_buy: bitcoin::Amount, min_buy: bitcoin::Amount,
max_buy: bitcoin::Amount, max_buy: bitcoin::Amount,
max_swap_timeout: Duration,
external_redeem_address: Option<bitcoin::Address>, external_redeem_address: Option<bitcoin::Address>,
swap_sender: mpsc::Sender<Swap>, swap_sender: mpsc::Sender<Swap>,
@ -77,6 +79,7 @@ where
latest_rate: LR, latest_rate: LR,
min_buy: bitcoin::Amount, min_buy: bitcoin::Amount,
max_buy: bitcoin::Amount, max_buy: bitcoin::Amount,
max_swap_timeout: Duration,
external_redeem_address: Option<bitcoin::Address>, external_redeem_address: Option<bitcoin::Address>,
) -> Result<(Self, mpsc::Receiver<Swap>)> { ) -> Result<(Self, mpsc::Receiver<Swap>)> {
let swap_channel = MpscChannels::default(); let swap_channel = MpscChannels::default();
@ -91,6 +94,7 @@ where
swap_sender: swap_channel.sender, swap_sender: swap_channel.sender,
min_buy, min_buy,
max_buy, max_buy,
max_swap_timeout,
external_redeem_address, external_redeem_address,
recv_encrypted_signature: Default::default(), recv_encrypted_signature: Default::default(),
inflight_encrypted_signatures: Default::default(), inflight_encrypted_signatures: Default::default(),
@ -186,7 +190,7 @@ where
tracing::warn!(%peer, "Ignoring spot price request: {}", error); tracing::warn!(%peer, "Ignoring spot price request: {}", error);
} }
SwarmEvent::Behaviour(OutEvent::QuoteRequested { channel, peer }) => { SwarmEvent::Behaviour(OutEvent::QuoteRequested { channel, peer }) => {
let quote = match self.make_quote(self.min_buy, self.max_buy).await { let quote = match self.make_quote(self.min_buy, self.max_buy, self.max_swap_timeout).await {
Ok(quote) => quote, Ok(quote) => quote,
Err(error) => { Err(error) => {
tracing::warn!(%peer, "Failed to make quote: {:#}", error); tracing::warn!(%peer, "Failed to make quote: {:#}", error);
@ -322,6 +326,7 @@ where
&mut self, &mut self,
min_buy: bitcoin::Amount, min_buy: bitcoin::Amount,
max_buy: bitcoin::Amount, max_buy: bitcoin::Amount,
max_swap_timeout: Duration,
) -> Result<BidQuote> { ) -> Result<BidQuote> {
let ask_price = self let ask_price = self
.latest_rate .latest_rate
@ -351,6 +356,7 @@ where
price: ask_price, price: ask_price,
min_quantity: bitcoin::Amount::ZERO, min_quantity: bitcoin::Amount::ZERO,
max_quantity: bitcoin::Amount::ZERO, max_quantity: bitcoin::Amount::ZERO,
valid_duration: Some(max_swap_timeout),
}); });
} }
@ -363,6 +369,7 @@ where
price: ask_price, price: ask_price,
min_quantity: min_buy, min_quantity: min_buy,
max_quantity: max_bitcoin_for_monero, max_quantity: max_bitcoin_for_monero,
valid_duration: Some(max_swap_timeout),
}); });
} }
@ -370,6 +377,7 @@ where
price: ask_price, price: ask_price,
min_quantity: min_buy, min_quantity: min_buy,
max_quantity: max_buy, max_quantity: max_buy,
valid_duration: Some(max_swap_timeout),
}) })
} }

View File

@ -127,9 +127,11 @@ pub mod behaviour {
where where
LR: LatestRate + Send + 'static, LR: LatestRate + Send + 'static,
{ {
#[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
min_buy: bitcoin::Amount, min_buy: bitcoin::Amount,
max_buy: bitcoin::Amount, max_buy: bitcoin::Amount,
max_swap_timeout: Duration,
latest_rate: LR, latest_rate: LR,
resume_only: bool, resume_only: bool,
env_config: env::Config, env_config: env::Config,
@ -154,6 +156,7 @@ pub mod behaviour {
swap_setup: alice::Behaviour::new( swap_setup: alice::Behaviour::new(
min_buy, min_buy,
max_buy, max_buy,
max_swap_timeout,
env_config, env_config,
latest_rate, latest_rate,
resume_only, resume_only,

View File

@ -22,6 +22,7 @@ use std::convert::TryInto;
use std::env; use std::env;
use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration;
use structopt::clap; use structopt::clap;
use structopt::clap::ErrorKind; use structopt::clap::ErrorKind;
use swap::asb::command::{parse_args, Arguments, Command}; use swap::asb::command::{parse_args, Arguments, Command};
@ -170,6 +171,7 @@ async fn main() -> Result<()> {
&seed, &seed,
config.maker.min_buy_btc, config.maker.min_buy_btc,
config.maker.max_buy_btc, config.maker.max_buy_btc,
Duration::from_secs(120),
kraken_rate.clone(), kraken_rate.clone(),
resume_only, resume_only,
env_config, env_config,
@ -201,6 +203,7 @@ async fn main() -> Result<()> {
kraken_rate.clone(), kraken_rate.clone(),
config.maker.min_buy_btc, config.maker.min_buy_btc,
config.maker.max_buy_btc, config.maker.max_buy_btc,
Duration::from_secs(120),
config.maker.external_bitcoin_redeem_address, config.maker.external_bitcoin_redeem_address,
) )
.unwrap(); .unwrap();

View File

@ -403,6 +403,7 @@ mod tests {
price: Amount::from_btc(0.001).unwrap(), price: Amount::from_btc(0.001).unwrap(),
max_quantity: Amount::from_btc(btc).unwrap(), max_quantity: Amount::from_btc(btc).unwrap(),
min_quantity: Amount::ZERO, min_quantity: Amount::ZERO,
valid_duration: Some(Duration::from_secs(120)),
} }
} }
@ -411,6 +412,7 @@ mod tests {
price: Amount::from_btc(0.001).unwrap(), price: Amount::from_btc(0.001).unwrap(),
max_quantity: Amount::max_value(), max_quantity: Amount::max_value(),
min_quantity: Amount::from_btc(btc).unwrap(), min_quantity: Amount::from_btc(btc).unwrap(),
valid_duration: Some(Duration::from_secs(120)),
} }
} }

View File

@ -78,6 +78,7 @@ mod tests {
price: bitcoin::Amount::from_sat(1337), price: bitcoin::Amount::from_sat(1337),
min_quantity: bitcoin::Amount::from_sat(42), min_quantity: bitcoin::Amount::from_sat(42),
max_quantity: bitcoin::Amount::from_sat(9001), max_quantity: bitcoin::Amount::from_sat(9001),
valid_duration: Some(Duration::from_secs(120)),
}; };
let mut asb = new_swarm(|_, identity| { let mut asb = new_swarm(|_, identity| {

View File

@ -344,6 +344,7 @@ mod tests {
price: Default::default(), price: Default::default(),
min_quantity: Default::default(), min_quantity: Default::default(),
max_quantity: Default::default(), max_quantity: Default::default(),
valid_duration: Some(Duration::from_secs(120)),
}), }),
}, },
]; ];
@ -359,6 +360,7 @@ mod tests {
price: Default::default(), price: Default::default(),
min_quantity: Default::default(), min_quantity: Default::default(),
max_quantity: Default::default(), max_quantity: Default::default(),
valid_duration: Some(Duration::from_secs(120)),
}) })
}, },
Seller { Seller {

View File

@ -7,6 +7,7 @@ use libp2p::request_response::{
}; };
use libp2p::PeerId; use libp2p::PeerId;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::time::Duration;
const PROTOCOL: &str = "/comit/xmr/btc/bid-quote/1.0.0"; const PROTOCOL: &str = "/comit/xmr/btc/bid-quote/1.0.0";
pub type OutEvent = RequestResponseEvent<(), BidQuote>; pub type OutEvent = RequestResponseEvent<(), BidQuote>;
@ -35,6 +36,7 @@ pub struct BidQuote {
/// The maximum quantity the maker is willing to buy. /// The maximum quantity the maker is willing to buy.
#[serde(with = "::bitcoin::util::amount::serde::as_sat")] #[serde(with = "::bitcoin::util::amount::serde::as_sat")]
pub max_quantity: bitcoin::Amount, pub max_quantity: bitcoin::Amount,
pub valid_duration: Option<Duration>,
} }
#[derive(Clone, Copy, Debug, thiserror::Error)] #[derive(Clone, Copy, Debug, thiserror::Error)]

View File

@ -118,6 +118,7 @@ pub struct Behaviour<LR> {
events: VecDeque<OutEvent>, events: VecDeque<OutEvent>,
min_buy: bitcoin::Amount, min_buy: bitcoin::Amount,
max_buy: bitcoin::Amount, max_buy: bitcoin::Amount,
max_swap_timeout: Duration,
env_config: env::Config, env_config: env::Config,
latest_rate: LR, latest_rate: LR,
@ -128,6 +129,7 @@ impl<LR> Behaviour<LR> {
pub fn new( pub fn new(
min_buy: bitcoin::Amount, min_buy: bitcoin::Amount,
max_buy: bitcoin::Amount, max_buy: bitcoin::Amount,
max_swap_timeout: Duration,
env_config: env::Config, env_config: env::Config,
latest_rate: LR, latest_rate: LR,
resume_only: bool, resume_only: bool,
@ -136,6 +138,7 @@ impl<LR> Behaviour<LR> {
events: Default::default(), events: Default::default(),
min_buy, min_buy,
max_buy, max_buy,
max_swap_timeout,
env_config, env_config,
latest_rate, latest_rate,
resume_only, resume_only,
@ -154,6 +157,7 @@ where
Handler::new( Handler::new(
self.min_buy, self.min_buy,
self.max_buy, self.max_buy,
self.max_swap_timeout,
self.env_config, self.env_config,
self.latest_rate.clone(), self.latest_rate.clone(),
self.resume_only, self.resume_only,
@ -214,7 +218,7 @@ pub struct Handler<LR> {
latest_rate: LR, latest_rate: LR,
resume_only: bool, resume_only: bool,
timeout: Duration, max_swap_timeout: Duration,
keep_alive: KeepAlive, keep_alive: KeepAlive,
} }
@ -222,6 +226,7 @@ impl<LR> Handler<LR> {
fn new( fn new(
min_buy: bitcoin::Amount, min_buy: bitcoin::Amount,
max_buy: bitcoin::Amount, max_buy: bitcoin::Amount,
max_swap_timeout: Duration,
env_config: env::Config, env_config: env::Config,
latest_rate: LR, latest_rate: LR,
resume_only: bool, resume_only: bool,
@ -234,7 +239,7 @@ impl<LR> Handler<LR> {
env_config, env_config,
latest_rate, latest_rate,
resume_only, resume_only,
timeout: Duration::from_secs(120), max_swap_timeout,
keep_alive: KeepAlive::Until(Instant::now() + Duration::from_secs(10)), keep_alive: KeepAlive::Until(Instant::now() + Duration::from_secs(10)),
} }
} }
@ -280,7 +285,7 @@ where
let latest_rate = self.latest_rate.latest_rate(); let latest_rate = self.latest_rate.latest_rate();
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.max_swap_timeout, async move {
let request = swap_setup::read_cbor_message::<SpotPriceRequest>(&mut substream) let request = swap_setup::read_cbor_message::<SpotPriceRequest>(&mut substream)
.await .await
.context("Failed to read spot price request")?; .context("Failed to read spot price request")?;
@ -404,7 +409,7 @@ where
Ok((swap_id, state3)) Ok((swap_id, state3))
}); });
let max_seconds = self.timeout.as_secs(); let max_seconds = self.max_swap_timeout.as_secs();
self.inbound_stream = OptionFuture::from(Some( self.inbound_stream = OptionFuture::from(Some(
async move { async move {
protocol.await.with_context(|| { protocol.await.with_context(|| {

View File

@ -7,12 +7,14 @@ use anyhow::Result;
use libp2p::swarm::{NetworkBehaviour, SwarmBuilder}; use libp2p::swarm::{NetworkBehaviour, SwarmBuilder};
use libp2p::{identity, Multiaddr, Swarm}; use libp2p::{identity, Multiaddr, Swarm};
use std::fmt::Debug; use std::fmt::Debug;
use std::time::Duration;
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn asb<LR>( pub fn asb<LR>(
seed: &Seed, seed: &Seed,
min_buy: bitcoin::Amount, min_buy: bitcoin::Amount,
max_buy: bitcoin::Amount, max_buy: bitcoin::Amount,
max_swap_timeout: Duration,
latest_rate: LR, latest_rate: LR,
resume_only: bool, resume_only: bool,
env_config: env::Config, env_config: env::Config,
@ -38,6 +40,7 @@ where
let behaviour = asb::Behaviour::new( let behaviour = asb::Behaviour::new(
min_buy, min_buy,
max_buy, max_buy,
max_swap_timeout,
latest_rate, latest_rate,
resume_only, resume_only,
env_config, env_config,

View File

@ -242,6 +242,7 @@ async fn start_alice(
seed, seed,
min_buy, min_buy,
max_buy, max_buy,
Duration::from_secs(120),
latest_rate, latest_rate,
resume_only, resume_only,
env_config, env_config,
@ -260,6 +261,7 @@ async fn start_alice(
FixedRate::default(), FixedRate::default(),
min_buy, min_buy,
max_buy, max_buy,
Duration::from_secs(120),
None, None,
) )
.unwrap(); .unwrap();