[tor-commits] [tor/master] Allow consensus interval of 10 seconds when testing

nickm at torproject.org nickm at torproject.org
Tue Dec 23 19:25:51 UTC 2014


commit 1ee41b3eef4b5e561c7c73e79885fe858dac6d80
Author: teor <teor2345 at gmail.com>
Date:   Sat Dec 20 21:53:00 2014 +1100

    Allow consensus interval of 10 seconds when testing
    
    Decrease minimum consensus interval to 10 seconds
    when TestingTorNetwork is set. (Or 5 seconds for
    the first consensus.)
    
    Fix code that assumes larger interval values.
    
    This assists in quickly bootstrapping a testing
    Tor network.
    
    Fixes bugs 13718 & 13823.
---
 changes/bug13823-decrease-consensus-interval |    8 +++
 src/or/config.c                              |   78 +++++++++++++++++++++-----
 src/or/dirvote.c                             |    8 ++-
 src/or/dirvote.h                             |   32 ++++++++++-
 src/or/networkstatus.c                       |   12 ++++
 src/or/router.c                              |   13 ++++-
 src/or/routerlist.c                          |   22 +++++++-
 src/or/routerparse.c                         |    8 ++-
 8 files changed, 160 insertions(+), 21 deletions(-)

diff --git a/changes/bug13823-decrease-consensus-interval b/changes/bug13823-decrease-consensus-interval
new file mode 100644
index 0000000..1d99bd7
--- /dev/null
+++ b/changes/bug13823-decrease-consensus-interval
@@ -0,0 +1,8 @@
+  o Minor bugfixes:
+    - Decrease minimum consensus interval to 10 seconds
+      when TestingTorNetwork is set. (Or 5 seconds for
+      the first consensus.)
+      Fix code that assumes larger interval values.
+      This assists in quickly bootstrapping a testing
+      Tor network.
+      Fixes bugs 13718 & 13823.
diff --git a/src/or/config.c b/src/or/config.c
index 28f1df0..a779771 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -468,7 +468,7 @@ static const config_var_t testing_tor_network_defaults[] = {
   V(V3AuthVotingInterval,        INTERVAL, "5 minutes"),
   V(V3AuthVoteDelay,             INTERVAL, "20 seconds"),
   V(V3AuthDistDelay,             INTERVAL, "20 seconds"),
-  V(TestingV3AuthInitialVotingInterval, INTERVAL, "5 minutes"),
+  V(TestingV3AuthInitialVotingInterval, INTERVAL, "150 seconds"),
   V(TestingV3AuthInitialVoteDelay, INTERVAL, "20 seconds"),
   V(TestingV3AuthInitialDistDelay, INTERVAL, "20 seconds"),
   V(TestingV3AuthVotingStartOffset, INTERVAL, "0"),
@@ -3397,19 +3397,68 @@ options_validate(or_options_t *old_options, or_options_t *options,
 
   if (options->V3AuthVoteDelay + options->V3AuthDistDelay >=
       options->V3AuthVotingInterval/2) {
-    REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half "
-           "V3AuthVotingInterval");
+    /*
+    This doesn't work, but it seems like it should:
+     what code is preventing the interval being less than twice the lead-up?
+    if (options->TestingTorNetwork) {
+      if (options->V3AuthVoteDelay + options->V3AuthDistDelay >=
+          options->V3AuthVotingInterval) {
+        REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than "
+               "V3AuthVotingInterval");
+      } else {
+        COMPLAIN("V3AuthVoteDelay plus V3AuthDistDelay is more than half "
+                 "V3AuthVotingInterval. This may lead to "
+                 "consensus instability, particularly if clocks drift.");
+      }
+    } else {
+     */
+      REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half "
+             "V3AuthVotingInterval");
+    /*
+    }
+     */
+  }
+
+  if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS) {
+    if (options->TestingTorNetwork) {
+      if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS_TESTING) {
+        REJECT("V3AuthVoteDelay is way too low.");
+      } else {
+        COMPLAIN("V3AuthVoteDelay is very low. "
+                 "This may lead to failure to vote for a consensus.");
+      }
+    } else {
+      REJECT("V3AuthVoteDelay is way too low.");
+    }
+  }
+
+  if (options->V3AuthDistDelay < MIN_DIST_SECONDS) {
+    if (options->TestingTorNetwork) {
+      if (options->V3AuthDistDelay < MIN_DIST_SECONDS_TESTING) {
+        REJECT("V3AuthDistDelay is way too low.");
+      } else {
+        COMPLAIN("V3AuthDistDelay is very low. "
+                 "This may lead to missing votes in a consensus.");
+      }
+    } else {
+      REJECT("V3AuthDistDelay is way too low.");
+    }
   }
-  if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS)
-    REJECT("V3AuthVoteDelay is way too low.");
-  if (options->V3AuthDistDelay < MIN_DIST_SECONDS)
-    REJECT("V3AuthDistDelay is way too low.");
 
   if (options->V3AuthNIntervalsValid < 2)
     REJECT("V3AuthNIntervalsValid must be at least 2.");
 
   if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL) {
-    REJECT("V3AuthVotingInterval is insanely low.");
+    if (options->TestingTorNetwork) {
+      if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL_TESTING) {
+        REJECT("V3AuthVotingInterval is insanely low.");
+      } else {
+        COMPLAIN("V3AuthVotingInterval is very low. "
+                 "This may lead to failure to synchronise for a consensus.");
+      }
+    } else {
+      REJECT("V3AuthVotingInterval is insanely low.");
+    }
   } else if (options->V3AuthVotingInterval > 24*60*60) {
     REJECT("V3AuthVotingInterval is insanely high.");
   } else if (((24*60*60) % options->V3AuthVotingInterval) != 0) {
@@ -3484,26 +3533,27 @@ options_validate(or_options_t *old_options, or_options_t *options,
   CHECK_DEFAULT(TestingCertMaxDownloadTries);
 #undef CHECK_DEFAULT
 
-  if (options->TestingV3AuthInitialVotingInterval < MIN_VOTE_INTERVAL) {
+  if (options->TestingV3AuthInitialVotingInterval
+      < MIN_VOTE_INTERVAL_TESTING_INITIAL) {
     REJECT("TestingV3AuthInitialVotingInterval is insanely low.");
   } else if (((30*60) % options->TestingV3AuthInitialVotingInterval) != 0) {
     REJECT("TestingV3AuthInitialVotingInterval does not divide evenly into "
            "30 minutes.");
   }
 
-  if (options->TestingV3AuthInitialVoteDelay < MIN_VOTE_SECONDS) {
+  if (options->TestingV3AuthInitialVoteDelay < MIN_VOTE_SECONDS_TESTING) {
     REJECT("TestingV3AuthInitialVoteDelay is way too low.");
   }
 
-  if (options->TestingV3AuthInitialDistDelay < MIN_DIST_SECONDS) {
+  if (options->TestingV3AuthInitialDistDelay < MIN_DIST_SECONDS_TESTING) {
     REJECT("TestingV3AuthInitialDistDelay is way too low.");
   }
 
   if (options->TestingV3AuthInitialVoteDelay +
       options->TestingV3AuthInitialDistDelay >=
-      options->TestingV3AuthInitialVotingInterval/2) {
+      options->TestingV3AuthInitialVotingInterval) {
     REJECT("TestingV3AuthInitialVoteDelay plus TestingV3AuthInitialDistDelay "
-           "must be less than half TestingV3AuthInitialVotingInterval");
+           "must be less than TestingV3AuthInitialVotingInterval");
   }
 
   if (options->TestingV3AuthVotingStartOffset >
@@ -3511,6 +3561,8 @@ options_validate(or_options_t *old_options, or_options_t *options,
           options->V3AuthVotingInterval)) {
     REJECT("TestingV3AuthVotingStartOffset is higher than the voting "
            "interval.");
+  } else if (options->TestingV3AuthVotingStartOffset < 0) {
+    REJECT("TestingV3AuthVotingStartOffset must be non-negative.");
   }
 
   if (options->TestingAuthDirTimeToLearnReachability < 0) {
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 39505a4..c606822 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -1107,8 +1107,12 @@ networkstatus_compute_consensus(smartlist_t *votes,
     vote_seconds = median_int(votesec_list, n_votes);
     dist_seconds = median_int(distsec_list, n_votes);
 
-    tor_assert(valid_after+MIN_VOTE_INTERVAL <= fresh_until);
-    tor_assert(fresh_until+MIN_VOTE_INTERVAL <= valid_until);
+    tor_assert(valid_after +
+               (get_options()->TestingTorNetwork ?
+                MIN_VOTE_INTERVAL_TESTING : MIN_VOTE_INTERVAL) <= fresh_until);
+    tor_assert(fresh_until +
+               (get_options()->TestingTorNetwork ?
+                MIN_VOTE_INTERVAL_TESTING : MIN_VOTE_INTERVAL) <= valid_until);
     tor_assert(vote_seconds >= MIN_VOTE_SECONDS);
     tor_assert(dist_seconds >= MIN_DIST_SECONDS);
 
diff --git a/src/or/dirvote.h b/src/or/dirvote.h
index 5d44ba4..b570e9d 100644
--- a/src/or/dirvote.h
+++ b/src/or/dirvote.h
@@ -14,12 +14,42 @@
 
 #include "testsupport.h"
 
+/*
+ * Ideally, assuming synced clocks, we should only need 1 second for each of:
+ *  - Vote
+ *  - Distribute
+ *  - Consensus Publication
+ * As we can gather descriptors continuously.
+ * (Could we even go as far as publishing the previous consensus,
+ *  in the same second that we vote for the next one?)
+ * But we're not there yet: these are the lowest working values at this time.
+ */
+
 /** Lowest allowable value for VoteSeconds. */
 #define MIN_VOTE_SECONDS 2
+/** Lowest allowable value for VoteSeconds when TestingTorNetwork is 1 */
+#define MIN_VOTE_SECONDS_TESTING 2
+
 /** Lowest allowable value for DistSeconds. */
 #define MIN_DIST_SECONDS 2
-/** Smallest allowable voting interval. */
+/** Lowest allowable value for DistSeconds when TestingTorNetwork is 1 */
+#define MIN_DIST_SECONDS_TESTING 2
+
+/** Lowest allowable voting interval. */
 #define MIN_VOTE_INTERVAL 300
+/** Lowest allowable voting interval when TestingTorNetwork is 1:
+ * Voting Interval can be:
+ *   10, 12, 15, 18, 20, 24, 25, 30, 36, 40, 45, 50, 60, ...
+ * Testing Initial Voting Interval can be:
+ *    5,  6,  8,  9, or any of the possible values for Voting Interval,
+ * as they both need to evenly divide 30 minutes.
+ * If clock desynchronisation is an issue, use an interval of at least:
+ *   18 * drift in seconds, to allow for a clock slop factor */
+#define MIN_VOTE_INTERVAL_TESTING \
+                (((MIN_VOTE_SECONDS_TESTING)+(MIN_DIST_SECONDS_TESTING)+1)*2)
+
+#define MIN_VOTE_INTERVAL_TESTING_INITIAL \
+                ((MIN_VOTE_SECONDS_TESTING)+(MIN_DIST_SECONDS_TESTING)+1)
 
 /** The lowest consensus method that we currently support. */
 #define MIN_SUPPORTED_CONSENSUS_METHOD 13
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 21efdd1..9b24405 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -832,6 +832,10 @@ update_consensus_networkstatus_fetch_time_impl(time_t now, int flav)
          a crazy-fast voting interval, though, 2 minutes may be too
          much. */
       min_sec_before_caching = interval/16;
+      /* make sure we always delay by at least a second before caching */
+      if (min_sec_before_caching == 0) {
+        min_sec_before_caching = 1;
+      }
     }
 
     if (directory_fetches_dir_info_early(options)) {
@@ -863,8 +867,16 @@ update_consensus_networkstatus_fetch_time_impl(time_t now, int flav)
         dl_interval = (c->valid_until - start) - min_sec_before_caching;
       }
     }
+    /* catch low dl_interval in crazy-fast networks */
     if (dl_interval < 1)
       dl_interval = 1;
+    /* catch late start in crazy-fast networks */
+    if (start+dl_interval >= c->valid_until)
+      start = c->valid_until - dl_interval - 1;
+    log_debug(LD_DIR,
+              "fresh_until: %ld start: %ld "
+              "dl_interval: %ld valid_until: %ld ",
+              c->fresh_until, start, dl_interval, c->valid_until);
     /* We must not try to replace c while it's still fresh: */
     tor_assert(c->fresh_until < start);
     /* We must download the next one before c is invalid: */
diff --git a/src/or/router.c b/src/or/router.c
index 56bb909..bad5242 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -1223,6 +1223,11 @@ router_orport_found_reachable(void)
                  " Publishing server descriptor." : "");
     can_reach_or_port = 1;
     mark_my_descriptor_dirty("ORPort found reachable");
+    /* This is a significant enough change to upload immediately,
+     * at least in a test network */
+    if (get_options()->TestingTorNetwork == 1) {
+      reschedule_descriptor_update_check();
+    }
     control_event_server_status(LOG_NOTICE,
                                 "REACHABILITY_SUCCEEDED ORADDRESS=%s:%d",
                                 address, me->or_port);
@@ -1240,8 +1245,14 @@ router_dirport_found_reachable(void)
     log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable "
                "from the outside. Excellent.");
     can_reach_dir_port = 1;
-    if (decide_to_advertise_dirport(get_options(), me->dir_port))
+    if (decide_to_advertise_dirport(get_options(), me->dir_port)) {
       mark_my_descriptor_dirty("DirPort found reachable");
+      /* This is a significant enough change to upload immediately,
+       * at least in a test network */
+      if (get_options()->TestingTorNetwork == 1) {
+        reschedule_descriptor_update_check();
+      }
+    }
     control_event_server_status(LOG_NOTICE,
                                 "REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d",
                                 address, me->dir_port);
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 8379bc8..60d8e71 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -2210,11 +2210,29 @@ router_choose_random_node(smartlist_t *excludedsmartlist,
   router_add_running_nodes_to_smartlist(sl, allow_invalid,
                                         need_uptime, need_capacity,
                                         need_guard, need_desc);
+  log_debug(LD_CIRC,
+           "We found %d running nodes.",
+            smartlist_len(sl));
+
   smartlist_subtract(sl,excludednodes);
-  if (excludedsmartlist)
+  log_debug(LD_CIRC,
+            "We removed %d excludednodes, leaving %d nodes.",
+            smartlist_len(excludednodes),
+            smartlist_len(sl));
+
+  if (excludedsmartlist) {
     smartlist_subtract(sl,excludedsmartlist);
-  if (excludedset)
+    log_debug(LD_CIRC,
+              "We removed %d excludedsmartlist, leaving %d nodes.",
+              smartlist_len(excludedsmartlist),
+              smartlist_len(sl));
+  }
+  if (excludedset) {
     routerset_subtract_nodes(sl,excludedset);
+    log_debug(LD_CIRC,
+              "We removed excludedset, leaving %d nodes.",
+              smartlist_len(sl));
+  }
 
   // Always weight by bandwidth
   choice = node_sl_choose_by_bandwidth(sl, rule);
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index bc3b002..8176d47 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -2598,11 +2598,15 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
     (int) tor_parse_long(tok->args[1], 10, 0, INT_MAX, &ok, NULL);
   if (!ok)
     goto err;
-  if (ns->valid_after + MIN_VOTE_INTERVAL > ns->fresh_until) {
+  if (ns->valid_after +
+      (get_options()->TestingTorNetwork ?
+       MIN_VOTE_INTERVAL_TESTING : MIN_VOTE_INTERVAL) > ns->fresh_until) {
     log_warn(LD_DIR, "Vote/consensus freshness interval is too short");
     goto err;
   }
-  if (ns->valid_after + MIN_VOTE_INTERVAL*2 > ns->valid_until) {
+  if (ns->valid_after +
+      (get_options()->TestingTorNetwork ?
+       MIN_VOTE_INTERVAL_TESTING : MIN_VOTE_INTERVAL)*2 > ns->valid_until) {
     log_warn(LD_DIR, "Vote/consensus liveness interval is too short");
     goto err;
   }





More information about the tor-commits mailing list