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

Rate limiter for bootstrap server #4818

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
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
25 changes: 20 additions & 5 deletions nano/node/bootstrap/bootstrap_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ nano::bootstrap_server::bootstrap_server (bootstrap_server_config const & config
store{ store_a },
ledger{ ledger_a },
network_constants{ network_constants_a },
stats{ stats_a }
stats{ stats_a },
limiter{ config.limiter, /* allow bursts */ 3.0 } // TODO: Limiter bucket capacity should be at least equal to the batch size, currently it's not configurable
{
queue.max_size_query = [this] (auto const & origin) {
return config.max_queue;
Expand Down Expand Up @@ -181,6 +182,22 @@ void nano::bootstrap_server::run ()
nano::unique_lock<nano::mutex> lock{ mutex };
while (!stopped)
{
condition.wait (lock, [this] () {
return stopped || !queue.empty ();
});

// Rate limit the processing
while (!stopped && !limiter.should_pass (config.batch_size))
{
stats.inc (nano::stat::type::bootstrap_server, nano::stat::detail::cooldown);
condition.wait_for (lock, 100ms);
}

if (stopped)
{
return;
}

if (!queue.empty ())
{
stats.inc (nano::stat::type::bootstrap_server, nano::stat::detail::loop);
Expand All @@ -190,10 +207,6 @@ void nano::bootstrap_server::run ()

lock.lock ();
}
else
{
condition.wait (lock, [this] () { return stopped || !queue.empty (); });
}
}
}

Expand Down Expand Up @@ -429,6 +442,7 @@ nano::error nano::bootstrap_server_config::serialize (nano::tomlconfig & toml) c
toml.put ("max_queue", max_queue, "Maximum number of queued requests per peer. \ntype:uint64");
toml.put ("threads", threads, "Number of threads to process requests. \ntype:uint64");
toml.put ("batch_size", batch_size, "Maximum number of requests to process in a single batch. \ntype:uint64");
toml.put ("limiter", limiter, "Rate limit for processing requests. Use 0 for unlimited. \ntype:uint64");

return toml.get_error ();
}
Expand All @@ -438,6 +452,7 @@ nano::error nano::bootstrap_server_config::deserialize (nano::tomlconfig & toml)
toml.get ("max_queue", max_queue);
toml.get ("threads", threads);
toml.get ("batch_size", batch_size);
toml.get ("limiter", limiter);

return toml.get_error ();
}
3 changes: 3 additions & 0 deletions nano/node/bootstrap/bootstrap_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <nano/lib/locks.hpp>
#include <nano/lib/observer_set.hpp>
#include <nano/lib/rate_limiting.hpp>
#include <nano/node/fair_queue.hpp>
#include <nano/node/fwd.hpp>
#include <nano/node/messages.hpp>
Expand All @@ -24,6 +25,7 @@ class bootstrap_server_config final
size_t max_queue{ 16 };
size_t threads{ 1 };
size_t batch_size{ 64 };
size_t limiter{ 500 };
};

/**
Expand Down Expand Up @@ -91,6 +93,7 @@ class bootstrap_server final

private:
nano::fair_queue<request_t, nano::no_value> queue;
nano::rate_limiter limiter;

std::atomic<bool> stopped{ false };
nano::condition_variable condition;
Expand Down
Loading