Skip to content

Commit 5c6a39b

Browse files
authored
Merge pull request #2163 from TheBlueMatt/2023-04-less-lock
Avoid holding a `per_peer_state` lock while claiming from a monitor
2 parents ba13499 + b189df5 commit 5c6a39b

File tree

1 file changed

+36
-35
lines changed

1 file changed

+36
-35
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4116,45 +4116,46 @@ where
41164116
-> Result<(), (PublicKey, MsgHandleErrInternal)> {
41174117
//TODO: Delay the claimed_funds relaying just like we do outbound relay!
41184118

4119-
let per_peer_state = self.per_peer_state.read().unwrap();
4120-
let chan_id = prev_hop.outpoint.to_channel_id();
4121-
let counterparty_node_id_opt = match self.short_to_chan_info.read().unwrap().get(&prev_hop.short_channel_id) {
4122-
Some((cp_id, _dup_chan_id)) => Some(cp_id.clone()),
4123-
None => None
4124-
};
4119+
{
4120+
let per_peer_state = self.per_peer_state.read().unwrap();
4121+
let chan_id = prev_hop.outpoint.to_channel_id();
4122+
let counterparty_node_id_opt = match self.short_to_chan_info.read().unwrap().get(&prev_hop.short_channel_id) {
4123+
Some((cp_id, _dup_chan_id)) => Some(cp_id.clone()),
4124+
None => None
4125+
};
41254126

4126-
let peer_state_opt = counterparty_node_id_opt.as_ref().map(
4127-
|counterparty_node_id| per_peer_state.get(counterparty_node_id).map(
4128-
|peer_mutex| peer_mutex.lock().unwrap()
4129-
)
4130-
).unwrap_or(None);
4127+
let peer_state_opt = counterparty_node_id_opt.as_ref().map(
4128+
|counterparty_node_id| per_peer_state.get(counterparty_node_id)
4129+
.map(|peer_mutex| peer_mutex.lock().unwrap())
4130+
).unwrap_or(None);
41314131

4132-
if peer_state_opt.is_some() {
4133-
let mut peer_state_lock = peer_state_opt.unwrap();
4134-
let peer_state = &mut *peer_state_lock;
4135-
if let hash_map::Entry::Occupied(mut chan) = peer_state.channel_by_id.entry(chan_id) {
4136-
let counterparty_node_id = chan.get().get_counterparty_node_id();
4137-
let fulfill_res = chan.get_mut().get_update_fulfill_htlc_and_commit(prev_hop.htlc_id, payment_preimage, &self.logger);
4138-
4139-
if let UpdateFulfillCommitFetch::NewClaim { htlc_value_msat, monitor_update } = fulfill_res {
4140-
if let Some(action) = completion_action(Some(htlc_value_msat)) {
4141-
log_trace!(self.logger, "Tracking monitor update completion action for channel {}: {:?}",
4142-
log_bytes!(chan_id), action);
4143-
peer_state.monitor_update_blocked_actions.entry(chan_id).or_insert(Vec::new()).push(action);
4144-
}
4145-
let update_id = monitor_update.update_id;
4146-
let update_res = self.chain_monitor.update_channel(prev_hop.outpoint, monitor_update);
4147-
let res = handle_new_monitor_update!(self, update_res, update_id, peer_state_lock,
4148-
peer_state, per_peer_state, chan);
4149-
if let Err(e) = res {
4150-
// TODO: This is a *critical* error - we probably updated the outbound edge
4151-
// of the HTLC's monitor with a preimage. We should retry this monitor
4152-
// update over and over again until morale improves.
4153-
log_error!(self.logger, "Failed to update channel monitor with preimage {:?}", payment_preimage);
4154-
return Err((counterparty_node_id, e));
4132+
if peer_state_opt.is_some() {
4133+
let mut peer_state_lock = peer_state_opt.unwrap();
4134+
let peer_state = &mut *peer_state_lock;
4135+
if let hash_map::Entry::Occupied(mut chan) = peer_state.channel_by_id.entry(chan_id) {
4136+
let counterparty_node_id = chan.get().get_counterparty_node_id();
4137+
let fulfill_res = chan.get_mut().get_update_fulfill_htlc_and_commit(prev_hop.htlc_id, payment_preimage, &self.logger);
4138+
4139+
if let UpdateFulfillCommitFetch::NewClaim { htlc_value_msat, monitor_update } = fulfill_res {
4140+
if let Some(action) = completion_action(Some(htlc_value_msat)) {
4141+
log_trace!(self.logger, "Tracking monitor update completion action for channel {}: {:?}",
4142+
log_bytes!(chan_id), action);
4143+
peer_state.monitor_update_blocked_actions.entry(chan_id).or_insert(Vec::new()).push(action);
4144+
}
4145+
let update_id = monitor_update.update_id;
4146+
let update_res = self.chain_monitor.update_channel(prev_hop.outpoint, monitor_update);
4147+
let res = handle_new_monitor_update!(self, update_res, update_id, peer_state_lock,
4148+
peer_state, per_peer_state, chan);
4149+
if let Err(e) = res {
4150+
// TODO: This is a *critical* error - we probably updated the outbound edge
4151+
// of the HTLC's monitor with a preimage. We should retry this monitor
4152+
// update over and over again until morale improves.
4153+
log_error!(self.logger, "Failed to update channel monitor with preimage {:?}", payment_preimage);
4154+
return Err((counterparty_node_id, e));
4155+
}
41554156
}
4157+
return Ok(());
41564158
}
4157-
return Ok(());
41584159
}
41594160
}
41604161
let preimage_update = ChannelMonitorUpdate {

0 commit comments

Comments
 (0)