Skip to content

Commit

Permalink
gui: add option to use internal bitcoind
Browse files Browse the repository at this point in the history
During installation, the user may choose for Liana to configure and start bitcoind for them.

This internal bitcoind uses as its data directory the `bitcoind_datadir` folder within the
Liana data directory.

If the internal bitcoind option has been selected for a network, it will be automatically
started when the user returns to Liana and stopped when Liana is closed.
  • Loading branch information
jp1ac4 committed Aug 21, 2023
1 parent 495e33e commit fc7a6af
Show file tree
Hide file tree
Showing 12 changed files with 989 additions and 24 deletions.
85 changes: 85 additions & 0 deletions gui/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions gui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ toml = "0.5"

chrono = "0.4"

rust-ini = "0.19.0"
which = "4.4.0"

[dev-dependencies]
tokio = {version = "1.9.0", features = ["rt", "macros"]}

Expand Down
17 changes: 16 additions & 1 deletion gui/src/app/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ 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.
Expand All @@ -16,18 +25,24 @@ 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>,
}

pub const DEFAULT_FILE_NAME: &str = "gui.toml";

impl Config {
pub fn new(daemon_config_path: PathBuf) -> Self {
pub fn new(
daemon_config_path: PathBuf,
internal_bitcoind_exe_config: Option<InternalBitcoindExeConfig>,
) -> 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,
}
}

Expand Down
41 changes: 41 additions & 0 deletions gui/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::sync::Arc;
use std::time::Duration;

use iced::{clipboard, time, Command, Subscription};
use liana::config::BitcoindConfig;
use tracing::{info, warn};

pub use liana::{config::Config as DaemonConfig, miniscript::bitcoin};
Expand All @@ -34,6 +35,8 @@ use crate::{
daemon::Daemon,
};

use self::config::InternalBitcoindExeConfig;

pub struct App {
data_dir: PathBuf,
state: Box<dyn State>,
Expand Down Expand Up @@ -119,6 +122,13 @@ impl App {
info!("Internal daemon stopped");
}
}
if self.config.internal_bitcoind_exe_config.is_some() {
if let Some(daemon_config) = self.daemon.config() {
if let Some(bitcoind_config) = &daemon_config.bitcoind_config {
stop_internal_bitcoind(bitcoind_config);
}
}
}
}

pub fn update(&mut self, message: Message) -> Command<Message> {
Expand Down Expand Up @@ -212,3 +222,34 @@ impl App {
self.state.view(&self.cache).map(Message::View)
}
}

/// Start internal bitcoind for the given network.
pub fn start_internal_bitcoind(
network: &bitcoin::Network,
exe_config: InternalBitcoindExeConfig,
) -> Result<std::process::Child, std::io::Error> {
let args = vec![
format!("-chain={}", network.to_core_arg()),
format!(
"-datadir={}",
exe_config.data_dir.canonicalize()?.to_string_lossy()
),
];
std::process::Command::new(exe_config.exe_path)
.args(&args)
.stdout(std::process::Stdio::null()) // We still get bitcoind's logs in debug.log.
.spawn()
}

/// Stop (internal) bitcoind.
pub fn stop_internal_bitcoind(bitcoind_config: &BitcoindConfig) {
match liana::BitcoinD::new(bitcoind_config, "internal_bitcoind_stop".to_string()) {
Ok(bitcoind) => {
info!("Stopping internal bitcoind...");
bitcoind.stop();
}
Err(e) => {
warn!("Could not create interface to internal bitcoind: '{}'.", e);
}
}
}
9 changes: 9 additions & 0 deletions gui/src/installer/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::time::Duration;

use crate::{
app::{
config::InternalBitcoindExeConfig,
settings::{KeySetting, Settings, WalletSetting},
wallet::DEFAULT_WALLET_NAME,
},
Expand All @@ -18,6 +19,8 @@ use liana::{
miniscript::bitcoin,
};

use super::step::InternalBitcoindConfig;

#[derive(Clone)]
pub struct Context {
pub bitcoin_config: BitcoinConfig,
Expand All @@ -30,6 +33,9 @@ pub struct Context {
// In case a user entered a mnemonic,
// we dont want to override the generated signer with it.
pub recovered_signer: Option<Arc<Signer>>,
pub bitcoind_is_external: bool,
pub internal_bitcoind_config: Option<InternalBitcoindConfig>,
pub internal_bitcoind_exe_config: Option<InternalBitcoindExeConfig>,
}

impl Context {
Expand All @@ -46,6 +52,9 @@ impl Context {
data_dir,
hw_is_used: false,
recovered_signer: None,
bitcoind_is_external: true,
internal_bitcoind_config: None,
internal_bitcoind_exe_config: None,
}
}

Expand Down
15 changes: 15 additions & 0 deletions gui/src/installer/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub enum Message {
UseHotSigner,
Installed(Result<PathBuf, Error>),
Network(Network),
SelectBitcoindType(SelectBitcoindTypeMsg),
InternalBitcoind(InternalBitcoindMsg),
DefineBitcoind(DefineBitcoind),
DefineDescriptor(DefineDescriptor),
ImportXpub(usize, Result<DescriptorPublicKey, Error>),
Expand All @@ -43,6 +45,19 @@ pub enum DefineBitcoind {
PingBitcoind,
}

#[derive(Debug, Clone)]
pub enum SelectBitcoindTypeMsg {
UseExternal(bool),
}

#[derive(Debug, Clone)]
pub enum InternalBitcoindMsg {
Previous,
Reload,
DefineConfig,
Start,
}

#[derive(Debug, Clone)]
pub enum DefineDescriptor {
ImportDescriptor(String),
Expand Down
Loading

0 comments on commit fc7a6af

Please sign in to comment.