Move max_buy and ask_spread into config

Max-buy and spread is not something that one would configure on every run.
More convenient to keep this in the config.

The max-buy Bitcoin value was adapted to `0.02` which is more reasonable for mainnet.
Activated feature `serde-float` to serialize the spread (Decimal) as float instead of string.

```
...

[maker]
max_buy_btc = 0.02
ask_spread = 0.02
```
This commit is contained in:
Daniel Karzel 2021-05-07 13:25:25 +10:00
parent 538b25a6dd
commit 1d62f4916c
No known key found for this signature in database
GPG Key ID: 30C3FC2E438ADB6E
5 changed files with 49 additions and 26 deletions

View File

@ -41,6 +41,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2. Buy amount sent by CLI exceeds maximum buy amount accepted by ASB 2. Buy amount sent by CLI exceeds maximum buy amount accepted by ASB
3. ASB is running in resume-only mode and does not accept incoming swap requests 3. ASB is running in resume-only mode and does not accept incoming swap requests
### Changed
- The ASB's `--max-buy` and `ask-spread` parameter were removed in favour of entries in the config file.
The initial setup includes setting these two values now.
## [0.5.0] - 2021-04-17 ## [0.5.0] - 2021-04-17
### Changed ### Changed

View File

@ -40,7 +40,7 @@ proptest = "1"
rand = "0.7" rand = "0.7"
rand_chacha = "0.2" rand_chacha = "0.2"
reqwest = { version = "0.11", features = [ "rustls-tls", "stream", "socks" ], default-features = false } reqwest = { version = "0.11", features = [ "rustls-tls", "stream", "socks" ], default-features = false }
rust_decimal = "1" rust_decimal = { version = "1", features = [ "serde-float" ] }
rust_decimal_macros = "1" rust_decimal_macros = "1"
serde = { version = "1", features = [ "derive" ] } serde = { version = "1", features = [ "derive" ] }
serde_cbor = "0.11" serde_cbor = "0.11"

View File

@ -1,7 +1,5 @@
use crate::bitcoin::Amount; use crate::bitcoin::Amount;
use bitcoin::util::amount::ParseAmountError; use bitcoin::Address;
use bitcoin::{Address, Denomination};
use rust_decimal::Decimal;
use std::path::PathBuf; use std::path::PathBuf;
use uuid::Uuid; use uuid::Uuid;
@ -28,15 +26,6 @@ pub struct Arguments {
pub enum Command { pub enum Command {
#[structopt(about = "Main command to run the ASB.")] #[structopt(about = "Main command to run the ASB.")]
Start { Start {
#[structopt(long = "max-buy-btc", help = "The maximum amount of BTC the ASB is willing to buy.", default_value = "0.005", parse(try_from_str = parse_btc))]
max_buy: Amount,
#[structopt(
long = "ask-spread",
help = "The spread in percent that should be applied to the asking price.",
default_value = "0.02"
)]
ask_spread: Decimal,
#[structopt( #[structopt(
long = "resume-only", long = "resume-only",
help = "For maintenance only. When set, no new swap requests will be accepted, but existing unfinished swaps will be resumed." help = "For maintenance only. When set, no new swap requests will be accepted, but existing unfinished swaps will be resumed."
@ -124,7 +113,3 @@ pub struct RecoverCommandParams {
)] )]
pub force: bool, pub force: bool,
} }
fn parse_btc(s: &str) -> Result<Amount, ParseAmountError> {
Amount::from_str_in(s, Denomination::Bitcoin)
}

View File

@ -1,10 +1,12 @@
use crate::fs::{ensure_directory_exists, system_config_dir, system_data_dir}; use crate::fs::{ensure_directory_exists, system_config_dir, system_data_dir};
use crate::tor::{DEFAULT_CONTROL_PORT, DEFAULT_SOCKS5_PORT}; use crate::tor::{DEFAULT_CONTROL_PORT, DEFAULT_SOCKS5_PORT};
use anyhow::{Context, Result}; use anyhow::{bail, Context, Result};
use config::ConfigError; use config::ConfigError;
use dialoguer::theme::ColorfulTheme; use dialoguer::theme::ColorfulTheme;
use dialoguer::Input; use dialoguer::Input;
use libp2p::core::Multiaddr; use libp2p::core::Multiaddr;
use rust_decimal::prelude::FromPrimitive;
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fs; use std::fs;
@ -18,6 +20,9 @@ const DEFAULT_ELECTRUM_RPC_URL: &str = "ssl://electrum.blockstream.info:60002";
const DEFAULT_MONERO_WALLET_RPC_TESTNET_URL: &str = "http://127.0.0.1:38083/json_rpc"; const DEFAULT_MONERO_WALLET_RPC_TESTNET_URL: &str = "http://127.0.0.1:38083/json_rpc";
const DEFAULT_BITCOIN_CONFIRMATION_TARGET: usize = 3; const DEFAULT_BITCOIN_CONFIRMATION_TARGET: usize = 3;
const DEFAULT_MAX_BUY_AMOUNT: f64 = 0.02f64;
const DEFAULT_SPREAD: f64 = 0.02f64;
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)] #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)]
pub struct Config { pub struct Config {
pub data: Data, pub data: Data,
@ -25,6 +30,7 @@ pub struct Config {
pub bitcoin: Bitcoin, pub bitcoin: Bitcoin,
pub monero: Monero, pub monero: Monero,
pub tor: TorConf, pub tor: TorConf,
pub maker: Maker,
} }
impl Config { impl Config {
@ -72,6 +78,14 @@ pub struct TorConf {
pub socks5_port: u16, pub socks5_port: u16,
} }
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Maker {
#[serde(with = "::bitcoin::util::amount::serde::as_btc")]
pub max_buy_btc: bitcoin::Amount,
pub ask_spread: Decimal,
}
impl Default for TorConf { impl Default for TorConf {
fn default() -> Self { fn default() -> Self {
Self { Self {
@ -186,6 +200,21 @@ pub fn query_user_for_initial_testnet_config() -> Result<Config> {
.default(DEFAULT_SOCKS5_PORT.to_owned()) .default(DEFAULT_SOCKS5_PORT.to_owned())
.interact_text()?; .interact_text()?;
let max_buy = Input::with_theme(&ColorfulTheme::default())
.with_prompt("Enter maximum Bitcoin amount you are willing to accept per swap or hit enter to use default.")
.default(DEFAULT_MAX_BUY_AMOUNT)
.interact_text()?;
let max_buy = bitcoin::Amount::from_btc(max_buy)?;
let ask_spread = Input::with_theme(&ColorfulTheme::default())
.with_prompt("Enter spread (in percent; value between 0.x and 1.0) to be used on top of the market rate or hit enter to use default.")
.default(DEFAULT_SPREAD)
.interact_text()?;
if !(0.0..=1.0).contains(&ask_spread) {
bail!(format!("Invalid spread {}. For the spread value floating point number in interval [0..1] are allowed.", ask_spread))
}
let ask_spread = Decimal::from_f64(ask_spread).context("Unable to parse spread")?;
println!(); println!();
Ok(Config { Ok(Config {
@ -204,6 +233,10 @@ pub fn query_user_for_initial_testnet_config() -> Result<Config> {
control_port: tor_control_port, control_port: tor_control_port,
socks5_port: tor_socks5_port, socks5_port: tor_socks5_port,
}, },
maker: Maker {
max_buy_btc: max_buy,
ask_spread,
},
}) })
} }
@ -237,6 +270,10 @@ mod tests {
wallet_rpc_url: Url::from_str(DEFAULT_MONERO_WALLET_RPC_TESTNET_URL).unwrap(), wallet_rpc_url: Url::from_str(DEFAULT_MONERO_WALLET_RPC_TESTNET_URL).unwrap(),
}, },
tor: Default::default(), tor: Default::default(),
maker: Maker {
max_buy_btc: bitcoin::Amount::from_btc(DEFAULT_MAX_BUY_AMOUNT).unwrap(),
ask_spread: Decimal::from_f64(DEFAULT_SPREAD).unwrap(),
},
}; };
initial_setup(config_path.clone(), || Ok(expected.clone())).unwrap(); initial_setup(config_path.clone(), || Ok(expected.clone())).unwrap();

View File

@ -79,11 +79,7 @@ async fn main() -> Result<()> {
let env_config = env::Testnet::get_config(); let env_config = env::Testnet::get_config();
match opt.cmd { match opt.cmd {
Command::Start { Command::Start { resume_only } => {
max_buy,
ask_spread,
resume_only,
} => {
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?; let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
let monero_wallet = init_monero_wallet(&config, env_config).await?; let monero_wallet = init_monero_wallet(&config, env_config).await?;
@ -122,12 +118,12 @@ async fn main() -> Result<()> {
let current_balance = monero_wallet.get_balance().await?; let current_balance = monero_wallet.get_balance().await?;
let lock_fee = monero_wallet.static_tx_fee_estimate(); let lock_fee = monero_wallet.static_tx_fee_estimate();
let kraken_rate = KrakenRate::new(ask_spread, kraken_price_updates); let kraken_rate = KrakenRate::new(config.maker.ask_spread, kraken_price_updates);
let mut swarm = swarm::alice( let mut swarm = swarm::alice(
&seed, &seed,
current_balance, current_balance,
lock_fee, lock_fee,
max_buy, config.maker.max_buy_btc,
kraken_rate.clone(), kraken_rate.clone(),
resume_only, resume_only,
)?; )?;
@ -144,7 +140,7 @@ async fn main() -> Result<()> {
Arc::new(monero_wallet), Arc::new(monero_wallet),
Arc::new(db), Arc::new(db),
kraken_rate, kraken_rate,
max_buy, config.maker.max_buy_btc,
) )
.unwrap(); .unwrap();