Skip to content

Commit

Permalink
Using limiter
Browse files Browse the repository at this point in the history
  • Loading branch information
clemahieu committed Sep 11, 2023
1 parent b8db18c commit c70ec63
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 33 deletions.
9 changes: 5 additions & 4 deletions nano/core_test/active_transactions.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <nano/lib/jsonconfig.hpp>
#include <nano/node/election.hpp>
#include <nano/node/scheduler/component.hpp>
#include <nano/node/scheduler/hinted.hpp>
#include <nano/node/scheduler/priority.hpp>
#include <nano/node/transport/inproc.hpp>
#include <nano/test_common/chains.hpp>
Expand Down Expand Up @@ -1520,9 +1521,9 @@ TEST (active_transactions, allow_limited_overflow)
}

// Ensure active elections overfill AEC only up to normal + hinted limit
ASSERT_TIMELY_EQ (5s, node.active.size (), node.active.limit () + node.active.limit (nano::election_behavior::hinted));
ASSERT_TIMELY_EQ (5s, node.active.size (), node.active.limit () + node.scheduler.hinted.limit ());
// And it stays that way without increasing
ASSERT_ALWAYS (1s, node.active.size () == node.active.limit () + node.active.limit (nano::election_behavior::hinted));
ASSERT_ALWAYS (1s, node.active.size () == node.active.limit () + node.scheduler.hinted.limit ());
}

/*
Expand Down Expand Up @@ -1558,9 +1559,9 @@ TEST (active_transactions, allow_limited_overflow_adapt)
}

// Ensure hinted election amount is bounded by hinted limit
ASSERT_TIMELY_EQ (5s, node.active.size (), node.active.limit (nano::election_behavior::hinted));
ASSERT_TIMELY_EQ (5s, node.active.size (), node.scheduler.hinted.limit ());
// And it stays that way without increasing
ASSERT_ALWAYS (1s, node.active.size () == node.active.limit (nano::election_behavior::hinted));
ASSERT_ALWAYS (1s, node.active.size () == node.scheduler.hinted.limit ());

// Insert the first part of the blocks into normal election scheduler
for (auto const & block : blocks1)
Expand Down
3 changes: 2 additions & 1 deletion nano/lib/stats_enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,10 @@ enum class detail : uint8_t
election_block_conflict,
election_restart,
election_not_confirmed,
election_hinted_overflow,
election_hinted_confirmed,
election_hinted_drop,
election_hinted_overflow,
election_hinted_started,
generate_vote,
generate_vote_normal,
generate_vote_final,
Expand Down
12 changes: 8 additions & 4 deletions nano/node/active_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,13 @@ int64_t nano::active_transactions::limit (nano::election_behavior behavior) cons
}
case nano::election_behavior::hinted:
{
const uint64_t limit = node.config.active_elections_hinted_limit_percentage * node.config.active_elections_size / 100;
return static_cast<int64_t> (limit);
debug_assert (false);
return 0;
}
case nano::election_behavior::optimistic:
{
const uint64_t limit = node.config.active_elections_optimistic_limit_percentage * node.config.active_elections_size / 100;
return static_cast<int64_t> (limit);
debug_assert (false);
return 0;
}
}

Expand Down Expand Up @@ -450,6 +450,10 @@ nano::election_insertion_result nano::active_transactions::insert_impl (nano::un
}
trim ();
}
if (result.election == nullptr)
{
std::cerr << '\0';
}
return result;
}

Expand Down
21 changes: 15 additions & 6 deletions nano/node/scheduler/hinted.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <nano/lib/stats.hpp>
#include <nano/node/node.hpp>
#include <nano/node/scheduler/hinted.hpp>
#include <nano/node/scheduler/limiter.hpp>

nano::scheduler::hinted::config::config (nano::node_config const & config) :
vote_cache_check_interval_ms{ config.network_params.network.is_dev_network () ? 100u : 1000u }
Expand All @@ -11,9 +12,8 @@ nano::scheduler::hinted::hinted (config const & config_a, nano::node & node_a, n
config_m{ config_a },
node{ node_a },
inactive_vote_cache{ inactive_vote_cache_a },
active{ active_a },
online_reps{ online_reps_a },
stats{ stats_a }
limiter{ std::make_shared<nano::scheduler::limiter> (node.active.insert_fn (), std::max<size_t> (node.config.active_elections_hinted_limit_percentage * node.config.active_elections_size / 100, 1u), nano::election_behavior::hinted) },
online_reps{ online_reps_a }, stats{ stats_a }
{
}

Expand Down Expand Up @@ -48,17 +48,26 @@ void nano::scheduler::hinted::notify ()
condition.notify_all ();
}

size_t nano::scheduler::hinted::limit () const
{
return limiter->limit ();
}

bool nano::scheduler::hinted::predicate (nano::uint128_t const & minimum_tally) const
{
// Check if there is space inside AEC for a new hinted election
if (active.vacancy (nano::election_behavior::hinted) > 0)
if (limiter->available ())
{
// Check if there is any vote cache entry surpassing our minimum vote tally threshold
if (inactive_vote_cache.peek (minimum_tally))
{
return true;
}
}
else
{
std::cerr << '\0';
}
return false;
}

Expand All @@ -77,9 +86,9 @@ bool nano::scheduler::hinted::run_one (nano::uint128_t const & minimum_tally)
{
// Try to insert it into AEC as hinted election
// We check for AEC vacancy inside our predicate
auto result = node.active.insert (block, nano::election_behavior::hinted);
auto result = limiter->activate (block);

stats.inc (nano::stat::type::hinting, result.inserted ? nano::stat::detail::insert : nano::stat::detail::insert_failed);
stats.inc (nano::stat::type::hinting, result.inserted ? nano::stat::detail::hinted : nano::stat::detail::insert_failed);

return result.inserted; // Return whether block was inserted
}
Expand Down
7 changes: 6 additions & 1 deletion nano/node/scheduler/hinted.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <nano/lib/locks.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/node/election_insertion_result.hpp>
#include <nano/secure/common.hpp>

#include <condition_variable>
Expand All @@ -12,11 +13,13 @@ namespace nano
class node;
class node_config;
class active_transactions;
class node;
class vote_cache;
class online_reps;
}
namespace nano::scheduler
{
class limiter;
/*
* Monitors inactive vote cache and schedules elections with the highest observed vote tally.
*/
Expand All @@ -41,18 +44,20 @@ class hinted final
* Notify about changes in AEC vacancy
*/
void notify ();
size_t limit () const;

private:
bool predicate (nano::uint128_t const & minimum_tally) const;
void run ();
bool run_one (nano::uint128_t const & minimum_tally);
nano::election_insertion_result insert_action (std::shared_ptr<nano::block> block);

nano::uint128_t tally_threshold () const;

private: // Dependencies
nano::node & node;
nano::vote_cache & inactive_vote_cache;
nano::active_transactions & active;
std::shared_ptr<nano::scheduler::limiter> limiter;
nano::online_reps & online_reps;
nano::stats & stats;

Expand Down
7 changes: 4 additions & 3 deletions nano/node/scheduler/optimistic.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#include <nano/lib/stats.hpp>
#include <nano/lib/tomlconfig.hpp>
#include <nano/node/node.hpp>
#include <nano/node/scheduler/limiter.hpp>
#include <nano/node/scheduler/optimistic.hpp>

nano::scheduler::optimistic::optimistic (optimistic_config const & config_a, nano::node & node_a, nano::ledger & ledger_a, nano::active_transactions & active_a, nano::network_constants const & network_constants_a, nano::stats & stats_a) :
config{ config_a },
node{ node_a },
ledger{ ledger_a },
active{ active_a },
limiter{ std::make_shared<nano::scheduler::limiter> (node.active.insert_fn (), std::max<size_t> (node.config.active_elections_optimistic_limit_percentage * node.config.active_elections_size / 100, 1u), nano::election_behavior::optimistic) },
network_constants{ network_constants_a },
stats{ stats_a }
{
Expand Down Expand Up @@ -100,7 +101,7 @@ bool nano::scheduler::optimistic::predicate () const
{
debug_assert (!mutex.try_lock ());

if (active.vacancy (nano::election_behavior::optimistic) <= 0)
if (!limiter->available ())
{
return false;
}
Expand Down Expand Up @@ -154,7 +155,7 @@ void nano::scheduler::optimistic::run_one (nano::transaction const & transaction
{
// Try to insert it into AEC
// We check for AEC vacancy inside our predicate
auto result = node.active.insert (block, nano::election_behavior::optimistic);
auto result = limiter->activate (block);

stats.inc (nano::stat::type::optimistic_scheduler, result.inserted ? nano::stat::detail::insert : nano::stat::detail::insert_failed);
}
Expand Down
7 changes: 4 additions & 3 deletions nano/node/scheduler/optimistic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ namespace mi = boost::multi_index;

namespace nano
{
class node;
class ledger;
class active_transactions;
class ledger;
class node;
}

namespace nano::scheduler
{
class limiter;
class optimistic_config final
{
public:
Expand Down Expand Up @@ -76,7 +77,7 @@ class optimistic final
optimistic_config const & config;
nano::node & node;
nano::ledger & ledger;
nano::active_transactions & active;
std::shared_ptr<nano::scheduler::limiter> limiter;
nano::network_constants const & network_constants;
nano::stats & stats;

Expand Down
35 changes: 24 additions & 11 deletions nano/node/scheduler/priority.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <nano/node/node.hpp>
#include <nano/node/scheduler/buckets.hpp>
#include <nano/node/scheduler/limiter.hpp>
#include <nano/node/scheduler/priority.hpp>

nano::scheduler::priority::priority (nano::node & node_a, nano::stats & stats_a) :
Expand Down Expand Up @@ -124,30 +125,42 @@ void nano::scheduler::priority::run ()
if (manual_queue_predicate ())
{
auto const [block, previous_balance, election_behavior] = manual_queue.front ();
manual_queue.pop_front ();
lock.unlock ();
stats.inc (nano::stat::type::election_scheduler, nano::stat::detail::insert_manual);
auto result = node.active.insert (block, election_behavior);
if (result.election != nullptr)
if (result.election)
{
result.election->transition_active ();
manual_queue.pop_front ();
}
else
{
std::cerr << '\0';
}
stats.inc (nano::stat::type::election_scheduler, nano::stat::detail::insert_manual);
}
else if (priority_queue_predicate ())
{
auto block = buckets->top ();
buckets->pop ();
lock.unlock ();
stats.inc (nano::stat::type::election_scheduler, nano::stat::detail::insert_priority);
auto result = node.active.insert (block.first);
if (result.inserted)
if (!buckets->top ().second->available ())
{
stats.inc (nano::stat::type::election_scheduler, nano::stat::detail::insert_priority_success);
buckets->seek ();
}
auto [block, limiter] = buckets->top ();
debug_assert (limiter->available ());
auto result = limiter->activate (block);
if (result.election != nullptr)
{
buckets->pop ();
lock.unlock ();
result.election->transition_active ();
if (result.inserted)
{
stats.inc (nano::stat::type::election_scheduler, nano::stat::detail::insert_priority_success);
}
}
else
{
lock.unlock ();
}
stats.inc (nano::stat::type::election_scheduler, nano::stat::detail::insert_priority);
}
else
{
Expand Down

0 comments on commit c70ec63

Please sign in to comment.