Browse Source

consdiffmgr: Reload latest consensus entries on start.

Nick Mathewson 7 years ago
parent
commit
30dfb36148
1 changed files with 58 additions and 9 deletions
  1. 58 9
      src/or/consdiffmgr.c

+ 58 - 9
src/or/consdiffmgr.c

@@ -516,6 +516,20 @@ sort_and_find_most_recent(smartlist_t *lst)
   }
 }
 
+/** Return i such that compress_consensus_with[i] == method. Return
+ * -1 if no such i exists. */
+static int
+consensus_compression_method_pos(compress_method_t method)
+{
+  unsigned i;
+  for (i = 0; i < n_consensus_compression_methods(); ++i) {
+    if (compress_consensus_with[i] == method) {
+      return i;
+    }
+  }
+  return -1;
+}
+
 /**
  * If we know a consensus with the flavor <b>flavor</b> compressed with
  * <b>method</b>, set *<b>entry_out</b> to that value.  Return values are as
@@ -526,17 +540,9 @@ consdiffmgr_find_consensus(struct consensus_cache_entry_t **entry_out,
                            consensus_flavor_t flavor,
                            compress_method_t method)
 {
-  int pos=-1;
-  unsigned i;
   tor_assert(flavor < N_CONSENSUS_FLAVORS);
 
-  // Find the index of method withing compress_consensus_with
-  for (i = 0; i < n_consensus_compression_methods(); ++i) {
-    if (compress_consensus_with[i] == method) {
-      pos = i;
-      break;
-    }
-  }
+  int pos = consensus_compression_method_pos(method);
   if (pos < 0) {
      // We don't compress consensuses with this method.
     return CONSDIFF_NOT_FOUND;
@@ -932,6 +938,48 @@ consdiffmgr_rescan_flavor_(consensus_flavor_t flavor)
   strmap_free(have_diff_from, NULL);
 }
 
+/**
+ * Scan the cache for the latest consensuses and add their handles to
+ * latest_consensus
+ */
+static void
+consdiffmgr_consensus_load(void)
+{
+  smartlist_t *matches = smartlist_new();
+  for (int flav = 0; flav < N_CONSENSUS_FLAVORS; ++flav) {
+    const char *flavname = networkstatus_get_flavor_name(flav);
+    smartlist_clear(matches);
+    consensus_cache_find_all(matches, cdm_cache_get(),
+                             LABEL_FLAVOR, flavname);
+    consensus_cache_filter_list(matches, LABEL_DOCTYPE, DOCTYPE_CONSENSUS);
+    consensus_cache_entry_t *most_recent = sort_and_find_most_recent(matches);
+    if (! most_recent)
+      continue; // no consensuses.
+    const char *most_recent_sha3 =
+      consensus_cache_entry_get_value(most_recent,
+                                      LABEL_SHA3_DIGEST_UNCOMPRESSED);
+    if (BUG(most_recent_sha3 == NULL))
+      continue; // LCOV_EXCL_LINE
+    consensus_cache_filter_list(matches, LABEL_SHA3_DIGEST_UNCOMPRESSED,
+                                most_recent_sha3);
+
+    // Everything that remains matches the most recent consensus of this
+    // flavor.
+    SMARTLIST_FOREACH_BEGIN(matches, consensus_cache_entry_t *, ent) {
+      const char *lv_compression =
+        consensus_cache_entry_get_value(ent, LABEL_COMPRESSION_TYPE);
+      compress_method_t method =
+        compression_method_get_by_name(lv_compression);
+      int pos = consensus_compression_method_pos(method);
+      if (pos < 0)
+        continue;
+      consensus_cache_entry_handle_free(latest_consensus[flav][pos]);
+      latest_consensus[flav][pos] = consensus_cache_entry_handle_new(ent);
+    } SMARTLIST_FOREACH_END(ent);
+  }
+  smartlist_free(matches);
+}
+
 /**
  * Scan the cache for diffs, and add them to the hashtable.
  */
@@ -989,6 +1037,7 @@ consdiffmgr_rescan(void)
 
   if (cdm_cache_loaded == 0) {
     consdiffmgr_diffs_load();
+    consdiffmgr_consensus_load();
     cdm_cache_loaded = 1;
   }