From 32823217068a40b5865fb382fcfcf16cf7d310d0 Mon Sep 17 00:00:00 2001 From: jbesraa Date: Sun, 24 Mar 2024 07:57:45 +0200 Subject: [PATCH] Add `prune_stale_channel_monitors` to `ChainMonitor` --- lightning/src/chain/chainmonitor.rs | 41 +++++++++++++++++++++++++++ lightning/src/chain/channelmonitor.rs | 4 +++ 2 files changed, 45 insertions(+) diff --git a/lightning/src/chain/chainmonitor.rs b/lightning/src/chain/chainmonitor.rs index a15d9a11cdd..25f78dc8e6e 100644 --- a/lightning/src/chain/chainmonitor.rs +++ b/lightning/src/chain/chainmonitor.rs @@ -662,6 +662,24 @@ where C::Target: chain::Filter, } } } + + pub fn prune_stale_channel_monitors(&self, to_prune: Vec) { + let mut monitors = self.monitors.write().unwrap(); + for funding_txo in to_prune { + let channel_monitor = monitors.get(&funding_txo); + if let Some(channel_monitor) = channel_monitor { + if channel_monitor.monitor.is_stale() { + log_info!(self.logger, "Pruning stale ChannelMonitor for + channel {}", log_funding_info!(channel_monitor.monitor)); + //TODO: save the channel monitor to disk in an archived namespace before removing it + + self.persister.prune_persisted_channel(funding_txo); + monitors.remove(&funding_txo); + } + } + + } + } } impl @@ -1114,4 +1132,27 @@ mod tests { core::mem::drop(nodes); }).is_err()); } + + #[test] + fn prune_stale_channel_monitor() { + // Test that we can prune a ChannelMonitor that has no active channel. + let chanmon_cfgs = create_chanmon_cfgs(2); + let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); + let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); + let nodes = create_network(2, &node_cfgs, &node_chanmgrs); + create_announced_chan_between_nodes(&nodes, 0, 1); + // Get a route for later and rebalance the channel somewhat + send_payment(&nodes[0], &[&nodes[1]], 10_000_000); + // First route a payment that we will claim on chain and give the recipient the preimage. + let (payment_preimage, payment_hash, ..) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000); + nodes[1].node.claim_funds(payment_preimage); + expect_payment_claimed!(nodes[1], payment_hash, 1_000_000); + nodes[1].node.get_and_clear_pending_msg_events(); + let binding = node_cfgs[1].chain_monitor.added_monitors.lock().unwrap(); + let monitors_b = binding.first().unwrap(); + let outpoint = monitors_b.0.clone(); + dbg!(&outpoint); + // nodes[1].chain_monitor().unwrap().chain_monitor.prune_stale_channel_monitors(vec![outpoint]); // lock order problem + assert!(false); + } } diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 4352076e94d..7774e0e13cb 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -1855,6 +1855,10 @@ impl ChannelMonitor { spendable_outputs } + pub(crate) fn is_stale(&self) -> bool { + self.get_claimable_balances().is_empty() + } + #[cfg(test)] pub fn get_counterparty_payment_script(&self) -> ScriptBuf { self.inner.lock().unwrap().counterparty_payment_script.clone()