Attempt to unblock blocked monitor updates on startup
What changed, and why it matters
This patch fixes a Lightning node startup issue. When a multi-part payment is claimed, the node temporarily blocks certain channel updates until all parts of the payment are safely recorded. Those temporary blockers are intentionally not saved to disk. But if the node restarts, a later blocked update could stay stuck forever, potentially preventing a channel from making progress or resolving funds. The fix adds a startup step that tries to release any blocked channel monitor updates.
Review and merge. Consider adding regression tests that simulate an MPP claim, restart with blocked monitor updates, and verify the updates are unblocked and completed. Audit handle_monitor_update_release for safety when called with no specific update ID.
Security signals we found
Fixes a liveness/progress issue in channel monitor update processing after restart
Blocked monitor updates could prevent preimage propagation to channel monitors
Potential funds-availability or channel-stall risk if updates remain blocked
Issue linked as #4518
Evidence from the diff
In rust-lightning, MPP preimage claims insert RAA blockers across channels to ensure no single channel advances until all ChannelMonitorUpdates containing the preimage are durably persisted. These blockers are memory-only and lost on restart. If a ChannelMonitorUpdate was queued and blocked behind such a blocker, and the node restarts, there was no logic to unblock it. The commit introduces a non-persistent BackgroundEvent::AttemptUnblockMonitorUpdates emitted during deserialization for any funded channel with blocked_monitor_updates_pending() > 0. The event handler calls handle_monitor_update_release(counterparty_node_id, channel_id, None), allowing the update to proceed if its dependencies are now satisfied.
Changed components
lightning/src/ln/channelmanager.rsBackgroundEvent handling loopChannelManager deserialization/startup pathChannel monitor update blocking/unblocking logicInspect captured patch +20 / −0
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index a7a0942..980325a 100644
--- a/lightning/src/ln/channelmanager.rs
+++ b/lightning/src/ln/channelmanager.rs
@@ -1473,6 +1473,11 @@ enum BackgroundEvent {
channel_id: ChannelId,
highest_update_id_completed: u64,
},
+ /// A channel had blocked monitor updates waiting on startup. If the updates were blocked on
+ /// an MPP claim blocker not written to disk, we may be able to unblock them now.
+ ///
+ /// This event is never written to disk.
+ AttemptUnblockMonitorUpdates { counterparty_node_id: PublicKey, channel_id: ChannelId },
}
/// A pointer to a channel that is unblocked when an event is surfaced
@@ -8795,6 +8800,12 @@ impl<
&counterparty_node_id,
);
},
+ BackgroundEvent::AttemptUnblockMonitorUpdates {
+ counterparty_node_id,
+ channel_id,
+ } => {
+ self.handle_monitor_update_release(counterparty_node_id, channel_id, None);
+ },
}
}
NotifyOption::DoPersist
@@ -9751,6 +9762,7 @@ impl<
BackgroundEvent::MonitorUpdatesComplete {
channel_id, ..
} => *channel_id == _prev_channel_id,
+ BackgroundEvent::AttemptUnblockMonitorUpdates { .. } => false,
}
});
assert!(channel_closed || matching_bg_event, "{:?}", *background_events);
@@ -19456,6 +19468,14 @@ impl<
log_error!(logger, " Please ensure the chain::Watch API requirements are met and file a bug report at https://github.com/lightningdevkit/rust-lightning");
return Err(DecodeError::DangerousValue);
}
+ if funded_chan.blocked_monitor_updates_pending() > 0 {
+ pending_background_events.push(
+ BackgroundEvent::AttemptUnblockMonitorUpdates {
+ counterparty_node_id: *counterparty_id,
+ channel_id: *chan_id,
+ },
+ );
+ }
} else {
// We shouldn't have persisted (or read) any unfunded channel types so none should have been
// created in this `channel_by_id` map.
Why this scored 55/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.