From 63ef4838a705a6f9187cf607a4e320b71f374557 Mon Sep 17 00:00:00 2001 From: Michael Mallan Date: Fri, 16 May 2025 13:06:07 +0100 Subject: [PATCH] fix: use cookie file auth for new wallets with managed bitcoind There would be no way to get the RPC password of an existing managed bitcoind installation without looking in other daemon.toml files. An existing rpcauth field in the bitcoin.conf file will remain unchanged so that an existing wallet using username/password authentication will continue to work. --- liana-gui/src/installer/mod.rs | 21 ++++++++- liana-gui/src/installer/step/node/bitcoind.rs | 46 ++++++++++--------- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/liana-gui/src/installer/mod.rs b/liana-gui/src/installer/mod.rs index 2ebce40b..692bc0e0 100644 --- a/liana-gui/src/installer/mod.rs +++ b/liana-gui/src/installer/mod.rs @@ -12,7 +12,7 @@ use liana_ui::{ component::network_banner, widget::{Column, Element}, }; -use lianad::config::Config; +use lianad::config::{BitcoinBackend, BitcoindConfig, BitcoindRpcAuth, Config}; use std::ops::Deref; use tracing::{error, info, warn}; @@ -721,9 +721,26 @@ pub fn extract_daemon_config(ctx: &Context) -> Result { .to_path_buf() .canonicalize() .map_err(|e| Error::Unexpected(format!("Failed to canonicalize datadir path: {}", e)))?; + let bitcoin_backend = if let Some(BitcoinBackend::Bitcoind(BitcoindConfig { + rpc_auth: BitcoindRpcAuth::CookieFile(cookie_path), + addr, + })) = &ctx.bitcoin_backend + { + // The cookie path must exist for this canonicalization to succeed, which means bitcoind must be running. + // We already checked in the installer that bitcoind is running. + let cookie_path = cookie_path + .canonicalize() + .map_err(|e| Error::Unexpected(format!("Failed to canonicalize cookie path: {}", e)))?; + Some(BitcoinBackend::Bitcoind(BitcoindConfig { + rpc_auth: BitcoindRpcAuth::CookieFile(cookie_path), + addr: *addr, + })) + } else { + ctx.bitcoin_backend.clone() + }; Ok(Config::new( ctx.bitcoin_config.clone(), - ctx.bitcoin_backend.clone(), + bitcoin_backend, log::LevelFilter::Info, ctx.descriptor .clone() diff --git a/liana-gui/src/installer/step/node/bitcoind.rs b/liana-gui/src/installer/step/node/bitcoind.rs index 5388d49d..c6793f13 100644 --- a/liana-gui/src/installer/step/node/bitcoind.rs +++ b/liana-gui/src/installer/step/node/bitcoind.rs @@ -29,9 +29,9 @@ use crate::{ view, Error, }, node::bitcoind::{ - self, bitcoind_network_dir, internal_bitcoind_datadir, internal_bitcoind_directory, - Bitcoind, ConfigField, InternalBitcoindConfig, InternalBitcoindConfigError, - InternalBitcoindNetworkConfig, RpcAuth, RpcAuthType, RpcAuthValues, + self, bitcoind_network_dir, internal_bitcoind_cookie_path, internal_bitcoind_datadir, + internal_bitcoind_directory, Bitcoind, ConfigField, InternalBitcoindConfig, + InternalBitcoindConfigError, InternalBitcoindNetworkConfig, RpcAuthType, RpcAuthValues, StartInternalBitcoindError, VERSION, }, }; @@ -583,9 +583,9 @@ impl Step for InternalBitcoindStep { return Task::none(); } }; - let (rpc_port, p2p_port) = if let Some(network_conf) = - conf.networks.get(&self.network) - { + let network_conf = conf.networks.get(&self.network); + // Use same ports again if there is an existing installation. + let (rpc_port, p2p_port) = if let Some(network_conf) = network_conf { (network_conf.rpc_port, network_conf.p2p_port) } else { match (get_available_port(), get_available_port()) { @@ -611,24 +611,28 @@ impl Step for InternalBitcoindStep { } } }; - let (rpc_auth, rpc_password) = match RpcAuth::new("liana") { - Ok((rpc_auth, password)) => (rpc_auth, password), - Err(e) => { - self.error = Some(e.to_string()); - return Task::none(); - } - }; + + // Use cookie file authentication for new wallets. + // For an existing bitcoind, we would not know the RPC password to use without checking + // in other daemon.toml files. + let cookie_file_auth = BitcoindRpcAuth::CookieFile( + internal_bitcoind_cookie_path(&self.bitcoind_datadir, &self.network), + ); let bitcoind_config = BitcoindConfig { - rpc_auth: BitcoindRpcAuth::UserPass(rpc_auth.user.clone(), rpc_password), + rpc_auth: cookie_file_auth, addr: internal_bitcoind_address(rpc_port), }; - let network_conf = InternalBitcoindNetworkConfig { - rpc_port, - p2p_port, - prune: PRUNE_DEFAULT, - // Overwrite any previous entry for this network as we would no longer know the RPC password. - rpc_auth: Some(rpc_auth), - }; + // Use existing network conf if it exists as it may have rpc_auth field set. + // This ensures an existing wallet using username/password authentication will continue to work. + let network_conf = + network_conf + .cloned() + .unwrap_or(InternalBitcoindNetworkConfig { + rpc_port, + p2p_port, + prune: PRUNE_DEFAULT, + rpc_auth: None, // can be omitted for new bitcoin.conf entries + }); conf.networks.insert(self.network, network_conf); if let Err(e) = conf.to_file(&bitcoind::internal_bitcoind_config_path( &self.bitcoind_datadir,