From 9fb18756df3f76545f8f591881a95e1e09e735a0 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 24 Feb 2020 11:06:44 -0500 Subject: Stop using all dirauth-only options in shared_random_client.c This is not as clean a patch as I would like: see the comment on ASSUME_AUTHORITY_SCHEDULING. This issue here is that the unit tests sometimes assume that we are going to be looking at the dirauth options and behaving like a dirauth, but without setting the options to turn is into one. This isn't an issue for actually running Tor, as far as I can tell with chutney. --- src/feature/dirauth/shared_random_state.c | 2 +- src/feature/dirauth/voting_schedule.c | 19 +++++++++ src/feature/dirauth/voting_schedule.h | 4 ++ src/feature/hs_common/shared_random_client.c | 58 ++++++++++++++-------------- src/feature/hs_common/shared_random_client.h | 2 - src/test/test_shared_random.c | 2 +- 6 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/feature/dirauth/shared_random_state.c b/src/feature/dirauth/shared_random_state.c index 305c2cc94c..c15f8c9937 100644 --- a/src/feature/dirauth/shared_random_state.c +++ b/src/feature/dirauth/shared_random_state.c @@ -139,7 +139,7 @@ get_state_valid_until_time(time_t now) voting_interval = get_voting_interval(); /* Find the time the current round started. */ - beginning_of_current_round = get_start_time_of_current_round(); + beginning_of_current_round = dirauth_sched_get_cur_valid_after_time(); /* Find how many rounds are left till the end of the protocol run */ current_round = (now / voting_interval) % total_rounds; diff --git a/src/feature/dirauth/voting_schedule.c b/src/feature/dirauth/voting_schedule.c index 5e076a0ef5..ddb2c4bb07 100644 --- a/src/feature/dirauth/voting_schedule.c +++ b/src/feature/dirauth/voting_schedule.c @@ -51,6 +51,7 @@ create_voting_schedule(const or_options_t *options, time_t now, int severity) } tor_assert(interval > 0); + new_voting_schedule->interval = interval; if (vote_delay + dist_delay > interval/2) vote_delay = dist_delay = interval / 4; @@ -143,6 +144,24 @@ dirauth_sched_get_next_valid_after_time(void) return dirauth_get_voting_schedule()->interval_starts; } +/** + * Return our best idea of what the valid-after time for the _current_ + * consensus, whether we have one or not. + * + * Dirauth only. + **/ +time_t +dirauth_sched_get_cur_valid_after_time(void) +{ + const voting_schedule_t *sched = dirauth_get_voting_schedule(); + time_t next_start = sched->interval_starts; + int interval = sched->interval; + int offset = get_options()->TestingV3AuthVotingStartOffset; + return voting_sched_get_start_of_interval_after(next_start - interval - 1, + interval, + offset); +} + /** Return the voting interval that we are configured to use. * * Dirauth only. */ diff --git a/src/feature/dirauth/voting_schedule.h b/src/feature/dirauth/voting_schedule.h index b5dc811bfc..5472719b25 100644 --- a/src/feature/dirauth/voting_schedule.h +++ b/src/feature/dirauth/voting_schedule.h @@ -26,6 +26,9 @@ typedef struct { /** When do we publish the consensus? */ time_t interval_starts; + /** Our computed dirauth interval */ + int interval; + /** True iff we have generated and distributed our vote. */ int have_voted; /** True iff we've requested missing votes. */ @@ -57,6 +60,7 @@ void dirauth_sched_recalculate_timing(const or_options_t *options, time_t now); time_t dirauth_sched_get_next_valid_after_time(void); +time_t dirauth_sched_get_cur_valid_after_time(void); int dirauth_sched_get_configured_interval(void); #endif /* !defined(TOR_VOTING_SCHEDULE_H) */ diff --git a/src/feature/hs_common/shared_random_client.c b/src/feature/hs_common/shared_random_client.c index b30d68fb43..6b291c9344 100644 --- a/src/feature/hs_common/shared_random_client.c +++ b/src/feature/hs_common/shared_random_client.c @@ -11,6 +11,7 @@ #include "feature/hs_common/shared_random_client.h" #include "app/config/config.h" +#include "feature/dirauth/authmode.h" #include "feature/dirauth/voting_schedule.h" #include "feature/nodelist/networkstatus.h" #include "lib/encoding/binascii.h" @@ -31,6 +32,24 @@ srv_to_control_string(const sr_srv_t *srv) return srv_str; } +/** + * If we have no consensus and we are not an authority, assume that this is + * the voting interval. We should never actually use this: only authorities + * should be trying to figure out the schedule when they don't have a + * consensus. + **/ +#define DEFAULT_NETWORK_VOTING_INTERVAL (3600) + +/* This is an unpleasing workaround for tests. Our unit tests assume that we + * are scheduling all of our shared random stuff as if we were a directory + * authority, but they do not always set V3AuthoritativeDir. + */ +#ifdef TOR_UNIT_TESTS +#define ASSUME_AUTHORITY_SCHEDULING 1 +#else +#define ASSUME_AUTHORITY_SCHEDULING 0 +#endif + /** Return the voting interval of the tor vote subsystem. */ int get_voting_interval(void) @@ -40,39 +59,16 @@ get_voting_interval(void) if (consensus) { interval = (int)(consensus->fresh_until - consensus->valid_after); + } else if (authdir_mode(get_options()) || ASSUME_AUTHORITY_SCHEDULING) { + interval = dirauth_sched_get_configured_interval(); } else { - /* Same for both a testing and real network. We voluntarily ignore the - * InitialVotingInterval since it complexifies things and it doesn't - * affect the SR protocol. */ - interval = get_options()->V3AuthVotingInterval; + tor_assert_nonfatal_unreached_once(); + interval = DEFAULT_NETWORK_VOTING_INTERVAL; } tor_assert(interval > 0); return interval; } -/** Given the current consensus, return the start time of the current round of - * the SR protocol. For example, if it's 23:47:08, the current round thus - * started at 23:47:00 for a voting interval of 10 seconds. - * - * This function uses the consensus voting schedule to derive its results, - * instead of the actual consensus we are currently using, so it should be used - * for voting purposes. */ -time_t -get_start_time_of_current_round(void) -{ - const or_options_t *options = get_options(); - int voting_interval = get_voting_interval(); - /* First, get the start time of the next round */ - time_t next_start = dirauth_sched_get_next_valid_after_time(); - /* Now roll back next_start by a voting interval to find the start time of - the current round. */ - time_t curr_start = voting_sched_get_start_of_interval_after( - next_start - voting_interval - 1, - voting_interval, - options->TestingV3AuthVotingStartOffset); - return curr_start; -} - /* * Public API */ @@ -242,8 +238,14 @@ sr_state_get_start_time_of_current_protocol_run(void) networkstatus_t *ns = networkstatus_get_live_consensus(approx_time()); if (ns) { beginning_of_curr_round = ns->valid_after; + } else if (authdir_mode(get_options()) || ASSUME_AUTHORITY_SCHEDULING) { + beginning_of_curr_round = dirauth_sched_get_cur_valid_after_time(); } else { - beginning_of_curr_round = get_start_time_of_current_round(); + tor_assert_nonfatal_unreached_once(); + beginning_of_curr_round = voting_sched_get_start_of_interval_after( + approx_time() - voting_interval, + voting_interval, + 0); } /* Get current SR protocol round */ diff --git a/src/feature/hs_common/shared_random_client.h b/src/feature/hs_common/shared_random_client.h index 3031a2bb9a..37a086d590 100644 --- a/src/feature/hs_common/shared_random_client.h +++ b/src/feature/hs_common/shared_random_client.h @@ -38,11 +38,9 @@ time_t sr_state_get_start_time_of_current_protocol_run(void); time_t sr_state_get_start_time_of_previous_protocol_run(void); unsigned int sr_state_get_phase_duration(void); unsigned int sr_state_get_protocol_run_duration(void); -time_t get_start_time_of_current_round(void); #ifdef TOR_UNIT_TESTS #endif /* TOR_UNIT_TESTS */ #endif /* !defined(TOR_SHARED_RANDOM_CLIENT_H) */ - diff --git a/src/test/test_shared_random.c b/src/test/test_shared_random.c index 0e4328cb34..148eb5cf90 100644 --- a/src/test/test_shared_random.c +++ b/src/test/test_shared_random.c @@ -384,7 +384,7 @@ test_get_start_time_functions(void *arg) tt_assert(start_time_of_protocol_run); /* Check that the round start time of the beginning of the run, is itself */ - tt_int_op(get_start_time_of_current_round(), OP_EQ, + tt_int_op(dirauth_sched_get_cur_valid_after_time(), OP_EQ, start_time_of_protocol_run); done: -- cgit v1.2.3-54-g00ecf