Skip to content

Commit 6f9300f

Browse files
committed
Persist unresolved ChannelMonitors on empty height change
1 parent 726dd5c commit 6f9300f

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

lightning/src/chain/chainmonitor.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -640,17 +640,22 @@ where C::Target: chain::Filter,
640640
/// data could be moved to an archive location or removed entirely.
641641
pub fn archive_fully_resolved_channel_monitors(&self) {
642642
let mut have_monitors_to_prune = false;
643-
for (_, monitor_holder) in self.monitors.read().unwrap().iter() {
643+
for (funding_txo, monitor_holder) in self.monitors.read().unwrap().iter() {
644644
let logger = WithChannelMonitor::from(&self.logger, &monitor_holder.monitor, None);
645-
if monitor_holder.monitor.is_fully_resolved(&logger) {
645+
let (is_fully_resolved, needs_persistence) = monitor_holder.monitor.check_and_update_full_resolution_status(&logger);
646+
if is_fully_resolved {
646647
have_monitors_to_prune = true;
647648
}
649+
if needs_persistence {
650+
self.persister.update_persisted_channel(*funding_txo, None, &monitor_holder.monitor);
651+
}
648652
}
649653
if have_monitors_to_prune {
650654
let mut monitors = self.monitors.write().unwrap();
651655
monitors.retain(|funding_txo, monitor_holder| {
652656
let logger = WithChannelMonitor::from(&self.logger, &monitor_holder.monitor, None);
653-
if monitor_holder.monitor.is_fully_resolved(&logger) {
657+
let (is_fully_resolved, _) = monitor_holder.monitor.check_and_update_full_resolution_status(&logger);
658+
if is_fully_resolved {
654659
log_info!(logger,
655660
"Archiving fully resolved ChannelMonitor for funding txo {}",
656661
funding_txo

lightning/src/chain/channelmonitor.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1994,10 +1994,15 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
19941994

19951995
/// Checks if the monitor is fully resolved. Resolved monitor is one that has claimed all of
19961996
/// its outputs and balances (i.e. [`Self::get_claimable_balances`] returns an empty set).
1997+
/// Additionally may update state to track when the balances set became empty.
19971998
///
1998-
/// This function returns true only if [`Self::get_claimable_balances`] has been empty for at least
1999+
/// This function returns a tuple of two booleans, the first indicating whether the monitor is
2000+
/// fully resolved, and the second whether the monitor needs persistence to ensure it is
2001+
/// reliably marked as resolved within 4032 blocks.
2002+
///
2003+
/// The first boolean is true only if [`Self::get_claimable_balances`] has been empty for at least
19992004
/// 4032 blocks as an additional protection against any bugs resulting in spuriously empty balance sets.
2000-
pub fn is_fully_resolved<L: Logger>(&self, logger: &L) -> bool {
2005+
pub fn check_and_update_full_resolution_status<L: Logger>(&self, logger: &L) -> (bool, bool) {
20012006
let mut is_all_funds_claimed = self.get_claimable_balances().is_empty();
20022007
let current_height = self.current_best_block().height;
20032008
let mut inner = self.inner.lock().unwrap();
@@ -2011,7 +2016,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
20112016
match (inner.balances_empty_height, is_all_funds_claimed) {
20122017
(Some(balances_empty_height), true) => {
20132018
// Claimed all funds, check if reached the blocks threshold.
2014-
current_height >= balances_empty_height + BLOCKS_THRESHOLD
2019+
(current_height >= balances_empty_height + BLOCKS_THRESHOLD, false)
20152020
},
20162021
(Some(_), false) => {
20172022
// previously assumed we claimed all funds, but we have new funds to claim.
@@ -2021,7 +2026,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
20212026
"WARNING: LDK thought it was done claiming all the available funds in the ChannelMonitor for channel {}, but later decided it had more to claim. This is potentially an important bug in LDK, please report it at https://github.com/lightningdevkit/rust-lightning/issues/new",
20222027
inner.get_funding_txo().0);
20232028
inner.balances_empty_height = None;
2024-
false
2029+
(false, true)
20252030
},
20262031
(None, true) => {
20272032
// Claimed all funds but `balances_empty_height` is None. It is set to the
@@ -2030,11 +2035,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
20302035
"ChannelMonitor funded at {} is now fully resolved. It will become archivable in {} blocks",
20312036
inner.get_funding_txo().0, BLOCKS_THRESHOLD);
20322037
inner.balances_empty_height = Some(current_height);
2033-
false
2038+
(false, true)
20342039
},
20352040
(None, false) => {
20362041
// Have funds to claim.
2037-
false
2042+
(false, false)
20382043
},
20392044
}
20402045
}

0 commit comments

Comments
 (0)