From 40dc9ae8c01da0b250bf0e8ea40e275ef77bd23c Mon Sep 17 00:00:00 2001 From: edouardparis Date: Tue, 6 May 2025 10:56:23 +0200 Subject: [PATCH] Delete process internal bitcoind locks in case of panic --- liana-gui/src/main.rs | 10 ++++++++-- liana-gui/src/node/bitcoind.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/liana-gui/src/main.rs b/liana-gui/src/main.rs index 1e46b09b..28397bfb 100644 --- a/liana-gui/src/main.rs +++ b/liana-gui/src/main.rs @@ -30,6 +30,7 @@ use liana_gui::{ launcher::{self, Launcher}, loader::{self, Loader}, logger::Logger, + node::bitcoind::delete_all_bitcoind_locks_for_process, services::connect::{ client::backend::{api, BackendWalletClient}, login, @@ -537,7 +538,7 @@ fn main() -> Result<(), Box> { None }; - setup_panic_hook(); + setup_panic_hook(&config.liana_directory); let settings = Settings { id: Some("Liana".to_string()), @@ -584,8 +585,13 @@ fn main() -> Result<(), Box> { } // A panic in any thread should stop the main thread, and print the panic. -fn setup_panic_hook() { +fn setup_panic_hook(liana_directory: &LianaDirectory) { + let bitcoind_dir = liana_directory.bitcoind_directory(); std::panic::set_hook(Box::new(move |panic_info| { + error!("Panic occured"); + if let Err(e) = delete_all_bitcoind_locks_for_process(bitcoind_dir.clone()) { + error!("Failed to delete internal bitcoind locks: {}", e); + } let file = panic_info .location() .map(|l| l.file()) diff --git a/liana-gui/src/node/bitcoind.rs b/liana-gui/src/node/bitcoind.rs index 26358f9f..e7df3345 100644 --- a/liana-gui/src/node/bitcoind.rs +++ b/liana-gui/src/node/bitcoind.rs @@ -616,6 +616,37 @@ impl LockFile { } } +// In case of panic, we remove all the bitcoind locks created by the process. +pub fn delete_all_bitcoind_locks_for_process( + directory: BitcoindDirectory, +) -> Result<(), Box> { + let locks_directory = directory.path().join(LOCK_DIRECTORY_NAME); + if !locks_directory.exists() { + tracing::debug!("No internal bitcoind locks for the current process"); + return Ok(()); + } + tracing::info!("Deleting all internal bitcoind locks for the current process"); + let process_prefix = format!("{}-", std::process::id()); + for network_dir in std::fs::read_dir(&locks_directory)? { + let dir = network_dir?.path(); + for lock_file in std::fs::read_dir(&dir)? { + let file = lock_file?.path(); + if let Some(name) = file.file_name().and_then(|n| n.to_str()) { + if name.starts_with(&process_prefix) { + std::fs::remove_file(file)?; + } + } + } + if std::fs::read_dir(&dir)?.next().is_none() { + std::fs::remove_dir(dir)?; + } + } + if std::fs::read_dir(&locks_directory)?.next().is_none() { + std::fs::remove_dir(locks_directory)?; + } + Ok(()) +} + #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum RpcAuthType { CookieFile,