Skip to content

Commit 45a2463

Browse files
jkczyzclaude
andcommitted
Persist splice intents until the splice locks
LDK only persists a splice once its negotiation reaches AwaitingSignatures, so a splice in flight when the node stops can leave no trace in LDK. Persist each user-initiated splice as an intent record before its contribution is handed to LDK, so such a splice can be recognized at the next startup — releasing whatever the wallet still holds for it, which a later commit adds — and so events about the splice can be described in terms of the original request. A fee bump reuses the channel's existing intent record, so at most one record ever exists per channel. The record is undone when LDK rejects the hand-off synchronously and settled once the splice locks, its failure is surfaced, or its channel closes. A failure event settles the intent only after the event is durably queued — a crash in between leaves the intent for the replayed event to settle, erring toward a duplicate report over a lost one — and only when the event's contribution identifies the recorded splice: a mismatch means the failure concerns an older, superseded attempt with no record of its own. A splice queued behind another pending splice survives the pending splice's lock, so its intent is re-anchored to the new funding rather than settled. Wallet state staged on a splice's behalf is flushed only after the intent record persists, so nothing the wallet reserves for a splice can outlive the record through which a later startup would release it. A splice that fails before the hand-off releases what the wallet holds for it immediately; one LDK rejects has it returned through the DiscardFunding event instead. When a lock settles an intent without spending its inputs — a replacement or counterparty-initiated splice locked instead — the inputs are released for other spends. Once a splice funding payment is classified, the intent is carried on the payment's record until the splice locks; a payment that already graduated instead removes the leftover intent record. Developed with assistance from Claude Code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 50bbfe1 commit 45a2463

7 files changed

Lines changed: 1092 additions & 45 deletions

File tree

‎src/builder.rs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ use lightning_dns_resolver::OMDomainResolver;
5353
use vss_client::headers::VssHeaderProvider;
5454

5555
use crate::chain::ChainSource;
56+
use crate::channel::SpliceTracker;
5657
#[cfg(feature = "chain-bitcoind")]
5758
use crate::config::BitcoindRestClientConfig;
5859
use crate::config::{
@@ -2451,6 +2452,14 @@ fn build_with_store_internal(
24512452
})
24522453
});
24532454

2455+
let splice_tracker = Arc::new(SpliceTracker::new(
2456+
Arc::clone(&channel_manager),
2457+
Arc::clone(&wallet),
2458+
Arc::clone(&pending_payment_store),
2459+
Arc::clone(&payment_store),
2460+
Arc::clone(&logger),
2461+
));
2462+
24542463
#[cfg(cycle_tests)]
24552464
let mut _leak_checker = crate::LeakChecker(Vec::new());
24562465
#[cfg(cycle_tests)]
@@ -2490,6 +2499,7 @@ fn build_with_store_internal(
24902499
scorer,
24912500
peer_store,
24922501
payment_store,
2502+
splice_tracker,
24932503
lnurl_auth,
24942504
is_running,
24952505
node_metrics,

0 commit comments

Comments
 (0)