Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend election lifetime when receiving new votes #4527

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions nano/node/election.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ bool nano::election::transition_time (nano::confirmation_solicitor & solicitor_a
break;
}

if (!confirmed_locked () && time_to_live () < std::chrono::steady_clock::now () - election_start)
if (!confirmed_locked () && has_expired ())
{
// It is possible the election confirmed while acquiring the mutex
// state_change returning true would indicate it
Expand All @@ -292,16 +292,24 @@ bool nano::election::transition_time (nano::confirmation_solicitor & solicitor_a
return result;
}

std::chrono::milliseconds nano::election::time_to_live () const
bool nano::election::has_expired () const
{
const auto now = std::chrono::steady_clock::now ();

if (now > election_start + max_total_duration)
{
return true;
}

switch (behavior ())
{
case election_behavior::manual:
case election_behavior::priority:
return std::chrono::milliseconds (5 * 60 * 1000);
return now > last_vote_received + max_idle_duration_default;
case election_behavior::hinted:
return now > last_vote_received + max_idle_duration_hinted;
case election_behavior::optimistic:
return std::chrono::milliseconds (30 * 1000);
return now > last_vote_received + max_idle_duration_optimistic;
}
debug_assert (false);
return {};
Expand Down Expand Up @@ -491,6 +499,8 @@ nano::vote_code nano::election::vote (nano::account const & rep, uint64_t timest
nano::log::arg{ "vote_source", vote_source_a },
nano::log::arg{ "weight", weight });

last_vote_received = std::chrono::steady_clock::now ();

if (!confirmed_locked ())
{
confirm_if_quorum (lock);
Expand Down
12 changes: 10 additions & 2 deletions nano/node/election.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ class election final : public std::enable_shared_from_this<election>
std::function<void (std::shared_ptr<nano::block> const &)> confirmation_action;
std::function<void (nano::account const &)> live_vote_action;

private:
// Election time to live
std::chrono::milliseconds max_total_duration = std::chrono::milliseconds (10 * 60 * 1000);
std::chrono::milliseconds max_idle_duration_default = std::chrono::milliseconds (30 * 1000);
std::chrono::milliseconds max_idle_duration_hinted = std::chrono::milliseconds (10 * 1000);
std::chrono::milliseconds max_idle_duration_optimistic = std::chrono::milliseconds (10 * 1000);

private: // State management
static unsigned constexpr passive_duration_factor = 5;
static unsigned constexpr active_request_count_min = 2;
Expand All @@ -76,7 +83,8 @@ class election final : public std::enable_shared_from_this<election>
nano::block_hash last_block_hash{ 0 };
std::chrono::steady_clock::time_point last_req{};
/** The last time vote for this election was generated */
std::chrono::steady_clock::time_point last_vote{};
std::chrono::steady_clock::time_point last_vote = {};
std::chrono::steady_clock::time_point last_vote_received = { std::chrono::steady_clock::now () };

bool valid_change (nano::election_state, nano::election_state) const;
bool state_change (nano::election_state, nano::election_state);
Expand Down Expand Up @@ -155,7 +163,7 @@ class election final : public std::enable_shared_from_this<election>
void remove_votes (nano::block_hash const &);
void remove_block (nano::block_hash const &);
bool replace_by_weight (nano::unique_lock<nano::mutex> & lock_a, nano::block_hash const &);
std::chrono::milliseconds time_to_live () const;
bool has_expired () const;
/**
* Calculates minimum time delay between subsequent votes when processing non-final votes
*/
Expand Down
Loading