Only sign funding transaction on monitor update resumption
What changed, and why it matters
This change fixes a timing issue in the Lightning Dev Kit where a funding transaction could be signed too early. Previously, the code that decides whether to sign a funding transaction could run both when a channel reconnects and when a pending monitor update finishes. The fix ensures signing only happens after the monitor update has actually completed, preventing a possible invalid or premature signature attempt if a channel reestablish happened while a monitor update was still pending.
Apply the patch. Review related resumption paths to ensure no other operations assume monitor-update completion without explicitly checking `is_awaiting_monitor_update()`. Consider adding regression tests that interleave channel reestablish with a pending monitor update during interactive funding.
Security signals we found
Premature cryptographic signature of funding transaction
Race between channel reestablish and monitor update completion
State-machine timing bug in dual-trigger resumption path
Potential invalid signature or inconsistent channel state
Evidence from the diff
In ChannelManager::handle_channel_resumption, the interactive transaction signing session was accessed unconditionally. The resumption path is reachable from both channel_reestablish and monitor-update completion. The patch gates access to channel.interactive_tx_signing_session on !channel.is_awaiting_monitor_update(), so holder transaction signatures are only requested and the funding transaction is only signed once the monitor update is no longer pending. It also simplifies the local-inputs branch to an if/else.
Changed components
lightning/src/ln/channelmanager.rsChannelManager::handle_channel_resumptionInteractive transaction signing sessionMonitor update resumption logicInspect captured patch +9 / −5
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index e34567d..2d7031c 100644
--- a/lightning/src/ln/channelmanager.rs
+++ b/lightning/src/ln/channelmanager.rs
@@ -9006,10 +9006,13 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
}
}
- if let Some(signing_session) = &mut channel.interactive_tx_signing_session {
- if signing_session.local_inputs_count() > 0
- && signing_session.holder_tx_signatures().is_none()
- {
+ if let Some(signing_session) = (!channel.is_awaiting_monitor_update())
+ .then(|| ())
+ .and_then(|_| channel.interactive_tx_signing_session.as_mut())
+ .filter(|signing_session| signing_session.holder_tx_signatures().is_none())
+ {
+ let local_inputs_count = signing_session.local_inputs_count();
+ if local_inputs_count > 0 {
let mut pending_events = self.pending_events.lock().unwrap();
let unsigned_transaction = signing_session.unsigned_tx().build_unsigned_tx();
let event_action = (
@@ -9027,7 +9030,8 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
} else {
pending_events.push_back(event_action);
}
- } else if signing_session.local_inputs_count() == 0 && signing_session.holder_tx_signatures().is_none() {
+ } else {
+ let txid = signing_session.unsigned_tx().compute_txid();
match channel.funding_transaction_signed(vec![]) {
Ok((Some(tx_signatures), funding_tx_opt)) => {
if let Some(funding_tx) = funding_tx_opt {
Why this scored 57/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.