Test + fuzz that Channel{,Monitor} would_broadcast are identical
authorMatt Corallo <git@bluematt.me>
Tue, 11 Aug 2020 17:58:28 +0000 (13:58 -0400)
committerMatt Corallo <git@bluematt.me>
Tue, 11 Aug 2020 18:39:32 +0000 (14:39 -0400)
fuzz/src/chanmon_consistency.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/channelmonitor.rs
lightning/src/util/test_utils.rs

index 9749361fdc1f581109bf709507947fe2b8c0e94c..7d8ee6ae956be2b3b9680c9bd6d5a6d0c0cb5759 100644 (file)
@@ -135,6 +135,10 @@ impl channelmonitor::ManyChannelMonitor for TestChannelMonitor {
                self.update_ret.lock().unwrap().clone()
        }
 
+       fn get_monitor_would_broadcast(&self, funding_txo: &OutPoint, height: u32) -> bool {
+               self.simple_monitor.get_monitor_would_broadcast(funding_txo, height)
+       }
+
        fn get_and_clear_pending_htlcs_updated(&self) -> Vec<HTLCUpdate> {
                return self.simple_monitor.get_and_clear_pending_htlcs_updated();
        }
index 748053595ffeaa8174d6d9757a96dfcc3e43cdf8..11eabb6b50e9731668d4a6a6cfb0727dee707c7a 100644 (file)
@@ -3104,6 +3104,15 @@ impl<ChanSigner: ChannelKeys, M: Deref + Sync + Send, T: Deref + Sync + Send, K:
                                                }
                                        }
                                }
+                               #[cfg(any(test, feature = "fuzztarget"))]
+                               if channel.is_funding_initiated() {
+                                       // In testing/fuzzing, check that the channel's would_broadcast_at_height
+                                       // implementation is always identical to the ChannelMonitor equivalent.
+                                       for i in height..height + 144 {
+                                               assert_eq!(channel.monitor_would_broadcast_at_height(i, &self.logger),
+                                                       self.monitor.get_monitor_would_broadcast(&channel.get_funding_txo().unwrap(), i));
+                                       }
+                               }
                                if channel.is_funding_initiated() && channel.monitor_would_broadcast_at_height(height, &self.logger) {
                                        if let Some(short_id) = channel.get_short_channel_id() {
                                                short_to_id.remove(&short_id);
index f80cac38ad5003964619d060c1d7926fdef671ee..3b8bf46b614633d1c7728d45ff1b70982a76c7fe 100644 (file)
@@ -292,6 +292,11 @@ impl<ChanSigner: ChannelKeys, T: Deref + Sync + Send, F: Deref + Sync + Send, L:
                }
        }
 
+       #[cfg(any(test, feature = "fuzztarget"))]
+       fn get_monitor_would_broadcast(&self, funding_txo: &OutPoint, height: u32) -> bool {
+               self.monitors.lock().unwrap().get(funding_txo).unwrap().would_broadcast_at_height(height, &self.logger)
+       }
+
        fn get_and_clear_pending_htlcs_updated(&self) -> Vec<HTLCUpdate> {
                let mut pending_htlcs_updated = Vec::new();
                for chan in self.monitors.lock().unwrap().values_mut() {
@@ -877,6 +882,11 @@ pub trait ManyChannelMonitor: Send + Sync {
        /// ChannelMonitors via block_connected may result in FUNDS LOSS.
        fn update_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitorUpdate) -> Result<(), ChannelMonitorUpdateErr>;
 
+       #[cfg(any(test, feature = "fuzztarget"))]
+       /// Calls would_broadcast_at_height() on the given monitor. Used in testing to check that the
+       /// ChannelMonitor copy can never get out of sync with the Channel copy.
+       fn get_monitor_would_broadcast(&self, funding_txo: &OutPoint, height: u32) -> bool;
+
        /// Used by ChannelManager to get list of HTLC resolved onchain and which needed to be updated
        /// with success or failure.
        ///
index d684e9c07b5fce335d893e8b93ee5cdb698b7d7a..35ad1134818b7e684af4ce95e3a10475763efadc 100644 (file)
@@ -129,6 +129,10 @@ impl<'a> channelmonitor::ManyChannelMonitor for TestChannelMonitor<'a> {
                ret
        }
 
+       fn get_monitor_would_broadcast(&self, funding_txo: &OutPoint, height: u32) -> bool {
+               self.simple_monitor.get_monitor_would_broadcast(funding_txo, height)
+       }
+
        fn get_and_clear_pending_htlcs_updated(&self) -> Vec<HTLCUpdate> {
                return self.simple_monitor.get_and_clear_pending_htlcs_updated();
        }