From bc347e81210e01efca1cba34a90ec825e0160e33 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Tue, 21 Apr 2026 15:04:16 +0200 Subject: [PATCH] Add `--rescan-from-height` CLI argument Expose the ldk-node wallet-recovery API through a new top-level CLI flag (also overridable via the `LDK_SERVER_RESCAN_FROM_HEIGHT` environment variable). When set on a fresh node's first startup, the value is passed through to `Builder::set_wallet_recovery_mode(Some(RecoveryMode { rescan_from_height: Some(h) }))` so the wallet picks up funds sent before the current chain tip. Bitcoin Core RPC/REST chain sources honor the height precisely by resolving the block hash at `h` and using it as the wallet birthday. Esplora/Electrum backends cannot resolve a block hash from a height via the BDK client APIs, so they ignore the value but still escalate the next sync to a one-shot `full_scan` to re-discover funds on previously-unknown addresses. The `ldk-node` dependency is temporarily pointed at the local `2026-04-abort-on-first-startup-tip-fetch-failure` worktree since the `RecoveryMode` API is not yet on ldk-node's upstream main; the Cargo.toml entry should be restored to a pinned upstream git rev once that branch merges. Co-Authored-By: HAL 9000 --- Cargo.lock | 29 ++++++++++++++++++++--------- ldk-server/Cargo.toml | 5 ++++- ldk-server/src/main.rs | 13 ++++++++++++- ldk-server/src/util/config.rs | 7 +++++++ 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 061ac6b6..9de9d352 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -530,7 +530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -1001,7 +1001,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.1", + "socket2 0.5.10", "tokio", "tower-service", "tracing", @@ -1203,7 +1203,6 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "ldk-node" version = "0.8.0+git" -source = "git+https://github.com/lightningdevkit/ldk-node?rev=c754e2fe85c70741b5e370334cd16856c615265e#c754e2fe85c70741b5e370334cd16856c615265e" dependencies = [ "async-trait", "base64 0.22.1", @@ -1224,6 +1223,7 @@ dependencies = [ "lightning", "lightning-background-processor", "lightning-block-sync", + "lightning-dns-resolver", "lightning-invoice", "lightning-liquidity", "lightning-macros", @@ -1381,6 +1381,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "lightning-dns-resolver" +version = "0.3.0+git" +source = "git+https://github.com/lightningdevkit/rust-lightning?rev=38a62c32454d3eac22578144c479dbf9a6d9bff6#38a62c32454d3eac22578144c479dbf9a6d9bff6" +dependencies = [ + "dnssec-prover", + "lightning", + "lightning-types", + "tokio", +] + [[package]] name = "lightning-invoice" version = "0.35.0+git" @@ -1733,7 +1744,7 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls 0.23.34", - "socket2 0.6.1", + "socket2 0.5.10", "thiserror", "tokio", "tracing", @@ -1770,9 +1781,9 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.1", + "socket2 0.5.10", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -2014,7 +2025,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.11.0", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2112,7 +2123,7 @@ version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ - "bitcoin_hashes 0.14.0", + "bitcoin_hashes 0.13.0", "rand 0.8.5", "secp256k1-sys", "serde", @@ -2335,7 +2346,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix 1.1.2", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] diff --git a/ldk-server/Cargo.toml b/ldk-server/Cargo.toml index bb1c10cd..f1dbc716 100644 --- a/ldk-server/Cargo.toml +++ b/ldk-server/Cargo.toml @@ -4,7 +4,10 @@ version = "0.1.0" edition = "2021" [dependencies] -ldk-node = { git = "https://github.com/lightningdevkit/ldk-node", rev = "c754e2fe85c70741b5e370334cd16856c615265e" } +# TODO: the `RecoveryMode` API used below lives on the ldk-node branch +# `2026-04-abort-on-first-startup-tip-fetch-failure`. Restore this to a pinned upstream git rev +# once that branch merges. +ldk-node = { path = "/home/tnull/workspace/worktrees/ldk-node/2026-04-abort-on-first-startup-tip-fetch-failure" } serde = { version = "1.0.203", default-features = false, features = ["derive"] } hyper = { version = "1", default-features = false, features = ["server", "http2"] } http-body-util = { version = "0.1", default-features = false } diff --git a/ldk-server/src/main.rs b/ldk-server/src/main.rs index 30807541..c298e491 100644 --- a/ldk-server/src/main.rs +++ b/ldk-server/src/main.rs @@ -28,7 +28,7 @@ use ldk_node::bitcoin::Network; use ldk_node::config::Config; use ldk_node::entropy::NodeEntropy; use ldk_node::lightning::ln::channelmanager::PaymentId; -use ldk_node::{Builder, Event, Node}; +use ldk_node::{Builder, Event, Node, RecoveryMode}; use ldk_server_grpc::events; use ldk_server_grpc::events::{event_envelope, EventEnvelope}; use ldk_server_grpc::types::Payment; @@ -194,6 +194,17 @@ fn main() { config_file.lsps2_service_config.expect("Missing liquidity.lsps2_server config"), ); + if let Some(rescan_from_height) = args_config.rescan_from_height { + info!( + "Wallet recovery mode requested via --rescan-from-height {}; the setting only \ + takes effect if this is the node's first startup.", + rescan_from_height + ); + builder.set_wallet_recovery_mode(Some(RecoveryMode { + rescan_from_height: Some(rescan_from_height), + })); + } + let runtime = match tokio::runtime::Builder::new_multi_thread().enable_all().build() { Ok(runtime) => Arc::new(runtime), Err(e) => { diff --git a/ldk-server/src/util/config.rs b/ldk-server/src/util/config.rs index 22e3b61b..0fe318d8 100644 --- a/ldk-server/src/util/config.rs +++ b/ldk-server/src/util/config.rs @@ -702,6 +702,13 @@ pub struct ArgsConfig { help = "Tor daemon SOCKS proxy address. Only connections to OnionV3 peers will be made via this proxy; other connections (IPv4 peers, Electrum server) will not be routed over Tor." )] tor_proxy_address: Option, + + #[arg( + long, + env = "LDK_SERVER_RESCAN_FROM_HEIGHT", + help = "Triggers wallet recovery on the next startup. On Bitcoin Core RPC/REST chain sources, the given block height is used as the wallet birthday so the chain is rescanned from that height (useful on pruned nodes when the wallet's birthday is known). On Esplora/Electrum chain sources the given height is ignored, but setting the flag still forces a one-shot BDK `full_scan` so funds sent to previously-unknown addresses are re-discovered. Only takes effect on first startup (i.e. for a freshly-persisted wallet)." + )] + pub rescan_from_height: Option, } pub fn load_config(args: &ArgsConfig) -> io::Result {