From 9be6449e49ee90401999ebcfeda07f1024563f6a Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Thu, 28 Jan 2021 16:05:14 +1100 Subject: [PATCH 1/2] Default directory for storage and data-dir per command With this PR we default to the proper OS default directory for storing application data. Since the reset-config command does not require a data directory (and causes side effects with the default one), the data directory is not initialized per command. --- swap/src/cli.rs | 11 +++++++---- swap/src/fs.rs | 12 ++++++++++-- swap/src/main.rs | 23 ++++++++++++++--------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/swap/src/cli.rs b/swap/src/cli.rs index 1f72e89d..a38b33ab 100644 --- a/swap/src/cli.rs +++ b/swap/src/cli.rs @@ -5,9 +5,12 @@ use uuid::Uuid; #[derive(structopt::StructOpt, Debug)] pub struct Options { - // TODO: Default value should points to proper configuration folder in home folder - #[structopt(long = "data-dir", default_value = "./.swap-data/")] - pub data_dir: String, + #[structopt( + long = "data-dir", + help = "Provide a custom path to the data directory.", + parse(from_os_str) + )] + pub data_dir: Option, #[structopt(subcommand)] pub cmd: Command, @@ -80,7 +83,7 @@ pub enum Resume { pub struct Config { #[structopt( long = "config", - help = "Provide a custom path to a configuration file. The configuration file must be a toml file.", + help = "Provide a custom path to the configuration file. The configuration file must be a toml file.", parse(from_os_str) )] pub config_path: Option, diff --git a/swap/src/fs.rs b/swap/src/fs.rs index be07733b..d67caf75 100644 --- a/swap/src/fs.rs +++ b/swap/src/fs.rs @@ -6,17 +6,25 @@ use std::path::{Path, PathBuf}; // Linux: /home//.config/xmr-btc-swap/ // OSX: /Users//Library/Preferences/xmr-btc-swap/ #[allow(dead_code)] -fn config_dir() -> Option { +fn default_config_dir() -> Option { ProjectDirs::from("", "", "xmr-btc-swap").map(|proj_dirs| proj_dirs.config_dir().to_path_buf()) } #[allow(dead_code)] pub fn default_config_path() -> anyhow::Result { - config_dir() + default_config_dir() .map(|dir| Path::join(&dir, "config.toml")) .context("Could not generate default configuration path") } +/// This is to store the DB +// Linux: /home//.local/share/nectar/ +// OSX: /Users//Library/Application Support/nectar/ +#[allow(dead_code)] +pub fn default_data_dir() -> Option { + ProjectDirs::from("", "", "nectar").map(|proj_dirs| proj_dirs.data_dir().to_path_buf()) +} + pub fn ensure_directory_exists(file: &Path) -> Result<(), std::io::Error> { if let Some(path) = file.parent() { if !path.exists() { diff --git a/swap/src/main.rs b/swap/src/main.rs index 78d1d7af..7d2f6ec7 100644 --- a/swap/src/main.rs +++ b/swap/src/main.rs @@ -20,7 +20,7 @@ use crate::{ }; use anyhow::{Context, Result}; use database::Database; -use fs::default_config_path; +use fs::{default_config_path, default_data_dir}; use prettytable::{row, Table}; use protocol::{alice, bob, bob::Builder, SwapAmounts}; use settings::Settings; @@ -53,13 +53,18 @@ async fn main() -> Result<()> { let opt = Options::from_args(); + let data_dir = if let Some(data_dir) = opt.data_dir { + data_dir + } else { + default_data_dir().context("unable to determine default data path")? + }; + info!( "Database and Seed will be stored in directory: {}", - opt.data_dir + data_dir.display() ); - let data_dir = std::path::Path::new(opt.data_dir.as_str()).to_path_buf(); - let db_path = data_dir.join("database"); + let db_path = data_dir.join("database"); let seed = config::seed::Seed::from_file_or_generate(&data_dir) .expect("Could not retrieve/initialize seed") .into(); @@ -78,7 +83,7 @@ async fn main() -> Result<()> { btc: receive_bitcoin, }; - let (bitcoin_wallet, monero_wallet) = setup_wallets(settings.wallets).await?; + let (bitcoin_wallet, monero_wallet) = init_wallets(settings.wallets).await?; let swap_id = Uuid::new_v4(); @@ -117,7 +122,7 @@ async fn main() -> Result<()> { xmr: receive_monero, }; - let (bitcoin_wallet, monero_wallet) = setup_wallets(settings.wallets).await?; + let (bitcoin_wallet, monero_wallet) = init_wallets(settings.wallets).await?; let swap_id = Uuid::new_v4(); @@ -162,7 +167,7 @@ async fn main() -> Result<()> { }) => { let settings = init_settings(config.config_path)?; - let (bitcoin_wallet, monero_wallet) = setup_wallets(settings.wallets).await?; + let (bitcoin_wallet, monero_wallet) = init_wallets(settings.wallets).await?; let alice_factory = alice::Builder::new( seed, @@ -187,7 +192,7 @@ async fn main() -> Result<()> { }) => { let settings = init_settings(config.config_path)?; - let (bitcoin_wallet, monero_wallet) = setup_wallets(settings.wallets).await?; + let (bitcoin_wallet, monero_wallet) = init_wallets(settings.wallets).await?; let bob_factory = Builder::new( seed, @@ -229,7 +234,7 @@ fn init_settings(config_path: Option) -> Result { Ok(settings) } -async fn setup_wallets(settings: settings::Wallets) -> Result<(bitcoin::Wallet, monero::Wallet)> { +async fn init_wallets(settings: settings::Wallets) -> Result<(bitcoin::Wallet, monero::Wallet)> { let bitcoin_wallet = bitcoin::Wallet::new( settings.bitcoin.wallet_name.as_str(), settings.bitcoin.bitcoind_url, From eb34adc45dec493023fe5af12b9105fe6189e422 Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Fri, 29 Jan 2021 11:31:34 +1100 Subject: [PATCH 2/2] Remove config and fs from the lib The settings module has to be part of the lib because settings are used in the test as well. Config is only used in main, thus it should not leak into the lib. Note that this allows to remove the dead_code allowance in fs. --- swap/src/config.rs | 11 +++++++++-- swap/src/fs.rs | 3 --- swap/src/lib.rs | 2 -- swap/src/main.rs | 7 ++++--- swap/src/settings.rs | 16 ++++++---------- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/swap/src/config.rs b/swap/src/config.rs index 4eb21ceb..18a713a3 100644 --- a/swap/src/config.rs +++ b/swap/src/config.rs @@ -1,4 +1,4 @@ -use crate::fs::ensure_directory_exists; +use crate::{fs::ensure_directory_exists, settings::Settings}; use anyhow::{Context, Result}; use config::{Config, ConfigError}; use dialoguer::{theme::ColorfulTheme, Input}; @@ -17,7 +17,6 @@ const DEFAULT_BITCOIND_TESTNET_URL: &str = "http://127.0.0.1:18332"; const DEFAULT_MONERO_WALLET_RPC_TESTNET_URL: &str = "http://127.0.0.1:38083/json_rpc"; #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)] -#[serde(deny_unknown_fields)] pub struct File { pub bitcoin: Bitcoin, pub monero: Monero, @@ -117,6 +116,14 @@ pub fn query_user_for_initial_testnet_config() -> Result { }) } +pub fn settings_from_config_file_and_defaults(config: File) -> Settings { + Settings::testnet( + config.bitcoin.bitcoind_url, + config.bitcoin.wallet_name, + config.monero.wallet_rpc_url, + ) +} + #[cfg(test)] mod tests { use super::*; diff --git a/swap/src/fs.rs b/swap/src/fs.rs index d67caf75..c0de4ec0 100644 --- a/swap/src/fs.rs +++ b/swap/src/fs.rs @@ -5,12 +5,10 @@ use std::path::{Path, PathBuf}; /// This is to store the configuration and seed files // Linux: /home//.config/xmr-btc-swap/ // OSX: /Users//Library/Preferences/xmr-btc-swap/ -#[allow(dead_code)] fn default_config_dir() -> Option { ProjectDirs::from("", "", "xmr-btc-swap").map(|proj_dirs| proj_dirs.config_dir().to_path_buf()) } -#[allow(dead_code)] pub fn default_config_path() -> anyhow::Result { default_config_dir() .map(|dir| Path::join(&dir, "config.toml")) @@ -20,7 +18,6 @@ pub fn default_config_path() -> anyhow::Result { /// This is to store the DB // Linux: /home//.local/share/nectar/ // OSX: /Users//Library/Application Support/nectar/ -#[allow(dead_code)] pub fn default_data_dir() -> Option { ProjectDirs::from("", "", "nectar").map(|proj_dirs| proj_dirs.data_dir().to_path_buf()) } diff --git a/swap/src/lib.rs b/swap/src/lib.rs index 22b7c4a5..dd7d02c3 100644 --- a/swap/src/lib.rs +++ b/swap/src/lib.rs @@ -17,7 +17,6 @@ )] pub mod bitcoin; -pub mod config; pub mod database; pub mod monero; pub mod network; @@ -26,5 +25,4 @@ pub mod seed; pub mod settings; pub mod trace; -mod fs; mod serde_peer_id; diff --git a/swap/src/main.rs b/swap/src/main.rs index 7d2f6ec7..98b4f1a5 100644 --- a/swap/src/main.rs +++ b/swap/src/main.rs @@ -15,15 +15,16 @@ use crate::{ cli::{Command, Options, Resume}, config::{ - initial_setup, query_user_for_initial_testnet_config, read_config, ConfigNotInitialized, + initial_setup, query_user_for_initial_testnet_config, read_config, + settings_from_config_file_and_defaults, ConfigNotInitialized, }, + settings::Settings, }; use anyhow::{Context, Result}; use database::Database; use fs::{default_config_path, default_data_dir}; use prettytable::{row, Table}; use protocol::{alice, bob, bob::Builder, SwapAmounts}; -use settings::Settings; use std::{path::PathBuf, sync::Arc}; use structopt::StructOpt; use trace::init_tracing; @@ -229,7 +230,7 @@ fn init_settings(config_path: Option) -> Result { } }; - let settings = Settings::from_config_file_and_defaults(config); + let settings = settings_from_config_file_and_defaults(config); Ok(settings) } diff --git a/swap/src/settings.rs b/swap/src/settings.rs index dee7b84d..74571078 100644 --- a/swap/src/settings.rs +++ b/swap/src/settings.rs @@ -1,4 +1,4 @@ -use crate::{bitcoin::Timelock, config::File}; +use crate::bitcoin::Timelock; use conquer_once::Lazy; use std::time::Duration; use url::Url; @@ -9,15 +9,11 @@ pub struct Settings { } impl Settings { - pub fn from_config_file_and_defaults(config: File) -> Self { - Settings::testnet( - config.bitcoin.bitcoind_url, - config.bitcoin.wallet_name, - config.monero.wallet_rpc_url, - ) - } - - fn testnet(bitcoind_url: Url, bitcoin_wallet_name: String, monero_wallet_rpc_url: Url) -> Self { + pub fn testnet( + bitcoind_url: Url, + bitcoin_wallet_name: String, + monero_wallet_rpc_url: Url, + ) -> Self { Self { wallets: Wallets::testnet(bitcoind_url, bitcoin_wallet_name, monero_wallet_rpc_url), protocol: Protocol::testnet(),