Skip to content

Commit 1a1beb6

Browse files
committed
Handle BackgroundEvents replaying non-closing monitor updates
`BackgroundEvent` was used to store `ChannelMonitorUpdate`s which result in a channel force-close, avoiding relying on `ChannelMonitor`s having been loaded while `ChannelManager` block-connection methods are called during startup. In the coming commit(s) we'll also generate non-channel-closing `ChannelMonitorUpdate`s during startup, which will need to be replayed prior to any other `ChannelMonitorUpdate`s generated from normal operation. In the next commit we'll handle that by handling `BackgroundEvent`s immediately after locking the `total_consistency_lock`.
1 parent 4811a1a commit 1a1beb6

File tree

1 file changed

+29
-5
lines changed

1 file changed

+29
-5
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,8 @@ enum BackgroundEvent {
509509
/// Note that any such events are lost on shutdown, so in general they must be updates which
510510
/// are regenerated on startup.
511511
ClosingMonitorUpdateRegeneratedOnStartup((OutPoint, ChannelMonitorUpdate)),
512-
/// Handle a ChannelMonitorUpdate.
512+
/// Handle a ChannelMonitorUpdate. This may or may not close the channel and may unblock the
513+
/// channel to continue normal operation.
513514
///
514515
/// Note that any such events are lost on shutdown, so in general they must be updates which
515516
/// are regenerated on startup.
@@ -3790,10 +3791,33 @@ where
37903791
// monitor updating completing.
37913792
let _ = self.chain_monitor.update_channel(funding_txo, &update);
37923793
},
3793-
BackgroundEvent::MonitorUpdateRegeneratedOnStartup((_, funding_txo, update)) => {
3794-
// The channel has already been closed, so no use bothering to care about the
3795-
// monitor updating completing.
3796-
let _ = self.chain_monitor.update_channel(funding_txo, &update);
3794+
BackgroundEvent::MonitorUpdateRegeneratedOnStartup((counterparty_id, funding_txo, update)) => {
3795+
let update_res = self.chain_monitor.update_channel(funding_txo, &update);
3796+
3797+
let mut found_chan = false;
3798+
let res = {
3799+
let per_peer_state = self.per_peer_state.read().unwrap();
3800+
if let Some(peer_state_mutex) = per_peer_state.get(&counterparty_id) {
3801+
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
3802+
let peer_state = &mut *peer_state_lock;
3803+
match peer_state.channel_by_id.entry(funding_txo.to_channel_id()) {
3804+
hash_map::Entry::Occupied(mut chan) => {
3805+
found_chan = true;
3806+
handle_new_monitor_update!(self, update_res, update.update_id, peer_state_lock, peer_state, per_peer_state, chan)
3807+
},
3808+
hash_map::Entry::Vacant(_) => {
3809+
Ok(())
3810+
},
3811+
}
3812+
} else { Ok(()) }
3813+
};
3814+
let _ = handle_error!(self, res, counterparty_id);
3815+
if !found_chan {
3816+
// TODO: If this channel has since closed, we're likely providing a payment
3817+
// preimage update, which we must ensure is durable! We currently don't,
3818+
// however, ensure that, and when we have a strategy therefor we should
3819+
// apply it here.
3820+
}
37973821
},
37983822
}
37993823
}

0 commit comments

Comments
 (0)