Test Router serialization round-trip in functional_tests. 2020-02-router-ser-fix
authorMatt Corallo <git@bluematt.me>
Mon, 24 Feb 2020 04:26:10 +0000 (23:26 -0500)
committerMatt Corallo <git@bluematt.me>
Wed, 4 Mar 2020 19:29:06 +0000 (14:29 -0500)
This tests Router serialization round-trip at the end of each
functional test in the same way we do ChannelMonitors and
ChannelManagers to catch any cases where we were able to get into
a state which would have prevented reading a Router back off disk.

We further walk all of the announcements which both the original
and deserialized Routers would send to peers requesting initial
sync to ensure they match.

lightning/src/ln/functional_test_utils.rs

index 25927a8ee4c8862f303b1e7e033e434f3d0365ed..655e3681de090572eccdd0c66e839d72f5d1de2a 100644 (file)
@@ -6,7 +6,7 @@ use chain::transaction::OutPoint;
 use chain::keysinterface::KeysInterface;
 use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash};
 use ln::channelmonitor::{ChannelMonitor, ManyChannelMonitor};
-use ln::router::{Route, Router};
+use ln::router::{Route, Router, RouterReadArgs};
 use ln::features::InitFeatures;
 use ln::msgs;
 use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler};
@@ -97,6 +97,36 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
                        assert!(self.node.get_and_clear_pending_events().is_empty());
                        assert!(self.chan_monitor.added_monitors.lock().unwrap().is_empty());
 
+                       // Check that if we serialize the Router, we can deserialize it again.
+                       {
+                               let mut w = test_utils::TestVecWriter(Vec::new());
+                               self.router.write(&mut w).unwrap();
+                               let deserialized_router = Router::read(&mut ::std::io::Cursor::new(&w.0), RouterReadArgs {
+                                       chain_monitor: Arc::clone(&self.chain_monitor) as Arc<chaininterface::ChainWatchInterface>,
+                                       logger: Arc::clone(&self.logger) as Arc<Logger>
+                               }).unwrap();
+                               let mut chan_progress = 0;
+                               loop {
+                                       let orig_announcements = self.router.get_next_channel_announcements(chan_progress, 255);
+                                       let deserialized_announcements = deserialized_router.get_next_channel_announcements(chan_progress, 255);
+                                       assert!(orig_announcements == deserialized_announcements);
+                                       chan_progress = match orig_announcements.last() {
+                                               Some(announcement) => announcement.0.contents.short_channel_id + 1,
+                                               None => break,
+                                       };
+                               }
+                               let mut node_progress = None;
+                               loop {
+                                       let orig_announcements = self.router.get_next_node_announcements(node_progress.as_ref(), 255);
+                                       let deserialized_announcements = deserialized_router.get_next_node_announcements(node_progress.as_ref(), 255);
+                                       assert!(orig_announcements == deserialized_announcements);
+                                       node_progress = match orig_announcements.last() {
+                                               Some(announcement) => Some(announcement.contents.node_id),
+                                               None => break,
+                                       };
+                               }
+                       }
+
                        // Check that if we serialize and then deserialize all our channel monitors we get the
                        // same set of outputs to watch for on chain as we have now. Note that if we write
                        // tests that fully close channels and remove the monitors at some point this may break.