Skip to content

Commit 271103d

Browse files
committed
Avoid writing ChannelManager when hitting lnd bug 6039
When we hit lnd bug 6039, we end up sending error messages to peers in a loop. This should be fine, but because we used the generic `PersistenceNotifierGuard::notify_on_drop` lock above the specific handling, we end up writing `ChannelManager` every time we manage a round-trip to our peer. This can add up quite quickly, and isn't actually changing, so we really need to avoid writing the `ChannelManager` in this case.
1 parent 72c4eb8 commit 271103d

File tree

1 file changed

+32
-23
lines changed

1 file changed

+32
-23
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9030,8 +9030,6 @@ where
90309030
}
90319031

90329032
fn handle_error(&self, counterparty_node_id: &PublicKey, msg: &msgs::ErrorMessage) {
9033-
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
9034-
90359033
match &msg.data as &str {
90369034
"cannot co-op close channel w/ active htlcs"|
90379035
"link failed to shutdown" =>
@@ -9044,34 +9042,45 @@ where
90449042
// We're not going to bother handling this in a sensible way, instead simply
90459043
// repeating the Shutdown message on repeat until morale improves.
90469044
if !msg.channel_id.is_zero() {
9047-
let per_peer_state = self.per_peer_state.read().unwrap();
9048-
let peer_state_mutex_opt = per_peer_state.get(counterparty_node_id);
9049-
if peer_state_mutex_opt.is_none() { return; }
9050-
let mut peer_state = peer_state_mutex_opt.unwrap().lock().unwrap();
9051-
if let Some(ChannelPhase::Funded(chan)) = peer_state.channel_by_id.get(&msg.channel_id) {
9052-
if let Some(msg) = chan.get_outbound_shutdown() {
9053-
peer_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
9054-
node_id: *counterparty_node_id,
9055-
msg,
9056-
});
9057-
}
9058-
peer_state.pending_msg_events.push(events::MessageSendEvent::HandleError {
9059-
node_id: *counterparty_node_id,
9060-
action: msgs::ErrorAction::SendWarningMessage {
9061-
msg: msgs::WarningMessage {
9062-
channel_id: msg.channel_id,
9063-
data: "You appear to be exhibiting LND bug 6039, we'll keep sending you shutdown messages until you handle them correctly".to_owned()
9064-
},
9065-
log_level: Level::Trace,
9045+
PersistenceNotifierGuard::optionally_notify(
9046+
self,
9047+
|| -> NotifyOption {
9048+
let per_peer_state = self.per_peer_state.read().unwrap();
9049+
let peer_state_mutex_opt = per_peer_state.get(counterparty_node_id);
9050+
if peer_state_mutex_opt.is_none() { return NotifyOption::SkipPersistNoEvents; }
9051+
let mut peer_state = peer_state_mutex_opt.unwrap().lock().unwrap();
9052+
if let Some(ChannelPhase::Funded(chan)) = peer_state.channel_by_id.get(&msg.channel_id) {
9053+
if let Some(msg) = chan.get_outbound_shutdown() {
9054+
peer_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
9055+
node_id: *counterparty_node_id,
9056+
msg,
9057+
});
9058+
}
9059+
peer_state.pending_msg_events.push(events::MessageSendEvent::HandleError {
9060+
node_id: *counterparty_node_id,
9061+
action: msgs::ErrorAction::SendWarningMessage {
9062+
msg: msgs::WarningMessage {
9063+
channel_id: msg.channel_id,
9064+
data: "You appear to be exhibiting LND bug 6039, we'll keep sending you shutdown messages until you handle them correctly".to_owned()
9065+
},
9066+
log_level: Level::Trace,
9067+
}
9068+
});
9069+
// This can happen in a fairly tight loop, so we absolutely cannot trigger
9070+
// a `ChannelManager` write here.
9071+
return NotifyOption::SkipPersistHandleEvents;
90669072
}
9067-
});
9068-
}
9073+
NotifyOption::SkipPersistNoEvents
9074+
}
9075+
);
90699076
}
90709077
return;
90719078
}
90729079
_ => {}
90739080
}
90749081

9082+
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
9083+
90759084
if msg.channel_id.is_zero() {
90769085
let channel_ids: Vec<ChannelId> = {
90779086
let per_peer_state = self.per_peer_state.read().unwrap();

0 commit comments

Comments
 (0)