Skip to content

Commit 42d7837

Browse files
committed
f avoid excess map lookups & lockorder assertions
1 parent b10127c commit 42d7837

File tree

1 file changed

+44
-54
lines changed

1 file changed

+44
-54
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 44 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -698,18 +698,6 @@ impl <Signer: ChannelSigner> PeerState<Signer> {
698698
self.outbound_v1_channel_by_id.contains_key(channel_id) ||
699699
self.inbound_v1_channel_by_id.contains_key(channel_id)
700700
}
701-
702-
/// Returns a bool indicating whether the given `channel_id` matches a channel we have with this
703-
/// peer that is in one of our pending (unfunded) channel maps.
704-
///
705-
/// NOTE: Although V1 established channels will always have a `temporary_channel_id` if they're
706-
/// in `(outbound/inbound)_v1_channel_by_id`, we use the more general `channel_id` as V2
707-
/// established channels will have a fixed `channel_id` already after the `accept_channel2`
708-
/// message is sent/received.
709-
fn has_pending_channel(&self, channel_id: &[u8; 32]) -> bool {
710-
self.outbound_v1_channel_by_id.contains_key(channel_id) ||
711-
self.inbound_v1_channel_by_id.contains_key(channel_id)
712-
}
713701
}
714702

715703
/// Stores a PaymentSecret and any other data we may need to validate an inbound payment is
@@ -2392,56 +2380,58 @@ where
23922380

23932381
let mut failed_htlcs: Vec<(HTLCSource, PaymentHash)>;
23942382
let result: Result<(), _> = loop {
2395-
let per_peer_state = self.per_peer_state.read().unwrap();
2383+
{
2384+
let per_peer_state = self.per_peer_state.read().unwrap();
23962385

2397-
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
2398-
.ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id) })?;
2386+
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
2387+
.ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id) })?;
23992388

2400-
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
2401-
let peer_state = &mut *peer_state_lock;
2389+
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
2390+
let peer_state = &mut *peer_state_lock;
24022391

2403-
if peer_state.has_pending_channel(&channel_id) {
2404-
// If the channel was still in an unfunded channel map, then we force-close the channel, ignoring
2405-
// any channel-not-found errors.
2406-
let _ = self.force_close_channel_with_peer(&channel_id, counterparty_node_id, None, false);
2407-
return Ok(());
2408-
}
2392+
match peer_state.channel_by_id.entry(channel_id.clone()) {
2393+
hash_map::Entry::Occupied(mut chan_entry) => {
2394+
let funding_txo_opt = chan_entry.get().context.get_funding_txo();
2395+
let their_features = &peer_state.latest_features;
2396+
let (shutdown_msg, mut monitor_update_opt, htlcs) = chan_entry.get_mut()
2397+
.get_shutdown(&self.signer_provider, their_features, target_feerate_sats_per_1000_weight, override_shutdown_script)?;
2398+
failed_htlcs = htlcs;
24092399

2410-
match peer_state.channel_by_id.entry(channel_id.clone()) {
2411-
hash_map::Entry::Occupied(mut chan_entry) => {
2412-
let funding_txo_opt = chan_entry.get().context.get_funding_txo();
2413-
let their_features = &peer_state.latest_features;
2414-
let (shutdown_msg, mut monitor_update_opt, htlcs) = chan_entry.get_mut()
2415-
.get_shutdown(&self.signer_provider, their_features, target_feerate_sats_per_1000_weight, override_shutdown_script)?;
2416-
failed_htlcs = htlcs;
2417-
2418-
// We can send the `shutdown` message before updating the `ChannelMonitor`
2419-
// here as we don't need the monitor update to complete until we send a
2420-
// `shutdown_signed`, which we'll delay if we're pending a monitor update.
2421-
peer_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
2422-
node_id: *counterparty_node_id,
2423-
msg: shutdown_msg,
2424-
});
2400+
// We can send the `shutdown` message before updating the `ChannelMonitor`
2401+
// here as we don't need the monitor update to complete until we send a
2402+
// `shutdown_signed`, which we'll delay if we're pending a monitor update.
2403+
peer_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
2404+
node_id: *counterparty_node_id,
2405+
msg: shutdown_msg,
2406+
});
24252407

2426-
// Update the monitor with the shutdown script if necessary.
2427-
if let Some(monitor_update) = monitor_update_opt.take() {
2428-
break handle_new_monitor_update!(self, funding_txo_opt.unwrap(), monitor_update,
2429-
peer_state_lock, peer_state, per_peer_state, chan_entry).map(|_| ());
2430-
}
2408+
// Update the monitor with the shutdown script if necessary.
2409+
if let Some(monitor_update) = monitor_update_opt.take() {
2410+
break handle_new_monitor_update!(self, funding_txo_opt.unwrap(), monitor_update,
2411+
peer_state_lock, peer_state, per_peer_state, chan_entry).map(|_| ());
2412+
}
24312413

2432-
if chan_entry.get().is_shutdown() {
2433-
let channel = remove_channel!(self, chan_entry);
2434-
if let Ok(channel_update) = self.get_channel_update_for_broadcast(&channel) {
2435-
peer_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
2436-
msg: channel_update
2437-
});
2414+
if chan_entry.get().is_shutdown() {
2415+
let channel = remove_channel!(self, chan_entry);
2416+
if let Ok(channel_update) = self.get_channel_update_for_broadcast(&channel) {
2417+
peer_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
2418+
msg: channel_update
2419+
});
2420+
}
2421+
self.issue_channel_close_events(&channel.context, ClosureReason::HolderForceClosed);
24382422
}
2439-
self.issue_channel_close_events(&channel.context, ClosureReason::HolderForceClosed);
2440-
}
2441-
break Ok(());
2442-
},
2443-
hash_map::Entry::Vacant(_) => return Err(APIError::ChannelUnavailable{err: format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!(*channel_id), counterparty_node_id) })
2423+
break Ok(());
2424+
},
2425+
hash_map::Entry::Vacant(_) => (),
2426+
}
24442427
}
2428+
// If we reach this point, it means that the channel_id either refers to an unfunded channel or
2429+
// it does not exists for this peer. Either way, we can attempt to force-close it.
2430+
//
2431+
// An appropriate error will be returned forn non-existence of the channel if that's the case.
2432+
return self.force_close_channel_with_peer(&channel_id, counterparty_node_id, None, false).map(|_| ())
2433+
// TODO(dunxen): This is still not ideal as we're doing some extra lookups.
2434+
// Fix this with https://github.com/lightningdevkit/rust-lightning/issues/2422
24452435
};
24462436

24472437
for htlc_source in failed_htlcs.drain(..) {

0 commit comments

Comments
 (0)