Add parent directory to bitcoind exe and datadir
.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
This commit is contained in:
parent
1bdc6e9fb4
commit
d700f8a3cf
@ -1,5 +1,8 @@
|
|||||||
use liana::{config::BitcoindConfig, miniscript::bitcoin};
|
use liana::{
|
||||||
use std::path::Path;
|
config::BitcoindConfig,
|
||||||
|
miniscript::bitcoin::{self, Network},
|
||||||
|
};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
@ -11,6 +14,95 @@ use std::os::windows::process::CommandExt;
|
|||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
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<String> {
|
||||||
|
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.
|
/// Possible errors when starting bitcoind.
|
||||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||||
pub enum StartInternalBitcoindError {
|
pub enum StartInternalBitcoindError {
|
||||||
@ -89,7 +181,7 @@ impl Bitcoind {
|
|||||||
|
|
||||||
let mut process = command
|
let mut process = command
|
||||||
.args(&args)
|
.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())
|
.stderr(std::process::Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.map_err(|e| StartInternalBitcoindError::CommandError(e.to_string()))?;
|
.map_err(|e| StartInternalBitcoindError::CommandError(e.to_string()))?;
|
||||||
|
|||||||
@ -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<Mutex<Signer>>) -> Result<PathBuf, Error> {
|
pub async fn install(ctx: Context, signer: Arc<Mutex<Signer>>) -> Result<PathBuf, Error> {
|
||||||
let mut cfg: liana::config::Config = ctx.extract_daemon_config();
|
let mut cfg: liana::config::Config = ctx.extract_daemon_config();
|
||||||
let data_dir = cfg.data_dir.unwrap();
|
let data_dir = cfg.data_dir.unwrap();
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use std::collections::BTreeMap;
|
|||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use std::io::{self, Cursor};
|
use std::io::{self, Cursor};
|
||||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener};
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use bitcoin_hashes::{sha256, Hash};
|
use bitcoin_hashes::{sha256, Hash};
|
||||||
@ -19,11 +19,13 @@ use jsonrpc::{client::Client, simple_http::SimpleHttpTransport};
|
|||||||
use liana_ui::{component::form, widget::*};
|
use liana_ui::{component::form, widget::*};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bitcoind::{Bitcoind, StartInternalBitcoindError},
|
bitcoind::{
|
||||||
|
self, bitcoind_network_dir, internal_bitcoind_datadir, internal_bitcoind_directory,
|
||||||
|
Bitcoind, StartInternalBitcoindError,
|
||||||
|
},
|
||||||
download,
|
download,
|
||||||
installer::{
|
installer::{
|
||||||
context::Context,
|
context::Context,
|
||||||
internal_bitcoind_datadir,
|
|
||||||
message::{self, Message},
|
message::{self, Message},
|
||||||
step::Step,
|
step::Step,
|
||||||
view, Error, InternalBitcoindExeConfig,
|
view, Error, InternalBitcoindExeConfig,
|
||||||
@ -86,52 +88,17 @@ impl Download {
|
|||||||
|
|
||||||
pub fn subscription(&self) -> Subscription<Message> {
|
pub fn subscription(&self) -> Subscription<Message> {
|
||||||
match self.state {
|
match self.state {
|
||||||
DownloadState::Downloading { .. } => {
|
DownloadState::Downloading { .. } => download::file(self.id, bitcoind::download_url())
|
||||||
download::file(self.id, download_url()).map(|(_, progress)| {
|
.map(|(_, progress)| {
|
||||||
Message::InternalBitcoind(message::InternalBitcoindMsg::DownloadProgressed(
|
Message::InternalBitcoind(message::InternalBitcoindMsg::DownloadProgressed(
|
||||||
progress,
|
progress,
|
||||||
))
|
))
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
_ => Subscription::none(),
|
_ => 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.
|
/// Default prune value used by internal bitcoind.
|
||||||
pub const PRUNE_DEFAULT: u32 = 15_000;
|
pub const PRUNE_DEFAULT: u32 = 15_000;
|
||||||
/// Default ports used by bitcoind across all networks.
|
/// 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 {
|
fn verify_hash(bytes: &[u8]) -> bool {
|
||||||
let bytes_hash = sha256::Hash::hash(bytes);
|
let bytes_hash = sha256::Hash::hash(bytes);
|
||||||
info!("Download hash: '{}'.", bytes_hash);
|
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
|
expected_hash == bytes_hash
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,35 +340,6 @@ fn install_bitcoind(install_dir: &PathBuf, bytes: &[u8]) -> Result<(), InstallBi
|
|||||||
unpack_bitcoind(install_dir, bytes)
|
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.
|
/// RPC address for internal bitcoind.
|
||||||
fn internal_bitcoind_address(rpc_port: u16) -> SocketAddr {
|
fn internal_bitcoind_address(rpc_port: u16) -> SocketAddr {
|
||||||
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), rpc_port)
|
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), rpc_port)
|
||||||
@ -426,19 +364,6 @@ fn bitcoind_default_datadir() -> Option<PathBuf> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bitcoind_network_dir(network: &Network) -> Option<String> {
|
|
||||||
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<String> {
|
fn bitcoind_default_cookie_path(network: &Network) -> Option<String> {
|
||||||
if let Some(mut path) = bitcoind_default_datadir() {
|
if let Some(mut path) = bitcoind_default_datadir() {
|
||||||
if let Some(dir) = bitcoind_network_dir(network) {
|
if let Some(dir) = bitcoind_network_dir(network) {
|
||||||
@ -710,8 +635,8 @@ impl InternalBitcoindStep {
|
|||||||
impl Step for InternalBitcoindStep {
|
impl Step for InternalBitcoindStep {
|
||||||
fn load_context(&mut self, ctx: &Context) {
|
fn load_context(&mut self, ctx: &Context) {
|
||||||
if self.exe_path.is_none() {
|
if self.exe_path.is_none() {
|
||||||
if internal_bitcoind_exe_path(&ctx.data_dir).exists() {
|
if bitcoind::internal_bitcoind_exe_path(&ctx.data_dir).exists() {
|
||||||
self.exe_path = Some(internal_bitcoind_exe_path(&ctx.data_dir))
|
self.exe_path = Some(bitcoind::internal_bitcoind_exe_path(&ctx.data_dir))
|
||||||
} else if self.exe_download.is_none() {
|
} else if self.exe_download.is_none() {
|
||||||
self.exe_download = Some(Download::new(0));
|
self.exe_download = Some(Download::new(0));
|
||||||
};
|
};
|
||||||
@ -739,7 +664,7 @@ impl Step for InternalBitcoindStep {
|
|||||||
}
|
}
|
||||||
message::InternalBitcoindMsg::DefineConfig => {
|
message::InternalBitcoindMsg::DefineConfig => {
|
||||||
let mut conf = match InternalBitcoindConfig::from_file(
|
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,
|
Ok(conf) => conf,
|
||||||
Err(InternalBitcoindConfigError::FileNotFound) => {
|
Err(InternalBitcoindConfigError::FileNotFound) => {
|
||||||
@ -780,9 +705,9 @@ impl Step for InternalBitcoindStep {
|
|||||||
};
|
};
|
||||||
conf.networks.insert(self.network, network_conf);
|
conf.networks.insert(self.network, network_conf);
|
||||||
}
|
}
|
||||||
if let Err(e) =
|
if let Err(e) = conf.to_file(&bitcoind::internal_bitcoind_config_path(
|
||||||
conf.to_file(&internal_bitcoind_config_path(&self.bitcoind_datadir))
|
&self.bitcoind_datadir,
|
||||||
{
|
)) {
|
||||||
self.error = Some(e.to_string());
|
self.error = Some(e.to_string());
|
||||||
return Command::none();
|
return Command::none();
|
||||||
};
|
};
|
||||||
@ -795,7 +720,7 @@ impl Step for InternalBitcoindStep {
|
|||||||
message::InternalBitcoindMsg::Download => {
|
message::InternalBitcoindMsg::Download => {
|
||||||
if let Some(download) = &mut self.exe_download {
|
if let Some(download) = &mut self.exe_download {
|
||||||
if let DownloadState::Idle = download.state {
|
if let DownloadState::Idle = download.state {
|
||||||
info!("Downloading bitcoind version {}...", &VERSION);
|
info!("Downloading bitcoind version {}...", &bitcoind::VERSION);
|
||||||
download.start();
|
download.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -816,12 +741,16 @@ impl Step for InternalBitcoindStep {
|
|||||||
if let DownloadState::Finished(bytes) = &download.state {
|
if let DownloadState::Finished(bytes) = &download.state {
|
||||||
info!("Installing bitcoind...");
|
info!("Installing bitcoind...");
|
||||||
self.install_state = Some(InstallState::InProgress);
|
self.install_state = Some(InstallState::InProgress);
|
||||||
match install_bitcoind(&self.liana_datadir, bytes) {
|
match install_bitcoind(
|
||||||
|
&internal_bitcoind_directory(&self.liana_datadir),
|
||||||
|
bytes,
|
||||||
|
) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
info!("Installation of bitcoind complete.");
|
info!("Installation of bitcoind complete.");
|
||||||
self.install_state = Some(InstallState::Finished);
|
self.install_state = Some(InstallState::Finished);
|
||||||
self.exe_path =
|
self.exe_path = Some(bitcoind::internal_bitcoind_exe_path(
|
||||||
Some(internal_bitcoind_exe_path(&self.liana_datadir));
|
&self.liana_datadir,
|
||||||
|
));
|
||||||
return Command::perform(async {}, |_| {
|
return Command::perform(async {}, |_| {
|
||||||
Message::InternalBitcoind(
|
Message::InternalBitcoind(
|
||||||
message::InternalBitcoindMsg::Start,
|
message::InternalBitcoindMsg::Start,
|
||||||
@ -864,8 +793,10 @@ impl Step for InternalBitcoindStep {
|
|||||||
return Command::none();
|
return Command::none();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let cookie_path =
|
let cookie_path = bitcoind::internal_bitcoind_cookie_path(
|
||||||
internal_bitcoind_cookie_path(&self.bitcoind_datadir, &self.network);
|
&self.bitcoind_datadir,
|
||||||
|
&self.network,
|
||||||
|
);
|
||||||
|
|
||||||
let rpc_port = self
|
let rpc_port = self
|
||||||
.internal_bitcoind_config
|
.internal_bitcoind_config
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user