Gui config: start_internal_bitcoind

Installer will install bitcoind in a directory
that will have always the same relative path to
the liana datadir.
GUI needs then only a flag "start_internal_bitcoind" set to true
to check the conventional path of the downloaded bitcoind exe
and start the internal bitcoind
This commit is contained in:
edouard 2023-08-31 11:50:43 +02:00
parent d700f8a3cf
commit bc87839e52
6 changed files with 63 additions and 100 deletions

View File

@ -3,15 +3,6 @@ use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};
use tracing_subscriber::filter;
/// Config required to start internal bitcoind.
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct InternalBitcoindExeConfig {
/// Internal bitcoind executable path.
pub exe_path: PathBuf,
/// Internal bitcoind data dir.
pub data_dir: PathBuf,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Config {
/// Path to lianad configuration file.
@ -25,24 +16,22 @@ pub struct Config {
/// hardware wallets config.
/// LEGACY: Use Settings module instead.
pub hardware_wallets: Option<Vec<HardwareWalletConfig>>,
/// Internal bitcoind executable config.
pub internal_bitcoind_exe_config: Option<InternalBitcoindExeConfig>,
/// Start internal bitcoind executable.
#[serde(default)]
pub start_internal_bitcoind: bool,
}
pub const DEFAULT_FILE_NAME: &str = "gui.toml";
impl Config {
pub fn new(
daemon_config_path: PathBuf,
internal_bitcoind_exe_config: Option<InternalBitcoindExeConfig>,
) -> Self {
pub fn new(daemon_config_path: PathBuf, start_internal_bitcoind: bool) -> Self {
Self {
daemon_config_path: Some(daemon_config_path),
daemon_rpc_path: None,
log_level: None,
debug: None,
hardware_wallets: None,
internal_bitcoind_exe_config,
start_internal_bitcoind,
}
}

View File

@ -152,9 +152,10 @@ impl Bitcoind {
pub fn start(
network: &bitcoin::Network,
mut config: BitcoindConfig,
bitcoind_datadir: &Path,
exe_path: &Path,
liana_datadir: &PathBuf,
) -> Result<Self, StartInternalBitcoindError> {
let bitcoind_datadir = internal_bitcoind_datadir(liana_datadir);
let bitcoind_exe_path = internal_bitcoind_exe_path(liana_datadir);
let datadir_path_str = bitcoind_datadir
.canonicalize()
.map_err(|e| StartInternalBitcoindError::CouldNotCanonicalizeDataDir(e.to_string()))?
@ -174,7 +175,7 @@ impl Bitcoind {
format!("-chain={}", network.to_core_arg()),
format!("-datadir={}", datadir_path_str),
];
let mut command = std::process::Command::new(exe_path);
let mut command = std::process::Command::new(bitcoind_exe_path);
#[cfg(target_os = "windows")]
let command = command.creation_flags(CREATE_NO_WINDOW);

View File

@ -4,7 +4,6 @@ use std::time::Duration;
use crate::{
app::{
config::InternalBitcoindExeConfig,
settings::{KeySetting, Settings, WalletSetting},
wallet::DEFAULT_WALLET_NAME,
},
@ -36,7 +35,6 @@ pub struct Context {
pub recovered_signer: Option<Arc<Signer>>,
pub bitcoind_is_external: bool,
pub internal_bitcoind_config: Option<InternalBitcoindConfig>,
pub internal_bitcoind_exe_config: Option<InternalBitcoindExeConfig>,
pub internal_bitcoind: Option<Bitcoind>,
}
@ -56,7 +54,6 @@ impl Context {
recovered_signer: None,
bitcoind_is_external: true,
internal_bitcoind_config: None,
internal_bitcoind_exe_config: None,
internal_bitcoind: None,
}
}

View File

@ -16,7 +16,6 @@ use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use crate::{
app::config::InternalBitcoindExeConfig,
app::{config as gui_config, settings as gui_settings},
signer::Signer,
};
@ -317,7 +316,8 @@ pub async fn install(ctx: Context, signer: Arc<Mutex<Signer>>) -> Result<PathBuf
daemon_config_path.canonicalize().map_err(|e| {
Error::Unexpected(format!("Failed to canonicalize daemon config path: {}", e))
})?,
ctx.internal_bitcoind_exe_config.clone(),
// Installer started a bitcoind, it is expected that gui will start it on on startup
ctx.internal_bitcoind.is_some(),
))
.map_err(|e| Error::Unexpected(format!("Failed to serialize gui config: {}", e)))?
.as_bytes(),

View File

@ -28,7 +28,7 @@ use crate::{
context::Context,
message::{self, Message},
step::Step,
view, Error, InternalBitcoindExeConfig,
view, Error,
},
};
@ -453,7 +453,6 @@ impl Step for SelectBitcoindTypeStep {
}
} else {
ctx.internal_bitcoind_config = None;
ctx.internal_bitcoind_exe_config = None;
}
ctx.bitcoind_is_external = self.use_external;
true
@ -599,7 +598,6 @@ pub struct InternalBitcoindStep {
started: Option<Result<(), StartInternalBitcoindError>>,
exe_path: Option<PathBuf>,
bitcoind_config: Option<BitcoindConfig>,
exe_config: Option<InternalBitcoindExeConfig>,
internal_bitcoind_config: Option<InternalBitcoindConfig>,
error: Option<String>,
exe_download: Option<Download>,
@ -622,7 +620,6 @@ impl InternalBitcoindStep {
started: None,
exe_path: None,
bitcoind_config: None,
exe_config: None,
internal_bitcoind_config: None,
error: None,
exe_download: None,
@ -657,6 +654,7 @@ impl Step for InternalBitcoindStep {
bitcoind.stop();
self.started = None;
}
self.internal_bitcoind = None;
return Command::perform(async {}, |_| Message::Previous);
}
message::InternalBitcoindMsg::Reload => {
@ -768,70 +766,48 @@ impl Step for InternalBitcoindStep {
}
}
message::InternalBitcoindMsg::Start => {
if let Some(exe_path) = &self.exe_path {
let exe_config = match (
exe_path.canonicalize(),
self.bitcoind_datadir.canonicalize(),
) {
(Ok(exe_path), Ok(data_dir)) => {
InternalBitcoindExeConfig { exe_path, data_dir }
}
(Err(e), Ok(_)) | (Err(e), Err(_)) => {
self.started = Some(Err(
StartInternalBitcoindError::CouldNotCanonicalizeExePath(
e.to_string(),
),
));
return Command::none();
}
(Ok(_), Err(e)) => {
self.started = Some(Err(
StartInternalBitcoindError::CouldNotCanonicalizeDataDir(
e.to_string(),
),
));
return Command::none();
}
};
let cookie_path = bitcoind::internal_bitcoind_cookie_path(
&self.bitcoind_datadir,
&self.network,
);
let rpc_port = self
.internal_bitcoind_config
.as_ref()
.expect("Already added")
.clone()
.networks
.get(&self.network)
.expect("Already added")
.rpc_port;
match Bitcoind::start(
&self.network,
BitcoindConfig {
cookie_path,
addr: internal_bitcoind_address(rpc_port),
},
&exe_config.data_dir,
&exe_config.exe_path,
) {
Err(e) => {
self.started = Some(Err(StartInternalBitcoindError::CommandError(
e.to_string(),
)));
return Command::none();
}
Ok(bitcoind) => {
self.error = None;
self.bitcoind_config = Some(bitcoind.config.clone());
self.exe_config = Some(exe_config);
self.started = Some(Ok(()));
self.internal_bitcoind = Some(bitcoind);
}
};
if let Err(e) = self.bitcoind_datadir.canonicalize() {
self.started = Some(Err(
StartInternalBitcoindError::CouldNotCanonicalizeDataDir(e.to_string()),
));
return Command::none();
}
let cookie_path = bitcoind::internal_bitcoind_cookie_path(
&self.bitcoind_datadir,
&self.network,
);
let rpc_port = self
.internal_bitcoind_config
.as_ref()
.expect("Already added")
.clone()
.networks
.get(&self.network)
.expect("Already added")
.rpc_port;
match Bitcoind::start(
&self.network,
BitcoindConfig {
cookie_path,
addr: internal_bitcoind_address(rpc_port),
},
&self.liana_datadir,
) {
Err(e) => {
self.started =
Some(Err(StartInternalBitcoindError::CommandError(e.to_string())));
return Command::none();
}
Ok(bitcoind) => {
self.error = None;
self.bitcoind_config = Some(bitcoind.config.clone());
self.started = Some(Ok(()));
self.internal_bitcoind = Some(bitcoind);
}
};
}
};
};
@ -871,7 +847,6 @@ impl Step for InternalBitcoindStep {
if let Some(Ok(_)) = self.started {
ctx.bitcoind_config = self.bitcoind_config.clone();
ctx.internal_bitcoind_config = self.internal_bitcoind_config.clone();
ctx.internal_bitcoind_exe_config = self.exe_config.clone();
ctx.internal_bitcoind = self.internal_bitcoind.clone();
self.error = None;
return true;

View File

@ -24,7 +24,7 @@ use liana_ui::{
use crate::{
app::{
cache::Cache,
config::{Config as GUIConfig, InternalBitcoindExeConfig},
config::Config as GUIConfig,
wallet::{Wallet, WalletError},
},
bitcoind::{Bitcoind, StartInternalBitcoindError},
@ -109,8 +109,8 @@ impl Loader {
progress: 0.0,
bitcoind_logs: String::new(),
};
if self.gui_config.internal_bitcoind_exe_config.is_some() {
warn!("Ignoring internal bitcoind config because Liana daemon is external.");
if self.gui_config.start_internal_bitcoind {
warn!("Lianad is external, gui will not start internal bitcoind");
}
return Command::perform(sync(daemon, false), Message::Syncing);
}
@ -127,7 +127,8 @@ impl Loader {
return Command::perform(
start_bitcoind_and_daemon(
daemon_config_path,
self.gui_config.internal_bitcoind_exe_config.clone(),
self.datadir_path.clone(),
self.gui_config.start_internal_bitcoind,
),
Message::Started,
);
@ -411,11 +412,12 @@ async fn connect(socket_path: PathBuf) -> Result<Arc<dyn Daemon + Sync + Send>,
// Daemon can start only if a config path is given.
pub async fn start_bitcoind_and_daemon(
config_path: PathBuf,
bitcoind_exe_config: Option<InternalBitcoindExeConfig>,
liana_datadir_path: PathBuf,
start_internal_bitcoind: bool,
) -> Result<(Arc<dyn Daemon + Sync + Send>, Option<Bitcoind>), Error> {
let config = Config::from_file(Some(config_path)).map_err(Error::Config)?;
let mut bitcoind: Option<Bitcoind> = None;
if let Some(exe_config) = bitcoind_exe_config {
if start_internal_bitcoind {
if let Some(bitcoind_config) = &config.bitcoind_config {
// Check if bitcoind is already running before trying to start it.
if liana::BitcoinD::new(bitcoind_config, "internal_bitcoind_start".to_string()).is_ok()
@ -427,8 +429,7 @@ pub async fn start_bitcoind_and_daemon(
Bitcoind::start(
&config.bitcoin_config.network,
bitcoind_config.clone(),
&exe_config.data_dir,
&exe_config.exe_path,
&liana_datadir_path,
)
.map_err(Error::Bitcoind)?,
);