Skip to content

Commit a3c5cce

Browse files
committed
Remove sync_wallets from hot paths
sync_wallets() issues serial HTTP requests to Esplora (fee rate estimation, lightning tx sync across multiple block heights, BDK wallet sync). This blocks the NAPI thread for a few seconds via runtime.block_on(), which prevents the JS event loop from polling nextEvent() for incoming HTLCs. The 10+ second payment latency observed traces directly to this: the sender's HTLC sits unprocessed while the receiver node grinds through chain sync before the webhook handler can start its event loop. Removed sync_wallets from start_receiving, receive_payment, get_invoice, and execute_payment. Receiving HTLCs only needs a peer connection and channel manager, both provided by node.start(). Sending payments routes via the gossip graph with fee rates already cached by node.start(). Also disabled background wallet syncing (the 30s/80s interval loop). For a webhook-based node that lives 40-60s, the immediate first tick just competes with the peer handler for Esplora bandwidth. LDK uses highest_seen_timestamp (set via best_block_updated) for inbound payment verification with a 2-hour grace window. A stale chain tip could cause valid payments to be rejected as expired. The platform's 30-minute ping cron calls sync_wallets via the balance handler, which keeps the timestamp well within that window. get_balance() also syncs explicitly before reading UTXOs.
1 parent 63f07dd commit a3c5cce

1 file changed

Lines changed: 6 additions & 27 deletions

File tree

src/lib.rs

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use ldk_node::{
3838
hashes::{Hash, sha256},
3939
secp256k1::PublicKey,
4040
},
41-
config::Config,
41+
config::{Config, EsploraSyncConfig},
4242
generate_entropy_mnemonic,
4343
lightning::ln::channelmanager::PaymentId,
4444
lightning::sign::{KeysManager as LdkKeysManager, NodeSigner, Recipient},
@@ -373,7 +373,10 @@ impl MdkNode {
373373

374374
let mut builder = Builder::from_config(config);
375375
builder.set_network(network);
376-
builder.set_chain_source_esplora(options.esplora_url, None);
376+
// Disable background wallet syncing. These nodes are intended to be short
377+
// lived and are kept in sync via other means.
378+
let esplora_sync_config = EsploraSyncConfig { background_sync_config: None };
379+
builder.set_chain_source_esplora(options.esplora_url, Some(esplora_sync_config));
377380
builder.set_gossip_source_rgs(options.rgs_url);
378381
builder.set_entropy_bip39_mnemonic(mnemonic, None);
379382
let logger_arc = Arc::clone(logger_instance());
@@ -441,18 +444,12 @@ impl MdkNode {
441444
}
442445
}
443446

444-
/// Start the node and sync wallets. Call once before polling for events.
447+
/// Start the node. Call once before polling for events.
445448
#[napi]
446449
pub fn start_receiving(&self) -> napi::Result<()> {
447450
self.node().start().map_err(|e| {
448451
eprintln!("[lightning-js] Failed to start node in start_receiving: {e}");
449452
napi::Error::from_reason(format!("Failed to start: {e}"))
450-
})?;
451-
452-
self.node().sync_wallets().map_err(|e| {
453-
eprintln!("[lightning-js] Failed to sync wallets in start_receiving: {e}");
454-
let _ = self.node().stop();
455-
napi::Error::from_reason(format!("Failed to sync: {e}"))
456453
})
457454
}
458455

@@ -717,11 +714,6 @@ impl MdkNode {
717714
return received_payments;
718715
}
719716

720-
if let Err(err) = self.node().sync_wallets() {
721-
eprintln!("[lightning-js] Failed to sync wallets: {err}");
722-
panic!("failed to sync wallets: {err}");
723-
}
724-
725717
let start_sync_at = std::time::Instant::now();
726718
let mut last_event_time = start_sync_at;
727719

@@ -848,10 +840,6 @@ impl MdkNode {
848840
eprintln!("[lightning-js] Failed to start node for get_invoice: {err}");
849841
panic!("failed to start node for get_invoice: {err}");
850842
}
851-
if let Err(err) = self.node().sync_wallets() {
852-
eprintln!("[lightning-js] Failed to sync wallets: {err}");
853-
panic!("failed to sync wallets: {err}");
854-
}
855843

856844
let result = self.get_invoice_impl(Some(amount), description, expiry_secs);
857845

@@ -1154,15 +1142,6 @@ impl MdkNode {
11541142
napi::Error::new(Status::GenericFailure, format!("failed to start node: {e}"))
11551143
})?;
11561144

1157-
// Sync wallets
1158-
if let Err(e) = self.node().sync_wallets() {
1159-
let _ = self.node().stop();
1160-
return Err(napi::Error::new(
1161-
Status::GenericFailure,
1162-
format!("failed to sync wallets: {e}"),
1163-
));
1164-
}
1165-
11661145
let result = self.execute_payment_impl(&payment_target, wait_secs);
11671146
let _ = self.node().stop();
11681147
result

0 commit comments

Comments
 (0)