Merge pull request #4182 from thsfs/add_bootstrap_ascending_config

Add config classes for ascending bootstrap
This commit is contained in:
Thiago Silva 2023-04-01 13:45:16 -03:00 committed by GitHub
commit 168367ac78
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 124 additions and 22 deletions

View file

@ -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

View file

@ -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<tag_account> ().find (account);
if (iter != priorities.get<tag_account> ().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<tag_priority> ().erase (priorities.get<tag_priority> ().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<tag_priority> ().erase (blocking.get<tag_priority> ().begin ());
@ -276,7 +277,7 @@ nano::account nano::bootstrap_ascending::account_sets::next ()
std::vector<nano::account> 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::transport::channel>
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<tag_sequenced> ();
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 ();

View file

@ -4,6 +4,7 @@
#include <nano/lib/timer.hpp>
#include <nano/node/bandwidth_limiter.hpp>
#include <nano/node/bootstrap/bootstrap_attempt.hpp>
#include <nano/node/bootstrap/bootstrap_config.hpp>
#include <nano/node/bootstrap/bootstrap_server.hpp>
#include <boost/multi_index/hashed_index.hpp>
@ -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 };
};
}

View file

@ -0,0 +1,58 @@
#include <nano/lib/tomlconfig.hpp>
#include <nano/node/bootstrap/bootstrap_config.hpp>
/*
* 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 ();
}

View file

@ -0,0 +1,36 @@
#pragma once
#include <nano/lib/errors.hpp>
#include <nano/lib/timer.hpp>
#include <nano/node/bootstrap/bootstrap_server.hpp>
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;
};
}

View file

@ -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 ();

View file

@ -7,6 +7,7 @@
#include <nano/lib/numbers.hpp>
#include <nano/lib/rocksdbconfig.hpp>
#include <nano/lib/stats.hpp>
#include <nano/node/bootstrap/bootstrap_config.hpp>
#include <nano/node/ipc/ipc_config.hpp>
#include <nano/node/logging.hpp>
#include <nano/node/optimistic_scheduler.hpp>
@ -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. };