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

Adjust election block rebroadcasting #4423

Merged
Merged
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
12 changes: 8 additions & 4 deletions nano/lib/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ class network_constants
max_peers_per_subnetwork (default_max_peers_per_ip * 4),
ipv6_subnetwork_prefix_for_limiting (64), // Equivalent to network prefix /64.
peer_dump_interval (std::chrono::seconds (5 * 60)),
vote_broadcast_interval (15 * 1000)
vote_broadcast_interval (15 * 1000),
block_broadcast_interval (150 * 1000)
{
if (is_live_network ())
{
Expand Down Expand Up @@ -243,7 +244,8 @@ class network_constants
max_peers_per_ip = 20;
max_peers_per_subnetwork = max_peers_per_ip * 4;
peer_dump_interval = std::chrono::seconds (1);
vote_broadcast_interval = 500;
vote_broadcast_interval = 500ms;
block_broadcast_interval = 500ms;
telemetry_request_cooldown = 500ms;
telemetry_cache_cutoff = 2000ms;
telemetry_request_interval = 500ms;
Expand Down Expand Up @@ -288,8 +290,10 @@ class network_constants
size_t max_peers_per_subnetwork;
size_t ipv6_subnetwork_prefix_for_limiting;
std::chrono::seconds peer_dump_interval;
/** Time to wait before vote rebroadcasts for active elections (milliseconds) */
uint64_t vote_broadcast_interval;

/** Time to wait before rebroadcasts for active elections */
std::chrono::milliseconds vote_broadcast_interval;
std::chrono::milliseconds block_broadcast_interval;

/** We do not reply to telemetry requests made within cooldown period */
std::chrono::milliseconds telemetry_request_cooldown{ 1000 * 15 };
Expand Down
2 changes: 2 additions & 0 deletions nano/lib/stats_enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ enum class detail : uint8_t
generate_vote,
generate_vote_normal,
generate_vote_final,
broadcast_block_initial,
broadcast_block_repeat,

// election types
normal,
Expand Down
27 changes: 25 additions & 2 deletions nano/node/election.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,35 @@ bool nano::election::failed () const
return state_m == nano::election::state_t::expired_unconfirmed;
}

bool nano::election::broadcast_block_predicate () const
{
debug_assert (!mutex.try_lock ());

// Broadcast the block if enough time has passed since the last broadcast (or it's the first broadcast)
if (last_block + node.config.network_params.network.block_broadcast_interval < std::chrono::steady_clock::now ())
{
return true;
}
// Or the current election winner has changed
if (status.winner->hash () != last_block_hash)
{
return true;
}
return false;
}

void nano::election::broadcast_block (nano::confirmation_solicitor & solicitor_a)
{
if (base_latency () * 15 < std::chrono::steady_clock::now () - last_block)
debug_assert (!mutex.try_lock ());

if (broadcast_block_predicate ())
{
if (!solicitor_a.broadcast (*this))
{
node.stats.inc (nano::stat::type::election, last_block_hash.is_zero () ? nano::stat::detail::broadcast_block_initial : nano::stat::detail::broadcast_block_repeat);

last_block = std::chrono::steady_clock::now ();
last_block_hash = status.winner->hash ();
}
}
}
Expand Down Expand Up @@ -237,6 +259,7 @@ bool nano::election::transition_time (nano::confirmation_solicitor & solicitor_a
break;
case nano::election::state_t::confirmed:
result = true; // Return true to indicate this election should be cleaned up
broadcast_block (solicitor_a); // Ensure election winner is broadcasted
state_change (nano::election::state_t::confirmed, nano::election::state_t::expired_confirmed);
break;
case nano::election::state_t::expired_unconfirmed:
Expand Down Expand Up @@ -535,7 +558,7 @@ void nano::election::broadcast_vote_locked (nano::unique_lock<nano::mutex> & loc
{
debug_assert (lock.owns_lock ());

if (std::chrono::steady_clock::now () < last_vote + std::chrono::milliseconds (node.config.network_params.network.vote_broadcast_interval))
if (std::chrono::steady_clock::now () < last_vote + node.config.network_params.network.vote_broadcast_interval)
{
return;
}
Expand Down
8 changes: 5 additions & 3 deletions nano/node/election.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ class election final : public std::enable_shared_from_this<nano::election>
std::chrono::steady_clock::duration state_start{ std::chrono::steady_clock::now ().time_since_epoch () };

// These are modified while not holding the mutex from transition_time only
std::chrono::steady_clock::time_point last_block = { std::chrono::steady_clock::now () };
std::chrono::steady_clock::time_point last_req = {};
std::chrono::steady_clock::time_point last_block{};
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{};

bool valid_change (nano::election::state_t, nano::election::state_t) const;
bool state_change (nano::election::state_t, nano::election::state_t);
Expand Down Expand Up @@ -169,6 +170,7 @@ class election final : public std::enable_shared_from_this<nano::election>
bool confirmed_locked (nano::unique_lock<nano::mutex> & lock) const;
// lock_a does not own the mutex on return
void confirm_once (nano::unique_lock<nano::mutex> & lock_a, nano::election_status_type = nano::election_status_type::active_confirmed_quorum);
bool broadcast_block_predicate () const;
void broadcast_block (nano::confirmation_solicitor &);
void send_confirm_req (nano::confirmation_solicitor &);
/**
Expand Down
Loading