Skip to content

Commit 6bbfe3b

Browse files
committed
Add a BackgroundEvent to replay non-closing monitor updates
`BackgroundEvent` is 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`. The new `BackgroundEvent` variant is restricted to only `ChannelMonitorUpdate`s which will be regenerated on the next restart, as they're not persisted to disk.
1 parent d2d3036 commit 6bbfe3b

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,12 @@ enum BackgroundEvent {
486486
/// Handle a ChannelMonitorUpdate that closes a channel, broadcasting its current latest holder
487487
/// commitment transaction.
488488
ClosingMonitorUpdate((OutPoint, ChannelMonitorUpdate)),
489+
/// Handle a ChannelMonitorUpdate that does not close a channel, potentially unblocking the
490+
/// channel to continue normal operation.
491+
///
492+
/// Note that any such events are lost on shutdown, so in general they must be updates which
493+
/// are regenerated on startup.
494+
MonitorUpdateRegeneratedOnStartup((PublicKey, OutPoint, ChannelMonitorUpdate)),
489495
}
490496

491497
#[derive(Debug)]
@@ -3681,6 +3687,36 @@ where
36813687
// monitor updating completing.
36823688
let _ = self.chain_monitor.update_channel(funding_txo, &update);
36833689
},
3690+
BackgroundEvent::MonitorUpdateRegeneratedOnStartup((counterparty_id, funding_txo, update)) => {
3691+
// The channel has already been closed, so no use bothering to care about the
3692+
// monitor updating completing.
3693+
let update_res = self.chain_monitor.update_channel(funding_txo, &update);
3694+
3695+
let mut found_chan = false;
3696+
{
3697+
let per_peer_state = self.per_peer_state.read().unwrap();
3698+
let res = if let Some(peer_state_mutex) = per_peer_state.get(&counterparty_id) {
3699+
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
3700+
let peer_state = &mut *peer_state_lock;
3701+
match peer_state.channel_by_id.entry(funding_txo.to_channel_id()) {
3702+
hash_map::Entry::Occupied(mut chan) => {
3703+
found_chan = true;
3704+
handle_new_monitor_update!(self, update_res, update.update_id, peer_state_lock, peer_state, per_peer_state, chan)
3705+
},
3706+
hash_map::Entry::Vacant(_) => {
3707+
Ok(())
3708+
},
3709+
}
3710+
} else { Ok(()) };
3711+
let _ = handle_error!(self, res, counterparty_id);
3712+
}
3713+
if !found_chan {
3714+
// TODO: If this channel has since closed, we're likely providing a payment
3715+
// preimage update, which we must ensure is durable! We currently don't,
3716+
// however, ensure that, and when we have a strategy therefor we should
3717+
// apply it here.
3718+
}
3719+
},
36843720
}
36853721
}
36863722
true
@@ -7272,14 +7308,18 @@ where
72727308
}
72737309

72747310
let background_events = self.pending_background_events.lock().unwrap();
7275-
(background_events.len() as u64).write(writer)?;
7311+
(background_events.iter()
7312+
.filter(|ev| if let BackgroundEvent::MonitorUpdateRegeneratedOnStartup(_) = ev { false } else { true })
7313+
.count() as u64)
7314+
.write(writer)?;
72767315
for event in background_events.iter() {
72777316
match event {
72787317
BackgroundEvent::ClosingMonitorUpdate((funding_txo, monitor_update)) => {
72797318
0u8.write(writer)?;
72807319
funding_txo.write(writer)?;
72817320
monitor_update.write(writer)?;
72827321
},
7322+
BackgroundEvent::MonitorUpdateRegeneratedOnStartup(_) => { },
72837323
}
72847324
}
72857325

@@ -7713,8 +7753,9 @@ where
77137753
0 => {
77147754
let (funding_txo, monitor_update): (OutPoint, ChannelMonitorUpdate) = (Readable::read(reader)?, Readable::read(reader)?);
77157755
if pending_background_events.iter().find(|e| {
7716-
let BackgroundEvent::ClosingMonitorUpdate((pending_funding_txo, pending_monitor_update)) = e;
7717-
*pending_funding_txo == funding_txo && *pending_monitor_update == monitor_update
7756+
if let BackgroundEvent::ClosingMonitorUpdate((pending_funding_txo, pending_monitor_update)) = e {
7757+
*pending_funding_txo == funding_txo && *pending_monitor_update == monitor_update
7758+
} else { false }
77187759
}).is_none() {
77197760
pending_background_events.push(BackgroundEvent::ClosingMonitorUpdate((funding_txo, monitor_update)));
77207761
}

0 commit comments

Comments
 (0)