Skip to content

Commit

Permalink
Evict fully synced accounts from priority set faster
Browse files Browse the repository at this point in the history
pwojcikdev committed Dec 10, 2024
1 parent 5a66e7e commit 6924d54
Showing 4 changed files with 41 additions and 19 deletions.
10 changes: 7 additions & 3 deletions nano/node/bootstrap/account_sets.cpp
Original file line number Diff line number Diff line change
@@ -220,7 +220,7 @@ void nano::bootstrap::account_sets::trim_overflow ()
}
}

nano::account nano::bootstrap::account_sets::next_priority (std::function<bool (nano::account const &)> const & filter)
auto nano::bootstrap::account_sets::next_priority (std::function<bool (nano::account const &)> const & filter) -> priority_result
{
if (priorities.empty ())
{
@@ -239,10 +239,14 @@ nano::account nano::bootstrap::account_sets::next_priority (std::function<bool (
{
continue;
}
return entry.account;
return {
.account = entry.account,
.priority = entry.priority,
.fails = entry.fails
};
}

return { 0 };
return {};
}

nano::block_hash nano::bootstrap::account_sets::next_blocking (std::function<bool (nano::block_hash const &)> const & filter)
9 changes: 8 additions & 1 deletion nano/node/bootstrap/account_sets.hpp
Original file line number Diff line number Diff line change
@@ -63,10 +63,17 @@ namespace bootstrap
*/
void sync_dependencies ();

struct priority_result
{
nano::account account;
double priority;
unsigned fails;
};

/**
* Sampling
*/
nano::account next_priority (std::function<bool (nano::account const &)> const & filter);
priority_result next_priority (std::function<bool (nano::account const &)> const & filter);
nano::block_hash next_blocking (std::function<bool (nano::block_hash const &)> const & filter);

bool blocked (nano::account const & account) const;
34 changes: 22 additions & 12 deletions nano/node/bootstrap/bootstrap_service.cpp
Original file line number Diff line number Diff line change
@@ -372,30 +372,28 @@ size_t nano::bootstrap_service::count_tags (nano::block_hash const & hash, query
return std::count_if (begin, end, [source] (auto const & tag) { return tag.source == source; });
}

std::pair<nano::account, double> nano::bootstrap_service::next_priority ()
nano::bootstrap::account_sets::priority_result nano::bootstrap_service::next_priority ()
{
debug_assert (!mutex.try_lock ());

auto account = accounts.next_priority ([this] (nano::account const & account) {
auto next = accounts.next_priority ([this] (nano::account const & account) {
return count_tags (account, query_source::priority) < 4;
});
if (account.is_zero ())
if (next.account.is_zero ())
{
return {};
}
stats.inc (nano::stat::type::bootstrap_next, nano::stat::detail::next_priority);
accounts.timestamp_set (account);
// TODO: Priority could be returned by the accounts.next_priority() call
return { account, accounts.priority (account) };
return next;
}

std::pair<nano::account, double> nano::bootstrap_service::wait_priority ()
nano::bootstrap::account_sets::priority_result nano::bootstrap_service::wait_priority ()
{
std::pair<nano::account, double> result{ 0, 0 };
nano::bootstrap::account_sets::priority_result result{};
wait ([this, &result] () {
debug_assert (!mutex.try_lock ());
result = next_priority ();
if (!result.first.is_zero ())
if (!result.account.is_zero ())
{
return true;
}
@@ -565,14 +563,26 @@ void nano::bootstrap_service::run_one_priority ()
{
return;
}
auto [account, priority] = wait_priority ();
auto [account, priority, fails] = wait_priority ();
if (account.is_zero ())
{
return;
}

// Decide how many blocks to request
size_t const min_pull_count = 2;
auto count = std::clamp (static_cast<size_t> (priority), min_pull_count, nano::bootstrap_server::max_blocks);
request (account, count, channel, query_source::priority);
auto pull_count = std::clamp (static_cast<size_t> (priority), min_pull_count, nano::bootstrap_server::max_blocks);

bool sent = request (account, pull_count, channel, query_source::priority);

// Only cooldown accounts that are likely to have more blocks
// This is to avoid requesting blocks from the same frontier multiple times, before the block processor had a chance to process them
// Not throttling accounts that are probably up-to-date allows us to evict them from the priority set faster
if (sent && fails == 0)
{
nano::lock_guard<nano::mutex> lock{ mutex };
accounts.timestamp_set (account);
}
}

void nano::bootstrap_service::run_priorities ()
7 changes: 4 additions & 3 deletions nano/node/bootstrap/bootstrap_service.hpp
Original file line number Diff line number Diff line change
@@ -117,9 +117,10 @@ class bootstrap_service
void wait_blockprocessor () const;
/* Waits for a channel that is not full */
std::shared_ptr<nano::transport::channel> wait_channel ();
/* Waits until a suitable account outside of cool down period is available */
std::pair<nano::account, double> next_priority ();
std::pair<nano::account, double> wait_priority ();
/* Waits until a suitable account outside of cooldown period is available */
using priority_result = nano::bootstrap::account_sets::priority_result;
priority_result next_priority ();
priority_result wait_priority ();
/* Gets the next account from the database */
nano::account next_database (bool should_throttle);
nano::account wait_database (bool should_throttle);

0 comments on commit 6924d54

Please sign in to comment.