Don't hold `per_peer_state` lock during chain monitor update
authorViktor Tigerström <11711198+ViktorTigerstrom@users.noreply.github.com>
Mon, 7 Nov 2022 00:11:44 +0000 (01:11 +0100)
committerViktor Tigerström <11711198+ViktorTigerstrom@users.noreply.github.com>
Mon, 21 Nov 2022 20:49:21 +0000 (21:49 +0100)
For Windows build only, the
`TestPersister::chain_sync_monitor_persistences` lock has a lock order
before the `ChannelManager::per_peer_state` lock. This fix ensures that
the `per_peer_state` lock isn't held before the
`TestPersister::chain_sync_monitor_persistences` lock is acquired.

lightning/src/ln/channelmanager.rs

index 7a11bd8167ca9eccebd8e7fb3151f60315df0556..e475cf13854ad7eca231811847c3fbb7dab40511 100644 (file)
@@ -1906,14 +1906,16 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
                                        if *counterparty_node_id != chan_entry.get().get_counterparty_node_id(){
                                                return Err(APIError::APIMisuseError { err: "The passed counterparty_node_id doesn't match the channel's counterparty node_id".to_owned() });
                                        }
-                                       let per_peer_state = self.per_peer_state.read().unwrap();
-                                       let (shutdown_msg, monitor_update, htlcs) = match per_peer_state.get(&counterparty_node_id) {
-                                               Some(peer_state) => {
-                                                       let peer_state = peer_state.lock().unwrap();
-                                                       let their_features = &peer_state.latest_features;
-                                                       chan_entry.get_mut().get_shutdown(&self.keys_manager, their_features, target_feerate_sats_per_1000_weight)?
-                                               },
-                                               None => return Err(APIError::ChannelUnavailable { err: format!("Not connected to node: {}", counterparty_node_id) }),
+                                       let (shutdown_msg, monitor_update, htlcs) = {
+                                               let per_peer_state = self.per_peer_state.read().unwrap();
+                                               match per_peer_state.get(&counterparty_node_id) {
+                                                       Some(peer_state) => {
+                                                               let peer_state = peer_state.lock().unwrap();
+                                                               let their_features = &peer_state.latest_features;
+                                                               chan_entry.get_mut().get_shutdown(&self.keys_manager, their_features, target_feerate_sats_per_1000_weight)?
+                                                       },
+                                                       None => return Err(APIError::ChannelUnavailable { err: format!("Not connected to node: {}", counterparty_node_id) }),
+                                               }
                                        };
                                        failed_htlcs = htlcs;