Fix active difficulty calculation (#2338)
* Fix active difficulty calculation Median for active difficulty calculation is now obtained from a sorted container. - Increase high confirmation request count to 128 to reduce tally logging and escalations under load - Switch order of active difficulty update and confirmation requesting - Move mutex unlock/lock inside search_frontiers scope - Only add active difficulty if more than 10 samples in container - Obtain active difficulty only from top 10k elections, not the whole container which can contain temporary elections * Missing check for non-empty container and simplify mutex owning check
This commit is contained in:
parent
cf77b55695
commit
7fdad9de11
1 changed files with 12 additions and 10 deletions
|
|
@ -151,7 +151,7 @@ void nano::active_transactions::post_confirmation_height_set (nano::transaction
|
||||||
|
|
||||||
void nano::active_transactions::election_escalate (std::shared_ptr<nano::election> & election_l, nano::transaction const & transaction_l, size_t const & roots_size_l)
|
void nano::active_transactions::election_escalate (std::shared_ptr<nano::election> & election_l, nano::transaction const & transaction_l, size_t const & roots_size_l)
|
||||||
{
|
{
|
||||||
static unsigned constexpr high_confirmation_request_count{ 16 };
|
static unsigned constexpr high_confirmation_request_count{ 128 };
|
||||||
// Log votes for very long unconfirmed elections
|
// Log votes for very long unconfirmed elections
|
||||||
if (election_l->confirmation_request_count % (4 * high_confirmation_request_count) == 1)
|
if (election_l->confirmation_request_count % (4 * high_confirmation_request_count) == 1)
|
||||||
{
|
{
|
||||||
|
|
@ -300,7 +300,6 @@ void nano::active_transactions::request_confirm (nano::unique_lock<std::mutex> &
|
||||||
std::deque<std::shared_ptr<nano::block>> blocks_bundle_l;
|
std::deque<std::shared_ptr<nano::block>> blocks_bundle_l;
|
||||||
std::unordered_map<std::shared_ptr<nano::transport::channel>, std::deque<std::pair<nano::block_hash, nano::root>>> batched_confirm_req_bundle_l;
|
std::unordered_map<std::shared_ptr<nano::transport::channel>, std::deque<std::pair<nano::block_hash, nano::root>>> batched_confirm_req_bundle_l;
|
||||||
std::deque<std::pair<std::shared_ptr<nano::block>, std::shared_ptr<std::vector<std::shared_ptr<nano::transport::channel>>>>> single_confirm_req_bundle_l;
|
std::deque<std::pair<std::shared_ptr<nano::block>, std::shared_ptr<std::vector<std::shared_ptr<nano::transport::channel>>>>> single_confirm_req_bundle_l;
|
||||||
lock_a.unlock ();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Confirm frontiers when there aren't many confirmations already pending and node finished initial bootstrap
|
* Confirm frontiers when there aren't many confirmations already pending and node finished initial bootstrap
|
||||||
|
|
@ -314,10 +313,11 @@ void nano::active_transactions::request_confirm (nano::unique_lock<std::mutex> &
|
||||||
bool bootstrap_weight_reached (node.ledger.block_count_cache >= node.ledger.bootstrap_weight_max_blocks);
|
bool bootstrap_weight_reached (node.ledger.block_count_cache >= node.ledger.bootstrap_weight_max_blocks);
|
||||||
if (node.config.frontiers_confirmation != nano::frontiers_confirmation_mode::disabled && bootstrap_weight_reached && probably_unconfirmed_frontiers && pending_confirmation_height_size < confirmed_frontiers_max_pending_cut_off)
|
if (node.config.frontiers_confirmation != nano::frontiers_confirmation_mode::disabled && bootstrap_weight_reached && probably_unconfirmed_frontiers && pending_confirmation_height_size < confirmed_frontiers_max_pending_cut_off)
|
||||||
{
|
{
|
||||||
|
lock_a.unlock ();
|
||||||
search_frontiers (transaction_l);
|
search_frontiers (transaction_l);
|
||||||
|
lock_a.lock ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lock_a.lock ();
|
|
||||||
|
|
||||||
// Any new election started from process_live only gets requests after at least 1 second
|
// Any new election started from process_live only gets requests after at least 1 second
|
||||||
auto cutoff_l (std::chrono::steady_clock::now () - election_request_delay);
|
auto cutoff_l (std::chrono::steady_clock::now () - election_request_delay);
|
||||||
|
|
@ -458,8 +458,8 @@ void nano::active_transactions::request_loop ()
|
||||||
// Account for the time spent in request_confirm by defining the wakeup point beforehand
|
// Account for the time spent in request_confirm by defining the wakeup point beforehand
|
||||||
const auto wakeup_l (std::chrono::steady_clock::now () + std::chrono::milliseconds (node.network_params.network.request_interval_ms));
|
const auto wakeup_l (std::chrono::steady_clock::now () + std::chrono::milliseconds (node.network_params.network.request_interval_ms));
|
||||||
|
|
||||||
request_confirm (lock);
|
|
||||||
update_active_difficulty (lock);
|
update_active_difficulty (lock);
|
||||||
|
request_confirm (lock);
|
||||||
|
|
||||||
// Sleep until all broadcasts are done, plus the remaining loop time
|
// Sleep until all broadcasts are done, plus the remaining loop time
|
||||||
while (!stopped && ongoing_broadcasts)
|
while (!stopped && ongoing_broadcasts)
|
||||||
|
|
@ -858,21 +858,23 @@ void nano::active_transactions::adjust_difficulty (nano::block_hash const & hash
|
||||||
|
|
||||||
void nano::active_transactions::update_active_difficulty (nano::unique_lock<std::mutex> & lock_a)
|
void nano::active_transactions::update_active_difficulty (nano::unique_lock<std::mutex> & lock_a)
|
||||||
{
|
{
|
||||||
assert (lock_a.mutex () == &mutex && lock_a.owns_lock ());
|
assert (!mutex.try_lock ());
|
||||||
double multiplier (1.);
|
double multiplier (1.);
|
||||||
if (!roots.empty ())
|
if (!roots.empty ())
|
||||||
{
|
{
|
||||||
|
auto & sorted_roots = roots.get<1> ();
|
||||||
std::vector<uint64_t> active_root_difficulties;
|
std::vector<uint64_t> active_root_difficulties;
|
||||||
active_root_difficulties.reserve (roots.size ());
|
active_root_difficulties.reserve (std::min (roots.size (), node.config.active_elections_size));
|
||||||
|
size_t count (0);
|
||||||
auto cutoff (std::chrono::steady_clock::now () - election_request_delay - 1s);
|
auto cutoff (std::chrono::steady_clock::now () - election_request_delay - 1s);
|
||||||
for (auto & root : roots)
|
for (auto it (sorted_roots.begin ()), end (sorted_roots.end ()); it != end && count++ < node.config.active_elections_size; ++it)
|
||||||
{
|
{
|
||||||
if (!root.election->confirmed && !root.election->stopped && root.election->election_start < cutoff)
|
if (!it->election->confirmed && !it->election->stopped && it->election->election_start < cutoff)
|
||||||
{
|
{
|
||||||
active_root_difficulties.push_back (root.adjusted_difficulty);
|
active_root_difficulties.push_back (it->adjusted_difficulty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!active_root_difficulties.empty ())
|
if (active_root_difficulties.size () > 10 || (!active_root_difficulties.empty () && node.network_params.network.is_test_network ()))
|
||||||
{
|
{
|
||||||
multiplier = nano::difficulty::to_multiplier (active_root_difficulties[active_root_difficulties.size () / 2], node.network_params.network.publish_threshold);
|
multiplier = nano::difficulty::to_multiplier (active_root_difficulties[active_root_difficulties.size () / 2], node.network_params.network.publish_threshold);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue