Skip to content

Commit 71bafec

Browse files
committed
Move a handful of channel messages to notify-without-persist
Many channel related messages don't actually change the channel state in a way that changes the persisted channel. For example, an `update_add_htlc` or `update_fail_htlc` message simply adds the change to a queue, changing the channel state when we receive a `commitment_signed` message. In these cases there's really no reason to wake the background processor at all - there's no response message and there's no state update. However, note that if we close the channel we should persist the `ChannelManager`. If we send an error message without closing the channel, we should wake the background processor without persisting. Here we move to the appropriate `NotifyOption` on some of the simpler channel message handlers.
1 parent 305df1d commit 71bafec

File tree

1 file changed

+118
-17
lines changed

1 file changed

+118
-17
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 118 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,10 @@ impl MsgHandleErrInternal {
494494
channel_capacity: None,
495495
}
496496
}
497+
498+
fn closes_channel(&self) -> bool {
499+
self.chan_id.is_some()
500+
}
497501
}
498502

499503
/// We hold back HTLCs we intend to relay for a random interval greater than this (see
@@ -1238,6 +1242,12 @@ struct PersistenceNotifierGuard<'a, F: Fn() -> NotifyOption> {
12381242
}
12391243

12401244
impl<'a> PersistenceNotifierGuard<'a, fn() -> NotifyOption> { // We don't care what the concrete F is here, it's unused
1245+
/// Notifies any waiters and indicates that we need to persist, in addition to possibly having
1246+
/// events to handle.
1247+
///
1248+
/// This must always be called if the changes included a `ChannelMonitorUpdate`, as well as in
1249+
/// other cases where losing the changes on restart may result in a force-close or otherwise
1250+
/// isn't ideal.
12411251
fn notify_on_drop<C: AChannelManager>(cm: &'a C) -> PersistenceNotifierGuard<'a, impl Fn() -> NotifyOption> {
12421252
Self::optionally_notify(cm, || -> NotifyOption { NotifyOption::DoPersist })
12431253
}
@@ -2152,9 +2162,14 @@ macro_rules! process_events_body {
21522162
processed_all_events = false;
21532163
}
21542164

2155-
if result == NotifyOption::DoPersist {
2156-
$self.needs_persist_flag.store(true, Ordering::Release);
2157-
$self.event_persist_notifier.notify();
2165+
match result {
2166+
NotifyOption::DoPersist => {
2167+
$self.needs_persist_flag.store(true, Ordering::Release);
2168+
$self.event_persist_notifier.notify();
2169+
},
2170+
NotifyOption::SkipPersistHandleEvents =>
2171+
$self.event_persist_notifier.notify(),
2172+
NotifyOption::SkipPersistNoEvents => {},
21582173
}
21592174
}
21602175
}
@@ -5560,6 +5575,8 @@ where
55605575
}
55615576

55625577
fn internal_open_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result<(), MsgHandleErrInternal> {
5578+
// Note that the ChannelManager is NOT re-persisted on disk after this, so any changes are
5579+
// likely to be lost on restart!
55635580
if msg.chain_hash != self.genesis_hash {
55645581
return Err(MsgHandleErrInternal::send_err_msg_no_close("Unknown genesis block hash".to_owned(), msg.temporary_channel_id.clone()));
55655582
}
@@ -5659,6 +5676,8 @@ where
56595676
}
56605677

56615678
fn internal_accept_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::AcceptChannel) -> Result<(), MsgHandleErrInternal> {
5679+
// Note that the ChannelManager is NOT re-persisted on disk after this, so any changes are
5680+
// likely to be lost on restart!
56625681
let (value, output_script, user_id) = {
56635682
let per_peer_state = self.per_peer_state.read().unwrap();
56645683
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
@@ -5819,6 +5838,8 @@ where
58195838
}
58205839

58215840
fn internal_channel_ready(&self, counterparty_node_id: &PublicKey, msg: &msgs::ChannelReady) -> Result<(), MsgHandleErrInternal> {
5841+
// Note that the ChannelManager is NOT re-persisted on disk after this (unless we error
5842+
// closing a channel), so any changes are likely to be lost on restart!
58225843
let per_peer_state = self.per_peer_state.read().unwrap();
58235844
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
58245845
.ok_or_else(|| {
@@ -5997,6 +6018,9 @@ where
59976018
//encrypted with the same key. It's not immediately obvious how to usefully exploit that,
59986019
//but we should prevent it anyway.
59996020

6021+
// Note that the ChannelManager is NOT re-persisted on disk after this (unless we error
6022+
// closing a channel), so any changes are likely to be lost on restart!
6023+
60006024
let decoded_hop_res = self.decode_update_add_htlc_onion(msg);
60016025
let per_peer_state = self.per_peer_state.read().unwrap();
60026026
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
@@ -6078,6 +6102,8 @@ where
60786102
}
60796103

60806104
fn internal_update_fail_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) -> Result<(), MsgHandleErrInternal> {
6105+
// Note that the ChannelManager is NOT re-persisted on disk after this (unless we error
6106+
// closing a channel), so any changes are likely to be lost on restart!
60816107
let per_peer_state = self.per_peer_state.read().unwrap();
60826108
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
60836109
.ok_or_else(|| {
@@ -6101,6 +6127,8 @@ where
61016127
}
61026128

61036129
fn internal_update_fail_malformed_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFailMalformedHTLC) -> Result<(), MsgHandleErrInternal> {
6130+
// Note that the ChannelManager is NOT re-persisted on disk after this (unless we error
6131+
// closing a channel), so any changes are likely to be lost on restart!
61046132
let per_peer_state = self.per_peer_state.read().unwrap();
61056133
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
61066134
.ok_or_else(|| {
@@ -7476,8 +7504,21 @@ where
74767504
L::Target: Logger,
74777505
{
74787506
fn handle_open_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannel) {
7479-
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
7480-
let _ = handle_error!(self, self.internal_open_channel(counterparty_node_id, msg), *counterparty_node_id);
7507+
// Note that we never need to persist the updated ChannelManager for an inbound
7508+
// open_channel message - pre-funded channels are never written so there should be no
7509+
// change to the contents.
7510+
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
7511+
let res = self.internal_open_channel(counterparty_node_id, msg);
7512+
let persist = match &res {
7513+
Err(e) if e.closes_channel() => {
7514+
debug_assert!(false, "We shouldn't close a new channel");
7515+
NotifyOption::DoPersist
7516+
},
7517+
_ => NotifyOption::SkipPersistHandleEvents,
7518+
};
7519+
let _ = handle_error!(self, res, *counterparty_node_id);
7520+
persist
7521+
});
74817522
}
74827523

74837524
fn handle_open_channel_v2(&self, counterparty_node_id: &PublicKey, msg: &msgs::OpenChannelV2) {
@@ -7487,8 +7528,13 @@ where
74877528
}
74887529

74897530
fn handle_accept_channel(&self, counterparty_node_id: &PublicKey, msg: &msgs::AcceptChannel) {
7490-
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
7491-
let _ = handle_error!(self, self.internal_accept_channel(counterparty_node_id, msg), *counterparty_node_id);
7531+
// Note that we never need to persist the updated ChannelManager for an inbound
7532+
// accept_channel message - pre-funded channels are never written so there should be no
7533+
// change to the contents.
7534+
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
7535+
let _ = handle_error!(self, self.internal_accept_channel(counterparty_node_id, msg), *counterparty_node_id);
7536+
NotifyOption::SkipPersistHandleEvents
7537+
});
74927538
}
74937539

74947540
fn handle_accept_channel_v2(&self, counterparty_node_id: &PublicKey, msg: &msgs::AcceptChannelV2) {
@@ -7508,8 +7554,19 @@ where
75087554
}
75097555

75107556
fn handle_channel_ready(&self, counterparty_node_id: &PublicKey, msg: &msgs::ChannelReady) {
7511-
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
7512-
let _ = handle_error!(self, self.internal_channel_ready(counterparty_node_id, msg), *counterparty_node_id);
7557+
// Note that we never need to persist the updated ChannelManager for an inbound
7558+
// channel_ready message - while the channel's state will change, any channel_ready message
7559+
// will ultimately be re-sent on startup and the `ChannelMonitor` won't be updated so we
7560+
// will not force-close the channel on startup.
7561+
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
7562+
let res = self.internal_channel_ready(counterparty_node_id, msg);
7563+
let persist = match &res {
7564+
Err(e) if e.closes_channel() => NotifyOption::DoPersist,
7565+
_ => NotifyOption::SkipPersistHandleEvents,
7566+
};
7567+
let _ = handle_error!(self, res, *counterparty_node_id);
7568+
persist
7569+
});
75137570
}
75147571

75157572
fn handle_shutdown(&self, counterparty_node_id: &PublicKey, msg: &msgs::Shutdown) {
@@ -7523,8 +7580,19 @@ where
75237580
}
75247581

75257582
fn handle_update_add_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateAddHTLC) {
7526-
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
7527-
let _ = handle_error!(self, self.internal_update_add_htlc(counterparty_node_id, msg), *counterparty_node_id);
7583+
// Note that we never need to persist the updated ChannelManager for an inbound
7584+
// update_add_htlc message - the message itself doesn't change our channel state only the
7585+
// `commitment_signed` message afterwards will.
7586+
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
7587+
let res = self.internal_update_add_htlc(counterparty_node_id, msg);
7588+
let persist = match &res {
7589+
Err(e) if e.closes_channel() => NotifyOption::DoPersist,
7590+
Err(_) => NotifyOption::SkipPersistHandleEvents,
7591+
Ok(()) => NotifyOption::SkipPersistNoEvents,
7592+
};
7593+
let _ = handle_error!(self, res, *counterparty_node_id);
7594+
persist
7595+
});
75287596
}
75297597

75307598
fn handle_update_fulfill_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFulfillHTLC) {
@@ -7533,13 +7601,35 @@ where
75337601
}
75347602

75357603
fn handle_update_fail_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) {
7536-
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
7537-
let _ = handle_error!(self, self.internal_update_fail_htlc(counterparty_node_id, msg), *counterparty_node_id);
7604+
// Note that we never need to persist the updated ChannelManager for an inbound
7605+
// update_fail_htlc message - the message itself doesn't change our channel state only the
7606+
// `commitment_signed` message afterwards will.
7607+
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
7608+
let res = self.internal_update_fail_htlc(counterparty_node_id, msg);
7609+
let persist = match &res {
7610+
Err(e) if e.closes_channel() => NotifyOption::DoPersist,
7611+
Err(_) => NotifyOption::SkipPersistHandleEvents,
7612+
Ok(()) => NotifyOption::SkipPersistNoEvents,
7613+
};
7614+
let _ = handle_error!(self, res, *counterparty_node_id);
7615+
persist
7616+
});
75387617
}
75397618

75407619
fn handle_update_fail_malformed_htlc(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFailMalformedHTLC) {
7541-
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
7542-
let _ = handle_error!(self, self.internal_update_fail_malformed_htlc(counterparty_node_id, msg), *counterparty_node_id);
7620+
// Note that we never need to persist the updated ChannelManager for an inbound
7621+
// update_fail_malformed_htlc message - the message itself doesn't change our channel state
7622+
// only the `commitment_signed` message afterwards will.
7623+
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
7624+
let res = self.internal_update_fail_malformed_htlc(counterparty_node_id, msg);
7625+
let persist = match &res {
7626+
Err(e) if e.closes_channel() => NotifyOption::DoPersist,
7627+
Err(_) => NotifyOption::SkipPersistHandleEvents,
7628+
Ok(()) => NotifyOption::SkipPersistNoEvents,
7629+
};
7630+
let _ = handle_error!(self, res, *counterparty_node_id);
7631+
persist
7632+
});
75437633
}
75447634

75457635
fn handle_commitment_signed(&self, counterparty_node_id: &PublicKey, msg: &msgs::CommitmentSigned) {
@@ -7553,8 +7643,19 @@ where
75537643
}
75547644

75557645
fn handle_update_fee(&self, counterparty_node_id: &PublicKey, msg: &msgs::UpdateFee) {
7556-
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
7557-
let _ = handle_error!(self, self.internal_update_fee(counterparty_node_id, msg), *counterparty_node_id);
7646+
// Note that we never need to persist the updated ChannelManager for an inbound
7647+
// update_fee message - the message itself doesn't change our channel state only the
7648+
// `commitment_signed` message afterwards will.
7649+
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
7650+
let res = self.internal_update_fee(counterparty_node_id, msg);
7651+
let persist = match &res {
7652+
Err(e) if e.closes_channel() => NotifyOption::DoPersist,
7653+
Err(_) => NotifyOption::SkipPersistHandleEvents,
7654+
Ok(()) => NotifyOption::SkipPersistNoEvents,
7655+
};
7656+
let _ = handle_error!(self, res, *counterparty_node_id);
7657+
persist
7658+
});
75587659
}
75597660

75607661
fn handle_announcement_signatures(&self, counterparty_node_id: &PublicKey, msg: &msgs::AnnouncementSignatures) {

0 commit comments

Comments
 (0)