diff --git a/nano/node/CMakeLists.txt b/nano/node/CMakeLists.txt index 20a0b5186..fa50e1048 100644 --- a/nano/node/CMakeLists.txt +++ b/nano/node/CMakeLists.txt @@ -42,6 +42,8 @@ add_library( bootstrap/bootstrap_bulk_pull.cpp bootstrap/bootstrap_bulk_push.hpp bootstrap/bootstrap_bulk_push.cpp + bootstrap/bootstrap_config.hpp + bootstrap/bootstrap_config.cpp bootstrap/bootstrap_connections.hpp bootstrap/bootstrap_connections.cpp bootstrap/bootstrap_frontier.hpp diff --git a/nano/node/bootstrap/bootstrap_ascending.cpp b/nano/node/bootstrap/bootstrap_ascending.cpp index 8d161efbb..ecc3629dc 100644 --- a/nano/node/bootstrap/bootstrap_ascending.cpp +++ b/nano/node/bootstrap/bootstrap_ascending.cpp @@ -119,8 +119,9 @@ void nano::bootstrap_ascending::buffered_iterator::fill () * account_sets */ -nano::bootstrap_ascending::account_sets::account_sets (nano::stats & stats_a) : - stats{ stats_a } +nano::bootstrap_ascending::account_sets::account_sets (nano::stats & stats_a, nano::account_sets_config config_a) : + stats{ stats_a }, + config{ std::move (config_a) } { } @@ -239,7 +240,7 @@ bool nano::bootstrap_ascending::account_sets::check_timestamp (const nano::accou auto iter = priorities.get ().find (account); if (iter != priorities.get ().end ()) { - if (nano::milliseconds_since_epoch () - iter->timestamp < cooldown) + if (nano::milliseconds_since_epoch () - iter->timestamp < config.cooldown) { return false; } @@ -249,14 +250,14 @@ bool nano::bootstrap_ascending::account_sets::check_timestamp (const nano::accou void nano::bootstrap_ascending::account_sets::trim_overflow () { - if (priorities.size () > priorities_max) + if (priorities.size () > config.priorities_max) { // Evict the lowest priority entry priorities.get ().erase (priorities.get ().begin ()); stats.inc (nano::stat::type::bootstrap_ascending_accounts, nano::stat::detail::priority_erase_overflow); } - if (blocking.size () > blocking_max) + if (blocking.size () > config.blocking_max) { // Evict the lowest priority entry blocking.get ().erase (blocking.get ().begin ()); @@ -276,7 +277,7 @@ nano::account nano::bootstrap_ascending::account_sets::next () std::vector candidates; int iterations = 0; - while (candidates.size () < account_sets::consideration_count && iterations++ < account_sets::consideration_count * 10) + while (candidates.size () < config.consideration_count && iterations++ < config.consideration_count * 10) { debug_assert (candidates.size () == weights.size ()); @@ -373,8 +374,8 @@ nano::bootstrap_ascending::bootstrap_ascending (nano::node & node_a, nano::store stats{ stat_a }, accounts{ stats }, iterator{ store }, - limiter{ requests_limit, 1.0 }, - database_limiter{ database_requests_limit, 1.0 } + limiter{ node.config.bootstrap_ascending.requests_limit, 1.0 }, + database_limiter{ node.config.bootstrap_ascending.database_requests_limit, 1.0 } { // TODO: This is called from a very congested blockprocessor thread. Offload this work to a dedicated processing thread block_processor.batch_processed.add ([this] (auto const & batch) { @@ -444,8 +445,9 @@ void nano::bootstrap_ascending::send (std::shared_ptr nano::asc_pull_req::blocks_payload request_payload; request_payload.start = tag.start; - request_payload.count = pull_count; + request_payload.count = node.config.bootstrap_ascending.pull_count; request_payload.start_type = (tag.type == async_tag::query_type::blocks_by_hash) ? nano::asc_pull_req::hash_type::block : nano::asc_pull_req::hash_type::account; + request.payload = request_payload; request.update_header (); @@ -691,7 +693,7 @@ void nano::bootstrap_ascending::run_timeouts () while (!stopped) { auto & tags_by_order = tags.get (); - while (!tags_by_order.empty () && nano::time_difference (tags_by_order.front ().time, nano::milliseconds_since_epoch ()) > timeout) + while (!tags_by_order.empty () && nano::time_difference (tags_by_order.front ().time, nano::milliseconds_since_epoch ()) > node.config.bootstrap_ascending.timeout) { auto tag = tags_by_order.front (); tags_by_order.pop_front (); diff --git a/nano/node/bootstrap/bootstrap_ascending.hpp b/nano/node/bootstrap/bootstrap_ascending.hpp index 62bac5b61..155fef139 100644 --- a/nano/node/bootstrap/bootstrap_ascending.hpp +++ b/nano/node/bootstrap/bootstrap_ascending.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -131,7 +132,7 @@ public: // account_sets class account_sets { public: - explicit account_sets (nano::stats &); + explicit account_sets (nano::stats &, nano::account_sets_config config = {}); /** * If an account is not blocked, increase its priority. @@ -229,11 +230,8 @@ public: // account_sets std::default_random_engine rng; - private: // TODO: Move into config - static std::size_t constexpr consideration_count = 4; - static std::size_t constexpr priorities_max = 256 * 1024; - static std::size_t constexpr blocking_max = 256 * 1024; - static nano::millis_t constexpr cooldown = 3 * 1000; + private: + nano::account_sets_config config; public: // Consts static float constexpr priority_initial = 8.0f; @@ -319,11 +317,5 @@ private: mutable nano::condition_variable condition; std::thread thread; std::thread timeout_thread; - -private: // TODO: Move into config - static std::size_t constexpr requests_limit{ 128 }; - static std::size_t constexpr database_requests_limit{ 1024 }; - static std::size_t constexpr pull_count{ nano::bootstrap_server::max_blocks }; - static nano::millis_t constexpr timeout{ 1000 * 3 }; }; } diff --git a/nano/node/bootstrap/bootstrap_config.cpp b/nano/node/bootstrap/bootstrap_config.cpp new file mode 100644 index 000000000..6ef466cd7 --- /dev/null +++ b/nano/node/bootstrap/bootstrap_config.cpp @@ -0,0 +1,58 @@ +#include +#include + +/* + * account_sets_config + */ +nano::error nano::account_sets_config::deserialize (nano::tomlconfig & toml) +{ + toml.get ("consideration_count", consideration_count); + toml.get ("priorities_max", priorities_max); + toml.get ("blocking_max", blocking_max); + toml.get ("cooldown", cooldown); + + return toml.get_error (); +} + +nano::error nano::account_sets_config::serialize (nano::tomlconfig & toml) const +{ + toml.put ("consideration_count", consideration_count, "Limit the number of account candidates to consider and also the number of iterations.\ntype:uint64"); + toml.put ("priorities_max", priorities_max, "Cutoff size limit for the priority list.\ntype:uint64"); + toml.put ("blocking_max", blocking_max, "Cutoff size limit for the blocked accounts from the priority list.\ntype:uint64"); + toml.put ("cooldown", cooldown, "Waiting time for an account to become available.\ntype:milliseconds"); + + return toml.get_error (); +} + +/* + * bootstrap_ascending_config + */ +nano::error nano::bootstrap_ascending_config::deserialize (nano::tomlconfig & toml) +{ + toml.get ("requests_limit", requests_limit); + toml.get ("database_requests_limit", database_requests_limit); + toml.get ("pull_count", pull_count); + toml.get ("timeout", timeout); + + if (toml.has_key ("account_sets")) + { + auto config_l = toml.get_required_child ("account_sets"); + account_sets.deserialize (config_l); + } + + return toml.get_error (); +} + +nano::error nano::bootstrap_ascending_config::serialize (nano::tomlconfig & toml) const +{ + 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 ("database_requests_limit", database_requests_limit, "Request limit for accounts from database after which requests will be dropped.\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 ("timeout", timeout, "Timeout in milliseconds for incoming ascending bootstrap messages to be processed.\ntype:milliseconds"); + + nano::tomlconfig account_sets_l; + account_sets.serialize (account_sets_l); + toml.put_child ("account_sets", account_sets_l); + + return toml.get_error (); +} diff --git a/nano/node/bootstrap/bootstrap_config.hpp b/nano/node/bootstrap/bootstrap_config.hpp new file mode 100644 index 000000000..c3c9a4b36 --- /dev/null +++ b/nano/node/bootstrap/bootstrap_config.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include + +namespace nano +{ +class tomlconfig; + +class account_sets_config final +{ +public: + nano::error deserialize (nano::tomlconfig & toml); + nano::error serialize (nano::tomlconfig & toml) const; + + std::size_t consideration_count{ 4 }; + std::size_t priorities_max{ 256 * 1024 }; + std::size_t blocking_max{ 256 * 1024 }; + nano::millis_t cooldown{ 1000 * 3 }; +}; + +class bootstrap_ascending_config final +{ +public: + nano::error deserialize (nano::tomlconfig & toml); + nano::error serialize (nano::tomlconfig & toml) const; + + std::size_t requests_limit{ 128 }; + std::size_t database_requests_limit{ 1024 }; + std::size_t pull_count{ nano::bootstrap_server::max_blocks }; + nano::millis_t timeout{ 1000 * 3 }; + + nano::account_sets_config account_sets; +}; +} diff --git a/nano/node/nodeconfig.cpp b/nano/node/nodeconfig.cpp index 8193560d6..bbc819391 100644 --- a/nano/node/nodeconfig.cpp +++ b/nano/node/nodeconfig.cpp @@ -198,6 +198,10 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const optimistic_scheduler.serialize (optimistic_l); toml.put_child ("optimistic_scheduler", optimistic_l); + nano::tomlconfig bootstrap_ascending_l; + bootstrap_ascending.serialize (bootstrap_ascending_l); + toml.put_child ("bootstrap_ascending", bootstrap_ascending_l); + return toml.get_error (); } @@ -255,6 +259,12 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml) optimistic_scheduler.deserialize (config_l); } + if (toml.has_key ("bootstrap_ascending")) + { + auto config_l = toml.get_required_child ("bootstrap_ascending"); + bootstrap_ascending.deserialize (config_l); + } + if (toml.has_key ("work_peers")) { work_peers.clear (); diff --git a/nano/node/nodeconfig.hpp b/nano/node/nodeconfig.hpp index 83826a21c..86abf8aa4 100644 --- a/nano/node/nodeconfig.hpp +++ b/nano/node/nodeconfig.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -105,6 +106,7 @@ public: std::size_t bootstrap_bandwidth_limit{ 5 * 1024 * 1024 }; /** Bootstrap traffic does not need bursts */ double bootstrap_bandwidth_burst_ratio{ 1. }; + nano::bootstrap_ascending_config bootstrap_ascending; std::chrono::milliseconds conf_height_processor_batch_min_time{ 50 }; bool backup_before_upgrade{ false }; double max_work_generate_multiplier{ 64. };