commit 41bcc3e8faf18221eff61b83bcbd3f720fc0c408
parent 8fb1cc0dc0874eee68781c420a37a89db986fbd9
Author: Antoine A <>
Date: Wed, 30 Jul 2025 15:26:23 +0200
bitcoin: improve rpc connect error
Diffstat:
2 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -2829,7 +2829,7 @@ dependencies = [
[[package]]
name = "taler-api"
version = "0.0.0"
-source = "git+https://git.taler.net/taler-rust.git/#a7021471084dbf2d6242517b147bdf94b0754da2"
+source = "git+https://git.taler.net/taler-rust.git/#0725b22564cab84463159e4461b8acfc2121776b"
dependencies = [
"axum",
"base64",
@@ -2852,7 +2852,7 @@ dependencies = [
[[package]]
name = "taler-common"
version = "0.0.0"
-source = "git+https://git.taler.net/taler-rust.git/#a7021471084dbf2d6242517b147bdf94b0754da2"
+source = "git+https://git.taler.net/taler-rust.git/#0725b22564cab84463159e4461b8acfc2121776b"
dependencies = [
"anyhow",
"clap",
@@ -2877,7 +2877,7 @@ dependencies = [
[[package]]
name = "taler-test-utils"
version = "0.0.0"
-source = "git+https://git.taler.net/taler-rust.git/#a7021471084dbf2d6242517b147bdf94b0754da2"
+source = "git+https://git.taler.net/taler-rust.git/#0725b22564cab84463159e4461b8acfc2121776b"
dependencies = [
"axum",
"http-body-util",
diff --git a/depolymerizer-bitcoin/src/rpc.rs b/depolymerizer-bitcoin/src/rpc.rs
@@ -32,6 +32,7 @@ use serde_json::{Value, json};
use std::{
fmt::Debug,
io::{ErrorKind, IoSlice, Write as _},
+ net::SocketAddr,
path::PathBuf,
str::FromStr as _,
time::Duration,
@@ -94,6 +95,8 @@ pub enum Error {
Bitcoin(String),
#[error("JSON: {0}")]
Json(#[from] serde_json::Error),
+ #[error("connect: {0}")]
+ Connect(#[from] RpcConnectErr),
#[error("Null rpc, no result or error")]
Null,
}
@@ -168,6 +171,16 @@ impl JsonSocket {
}
}
+#[derive(Debug, thiserror::Error)]
+pub enum RpcConnectErr {
+ #[error("failed to read cookie file at '{0}': {1}")]
+ Cookie(String, ErrorKind),
+ #[error("failed to connect {0}: {1}")]
+ Tcp(SocketAddr, ErrorKind),
+ #[error("failed to connect {0}: {1}")]
+ Elapsed(SocketAddr, tokio::time::error::Elapsed),
+}
+
/// Bitcoin RPC connection
pub struct Rpc {
socket: JsonSocket,
@@ -176,35 +189,41 @@ pub struct Rpc {
impl Rpc {
/// Start a RPC connection
- pub async fn common(cfg: &RpcCfg) -> io::Result<Self> {
+ pub async fn common(cfg: &RpcCfg) -> std::result::Result<Self, RpcConnectErr> {
Self::new(cfg, None).await
}
/// Start a wallet RPC connection
- pub async fn wallet(cfg: &RpcCfg, wallet: &str) -> io::Result<Self> {
+ pub async fn wallet(cfg: &RpcCfg, wallet: &str) -> std::result::Result<Self, RpcConnectErr> {
Self::new(cfg, Some(wallet)).await
}
- async fn new(cfg: &RpcCfg, wallet: Option<&str>) -> io::Result<Self> {
+ async fn new(cfg: &RpcCfg, wallet: Option<&str>) -> std::result::Result<Self, RpcConnectErr> {
let path = if let Some(wallet) = wallet {
format!("/wallet/{wallet}")
} else {
String::from("/")
};
- // TODO error
let token = match &cfg.auth {
RpcAuth::Basic(s) => s.as_bytes().to_vec(),
RpcAuth::Cookie(path) => match std::fs::read(path) {
Ok(content) => content,
Err(e) if e.kind() == ErrorKind::IsADirectory => {
- std::fs::read(PathBuf::from_str(path).unwrap().join(".cookie"))?
+ let path = PathBuf::from_str(path).unwrap().join(".cookie");
+ std::fs::read(&path).map_err(|e| {
+ RpcConnectErr::Cookie(path.to_string_lossy().to_string(), e.kind())
+ })?
}
- Err(e) => return Err(e),
+ Err(e) => return Err(RpcConnectErr::Cookie(path.clone(), e.kind())),
},
};
// Open connection
- let sock = timeout(Duration::from_secs(5), TcpStream::connect(&cfg.addr)).await??;
+ let sock = timeout(Duration::from_secs(5), TcpStream::connect(&cfg.addr))
+ .await
+ .map_err(|e| RpcConnectErr::Elapsed(cfg.addr, e))?
+ .map_err(|e| RpcConnectErr::Tcp(cfg.addr, e.kind()))?;
+
sock.set_nodelay(true).ok();
Ok(Self {
@@ -273,7 +292,6 @@ impl Rpc {
/// Unlock loaded wallet
pub async fn unlock_wallet(&mut self, passwd: &str) -> Result<()> {
- // TODO Capped at 3yrs, is it enough ?
expect_null(self.call("walletpassphrase", &(passwd, 100000000)).await)
}