Skip to content

Commit

Permalink
Rate limit ascending bootstrap requests
Browse files Browse the repository at this point in the history
  • Loading branch information
pwojcikdev committed Oct 29, 2024
1 parent 5eab498 commit 11fb745
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 7 deletions.
2 changes: 2 additions & 0 deletions nano/node/bootstrap/bootstrap_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ nano::error nano::bootstrap_config::deserialize (nano::tomlconfig & toml)
toml.get ("enable_dependency_walker", enable_dependency_walker);

toml.get ("channel_limit", channel_limit);
toml.get ("rate_limit", rate_limit);
toml.get ("database_rate_limit", database_rate_limit);
toml.get ("database_warmup_ratio", database_warmup_ratio);
toml.get ("max_pull_count", max_pull_count);
Expand All @@ -62,6 +63,7 @@ nano::error nano::bootstrap_config::serialize (nano::tomlconfig & toml) const
toml.put ("enable_dependency_walker", enable_dependency_walker, "Enable or disable the 'dependency walker` strategy.\ntype:bool");

toml.put ("channel_limit", channel_limit, "Maximum number of un-responded requests per channel.\nNote: changing to unlimited (0) is not recommended.\ntype:uint64");
toml.put ("rate_limit", rate_limit, "Rate limit on requests.\nNote: changing to unlimited (0) is not recommended as this operation competes for resources with realtime traffic.\ntype:uint64");
toml.put ("database_rate_limit", database_rate_limit, "Rate limit on scanning accounts and pending entries from database.\nNote: changing to unlimited (0) is not recommended as this operation competes for resources on querying the database.\ntype:uint64");
toml.put ("database_warmup_ratio", database_warmup_ratio, "Ratio of the database rate limit to use for the initial warmup.\ntype:uint64");
toml.put ("max_pull_count", max_pull_count, "Maximum number of requested blocks for bootstrap request.\ntype:uint64");
Expand Down
3 changes: 2 additions & 1 deletion nano/node/bootstrap/bootstrap_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class bootstrap_config final

// Maximum number of un-responded requests per channel, should be lower or equal to bootstrap server max queue size
std::size_t channel_limit{ 16 };
std::size_t database_rate_limit{ 256 };
std::size_t rate_limit{ 500 };
std::size_t database_rate_limit{ 250 };
std::size_t database_warmup_ratio{ 10 };
std::size_t max_pull_count{ nano::bootstrap_server::max_blocks };
std::chrono::milliseconds request_timeout{ 1000 * 5 };
Expand Down
17 changes: 11 additions & 6 deletions nano/node/bootstrap/bootstrap_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ nano::bootstrap_service::bootstrap_service (nano::node_config const & node_confi
database_scan{ ledger },
throttle{ compute_throttle_size () },
scoring{ config, node_config_a.network_params.network },
limiter{ config.rate_limit, 1.0 },
database_limiter{ config.database_rate_limit, 1.0 }
{
block_processor.batch_processed.add ([this] (auto const & batch) {
Expand Down Expand Up @@ -257,7 +258,6 @@ void nano::bootstrap_service::wait (std::function<bool ()> const & predicate) co
void nano::bootstrap_service::wait_tags () const
{
wait ([this] () {
debug_assert (!mutex.try_lock ());
return tags.size () < config.max_requests;
});
}
Expand All @@ -271,9 +271,17 @@ void nano::bootstrap_service::wait_blockprocessor () const

std::shared_ptr<nano::transport::channel> nano::bootstrap_service::wait_channel ()
{
// Limit max number of in-flight requests
wait_tags ();

// Wait until more requests can be sent
wait ([this] () {
return limiter.should_pass (1);
});

// Wait until a channel is available
std::shared_ptr<nano::transport::channel> channel;
wait ([this, &channel] () {
debug_assert (!mutex.try_lock ());
channel = scoring.channel ();
return channel != nullptr; // Wait until a channel is available
});
Expand Down Expand Up @@ -461,7 +469,6 @@ bool nano::bootstrap_service::request_info (nano::block_hash hash, std::shared_p

void nano::bootstrap_service::run_one_priority ()
{
wait_tags ();
wait_blockprocessor ();
auto channel = wait_channel ();
if (!channel)
Expand Down Expand Up @@ -492,7 +499,6 @@ void nano::bootstrap_service::run_priorities ()

void nano::bootstrap_service::run_one_database (bool should_throttle)
{
wait_tags ();
wait_blockprocessor ();
auto channel = wait_channel ();
if (!channel)
Expand Down Expand Up @@ -523,8 +529,7 @@ void nano::bootstrap_service::run_database ()

void nano::bootstrap_service::run_one_blocking ()
{
wait_tags ();
wait_blockprocessor ();
// No need to wait for blockprocessor, as we are not processing blocks
auto channel = wait_channel ();
if (!channel)
{
Expand Down
2 changes: 2 additions & 0 deletions nano/node/bootstrap/bootstrap_service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ class bootstrap_service
// clang-format on
ordered_tags tags;

// Rate limiter for all types of requests
nano::rate_limiter limiter;
// Requests for accounts from database have much lower hitrate and could introduce strain on the network
// A separate (lower) limiter ensures that we always reserve resources for querying accounts from priority queue
nano::rate_limiter database_limiter;
Expand Down

0 comments on commit 11fb745

Please sign in to comment.