From 19f5132ee8439ef3d4d27dd7254104d60c8540af Mon Sep 17 00:00:00 2001 From: edouardparis Date: Tue, 22 Apr 2025 17:43:05 +0200 Subject: [PATCH] Remove the link between gui config and lianad config This commit is part of preparatory work to support multiple wallets. This commit introduces two breaking change: The fields daemon_config_path and daemon_rpc_path are removed. The GUI will deduce these values from their expected location in the root data directory. Because this link is removed, the gui flag --conf is not useful anymore as it cannot then find the location of the root data directory. --- liana-gui/src/app/config.rs | 8 +--- liana-gui/src/app/mod.rs | 13 +++--- liana-gui/src/installer/mod.rs | 9 +--- liana-gui/src/launcher.rs | 25 +++++------ liana-gui/src/loader.rs | 43 ++++++++++--------- liana-gui/src/main.rs | 76 ++++------------------------------ 6 files changed, 49 insertions(+), 125 deletions(-) diff --git a/liana-gui/src/app/config.rs b/liana-gui/src/app/config.rs index 3e834deb..0d7b5aaf 100644 --- a/liana-gui/src/app/config.rs +++ b/liana-gui/src/app/config.rs @@ -6,10 +6,6 @@ use tracing_subscriber::filter; #[derive(Debug, Clone, Deserialize, Serialize)] pub struct Config { - /// Path to lianad configuration file. - pub daemon_config_path: Option, - /// Path to lianad_rpc socket file. - pub daemon_rpc_path: Option, /// log level, can be "info", "debug", "trace". pub log_level: Option, /// Use iced debug feature if true. @@ -22,10 +18,8 @@ pub struct Config { pub const DEFAULT_FILE_NAME: &str = "gui.toml"; impl Config { - pub fn new(daemon_config_path: PathBuf, start_internal_bitcoind: bool) -> Self { + pub fn new(start_internal_bitcoind: bool) -> Self { Self { - daemon_config_path: Some(daemon_config_path), - daemon_rpc_path: None, log_level: None, debug: None, start_internal_bitcoind, diff --git a/liana-gui/src/app/mod.rs b/liana-gui/src/app/mod.rs index cce65196..1e1d93ba 100644 --- a/liana-gui/src/app/mod.rs +++ b/liana-gui/src/app/mod.rs @@ -143,7 +143,6 @@ impl Panels { pub struct App { cache: Cache, - config: Arc, wallet: Arc, daemon: Arc, internal_bitcoind: Option, @@ -176,7 +175,6 @@ impl App { Self { panels, cache, - config, daemon, wallet, internal_bitcoind, @@ -361,10 +359,7 @@ impl App { Task::none() } Message::LoadDaemonConfig(cfg) => { - let path = self.config.daemon_config_path.clone().expect( - "Application config must have a daemon configuration file path at this point.", - ); - let res = self.load_daemon_config(&path, *cfg); + let res = self.load_daemon_config(self.cache.datadir_path.clone(), *cfg); self.update(Message::DaemonConfigLoaded(res)) } Message::WalletUpdated(Ok(wallet)) => { @@ -386,12 +381,16 @@ impl App { pub fn load_daemon_config( &mut self, - daemon_config_path: &PathBuf, + datadir_path: PathBuf, cfg: DaemonConfig, ) -> Result<(), Error> { Handle::current().block_on(async { self.daemon.stop().await })?; + let network = cfg.bitcoin_config.network; let daemon = EmbeddedDaemon::start(cfg)?; self.daemon = Arc::new(daemon); + let mut daemon_config_path = datadir_path; + daemon_config_path.push(network.to_string()); + daemon_config_path.push("daemon.toml"); let content = toml::to_string(&self.daemon.config()).map_err(|e| Error::Config(e.to_string()))?; diff --git a/liana-gui/src/installer/mod.rs b/liana-gui/src/installer/mod.rs index 245121cf..b012dead 100644 --- a/liana-gui/src/installer/mod.rs +++ b/liana-gui/src/installer/mod.rs @@ -380,7 +380,7 @@ pub async fn install_local_wallet( .map_err(|e| Error::Unexpected(format!("Failed to serialize daemon config: {}", e)))?; // create lianad configuration file - let daemon_config_path = create_and_write_file( + let _daemon_config_path = create_and_write_file( network_datadir_path.clone(), "daemon.toml", daemon_config.to_string().as_bytes(), @@ -421,9 +421,6 @@ pub async fn install_local_wallet( network_datadir_path.clone(), gui_config::DEFAULT_FILE_NAME, toml::to_string(&gui_config::Config::new( - daemon_config_path.canonicalize().map_err(|e| { - Error::Unexpected(format!("Failed to canonicalize daemon config path: {}", e)) - })?, // Installer started a bitcoind, it is expected that gui will start it on startup ctx.internal_bitcoind.is_some(), )) @@ -497,8 +494,6 @@ pub async fn create_remote_wallet( network_datadir_path.clone(), gui_config::DEFAULT_FILE_NAME, toml::to_string(&gui_config::Config { - daemon_config_path: None, - daemon_rpc_path: None, log_level: Some("info".to_string()), debug: Some(false), start_internal_bitcoind: false, @@ -613,8 +608,6 @@ pub async fn import_remote_wallet( network_datadir_path.clone(), gui_config::DEFAULT_FILE_NAME, toml::to_string(&gui_config::Config { - daemon_config_path: None, - daemon_rpc_path: None, log_level: Some("info".to_string()), debug: Some(false), start_internal_bitcoind: false, diff --git a/liana-gui/src/launcher.rs b/liana-gui/src/launcher.rs index c515ce5a..811af462 100644 --- a/liana-gui/src/launcher.rs +++ b/liana-gui/src/launcher.rs @@ -464,21 +464,22 @@ async fn check_network_datadir(path: PathBuf, network: Network) -> Result cfg, - Err(e) => { - if e == app::config::ConfigError::NotFound { - return Ok(State::NoWallet); - } else { - return Err(format!( - "Failed to read GUI configuration file in the directory: {}", - path.to_string_lossy() - )); - } + if let Err(e) = app::Config::from_file(&config_path) { + if e == app::config::ConfigError::NotFound { + return Ok(State::NoWallet); + } else { + return Err(format!( + "Failed to read GUI configuration file in the directory: {}", + path.to_string_lossy() + )); } }; - if let Some(daemon_config_path) = cfg.daemon_config_path { + let mut daemon_config_path = path.clone(); + daemon_config_path.push(network.to_string()); + daemon_config_path.push("daemon.toml"); + + if daemon_config_path.exists() { lianad::config::Config::from_file(Some(daemon_config_path.clone())).map_err(|e| match e { ConfigError::FileNotFound | ConfigError::DatadirNotFound => { diff --git a/liana-gui/src/loader.rs b/liana-gui/src/loader.rs index ccd66abe..bef26aac 100644 --- a/liana-gui/src/loader.rs +++ b/liana-gui/src/loader.rs @@ -119,10 +119,7 @@ impl Loader { internal_bitcoind: Option, backup: Option, ) -> (Self, Task) { - let path = gui_config - .daemon_rpc_path - .clone() - .unwrap_or_else(|| socket_path(&datadir_path, network)); + let path = socket_path(&datadir_path, network); ( Loader { network, @@ -185,22 +182,18 @@ impl Loader { Error::Daemon(DaemonError::ClientNotSupported) | Error::Daemon(DaemonError::RpcSocket(Some(ErrorKind::ConnectionRefused), _)) | Error::Daemon(DaemonError::RpcSocket(Some(ErrorKind::NotFound), _)) => { - if let Some(daemon_config_path) = self.gui_config.daemon_config_path.clone() { - self.step = Step::StartingDaemon; - self.daemon_started = true; - self.waiting_daemon_bitcoind = true; - return Task::perform( - start_bitcoind_and_daemon( - daemon_config_path, - self.datadir_path.clone(), - self.gui_config.start_internal_bitcoind - && self.internal_bitcoind.is_none(), - ), - Message::Started, - ); - } else { - self.step = Step::Error(Box::new(e)); - } + self.step = Step::StartingDaemon; + self.daemon_started = true; + self.waiting_daemon_bitcoind = true; + return Task::perform( + start_bitcoind_and_daemon( + self.datadir_path.clone(), + self.gui_config.start_internal_bitcoind + && self.internal_bitcoind.is_none(), + self.network, + ), + Message::Started, + ); } _ => { self.step = Step::Error(Box::new(e)); @@ -291,7 +284,10 @@ impl Loader { bitcoind.stop(); log::info!("Managed bitcoind stopped."); } else if self.waiting_daemon_bitcoind && self.gui_config.start_internal_bitcoind { - if let Ok(config) = Config::from_file(self.gui_config.daemon_config_path.clone()) { + let mut daemon_config_path = self.datadir_path.clone(); + daemon_config_path.push(self.network.to_string()); + daemon_config_path.push("daemon.toml"); + if let Ok(config) = Config::from_file(Some(daemon_config_path)) { if let Some(BitcoinBackend::Bitcoind(bitcoind_config)) = &config.bitcoin_backend { let mut retry = 0; while !stop_bitcoind(bitcoind_config) && retry < 10 { @@ -551,10 +547,13 @@ async fn connect( // Daemon can start only if a config path is given. pub async fn start_bitcoind_and_daemon( - config_path: PathBuf, liana_datadir_path: PathBuf, start_internal_bitcoind: bool, + network: bitcoin::Network, ) -> StartedResult { + let mut config_path = liana_datadir_path.clone(); + config_path.push(network.to_string()); + config_path.push("daemon.toml"); let config = Config::from_file(Some(config_path)).map_err(Error::Config)?; let mut bitcoind: Option = None; if start_internal_bitcoind { diff --git a/liana-gui/src/main.rs b/liana-gui/src/main.rs index 50cae804..ec867a14 100644 --- a/liana-gui/src/main.rs +++ b/liana-gui/src/main.rs @@ -19,7 +19,7 @@ extern crate serde_json; use liana::miniscript::bitcoin; use liana_ui::{component::text, font, image, theme, widget::Element}; -use lianad::{commands::ListCoinsResult, config::Config as DaemonConfig}; +use lianad::commands::ListCoinsResult; use liana_gui::{ app::{self, cache::Cache, config::default_datadir, wallet::Wallet, App}, @@ -39,7 +39,6 @@ use liana_gui::{ #[derive(Debug, PartialEq)] enum Arg { - ConfigPath(PathBuf), DatadirPath(PathBuf), Network(bitcoin::Network), } @@ -58,7 +57,6 @@ fn parse_args(args: Vec) -> Result, Box> { Usage: liana-gui [OPTIONS] Options: - --conf Path of configuration file (gui.toml) --datadir Path of liana datadir -v, --version Display liana-gui version -h, --help Print help @@ -72,13 +70,7 @@ Options: } for (i, arg) in args.iter().enumerate() { - if arg == "--conf" { - if let Some(a) = args.get(i + 1) { - res.push(Arg::ConfigPath(PathBuf::from(a))); - } else { - return Err("missing arg to --conf".into()); - } - } else if arg == "--datadir" { + if arg == "--datadir" { if let Some(a) = args.get(i + 1) { res.push(Arg::DatadirPath(PathBuf::from(a))); } else { @@ -315,27 +307,20 @@ impl GUI { command.map(|msg| Message::Login(Box::new(msg))) } else { let cfg = app::Config::from_file(&path).expect("A config file was created"); - let daemon_cfg = - DaemonConfig::from_file(cfg.daemon_config_path.clone()).unwrap(); - let datadir_path = daemon_cfg - .data_dir - .as_ref() - .expect("Installer must have set it") - .clone(); self.logger.set_running_mode( - datadir_path.clone(), - daemon_cfg.bitcoin_config.network, + i.datadir.clone(), + i.network, self.log_level .unwrap_or_else(|| cfg.log_level().unwrap_or(LevelFilter::INFO)), ); if remove_log { - self.logger.remove_install_log_file(datadir_path.clone()); + self.logger.remove_install_log_file(i.datadir.clone()); } let (loader, command) = Loader::new( - datadir_path, + i.datadir.clone(), cfg, - daemon_cfg.bitcoin_config.network, + i.network, internal_bitcoind, i.context.backup.take(), ); @@ -561,39 +546,6 @@ fn main() -> Result<(), Box> { let datadir_path = default_datadir().unwrap(); Config::new(datadir_path, Some(*network)) } - [Arg::ConfigPath(path)] => { - let cfg = app::Config::from_file(path)?; - if let Some(daemon_config_path) = cfg.daemon_config_path.clone() { - let daemon_cfg = DaemonConfig::from_file(Some(daemon_config_path))?; - let datadir_path = daemon_cfg - .data_dir - .unwrap_or_else(|| default_datadir().unwrap()); - Ok(Config::Run( - datadir_path, - cfg, - daemon_cfg.bitcoin_config.network, - )) - } else { - Err("Application cannot guess network".into()) - } - } - [Arg::ConfigPath(path), Arg::Network(network)] - | [Arg::Network(network), Arg::ConfigPath(path)] => { - let cfg = app::Config::from_file(path)?; - if let Some(daemon_config_path) = cfg.daemon_config_path.clone() { - let daemon_cfg = DaemonConfig::from_file(Some(daemon_config_path))?; - let datadir_path = daemon_cfg - .data_dir - .unwrap_or_else(|| default_datadir().unwrap()); - Ok(Config::Run( - datadir_path, - cfg, - daemon_cfg.bitcoin_config.network, - )) - } else { - Ok(Config::Run(default_datadir().unwrap(), cfg, *network)) - } - } [Arg::DatadirPath(datadir_path)] => Config::new(datadir_path.clone(), None), [Arg::DatadirPath(datadir_path), Arg::Network(network)] | [Arg::Network(network), Arg::DatadirPath(datadir_path)] => { @@ -692,20 +644,6 @@ mod tests { fn test_parse_args() { assert!(parse_args(vec!["--meth".into()]).is_err()); assert!(parse_args(vec!["--datadir".into()]).is_err()); - assert!(parse_args(vec!["--conf".into()]).is_err()); - assert_eq!( - Some(vec![ - Arg::DatadirPath(PathBuf::from(".")), - Arg::ConfigPath(PathBuf::from("hello.toml")), - ]), - parse_args( - "--datadir . --conf hello.toml" - .split(' ') - .map(|a| a.to_string()) - .collect() - ) - .ok() - ); assert_eq!( Some(vec![Arg::Network(bitcoin::Network::Regtest)]), parse_args(vec!["--regtest".into()]).ok()