Skip to content

Commit

Permalink
Bootstrap config tuning (#4698)
Browse files Browse the repository at this point in the history
* Reduce database rate limit

* Reduce max requests

* Config for max_pull_count

* Rename config to `block_processor_threshold`

* Rename config to `channel_limit`

* Serialization

* Adjust channel limit
  • Loading branch information
pwojcikdev authored Aug 11, 2024
1 parent 9d02d03 commit f029329
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 31 deletions.
25 changes: 14 additions & 11 deletions nano/core_test/toml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,14 @@ TEST (toml, daemon_config_deserialize_defaults)
ASSERT_EQ (conf.node.bootstrap_ascending.enable, defaults.node.bootstrap_ascending.enable);
ASSERT_EQ (conf.node.bootstrap_ascending.enable_database_scan, defaults.node.bootstrap_ascending.enable_database_scan);
ASSERT_EQ (conf.node.bootstrap_ascending.enable_dependency_walker, defaults.node.bootstrap_ascending.enable_dependency_walker);
ASSERT_EQ (conf.node.bootstrap_ascending.requests_limit, defaults.node.bootstrap_ascending.requests_limit);
ASSERT_EQ (conf.node.bootstrap_ascending.channel_limit, defaults.node.bootstrap_ascending.channel_limit);
ASSERT_EQ (conf.node.bootstrap_ascending.database_rate_limit, defaults.node.bootstrap_ascending.database_rate_limit);
ASSERT_EQ (conf.node.bootstrap_ascending.pull_count, defaults.node.bootstrap_ascending.pull_count);
ASSERT_EQ (conf.node.bootstrap_ascending.database_warmup_ratio, defaults.node.bootstrap_ascending.database_warmup_ratio);
ASSERT_EQ (conf.node.bootstrap_ascending.max_pull_count, defaults.node.bootstrap_ascending.max_pull_count);
ASSERT_EQ (conf.node.bootstrap_ascending.request_timeout, defaults.node.bootstrap_ascending.request_timeout);
ASSERT_EQ (conf.node.bootstrap_ascending.throttle_coefficient, defaults.node.bootstrap_ascending.throttle_coefficient);
ASSERT_EQ (conf.node.bootstrap_ascending.throttle_wait, defaults.node.bootstrap_ascending.throttle_wait);
ASSERT_EQ (conf.node.bootstrap_ascending.block_wait_count, defaults.node.bootstrap_ascending.block_wait_count);
ASSERT_EQ (conf.node.bootstrap_ascending.block_processor_threshold, defaults.node.bootstrap_ascending.block_processor_threshold);
ASSERT_EQ (conf.node.bootstrap_ascending.max_requests, defaults.node.bootstrap_ascending.max_requests);

ASSERT_EQ (conf.node.bootstrap_server.max_queue, defaults.node.bootstrap_server.max_queue);
Expand Down Expand Up @@ -593,13 +594,14 @@ TEST (toml, daemon_config_deserialize_no_defaults)
enable = false
enable_database_scan = false
enable_dependency_walker = false
requests_limit = 999
channel_limit = 999
database_rate_limit = 999
pull_count = 999
database_warmup_ratio = 999
max_pull_count = 999
request_timeout = 999
throttle_coefficient = 999
throttle_wait = 999
block_wait_count = 999
block_processor_threshold = 999
max_requests = 999
[node.bootstrap_server]
Expand Down Expand Up @@ -769,13 +771,14 @@ TEST (toml, daemon_config_deserialize_no_defaults)
ASSERT_NE (conf.node.bootstrap_ascending.enable, defaults.node.bootstrap_ascending.enable);
ASSERT_NE (conf.node.bootstrap_ascending.enable_database_scan, defaults.node.bootstrap_ascending.enable_database_scan);
ASSERT_NE (conf.node.bootstrap_ascending.enable_dependency_walker, defaults.node.bootstrap_ascending.enable_dependency_walker);
ASSERT_NE (conf.node.bootstrap_ascending.requests_limit, defaults.node.bootstrap_ascending.requests_limit);
ASSERT_NE (conf.node.bootstrap_ascending.channel_limit, defaults.node.bootstrap_ascending.channel_limit);
ASSERT_NE (conf.node.bootstrap_ascending.database_rate_limit, defaults.node.bootstrap_ascending.database_rate_limit);
ASSERT_NE (conf.node.bootstrap_ascending.pull_count, defaults.node.bootstrap_ascending.pull_count);
ASSERT_NE (conf.node.bootstrap_ascending.database_warmup_ratio, defaults.node.bootstrap_ascending.database_warmup_ratio);
ASSERT_NE (conf.node.bootstrap_ascending.max_pull_count, defaults.node.bootstrap_ascending.max_pull_count);
ASSERT_NE (conf.node.bootstrap_ascending.request_timeout, defaults.node.bootstrap_ascending.request_timeout);
ASSERT_NE (conf.node.bootstrap_ascending.throttle_coefficient, defaults.node.bootstrap_ascending.throttle_coefficient);
ASSERT_NE (conf.node.bootstrap_ascending.throttle_wait, defaults.node.bootstrap_ascending.throttle_wait);
ASSERT_NE (conf.node.bootstrap_ascending.block_wait_count, defaults.node.bootstrap_ascending.block_wait_count);
ASSERT_NE (conf.node.bootstrap_ascending.block_processor_threshold, defaults.node.bootstrap_ascending.block_processor_threshold);
ASSERT_NE (conf.node.bootstrap_ascending.max_requests, defaults.node.bootstrap_ascending.max_requests);

ASSERT_NE (conf.node.bootstrap_server.max_queue, defaults.node.bootstrap_server.max_queue);
Expand Down Expand Up @@ -1086,7 +1089,7 @@ TEST (toml, merge_config_files)
active_elections.size = 999
# backlog_scan_batch_size = 7777
[node.bootstrap_ascending]
block_wait_count = 33333
block_processor_threshold = 33333
old_entry = 34
)toml";

Expand All @@ -1109,6 +1112,6 @@ TEST (toml, merge_config_files)
ASSERT_NE (merged_config.node.active_elections.size, default_config.node.active_elections.size);
ASSERT_EQ (merged_config.node.active_elections.size, 999);
ASSERT_NE (merged_config.node.backlog_scan_batch_size, 7777);
ASSERT_EQ (merged_config.node.bootstrap_ascending.block_wait_count, 33333);
ASSERT_EQ (merged_config.node.bootstrap_ascending.block_processor_threshold, 33333);
ASSERT_TRUE (merged_config_string.find ("old_entry") == std::string::npos);
}
16 changes: 10 additions & 6 deletions nano/node/bootstrap/bootstrap_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/*
* account_sets_config
*/

nano::error nano::account_sets_config::deserialize (nano::tomlconfig & toml)
{
toml.get ("consideration_count", consideration_count);
Expand All @@ -27,19 +28,21 @@ nano::error nano::account_sets_config::serialize (nano::tomlconfig & toml) const
/*
* bootstrap_ascending_config
*/

nano::error nano::bootstrap_ascending_config::deserialize (nano::tomlconfig & toml)
{
toml.get ("enable", enable);
toml.get ("enable_database_scan", enable_database_scan);
toml.get ("enable_dependency_walker", enable_dependency_walker);

toml.get ("requests_limit", requests_limit);
toml.get ("channel_limit", channel_limit);
toml.get ("database_rate_limit", database_rate_limit);
toml.get ("pull_count", pull_count);
toml.get ("database_warmup_ratio", database_warmup_ratio);
toml.get ("max_pull_count", max_pull_count);
toml.get_duration ("request_timeout", request_timeout);
toml.get ("throttle_coefficient", throttle_coefficient);
toml.get_duration ("throttle_wait", throttle_wait);
toml.get ("block_wait_count", block_wait_count);
toml.get ("block_processor_threshold", block_processor_threshold);
toml.get ("max_requests", max_requests);

if (toml.has_key ("account_sets"))
Expand All @@ -57,13 +60,14 @@ nano::error nano::bootstrap_ascending_config::serialize (nano::tomlconfig & toml
toml.put ("enable_database_scan", enable_database_scan, "Enable or disable the 'database scan` strategy for the ascending bootstrap.\ntype:bool");
toml.put ("enable_dependency_walker", enable_dependency_walker, "Enable or disable the 'dependency walker` strategy for the ascending bootstrap.\ntype:bool");

toml.put ("requests_limit", requests_limit, "Request limit to ascending bootstrap after which requests will be dropped.\nNote: changing to unlimited (0) is not recommended.\ntype:uint64");
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 ("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 ("pull_count", pull_count, "Number of requested blocks for ascending bootstrap request.\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 ascending bootstrap request.\ntype:uint64");
toml.put ("request_timeout", request_timeout.count (), "Timeout in milliseconds for incoming ascending bootstrap messages to be processed.\ntype:milliseconds");
toml.put ("throttle_coefficient", throttle_coefficient, "Scales the number of samples to track for bootstrap throttling.\ntype:uint64");
toml.put ("throttle_wait", throttle_wait.count (), "Length of time to wait between requests when throttled.\ntype:milliseconds");
toml.put ("block_wait_count", block_wait_count, "Asending bootstrap will wait while block processor has more than this many blocks queued.\ntype:uint64");
toml.put ("block_processor_threshold", block_processor_threshold, "Asending bootstrap will wait while block processor has more than this many blocks queued.\ntype:uint64");
toml.put ("max_requests", max_requests, "Maximum total number of in flight requests.\ntype:uint64");

nano::tomlconfig account_sets_l;
Expand Down
13 changes: 7 additions & 6 deletions nano/node/bootstrap/bootstrap_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@ class bootstrap_ascending_config final
bool enable_database_scan{ true };
bool enable_dependency_walker{ true };

// Maximum number of un-responded requests per channel
std::size_t requests_limit{ 64 }; // TODO: => channel_requests_limit
std::size_t database_rate_limit{ 1024 }; // TODO: Adjust for live network (lower)
std::size_t pull_count{ nano::bootstrap_server::max_blocks }; // TODO: => max_pull_count & use in requests
// 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 database_warmup_ratio{ 10 };
std::size_t max_pull_count{ nano::bootstrap_server::max_blocks };
std::chrono::milliseconds request_timeout{ 1000 * 5 };
std::size_t throttle_coefficient{ 8 * 1024 };
std::chrono::milliseconds throttle_wait{ 100 };
std::size_t block_wait_count{ 1000 }; // TODO: Block processor threshold
std::size_t max_requests{ 1024 * 16 }; // TODO: Adjust for live network
std::size_t block_processor_threshold{ 1000 };
std::size_t max_requests{ 1024 };

nano::account_sets_config account_sets;
};
Expand Down
2 changes: 1 addition & 1 deletion nano/node/bootstrap_ascending/peer_scoring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ bool nano::bootstrap_ascending::peer_scoring::try_send_message (std::shared_ptr<
}
else
{
if (existing->outstanding < config.requests_limit)
if (existing->outstanding < config.channel_limit)
{
[[maybe_unused]] auto success = index.modify (existing, [] (auto & score) {
++score.outstanding;
Expand Down
13 changes: 8 additions & 5 deletions nano/node/bootstrap_ascending/service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,18 +255,18 @@ void nano::bootstrap_ascending::service::wait (std::function<bool ()> const & pr
}
}

void nano::bootstrap_ascending::service::wait_tags ()
void nano::bootstrap_ascending::service::wait_tags () const
{
wait ([this] () {
debug_assert (!mutex.try_lock ());
return tags.size () < config.max_requests;
});
}

void nano::bootstrap_ascending::service::wait_blockprocessor ()
void nano::bootstrap_ascending::service::wait_blockprocessor () const
{
wait ([this] () {
return block_processor.size (nano::block_source::bootstrap) < config.block_wait_count;
return block_processor.size (nano::block_source::bootstrap) < config.block_processor_threshold;
});
}

Expand Down Expand Up @@ -337,10 +337,10 @@ std::pair<nano::account, double> nano::bootstrap_ascending::service::wait_priori
nano::account nano::bootstrap_ascending::service::next_database (bool should_throttle)
{
debug_assert (!mutex.try_lock ());
debug_assert (config.database_warmup_ratio > 0);

// Throttling increases the weight of database requests
// TODO: Make this ratio configurable
if (!database_limiter.should_pass (should_throttle ? 22 : 1))
if (!database_limiter.should_pass (should_throttle ? config.database_warmup_ratio : 1))
{
return { 0 };
}
Expand Down Expand Up @@ -414,6 +414,9 @@ bool nano::bootstrap_ascending::service::request (nano::account account, size_t
debug_assert (count > 0);
debug_assert (count <= nano::bootstrap_server::max_blocks);

// Limit the max number of blocks to pull
count = std::min (count, config.max_pull_count);

async_tag tag{};
tag.source = source;
tag.account = account;
Expand Down
4 changes: 2 additions & 2 deletions nano/node/bootstrap_ascending/service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ namespace bootstrap_ascending
void wait (std::function<bool ()> const & predicate) const;

/* Avoid too many in-flight requests */
void wait_tags ();
void wait_tags () const;
/* Ensure there is enough space in blockprocessor for queuing new blocks */
void wait_blockprocessor ();
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 */
Expand Down

0 comments on commit f029329

Please sign in to comment.