mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
sr: Don't use a dynamic voting schedule
The exposed get_voting_schedule() allocates and return a new object everytime it is called leading to an awful lot of memory allocation when getting the start time of the current round which is done for each node in the consensus. Closes #23623 Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
60164f057c
commit
7ee0a2b9aa
@ -2790,7 +2790,7 @@ dirvote_get_start_of_next_interval(time_t now, int interval, int offset)
|
|||||||
/* Populate and return a new voting_schedule_t that can be used to schedule
|
/* Populate and return a new voting_schedule_t that can be used to schedule
|
||||||
* voting. The object is allocated on the heap and it's the responsibility of
|
* voting. The object is allocated on the heap and it's the responsibility of
|
||||||
* the caller to free it. Can't fail. */
|
* the caller to free it. Can't fail. */
|
||||||
voting_schedule_t *
|
static voting_schedule_t *
|
||||||
get_voting_schedule(const or_options_t *options, time_t now, int severity)
|
get_voting_schedule(const or_options_t *options, time_t now, int severity)
|
||||||
{
|
{
|
||||||
int interval, vote_delay, dist_delay;
|
int interval, vote_delay, dist_delay;
|
||||||
@ -2845,7 +2845,7 @@ get_voting_schedule(const or_options_t *options, time_t now, int severity)
|
|||||||
|
|
||||||
/** Frees a voting_schedule_t. This should be used instead of the generic
|
/** Frees a voting_schedule_t. This should be used instead of the generic
|
||||||
* tor_free. */
|
* tor_free. */
|
||||||
void
|
static void
|
||||||
voting_schedule_free(voting_schedule_t *voting_schedule_to_free)
|
voting_schedule_free(voting_schedule_t *voting_schedule_to_free)
|
||||||
{
|
{
|
||||||
if (!voting_schedule_to_free)
|
if (!voting_schedule_to_free)
|
||||||
@ -2857,18 +2857,9 @@ static voting_schedule_t voting_schedule;
|
|||||||
|
|
||||||
/* Using the time <b>now</b>, return the next voting valid-after time. */
|
/* Using the time <b>now</b>, return the next voting valid-after time. */
|
||||||
time_t
|
time_t
|
||||||
get_next_valid_after_time(time_t now)
|
dirvote_get_next_valid_after_time(void)
|
||||||
{
|
{
|
||||||
time_t next_valid_after_time;
|
return voting_schedule.interval_starts;
|
||||||
const or_options_t *options = get_options();
|
|
||||||
voting_schedule_t *new_voting_schedule =
|
|
||||||
get_voting_schedule(options, now, LOG_INFO);
|
|
||||||
tor_assert(new_voting_schedule);
|
|
||||||
|
|
||||||
next_valid_after_time = new_voting_schedule->interval_starts;
|
|
||||||
voting_schedule_free(new_voting_schedule);
|
|
||||||
|
|
||||||
return next_valid_after_time;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set voting_schedule to hold the timing for the next vote we should be
|
/** Set voting_schedule to hold the timing for the next vote we should be
|
||||||
|
@ -170,18 +170,13 @@ typedef struct {
|
|||||||
int have_published_consensus;
|
int have_published_consensus;
|
||||||
} voting_schedule_t;
|
} voting_schedule_t;
|
||||||
|
|
||||||
voting_schedule_t *get_voting_schedule(const or_options_t *options,
|
|
||||||
time_t now, int severity);
|
|
||||||
|
|
||||||
void voting_schedule_free(voting_schedule_t *voting_schedule_to_free);
|
|
||||||
|
|
||||||
void dirvote_get_preferred_voting_intervals(vote_timing_t *timing_out);
|
void dirvote_get_preferred_voting_intervals(vote_timing_t *timing_out);
|
||||||
time_t dirvote_get_start_of_next_interval(time_t now,
|
time_t dirvote_get_start_of_next_interval(time_t now,
|
||||||
int interval,
|
int interval,
|
||||||
int offset);
|
int offset);
|
||||||
void dirvote_recalculate_timing(const or_options_t *options, time_t now);
|
void dirvote_recalculate_timing(const or_options_t *options, time_t now);
|
||||||
void dirvote_act(const or_options_t *options, time_t now);
|
void dirvote_act(const or_options_t *options, time_t now);
|
||||||
time_t get_next_valid_after_time(time_t now);
|
time_t dirvote_get_next_valid_after_time(void);
|
||||||
|
|
||||||
/* invoked on timers and by outside triggers. */
|
/* invoked on timers and by outside triggers. */
|
||||||
struct pending_vote_t * dirvote_add_vote(const char *vote_body,
|
struct pending_vote_t * dirvote_add_vote(const char *vote_body,
|
||||||
|
@ -1333,13 +1333,7 @@ sr_act_post_consensus(const networkstatus_t *consensus)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare our state so that it's ready for the next voting period. */
|
/* Prepare our state so that it's ready for the next voting period. */
|
||||||
{
|
sr_state_update(dirvote_get_next_valid_after_time());
|
||||||
voting_schedule_t *voting_schedule =
|
|
||||||
get_voting_schedule(options,time(NULL), LOG_NOTICE);
|
|
||||||
time_t interval_starts = voting_schedule->interval_starts;
|
|
||||||
sr_state_update(interval_starts);
|
|
||||||
voting_schedule_free(voting_schedule);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize shared random subsystem. This MUST be called early in the boot
|
/* Initialize shared random subsystem. This MUST be called early in the boot
|
||||||
|
@ -139,25 +139,18 @@ get_voting_interval(void)
|
|||||||
* the SR protocol. For example, if it's 23:47:08, the current round thus
|
* 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. */
|
* started at 23:47:00 for a voting interval of 10 seconds. */
|
||||||
STATIC time_t
|
STATIC time_t
|
||||||
get_start_time_of_current_round(time_t now)
|
get_start_time_of_current_round(void)
|
||||||
{
|
{
|
||||||
const or_options_t *options = get_options();
|
const or_options_t *options = get_options();
|
||||||
int voting_interval = get_voting_interval();
|
int voting_interval = get_voting_interval();
|
||||||
voting_schedule_t *new_voting_schedule =
|
|
||||||
get_voting_schedule(options, now, LOG_DEBUG);
|
|
||||||
tor_assert(new_voting_schedule);
|
|
||||||
|
|
||||||
/* First, get the start time of the next round */
|
/* First, get the start time of the next round */
|
||||||
time_t next_start = new_voting_schedule->interval_starts;
|
time_t next_start = dirvote_get_next_valid_after_time();
|
||||||
/* Now roll back next_start by a voting interval to find the start time of
|
/* Now roll back next_start by a voting interval to find the start time of
|
||||||
the current round. */
|
the current round. */
|
||||||
time_t curr_start = dirvote_get_start_of_next_interval(
|
time_t curr_start = dirvote_get_start_of_next_interval(
|
||||||
next_start - voting_interval - 1,
|
next_start - voting_interval - 1,
|
||||||
voting_interval,
|
voting_interval,
|
||||||
options->TestingV3AuthVotingStartOffset);
|
options->TestingV3AuthVotingStartOffset);
|
||||||
|
|
||||||
voting_schedule_free(new_voting_schedule);
|
|
||||||
|
|
||||||
return curr_start;
|
return curr_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +163,7 @@ sr_state_get_start_time_of_current_protocol_run(time_t now)
|
|||||||
int total_rounds = SHARED_RANDOM_N_ROUNDS * SHARED_RANDOM_N_PHASES;
|
int total_rounds = SHARED_RANDOM_N_ROUNDS * SHARED_RANDOM_N_PHASES;
|
||||||
int voting_interval = get_voting_interval();
|
int voting_interval = get_voting_interval();
|
||||||
/* Find the time the current round started. */
|
/* Find the time the current round started. */
|
||||||
time_t beginning_of_current_round = get_start_time_of_current_round(now);
|
time_t beginning_of_current_round = get_start_time_of_current_round();
|
||||||
|
|
||||||
/* Get current SR protocol round */
|
/* Get current SR protocol round */
|
||||||
int current_round = (now / voting_interval) % total_rounds;
|
int current_round = (now / voting_interval) % total_rounds;
|
||||||
@ -208,7 +201,7 @@ get_state_valid_until_time(time_t now)
|
|||||||
|
|
||||||
voting_interval = get_voting_interval();
|
voting_interval = get_voting_interval();
|
||||||
/* Find the time the current round started. */
|
/* Find the time the current round started. */
|
||||||
beginning_of_current_round = get_start_time_of_current_round(now);
|
beginning_of_current_round = get_start_time_of_current_round();
|
||||||
|
|
||||||
/* Find how many rounds are left till the end of the protocol run */
|
/* Find how many rounds are left till the end of the protocol run */
|
||||||
current_round = (now / voting_interval) % total_rounds;
|
current_round = (now / voting_interval) % total_rounds;
|
||||||
@ -1370,7 +1363,7 @@ sr_state_init(int save_to_disk, int read_from_disk)
|
|||||||
/* We have a state in memory, let's make sure it's updated for the current
|
/* We have a state in memory, let's make sure it's updated for the current
|
||||||
* and next voting round. */
|
* and next voting round. */
|
||||||
{
|
{
|
||||||
time_t valid_after = get_next_valid_after_time(now);
|
time_t valid_after = dirvote_get_next_valid_after_time();
|
||||||
sr_state_update(valid_after);
|
sr_state_update(valid_after);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -130,7 +130,7 @@ unsigned int sr_state_get_protocol_run_duration(void);
|
|||||||
STATIC int disk_state_load_from_disk_impl(const char *fname);
|
STATIC int disk_state_load_from_disk_impl(const char *fname);
|
||||||
|
|
||||||
STATIC sr_phase_t get_sr_protocol_phase(time_t valid_after);
|
STATIC sr_phase_t get_sr_protocol_phase(time_t valid_after);
|
||||||
STATIC time_t get_start_time_of_current_round(time_t now);
|
STATIC time_t get_start_time_of_current_round(void);
|
||||||
|
|
||||||
STATIC time_t get_state_valid_until_time(time_t now);
|
STATIC time_t get_state_valid_until_time(time_t now);
|
||||||
STATIC const char *get_phase_str(sr_phase_t phase);
|
STATIC const char *get_phase_str(sr_phase_t phase);
|
||||||
|
@ -273,14 +273,9 @@ test_get_start_time_functions(void *arg)
|
|||||||
tt_assert(start_time_of_protocol_run);
|
tt_assert(start_time_of_protocol_run);
|
||||||
|
|
||||||
/* Check that the round start time of the beginning of the run, is itself */
|
/* Check that the round start time of the beginning of the run, is itself */
|
||||||
tt_int_op(get_start_time_of_current_round(start_time_of_protocol_run), OP_EQ,
|
tt_int_op(get_start_time_of_current_round(), OP_EQ,
|
||||||
start_time_of_protocol_run);
|
start_time_of_protocol_run);
|
||||||
|
|
||||||
/* Check that even if we increment the start time, we still get the start
|
|
||||||
time of the run as the beginning of the round. */
|
|
||||||
tt_int_op(get_start_time_of_current_round(start_time_of_protocol_run+1),
|
|
||||||
OP_EQ, start_time_of_protocol_run);
|
|
||||||
|
|
||||||
done: ;
|
done: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +306,7 @@ mock_networkstatus_get_live_consensus(time_t now)
|
|||||||
return mock_consensus;
|
return mock_consensus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Test the get_next_valid_after_time() function. */
|
/** Test the dirvote_get_next_valid_after_time() function. */
|
||||||
static void
|
static void
|
||||||
test_get_next_valid_after_time(void *arg)
|
test_get_next_valid_after_time(void *arg)
|
||||||
{
|
{
|
||||||
@ -324,7 +319,7 @@ test_get_next_valid_after_time(void *arg)
|
|||||||
|
|
||||||
{
|
{
|
||||||
/* Setup a fake consensus just to get the times out of it, since
|
/* Setup a fake consensus just to get the times out of it, since
|
||||||
get_next_valid_after_time() needs them. */
|
dirvote_get_next_valid_after_time() needs them. */
|
||||||
mock_consensus = tor_malloc_zero(sizeof(networkstatus_t));
|
mock_consensus = tor_malloc_zero(sizeof(networkstatus_t));
|
||||||
|
|
||||||
retval = parse_rfc1123_time("Mon, 13 Jan 2016 16:00:00 UTC",
|
retval = parse_rfc1123_time("Mon, 13 Jan 2016 16:00:00 UTC",
|
||||||
@ -344,7 +339,7 @@ test_get_next_valid_after_time(void *arg)
|
|||||||
retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
|
retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
|
||||||
¤t_time);
|
¤t_time);
|
||||||
tt_int_op(retval, OP_EQ, 0);
|
tt_int_op(retval, OP_EQ, 0);
|
||||||
valid_after_time = get_next_valid_after_time(current_time);
|
valid_after_time = dirvote_get_next_valid_after_time();
|
||||||
|
|
||||||
/* Compare it with the correct result */
|
/* Compare it with the correct result */
|
||||||
format_iso_time(tbuf, valid_after_time);
|
format_iso_time(tbuf, valid_after_time);
|
||||||
@ -356,7 +351,7 @@ test_get_next_valid_after_time(void *arg)
|
|||||||
retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:01 UTC",
|
retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:01 UTC",
|
||||||
¤t_time);
|
¤t_time);
|
||||||
tt_int_op(retval, OP_EQ, 0);
|
tt_int_op(retval, OP_EQ, 0);
|
||||||
valid_after_time = get_next_valid_after_time(current_time);
|
valid_after_time = dirvote_get_next_valid_after_time();
|
||||||
|
|
||||||
/* Compare it with the correct result */
|
/* Compare it with the correct result */
|
||||||
format_iso_time(tbuf, valid_after_time);
|
format_iso_time(tbuf, valid_after_time);
|
||||||
@ -367,7 +362,7 @@ test_get_next_valid_after_time(void *arg)
|
|||||||
retval = parse_rfc1123_time("Mon, 20 Apr 2015 23:30:01 UTC",
|
retval = parse_rfc1123_time("Mon, 20 Apr 2015 23:30:01 UTC",
|
||||||
¤t_time);
|
¤t_time);
|
||||||
tt_int_op(retval, OP_EQ, 0);
|
tt_int_op(retval, OP_EQ, 0);
|
||||||
valid_after_time = get_next_valid_after_time(current_time);
|
valid_after_time = dirvote_get_next_valid_after_time();
|
||||||
|
|
||||||
/* Compare it with the correct result */
|
/* Compare it with the correct result */
|
||||||
format_iso_time(tbuf, valid_after_time);
|
format_iso_time(tbuf, valid_after_time);
|
||||||
|
Loading…
Reference in New Issue
Block a user