Skip to content

Commit

Permalink
Adjust election block rebroadcasting
Browse files Browse the repository at this point in the history
  • Loading branch information
pwojcikdev committed Feb 5, 2024
1 parent 647c3c4 commit 9b89148
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 9 deletions.
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

0 comments on commit 9b89148

Please sign in to comment.