From d700f8a3cf6cf0f6b825e379d6ce10dd79f0ecf7 Mon Sep 17 00:00:00 2001 From: edouard Date: Thu, 31 Aug 2023 11:06:05 +0200 Subject: [PATCH] Add parent directory to bitcoind exe and datadir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .liana/bitcoind ├── bitcoin-25.0 │   └── bin └── datadir ├── anchors.dat ├── banlist.json ├── bitcoin.conf ├── blocks ├── chainstate ├── debug.log ├── fee_estimates.dat ├── mempool.dat ├── peers.dat └── settings.json --- gui/src/bitcoind.rs | 98 ++++++++++++++++++++++- gui/src/installer/mod.rs | 7 -- gui/src/installer/step/bitcoind.rs | 123 +++++++---------------------- 3 files changed, 122 insertions(+), 106 deletions(-) diff --git a/gui/src/bitcoind.rs b/gui/src/bitcoind.rs index 57f597a3..a52fc52d 100644 --- a/gui/src/bitcoind.rs +++ b/gui/src/bitcoind.rs @@ -1,5 +1,8 @@ -use liana::{config::BitcoindConfig, miniscript::bitcoin}; -use std::path::Path; +use liana::{ + config::BitcoindConfig, + miniscript::bitcoin::{self, Network}, +}; +use std::path::{Path, PathBuf}; use std::sync::Arc; use tokio::sync::Mutex; @@ -11,6 +14,95 @@ use std::os::windows::process::CommandExt; #[cfg(target_os = "windows")] const CREATE_NO_WINDOW: u32 = 0x08000000; +pub const VERSION: &str = "25.0"; + +#[cfg(all(target_os = "macos", target_arch = "x86_64"))] +pub const SHA256SUM: &str = "5708fc639cdfc27347cccfd50db9b73b53647b36fb5f3a4a93537cbe8828c27f"; + +#[cfg(all(target_os = "linux", target_arch = "x86_64"))] +pub const SHA256SUM: &str = "33930d432593e49d58a9bff4c30078823e9af5d98594d2935862788ce8a20aec"; + +#[cfg(all(target_os = "windows", target_arch = "x86_64"))] +pub const SHA256SUM: &str = "7154b35ecc8247589070ae739b7c73c4dee4794bea49eb18dc66faed65b819e7"; + +#[cfg(all(target_os = "macos", target_arch = "x86_64"))] +pub fn download_filename() -> String { + format!("bitcoin-{}-x86_64-apple-darwin.tar.gz", &VERSION) +} + +#[cfg(all(target_os = "linux", target_arch = "x86_64"))] +fn download_filename() -> String { + format!("bitcoin-{}-x86_64-linux-gnu.tar.gz", &VERSION) +} + +#[cfg(all(target_os = "windows", target_arch = "x86_64"))] +fn download_filename() -> String { + format!("bitcoin-{}-win64.zip", &VERSION) +} + +pub fn download_url() -> String { + format!( + "https://bitcoincore.org/bin/bitcoin-core-{}/{}", + &VERSION, + download_filename() + ) +} + +pub fn internal_bitcoind_directory(liana_datadir: &PathBuf) -> PathBuf { + let mut datadir = PathBuf::from(liana_datadir); + datadir.push("bitcoind"); + datadir +} + +/// Data directory used by internal bitcoind. +pub fn internal_bitcoind_datadir(liana_datadir: &PathBuf) -> PathBuf { + let mut datadir = internal_bitcoind_directory(liana_datadir); + datadir.push("datadir"); + datadir +} + +/// Internal bitcoind executable path. +pub fn internal_bitcoind_exe_path(liana_datadir: &PathBuf) -> PathBuf { + internal_bitcoind_directory(liana_datadir) + .join(format!("bitcoin-{}", &VERSION)) + .join("bin") + .join(if cfg!(target_os = "windows") { + "bitcoind.exe" + } else { + "bitcoind" + }) +} + +/// Path of the `bitcoin.conf` file used by internal bitcoind. +pub fn internal_bitcoind_config_path(bitcoind_datadir: &PathBuf) -> PathBuf { + let mut config_path = PathBuf::from(bitcoind_datadir); + config_path.push("bitcoin.conf"); + config_path +} + +/// Path of the cookie file used by internal bitcoind on a given network. +pub fn internal_bitcoind_cookie_path(bitcoind_datadir: &Path, network: &Network) -> PathBuf { + let mut cookie_path = bitcoind_datadir.to_path_buf(); + if let Some(dir) = bitcoind_network_dir(network) { + cookie_path.push(dir); + } + cookie_path.push(".cookie"); + cookie_path +} + +pub fn bitcoind_network_dir(network: &Network) -> Option { + let dir = match network { + Network::Bitcoin => { + return None; + } + Network::Testnet => "testnet3", + Network::Regtest => "regtest", + Network::Signet => "signet", + _ => panic!("Directory required for this network is unknown."), + }; + Some(dir.to_string()) +} + /// Possible errors when starting bitcoind. #[derive(PartialEq, Eq, Debug, Clone)] pub enum StartInternalBitcoindError { @@ -89,7 +181,7 @@ impl Bitcoind { let mut process = command .args(&args) - .stdout(std::process::Stdio::piped()) // We still get bitcoind's logs in debug.log. + .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()) .spawn() .map_err(|e| StartInternalBitcoindError::CommandError(e.to_string()))?; diff --git a/gui/src/installer/mod.rs b/gui/src/installer/mod.rs index b581c075..2e1eed55 100644 --- a/gui/src/installer/mod.rs +++ b/gui/src/installer/mod.rs @@ -252,13 +252,6 @@ pub fn daemon_check(cfg: liana::config::Config) -> Result<(), Error> { } } -/// Data directory used by internal bitcoind. -pub fn internal_bitcoind_datadir(liana_datadir: &PathBuf) -> PathBuf { - let mut datadir = PathBuf::from(liana_datadir); - datadir.push("bitcoind_datadir"); - datadir -} - pub async fn install(ctx: Context, signer: Arc>) -> Result { let mut cfg: liana::config::Config = ctx.extract_daemon_config(); let data_dir = cfg.data_dir.unwrap(); diff --git a/gui/src/installer/step/bitcoind.rs b/gui/src/installer/step/bitcoind.rs index 89a3e95b..036fd639 100644 --- a/gui/src/installer/step/bitcoind.rs +++ b/gui/src/installer/step/bitcoind.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; #[cfg(target_os = "windows")] use std::io::{self, Cursor}; use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener}; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::str::FromStr; use bitcoin_hashes::{sha256, Hash}; @@ -19,11 +19,13 @@ use jsonrpc::{client::Client, simple_http::SimpleHttpTransport}; use liana_ui::{component::form, widget::*}; use crate::{ - bitcoind::{Bitcoind, StartInternalBitcoindError}, + bitcoind::{ + self, bitcoind_network_dir, internal_bitcoind_datadir, internal_bitcoind_directory, + Bitcoind, StartInternalBitcoindError, + }, download, installer::{ context::Context, - internal_bitcoind_datadir, message::{self, Message}, step::Step, view, Error, InternalBitcoindExeConfig, @@ -86,52 +88,17 @@ impl Download { pub fn subscription(&self) -> Subscription { match self.state { - DownloadState::Downloading { .. } => { - download::file(self.id, download_url()).map(|(_, progress)| { + DownloadState::Downloading { .. } => download::file(self.id, bitcoind::download_url()) + .map(|(_, progress)| { Message::InternalBitcoind(message::InternalBitcoindMsg::DownloadProgressed( progress, )) - }) - } + }), _ => Subscription::none(), } } } -const VERSION: &str = "25.0"; - -#[cfg(all(target_os = "macos", target_arch = "x86_64"))] -const SHA256SUM: &str = "5708fc639cdfc27347cccfd50db9b73b53647b36fb5f3a4a93537cbe8828c27f"; - -#[cfg(all(target_os = "linux", target_arch = "x86_64"))] -const SHA256SUM: &str = "33930d432593e49d58a9bff4c30078823e9af5d98594d2935862788ce8a20aec"; - -#[cfg(all(target_os = "windows", target_arch = "x86_64"))] -const SHA256SUM: &str = "7154b35ecc8247589070ae739b7c73c4dee4794bea49eb18dc66faed65b819e7"; - -#[cfg(all(target_os = "macos", target_arch = "x86_64"))] -fn download_filename() -> String { - format!("bitcoin-{}-x86_64-apple-darwin.tar.gz", &VERSION) -} - -#[cfg(all(target_os = "linux", target_arch = "x86_64"))] -fn download_filename() -> String { - format!("bitcoin-{}-x86_64-linux-gnu.tar.gz", &VERSION) -} - -#[cfg(all(target_os = "windows", target_arch = "x86_64"))] -fn download_filename() -> String { - format!("bitcoin-{}-win64.zip", &VERSION) -} - -fn download_url() -> String { - format!( - "https://bitcoincore.org/bin/bitcoin-core-{}/{}", - &VERSION, - download_filename() - ) -} - /// Default prune value used by internal bitcoind. pub const PRUNE_DEFAULT: u32 = 15_000; /// Default ports used by bitcoind across all networks. @@ -361,7 +328,7 @@ fn unpack_bitcoind(install_dir: &PathBuf, bytes: &[u8]) -> Result<(), InstallBit fn verify_hash(bytes: &[u8]) -> bool { let bytes_hash = sha256::Hash::hash(bytes); info!("Download hash: '{}'.", bytes_hash); - let expected_hash = sha256::Hash::from_str(SHA256SUM).expect("This cannot fail."); + let expected_hash = sha256::Hash::from_str(bitcoind::SHA256SUM).expect("This cannot fail."); expected_hash == bytes_hash } @@ -373,35 +340,6 @@ fn install_bitcoind(install_dir: &PathBuf, bytes: &[u8]) -> Result<(), InstallBi unpack_bitcoind(install_dir, bytes) } -/// Internal bitcoind executable path. -fn internal_bitcoind_exe_path(liana_datadir: &PathBuf) -> PathBuf { - PathBuf::from(liana_datadir) - .join(format!("bitcoin-{}", &VERSION)) - .join("bin") - .join(if cfg!(target_os = "windows") { - "bitcoind.exe" - } else { - "bitcoind" - }) -} - -/// Path of the `bitcoin.conf` file used by internal bitcoind. -fn internal_bitcoind_config_path(bitcoind_datadir: &PathBuf) -> PathBuf { - let mut config_path = PathBuf::from(bitcoind_datadir); - config_path.push("bitcoin.conf"); - config_path -} - -/// Path of the cookie file used by internal bitcoind on a given network. -fn internal_bitcoind_cookie_path(bitcoind_datadir: &Path, network: &Network) -> PathBuf { - let mut cookie_path = bitcoind_datadir.to_path_buf(); - if let Some(dir) = bitcoind_network_dir(network) { - cookie_path.push(dir); - } - cookie_path.push(".cookie"); - cookie_path -} - /// RPC address for internal bitcoind. fn internal_bitcoind_address(rpc_port: u16) -> SocketAddr { SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), rpc_port) @@ -426,19 +364,6 @@ fn bitcoind_default_datadir() -> Option { None } -fn bitcoind_network_dir(network: &Network) -> Option { - let dir = match network { - Network::Bitcoin => { - return None; - } - Network::Testnet => "testnet3", - Network::Regtest => "regtest", - Network::Signet => "signet", - _ => panic!("Directory required for this network is unknown."), - }; - Some(dir.to_string()) -} - fn bitcoind_default_cookie_path(network: &Network) -> Option { if let Some(mut path) = bitcoind_default_datadir() { if let Some(dir) = bitcoind_network_dir(network) { @@ -710,8 +635,8 @@ impl InternalBitcoindStep { impl Step for InternalBitcoindStep { fn load_context(&mut self, ctx: &Context) { if self.exe_path.is_none() { - if internal_bitcoind_exe_path(&ctx.data_dir).exists() { - self.exe_path = Some(internal_bitcoind_exe_path(&ctx.data_dir)) + if bitcoind::internal_bitcoind_exe_path(&ctx.data_dir).exists() { + self.exe_path = Some(bitcoind::internal_bitcoind_exe_path(&ctx.data_dir)) } else if self.exe_download.is_none() { self.exe_download = Some(Download::new(0)); }; @@ -739,7 +664,7 @@ impl Step for InternalBitcoindStep { } message::InternalBitcoindMsg::DefineConfig => { let mut conf = match InternalBitcoindConfig::from_file( - &internal_bitcoind_config_path(&self.bitcoind_datadir), + &bitcoind::internal_bitcoind_config_path(&self.bitcoind_datadir), ) { Ok(conf) => conf, Err(InternalBitcoindConfigError::FileNotFound) => { @@ -780,9 +705,9 @@ impl Step for InternalBitcoindStep { }; conf.networks.insert(self.network, network_conf); } - if let Err(e) = - conf.to_file(&internal_bitcoind_config_path(&self.bitcoind_datadir)) - { + if let Err(e) = conf.to_file(&bitcoind::internal_bitcoind_config_path( + &self.bitcoind_datadir, + )) { self.error = Some(e.to_string()); return Command::none(); }; @@ -795,7 +720,7 @@ impl Step for InternalBitcoindStep { message::InternalBitcoindMsg::Download => { if let Some(download) = &mut self.exe_download { if let DownloadState::Idle = download.state { - info!("Downloading bitcoind version {}...", &VERSION); + info!("Downloading bitcoind version {}...", &bitcoind::VERSION); download.start(); } } @@ -816,12 +741,16 @@ impl Step for InternalBitcoindStep { if let DownloadState::Finished(bytes) = &download.state { info!("Installing bitcoind..."); self.install_state = Some(InstallState::InProgress); - match install_bitcoind(&self.liana_datadir, bytes) { + match install_bitcoind( + &internal_bitcoind_directory(&self.liana_datadir), + bytes, + ) { Ok(_) => { info!("Installation of bitcoind complete."); self.install_state = Some(InstallState::Finished); - self.exe_path = - Some(internal_bitcoind_exe_path(&self.liana_datadir)); + self.exe_path = Some(bitcoind::internal_bitcoind_exe_path( + &self.liana_datadir, + )); return Command::perform(async {}, |_| { Message::InternalBitcoind( message::InternalBitcoindMsg::Start, @@ -864,8 +793,10 @@ impl Step for InternalBitcoindStep { return Command::none(); } }; - let cookie_path = - internal_bitcoind_cookie_path(&self.bitcoind_datadir, &self.network); + let cookie_path = bitcoind::internal_bitcoind_cookie_path( + &self.bitcoind_datadir, + &self.network, + ); let rpc_port = self .internal_bitcoind_config