Skip to content

Commit bc347e8

Browse files
committed
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
1 parent 570ed52 commit bc347e8

4 files changed

Lines changed: 43 additions & 11 deletions

File tree

Cargo.lock

Lines changed: 20 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ldk-server/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7-
ldk-node = { git = "https://github.com/lightningdevkit/ldk-node", rev = "c754e2fe85c70741b5e370334cd16856c615265e" }
7+
# TODO: the `RecoveryMode` API used below lives on the ldk-node branch
8+
# `2026-04-abort-on-first-startup-tip-fetch-failure`. Restore this to a pinned upstream git rev
9+
# once that branch merges.
10+
ldk-node = { path = "/home/tnull/workspace/worktrees/ldk-node/2026-04-abort-on-first-startup-tip-fetch-failure" }
811
serde = { version = "1.0.203", default-features = false, features = ["derive"] }
912
hyper = { version = "1", default-features = false, features = ["server", "http2"] }
1013
http-body-util = { version = "0.1", default-features = false }

ldk-server/src/main.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use ldk_node::bitcoin::Network;
2828
use ldk_node::config::Config;
2929
use ldk_node::entropy::NodeEntropy;
3030
use ldk_node::lightning::ln::channelmanager::PaymentId;
31-
use ldk_node::{Builder, Event, Node};
31+
use ldk_node::{Builder, Event, Node, RecoveryMode};
3232
use ldk_server_grpc::events;
3333
use ldk_server_grpc::events::{event_envelope, EventEnvelope};
3434
use ldk_server_grpc::types::Payment;
@@ -194,6 +194,17 @@ fn main() {
194194
config_file.lsps2_service_config.expect("Missing liquidity.lsps2_server config"),
195195
);
196196

197+
if let Some(rescan_from_height) = args_config.rescan_from_height {
198+
info!(
199+
"Wallet recovery mode requested via --rescan-from-height {}; the setting only \
200+
takes effect if this is the node's first startup.",
201+
rescan_from_height
202+
);
203+
builder.set_wallet_recovery_mode(Some(RecoveryMode {
204+
rescan_from_height: Some(rescan_from_height),
205+
}));
206+
}
207+
197208
let runtime = match tokio::runtime::Builder::new_multi_thread().enable_all().build() {
198209
Ok(runtime) => Arc::new(runtime),
199210
Err(e) => {

ldk-server/src/util/config.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,13 @@ pub struct ArgsConfig {
702702
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."
703703
)]
704704
tor_proxy_address: Option<String>,
705+
706+
#[arg(
707+
long,
708+
env = "LDK_SERVER_RESCAN_FROM_HEIGHT",
709+
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)."
710+
)]
711+
pub rescan_from_height: Option<u32>,
705712
}
706713

707714
pub fn load_config(args: &ArgsConfig) -> io::Result<Config> {

0 commit comments

Comments
 (0)