mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-02-11 20:38:52 -05:00
Extract determine_btc_to_swap
function and test it
We also instantiate tracing in to order to quickly validate, what the output for the different scenarios looks like.
This commit is contained in:
parent
601bf07255
commit
14dcd150af
@ -16,6 +16,7 @@ use anyhow::{bail, Context, Result};
|
||||
use prettytable::{row, Table};
|
||||
use reqwest::Url;
|
||||
use std::cmp::min;
|
||||
use std::future::Future;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
@ -25,6 +26,7 @@ use swap::cli::command::{Arguments, Command};
|
||||
use swap::cli::config::{read_config, Config};
|
||||
use swap::database::Database;
|
||||
use swap::execution_params::GetExecutionParams;
|
||||
use swap::network::quote::BidQuote;
|
||||
use swap::protocol::bob;
|
||||
use swap::protocol::bob::cancel::CancelError;
|
||||
use swap::protocol::bob::{Builder, EventLoop};
|
||||
@ -124,39 +126,22 @@ async fn main() -> Result<()> {
|
||||
)?;
|
||||
let handle = tokio::spawn(event_loop.run());
|
||||
|
||||
let bid_quote = event_loop_handle
|
||||
.request_quote()
|
||||
.await
|
||||
.context("failed to request quote")?;
|
||||
let send_bitcoin = determine_btc_to_swap(
|
||||
event_loop_handle.request_quote(),
|
||||
bitcoin_wallet.balance(),
|
||||
bitcoin_wallet.new_address(),
|
||||
async {
|
||||
while bitcoin_wallet.balance().await? == Amount::ZERO {
|
||||
bitcoin_wallet.sync_wallet().await?;
|
||||
|
||||
info!("Received quote: 1 XMR ~ {}", bid_quote.price);
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
}
|
||||
|
||||
// TODO: Also wait for more funds if balance < dust
|
||||
if bitcoin_wallet.balance().await? == Amount::ZERO {
|
||||
info!(
|
||||
"Please deposit the BTC you want to swap to {} (max {})",
|
||||
bitcoin_wallet.new_address().await?,
|
||||
bid_quote.max_quantity
|
||||
);
|
||||
|
||||
while bitcoin_wallet.balance().await? == Amount::ZERO {
|
||||
bitcoin_wallet.sync_wallet().await?;
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
}
|
||||
|
||||
debug!("Received {}", bitcoin_wallet.balance().await?);
|
||||
} else {
|
||||
info!(
|
||||
"Still got {} left in wallet, swapping ...",
|
||||
bitcoin_wallet.balance().await?
|
||||
);
|
||||
}
|
||||
|
||||
let max_giveable = bitcoin_wallet.max_giveable(TxLock::script_size()).await?;
|
||||
let max_accepted = bid_quote.max_quantity;
|
||||
|
||||
let send_bitcoin = min(max_giveable, max_accepted);
|
||||
bitcoin_wallet.balance().await
|
||||
},
|
||||
bitcoin_wallet.max_giveable(TxLock::script_size()),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let swap = Builder::new(
|
||||
db,
|
||||
@ -320,3 +305,133 @@ async fn init_monero_wallet(
|
||||
|
||||
Ok(monero_wallet)
|
||||
}
|
||||
|
||||
async fn determine_btc_to_swap(
|
||||
request_quote: impl Future<Output = Result<BidQuote>>,
|
||||
initial_balance: impl Future<Output = Result<bitcoin::Amount>>,
|
||||
get_new_address: impl Future<Output = Result<bitcoin::Address>>,
|
||||
wait_for_deposit: impl Future<Output = Result<bitcoin::Amount>>,
|
||||
max_giveable: impl Future<Output = Result<bitcoin::Amount>>,
|
||||
) -> Result<bitcoin::Amount> {
|
||||
debug!("Requesting quote");
|
||||
|
||||
let bid_quote = request_quote.await.context("failed to request quote")?;
|
||||
|
||||
info!("Received quote: 1 XMR ~ {}", bid_quote.price);
|
||||
|
||||
// TODO: Also wait for more funds if balance < dust
|
||||
let initial_balance = initial_balance.await?;
|
||||
|
||||
if initial_balance == Amount::ZERO {
|
||||
info!(
|
||||
"Please deposit the BTC you want to swap to {} (max {})",
|
||||
get_new_address.await?,
|
||||
bid_quote.max_quantity
|
||||
);
|
||||
|
||||
let new_balance = wait_for_deposit.await?;
|
||||
|
||||
info!("Received {}", new_balance);
|
||||
} else {
|
||||
info!("Found {} in wallet", initial_balance);
|
||||
}
|
||||
|
||||
let max_giveable = max_giveable.await?;
|
||||
let max_accepted = bid_quote.max_quantity;
|
||||
|
||||
if max_giveable > max_accepted {
|
||||
info!(
|
||||
"Max giveable amount {} exceeds max accepted amount {}!",
|
||||
max_giveable, max_accepted
|
||||
);
|
||||
}
|
||||
|
||||
Ok(min(max_giveable, max_accepted))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::determine_btc_to_swap;
|
||||
use ::bitcoin::Amount;
|
||||
use tracing::subscriber;
|
||||
|
||||
#[tokio::test]
|
||||
async fn given_no_balance_and_transfers_less_than_max_swaps_max_giveable() {
|
||||
let _guard = subscriber::set_default(tracing_subscriber::fmt().with_test_writer().finish());
|
||||
|
||||
let amount = determine_btc_to_swap(
|
||||
async { Ok(quote_with_max(0.01)) },
|
||||
async { Ok(Amount::ZERO) },
|
||||
get_dummy_address(),
|
||||
async { Ok(Amount::from_btc(0.0001)?) },
|
||||
async { Ok(Amount::from_btc(0.00009)?) },
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(amount, Amount::from_btc(0.00009).unwrap())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn given_no_balance_and_transfers_more_then_swaps_max_quantity_from_quote() {
|
||||
let _guard = subscriber::set_default(tracing_subscriber::fmt().with_test_writer().finish());
|
||||
|
||||
let amount = determine_btc_to_swap(
|
||||
async { Ok(quote_with_max(0.01)) },
|
||||
async { Ok(Amount::ZERO) },
|
||||
get_dummy_address(),
|
||||
async { Ok(Amount::from_btc(0.1)?) },
|
||||
async { Ok(Amount::from_btc(0.09)?) },
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(amount, Amount::from_btc(0.01).unwrap())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn given_initial_balance_below_max_quantity_swaps_max_givable() {
|
||||
let _guard = subscriber::set_default(tracing_subscriber::fmt().with_test_writer().finish());
|
||||
|
||||
let amount = determine_btc_to_swap(
|
||||
async { Ok(quote_with_max(0.01)) },
|
||||
async { Ok(Amount::from_btc(0.005)?) },
|
||||
async { panic!("should not request new address when initial balance is > 0") },
|
||||
async { panic!("should not wait for deposit when initial balance > 0") },
|
||||
async { Ok(Amount::from_btc(0.0049)?) },
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(amount, Amount::from_btc(0.0049).unwrap())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn given_initial_balance_above_max_quantity_swaps_max_quantity() {
|
||||
let _guard = subscriber::set_default(tracing_subscriber::fmt().with_test_writer().finish());
|
||||
|
||||
let amount = determine_btc_to_swap(
|
||||
async { Ok(quote_with_max(0.01)) },
|
||||
async { Ok(Amount::from_btc(0.1)?) },
|
||||
async { panic!("should not request new address when initial balance is > 0") },
|
||||
async { panic!("should not wait for deposit when initial balance > 0") },
|
||||
async { Ok(Amount::from_btc(0.09)?) },
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(amount, Amount::from_btc(0.01).unwrap())
|
||||
}
|
||||
|
||||
fn quote_with_max(btc: f64) -> BidQuote {
|
||||
BidQuote {
|
||||
price: Amount::from_btc(0.001).unwrap(),
|
||||
max_quantity: Amount::from_btc(btc).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_dummy_address() -> Result<bitcoin::Address> {
|
||||
Ok("1PdfytjS7C8wwd9Lq5o4x9aXA2YRqaCpH6".parse()?)
|
||||
}
|
||||
}
|
||||
|
@ -23,10 +23,10 @@ pub mod database;
|
||||
pub mod execution_params;
|
||||
pub mod fs;
|
||||
pub mod monero;
|
||||
pub mod network;
|
||||
pub mod protocol;
|
||||
pub mod seed;
|
||||
pub mod trace;
|
||||
|
||||
mod monero_ext;
|
||||
mod network;
|
||||
mod serde_peer_id;
|
||||
|
Loading…
x
Reference in New Issue
Block a user