Use the new solver to compute time

Now that all the infrastructure exists, hook it up.  Track which nodes
are connected, if there are any orphaned nodes, and everything else the
old code used to do.

This doesn't yet handle single directions going and coming.

Change-Id: I658347797384f7608870d231a3ebbb2c05dad1dc
diff --git a/aos/events/logging/logger.cc b/aos/events/logging/logger.cc
index d4f4abd..2e0f5db 100644
--- a/aos/events/logging/logger.cc
+++ b/aos/events/logging/logger.cc
@@ -1101,7 +1101,8 @@
   remapped_configuration_ = event_loop_factory_->configuration();
   filters_ =
       std::make_unique<message_bridge::MultiNodeNoncausalOffsetEstimator>(
-          event_loop_factory_);
+          event_loop_factory_, logged_configuration(),
+          FLAGS_skip_order_validation);
 
   for (const Node *node : configuration::GetNodes(configuration())) {
     const size_t node_index =
@@ -1130,6 +1131,7 @@
 
     state->SetChannelCount(logged_configuration()->channels()->size());
   }
+  event_loop_factory_->SetTimeConverter(filters_.get());
 
   for (const Node *node : configuration::GetNodes(configuration())) {
     const size_t node_index =
@@ -1161,15 +1163,12 @@
            "you sure that the replay config matches the original config?";
   }
 
-  filters_->Initialize(logged_configuration());
+  filters_->CheckGraph();
 
   for (std::unique_ptr<State> &state : states_) {
     state->SeedSortedMessages();
   }
 
-  // And solve.
-  UpdateOffsets();
-
   // We want to start the log file at the last start time of the log files
   // from all the nodes.  Compute how long each node's simulation needs to run
   // to move time to this point.
@@ -1191,6 +1190,9 @@
         start_time, state->ToDistributedClock(state->monotonic_start_time()));
   }
 
+  // TODO(austin): If a node doesn't have a start time, we might not queue
+  // enough.  If this happens, we'll explode with a frozen error eventually.
+
   CHECK_GE(start_time, distributed_clock::epoch())
       << ": Hmm, we have a node starting before the start of time.  Offset "
          "everything.";
@@ -1255,14 +1257,6 @@
   }
 }
 
-void LogReader::UpdateOffsets() {
-  filters_->UpdateOffsets();
-
-  if (VLOG_IS_ON(1)) {
-    filters_->LogFit("Offset is");
-  }
-}
-
 message_bridge::NoncausalOffsetEstimator *LogReader::GetFilter(
     const Node *node_a, const Node *node_b) {
   if (filters_) {
@@ -1344,9 +1338,6 @@
       }
       return;
     }
-    if (VLOG_IS_ON(1)) {
-      filters_->LogFit("Offset was");
-    }
 
     bool update_time;
     TimestampedMessage timestamped_message = state->PopOldest(&update_time);
@@ -1388,8 +1379,13 @@
           // Confirm that the message was sent on the sending node before the
           // destination node (this node).  As a proxy, do this by making sure
           // that time on the source node is past when the message was sent.
+          //
+          // TODO(austin): <= means that the cause message (which we know) could
+          // happen after the effect even though we know they are at the same
+          // time.  I doubt anyone will notice for a bit, but we should really
+          // fix that.
           if (!FLAGS_skip_order_validation) {
-            CHECK_LT(
+            CHECK_LE(
                 timestamped_message.monotonic_remote_time,
                 state->monotonic_remote_now(timestamped_message.channel_index))
                 << state->event_loop()->node()->name()->string_view() << " to "
@@ -1401,7 +1397,7 @@
                        logged_configuration()->channels()->Get(
                            timestamped_message.channel_index))
                 << " " << state->DebugString();
-          } else if (timestamped_message.monotonic_remote_time >=
+          } else if (timestamped_message.monotonic_remote_time >
                      state->monotonic_remote_now(
                          timestamped_message.channel_index)) {
             LOG(WARNING)
@@ -1492,7 +1488,6 @@
                        return state->monotonic_now();
                      });
 
-      UpdateOffsets();
       VLOG(1) << MaybeNodeName(state->event_loop()->node()) << "Now is now "
               << state->monotonic_now();