Don't hold the counter lock while verifying gossip/waiting on DB
authorMatt Corallo <git@bluematt.me>
Mon, 22 Aug 2022 04:14:24 +0000 (04:14 +0000)
committerMatt Corallo <git@bluematt.me>
Tue, 23 Aug 2022 00:23:13 +0000 (00:23 +0000)
This resolves a deadlock if we block on the DB where we have one
thread blocked waiting on DB in a blocking thread, and the tokio
reactor blocked waiting on the counter lock which the blocking
thread holds.

src/downloader.rs

index 6bfaa14903b8e5f73e0154648f4bafa9f55cb3c4..997e9977061019558547dc2507fd075e98c74e95 100644 (file)
@@ -57,16 +57,19 @@ impl RoutingMessageHandler for GossipRouter {
        }
 
        fn handle_channel_announcement(&self, msg: &ChannelAnnouncement) -> Result<bool, LightningError> {
-               let mut counter = self.counter.write().unwrap();
-
-               let output_value = self.native_router.handle_channel_announcement(msg).map_err(|error| {
-                       if error.err.contains("didn't match on-chain script") {
-                               counter.channel_announcements_with_mismatched_scripts += 1;
-                       }
-                       error
-               })?;
+               let native_result = self.native_router.handle_channel_announcement(msg);
+               let output_value;
+               {
+                       let mut counter = self.counter.write().unwrap();
+                       output_value = native_result.map_err(|error| {
+                               if error.err.contains("didn't match on-chain script") {
+                                       counter.channel_announcements_with_mismatched_scripts += 1;
+                               }
+                               error
+                       })?;
+                       counter.channel_announcements += 1;
+               }
 
-               counter.channel_announcements += 1;
                let gossip_message = GossipMessage::ChannelAnnouncement(msg.clone());
                if let Err(err) = self.sender.try_send(gossip_message) {
                        let gossip_message = match err { TrySendError::Full(msg)|TrySendError::Closed(msg) => msg };
@@ -81,8 +84,7 @@ impl RoutingMessageHandler for GossipRouter {
        fn handle_channel_update(&self, msg: &ChannelUpdate) -> Result<bool, LightningError> {
                let output_value = self.native_router.handle_channel_update(msg)?;
 
-               let mut counter = self.counter.write().unwrap();
-               counter.channel_updates += 1;
+               self.counter.write().unwrap().channel_updates += 1;
                let gossip_message = GossipMessage::ChannelUpdate(msg.clone());
 
                if let Err(err) = self.sender.try_send(gossip_message) {