This commit is contained in:
Piotr Wójcik 2025-04-10 12:17:23 +02:00
commit 4b32ea1e38
6 changed files with 44 additions and 45 deletions

View file

@ -84,7 +84,7 @@ public:
default_rpc_port (45000), default_rpc_port (45000),
default_ipc_port (46000), default_ipc_port (46000),
default_websocket_port (47000), default_websocket_port (47000),
aec_loop_interval_ms (300), // Update AEC ~3 times per second aec_loop_interval (300ms), // Update AEC ~3 times per second
cleanup_period (default_cleanup_period), cleanup_period (default_cleanup_period),
merge_period (std::chrono::milliseconds (250)), merge_period (std::chrono::milliseconds (250)),
keepalive_period (std::chrono::seconds (15)), keepalive_period (std::chrono::seconds (15)),
@ -120,7 +120,7 @@ public:
} }
else if (is_dev_network ()) else if (is_dev_network ())
{ {
aec_loop_interval_ms = 20; aec_loop_interval = 20ms;
cleanup_period = std::chrono::seconds (1); cleanup_period = std::chrono::seconds (1);
merge_period = std::chrono::milliseconds (10); merge_period = std::chrono::milliseconds (10);
keepalive_period = std::chrono::seconds (1); keepalive_period = std::chrono::seconds (1);
@ -147,7 +147,7 @@ public:
uint16_t default_rpc_port; uint16_t default_rpc_port;
uint16_t default_ipc_port; uint16_t default_ipc_port;
uint16_t default_websocket_port; uint16_t default_websocket_port;
unsigned aec_loop_interval_ms; std::chrono::milliseconds aec_loop_interval;
std::chrono::seconds cleanup_period; std::chrono::seconds cleanup_period;
std::chrono::milliseconds cleanup_period_half () const std::chrono::milliseconds cleanup_period_half () const

View file

@ -46,8 +46,8 @@ std::string nano::thread_role::get_string (nano::thread_role::name role)
case nano::thread_role::name::ledger_notifications: case nano::thread_role::name::ledger_notifications:
thread_role_name_string = "Ledger notif"; thread_role_name_string = "Ledger notif";
break; break;
case nano::thread_role::name::request_loop: case nano::thread_role::name::aec_loop:
thread_role_name_string = "Request loop"; thread_role_name_string = "AEC";
break; break;
case nano::thread_role::name::wallet_actions: case nano::thread_role::name::wallet_actions:
thread_role_name_string = "Wallet actions"; thread_role_name_string = "Wallet actions";

View file

@ -20,7 +20,7 @@ enum class name
vote_rebroadcasting, vote_rebroadcasting,
block_processing, block_processing,
ledger_notifications, ledger_notifications,
request_loop, aec_loop,
wallet_actions, wallet_actions,
bootstrap_initiator, bootstrap_initiator,
bootstrap_connections, bootstrap_connections,

View file

@ -94,8 +94,8 @@ void nano::active_elections::start ()
debug_assert (!thread.joinable ()); debug_assert (!thread.joinable ());
thread = std::thread ([this] () { thread = std::thread ([this] () {
nano::thread_role::set (nano::thread_role::name::request_loop); nano::thread_role::set (nano::thread_role::name::aec_loop);
request_loop (); run ();
}); });
} }
@ -110,6 +110,27 @@ void nano::active_elections::stop ()
clear (); clear ();
} }
void nano::active_elections::run ()
{
nano::unique_lock<nano::mutex> lock{ mutex };
while (!stopped)
{
auto const stamp = std::chrono::steady_clock::now ();
node.stats.inc (nano::stat::type::active, nano::stat::detail::loop);
tick_elections (lock);
debug_assert (lock.owns_lock ());
auto const min_sleep = node.network_params.network.aec_loop_interval / 2;
auto const wakeup = std::max (stamp + node.network_params.network.aec_loop_interval, std::chrono::steady_clock::now () + min_sleep);
condition.wait_until (lock, wakeup, [this, wakeup] {
return stopped || std::chrono::steady_clock::now () >= wakeup;
});
}
}
auto nano::active_elections::block_cemented (std::shared_ptr<nano::block> const & block, nano::block_hash const & confirmation_root, std::shared_ptr<nano::election> const & source_election) -> block_cemented_result auto nano::active_elections::block_cemented (std::shared_ptr<nano::block> const & block, nano::block_hash const & confirmation_root, std::shared_ptr<nano::election> const & source_election) -> block_cemented_result
{ {
debug_assert (!mutex.try_lock ()); debug_assert (!mutex.try_lock ());
@ -245,14 +266,13 @@ int64_t nano::active_elections::vacancy (nano::election_behavior behavior) const
return std::min (election_vacancy (behavior), election_winners_vacancy ()); return std::min (election_vacancy (behavior), election_winners_vacancy ());
} }
void nano::active_elections::request_confirm (nano::unique_lock<nano::mutex> & lock_a) void nano::active_elections::tick_elections (nano::unique_lock<nano::mutex> & lock)
{ {
debug_assert (lock_a.owns_lock ()); debug_assert (lock.owns_lock ());
std::size_t const this_loop_target_l (roots.size ()); auto const elections_l = list_active_impl ();
auto const elections_l{ list_active_impl (this_loop_target_l) };
lock_a.unlock (); lock.unlock ();
nano::confirmation_solicitor solicitor (node.network, node.config); nano::confirmation_solicitor solicitor (node.network, node.config);
solicitor.prepare (node.rep_crawler.principal_representatives (std::numeric_limits<std::size_t>::max ())); solicitor.prepare (node.rep_crawler.principal_representatives (std::numeric_limits<std::size_t>::max ()));
@ -279,7 +299,7 @@ void nano::active_elections::request_confirm (nano::unique_lock<nano::mutex> & l
} }
solicitor.flush (); solicitor.flush ();
lock_a.lock (); lock.lock ();
} }
void nano::active_elections::cleanup_election (nano::unique_lock<nano::mutex> & lock_a, std::shared_ptr<nano::election> election) void nano::active_elections::cleanup_election (nano::unique_lock<nano::mutex> & lock_a, std::shared_ptr<nano::election> election)
@ -342,20 +362,19 @@ void nano::active_elections::cleanup_election (nano::unique_lock<nano::mutex> &
} }
} }
std::vector<std::shared_ptr<nano::election>> nano::active_elections::list_active (std::size_t max_a) std::vector<std::shared_ptr<nano::election>> nano::active_elections::list_active (std::size_t max_count)
{ {
nano::lock_guard<nano::mutex> guard{ mutex }; nano::lock_guard<nano::mutex> guard{ mutex };
return list_active_impl (max_a); return list_active_impl (max_count);
} }
std::vector<std::shared_ptr<nano::election>> nano::active_elections::list_active_impl (std::size_t max_a) const std::vector<std::shared_ptr<nano::election>> nano::active_elections::list_active_impl (std::size_t max_count) const
{ {
std::vector<std::shared_ptr<nano::election>> result_l; std::vector<std::shared_ptr<nano::election>> result_l;
result_l.reserve (std::min (max_a, roots.size ())); result_l.reserve (std::min (max_count, roots.size ()));
{ {
auto & sorted_roots_l (roots.get<tag_sequenced> ()); auto & sorted_roots_l (roots.get<tag_sequenced> ());
std::size_t count_l{ 0 }; for (auto i = sorted_roots_l.begin (), n = sorted_roots_l.end (); i != n && result_l.size () < max_count; ++i)
for (auto i = sorted_roots_l.begin (), n = sorted_roots_l.end (); i != n && count_l < max_a; ++i, ++count_l)
{ {
result_l.push_back (i->election); result_l.push_back (i->election);
} }
@ -363,27 +382,6 @@ std::vector<std::shared_ptr<nano::election>> nano::active_elections::list_active
return result_l; return result_l;
} }
void nano::active_elections::request_loop ()
{
nano::unique_lock<nano::mutex> lock{ mutex };
while (!stopped)
{
auto const stamp_l = std::chrono::steady_clock::now ();
node.stats.inc (nano::stat::type::active, nano::stat::detail::loop);
request_confirm (lock);
debug_assert (lock.owns_lock ());
if (!stopped)
{
auto const min_sleep_l = std::chrono::milliseconds (node.network_params.network.aec_loop_interval_ms / 2);
auto const wakeup_l = std::max (stamp_l + std::chrono::milliseconds (node.network_params.network.aec_loop_interval_ms), std::chrono::steady_clock::now () + min_sleep_l);
condition.wait_until (lock, wakeup_l, [&wakeup_l, &stopped = stopped] { return stopped || std::chrono::steady_clock::now () >= wakeup_l; });
}
}
}
nano::election_insertion_result nano::active_elections::insert (std::shared_ptr<nano::block> const & block_a, nano::election_behavior election_behavior_a, erased_callback_t erased_callback_a) nano::election_insertion_result nano::active_elections::insert (std::shared_ptr<nano::block> const & block_a, nano::election_behavior election_behavior_a, erased_callback_t erased_callback_a)
{ {
debug_assert (block_a); debug_assert (block_a);

View file

@ -129,8 +129,9 @@ public: // Events
nano::observer_set<> vacancy_updated; nano::observer_set<> vacancy_updated;
private: private:
void request_loop (); void run ();
void request_confirm (nano::unique_lock<nano::mutex> &); void tick_elections (nano::unique_lock<nano::mutex> &);
// Erase all blocks from active and, if not confirmed, clear digests from network filters // Erase all blocks from active and, if not confirmed, clear digests from network filters
void cleanup_election (nano::unique_lock<nano::mutex> & lock_a, std::shared_ptr<nano::election>); void cleanup_election (nano::unique_lock<nano::mutex> & lock_a, std::shared_ptr<nano::election>);
@ -139,7 +140,7 @@ private:
void notify_observers (nano::secure::transaction const &, nano::election_status const & status, std::vector<nano::vote_with_weight_info> const & votes) const; void notify_observers (nano::secure::transaction const &, nano::election_status const & status, std::vector<nano::vote_with_weight_info> const & votes) const;
std::shared_ptr<nano::election> election_impl (nano::qualified_root const &) const; std::shared_ptr<nano::election> election_impl (nano::qualified_root const &) const;
std::vector<std::shared_ptr<nano::election>> list_active_impl (std::size_t max_count) const; std::vector<std::shared_ptr<nano::election>> list_active_impl (std::size_t max_count = std::numeric_limits<std::size_t>::max ()) const;
private: // Dependencies private: // Dependencies
active_elections_config const & config; active_elections_config const & config;

View file

@ -1776,7 +1776,7 @@ TEST (node, mass_block_new)
nano::node_config node_config = system.default_config (); nano::node_config node_config = system.default_config ();
node_config.backlog_scan.enable = false; node_config.backlog_scan.enable = false;
auto & node = *system.add_node (node_config); auto & node = *system.add_node (node_config);
node.network_params.network.aec_loop_interval_ms = 500; node.network_params.network.aec_loop_interval = 500ms;
#ifndef NDEBUG #ifndef NDEBUG
auto const num_blocks = 5000; auto const num_blocks = 5000;