diff --git a/nano/core_test/toml.cpp b/nano/core_test/toml.cpp index af50f9ef38..ddf4505a72 100644 --- a/nano/core_test/toml.cpp +++ b/nano/core_test/toml.cpp @@ -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); @@ -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] @@ -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); @@ -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"; @@ -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); } \ No newline at end of file diff --git a/nano/node/bootstrap/bootstrap_config.cpp b/nano/node/bootstrap/bootstrap_config.cpp index 79560aeaa8..a55cbd51e3 100644 --- a/nano/node/bootstrap/bootstrap_config.cpp +++ b/nano/node/bootstrap/bootstrap_config.cpp @@ -4,6 +4,7 @@ /* * account_sets_config */ + nano::error nano::account_sets_config::deserialize (nano::tomlconfig & toml) { toml.get ("consideration_count", consideration_count); @@ -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")) @@ -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; diff --git a/nano/node/bootstrap/bootstrap_config.hpp b/nano/node/bootstrap/bootstrap_config.hpp index ed20fe9b59..af7b98bcb3 100644 --- a/nano/node/bootstrap/bootstrap_config.hpp +++ b/nano/node/bootstrap/bootstrap_config.hpp @@ -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; }; diff --git a/nano/node/bootstrap_ascending/peer_scoring.cpp b/nano/node/bootstrap_ascending/peer_scoring.cpp index dbabc6eedd..9fc2be605e 100644 --- a/nano/node/bootstrap_ascending/peer_scoring.cpp +++ b/nano/node/bootstrap_ascending/peer_scoring.cpp @@ -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; diff --git a/nano/node/bootstrap_ascending/service.cpp b/nano/node/bootstrap_ascending/service.cpp index 59e989aadb..fce8efe52f 100644 --- a/nano/node/bootstrap_ascending/service.cpp +++ b/nano/node/bootstrap_ascending/service.cpp @@ -255,7 +255,7 @@ void nano::bootstrap_ascending::service::wait (std::function const & pr } } -void nano::bootstrap_ascending::service::wait_tags () +void nano::bootstrap_ascending::service::wait_tags () const { wait ([this] () { debug_assert (!mutex.try_lock ()); @@ -263,10 +263,10 @@ void nano::bootstrap_ascending::service::wait_tags () }); } -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; }); } @@ -337,10 +337,10 @@ std::pair 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 }; } @@ -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; diff --git a/nano/node/bootstrap_ascending/service.hpp b/nano/node/bootstrap_ascending/service.hpp index 90ff08106d..7506f48b09 100644 --- a/nano/node/bootstrap_ascending/service.hpp +++ b/nano/node/bootstrap_ascending/service.hpp @@ -109,9 +109,9 @@ namespace bootstrap_ascending void wait (std::function 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 wait_channel (); /* Waits until a suitable account outside of cool down period is available */