From 2c89be696fd83a4643d9ca4f09013bd9e3cfb877 Mon Sep 17 00:00:00 2001 From: coranos Date: Mon, 26 Feb 2024 22:10:14 -0600 Subject: [PATCH] merging --- nano/node/optimistic_scheduler.cpp | 184 ----------------------------- nano/node/optimistic_scheduler.hpp | 108 ----------------- 2 files changed, 292 deletions(-) delete mode 100644 nano/node/optimistic_scheduler.cpp delete mode 100644 nano/node/optimistic_scheduler.hpp diff --git a/nano/node/optimistic_scheduler.cpp b/nano/node/optimistic_scheduler.cpp deleted file mode 100644 index c6da723a78..0000000000 --- a/nano/node/optimistic_scheduler.cpp +++ /dev/null @@ -1,184 +0,0 @@ -#include -#include -#include -#include - -nano::optimistic_scheduler::optimistic_scheduler (optimistic_scheduler_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 }, - network_constants{ network_constants_a }, - stats{ stats_a } -{ -} - -nano::optimistic_scheduler::~optimistic_scheduler () -{ - // Thread must be stopped before destruction - debug_assert (!thread.joinable ()); -} - -void nano::optimistic_scheduler::start () -{ - if (!config.enabled) - { - return; - } - - debug_assert (!thread.joinable ()); - - thread = std::thread{ [this] () { - nano::thread_role::set (nano::thread_role::name::optimistic_scheduler); - run (); - } }; -} - -void nano::optimistic_scheduler::stop () -{ - { - nano::lock_guard guard{ mutex }; - stopped = true; - } - notify (); - nano::join_or_pass (thread); -} - -void nano::optimistic_scheduler::notify () -{ - condition.notify_all (); -} - -bool nano::optimistic_scheduler::activate_predicate (const nano::account_info & account_info, const nano::confirmation_height_info & conf_info) const -{ - // Chain with a big enough gap between account frontier and confirmation frontier - if (account_info.block_count - conf_info.height > config.gap_threshold) - { - return true; - } - // Account with nothing confirmed yet - if (conf_info.height == 0) - { - return true; - } - return false; -} - -bool nano::optimistic_scheduler::activate (const nano::account & account, const nano::account_info & account_info, const nano::confirmation_height_info & conf_info) -{ - if (!config.enabled) - { - return false; - } - - debug_assert (account_info.block_count >= conf_info.height); - if (activate_predicate (account_info, conf_info)) - { - { - nano::lock_guard lock{ mutex }; - - // Prevent duplicate candidate accounts - if (candidates.get ().contains (account)) - { - return false; // Not activated - } - // Limit candidates container size - if (candidates.size () >= config.max_size) - { - return false; // Not activated - } - - stats.inc (nano::stat::type::optimistic_scheduler, nano::stat::detail::activated); - candidates.push_back ({ account, nano::clock::now () }); - } - return true; // Activated - } - return false; // Not activated -} - -bool nano::optimistic_scheduler::predicate () const -{ - debug_assert (!mutex.try_lock ()); - - if (active.vacancy (nano::election_behavior::optimistic) <= 0) - { - return false; - } - if (candidates.empty ()) - { - return false; - } - - auto candidate = candidates.front (); - bool result = nano::elapsed (candidate.timestamp, network_constants.optimistic_activation_delay); - return result; -} - -void nano::optimistic_scheduler::run () -{ - nano::unique_lock lock{ mutex }; - while (!stopped) - { - stats.inc (nano::stat::type::optimistic_scheduler, nano::stat::detail::loop); - - if (predicate ()) - { - auto transaction = ledger.store.tx_begin_read (); - - while (predicate ()) - { - debug_assert (!candidates.empty ()); - auto candidate = candidates.front (); - candidates.pop_front (); - lock.unlock (); - - run_one (transaction, candidate); - - lock.lock (); - } - } - - condition.wait_for (lock, network_constants.optimistic_activation_delay / 2, [this] () { - return stopped || predicate (); - }); - } -} - -void nano::optimistic_scheduler::run_one (nano::transaction const & transaction, entry const & candidate) -{ - auto block = ledger.head_block (transaction, candidate.account); - if (block) - { - // Ensure block is not already confirmed - if (!node.block_confirmed_or_being_confirmed (block->hash ())) - { - // Try to insert it into AEC - // We check for AEC vacancy inside our predicate - auto result = node.active.insert (block, nano::election_behavior::optimistic); - - stats.inc (nano::stat::type::optimistic_scheduler, result.inserted ? nano::stat::detail::insert : nano::stat::detail::insert_failed); - } - } -} - -/* - * optimistic_scheduler_config - */ - -nano::error nano::optimistic_scheduler_config::deserialize (nano::tomlconfig & toml) -{ - toml.get ("enabled", enabled); - toml.get ("gap_threshold", gap_threshold); - toml.get ("max_size", max_size); - - return toml.get_error (); -} - -nano::error nano::optimistic_scheduler_config::serialize (nano::tomlconfig & toml) const -{ - toml.put ("enable", enabled, "Enable or disable optimistic elections\ntype:bool"); - toml.put ("gap_threshold", gap_threshold, "Minimum difference between confirmation frontier and account frontier to become a candidate for optimistic confirmation\ntype:uint64"); - toml.put ("max_size", max_size, "Maximum number of candidates stored in memory\ntype:uint64"); - - return toml.get_error (); -} \ No newline at end of file diff --git a/nano/node/optimistic_scheduler.hpp b/nano/node/optimistic_scheduler.hpp deleted file mode 100644 index e5f13ae23c..0000000000 --- a/nano/node/optimistic_scheduler.hpp +++ /dev/null @@ -1,108 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace mi = boost::multi_index; - -namespace nano -{ -class node; -class ledger; -class active_transactions; - -class optimistic_scheduler_config final -{ -public: - nano::error deserialize (nano::tomlconfig & toml); - nano::error serialize (nano::tomlconfig & toml) const; - -public: - bool enabled{ true }; - - /** Minimum difference between confirmation frontier and account frontier to become a candidate for optimistic confirmation */ - std::size_t gap_threshold{ 32 }; - - /** Maximum number of candidates stored in memory */ - std::size_t max_size{ 1024 * 64 }; -}; - -class optimistic_scheduler final -{ - struct entry; - -public: - optimistic_scheduler (optimistic_scheduler_config const &, nano::node &, nano::ledger &, nano::active_transactions &, nano::network_constants const & network_constants, nano::stats &); - ~optimistic_scheduler (); - - void start (); - void stop (); - - /** - * Called from backlog population to process accounts with unconfirmed blocks - */ - bool activate (nano::account const &, nano::account_info const &, nano::confirmation_height_info const &); - - /** - * Notify about changes in AEC vacancy - */ - void notify (); - -private: - bool activate_predicate (nano::account_info const &, nano::confirmation_height_info const &) const; - - bool predicate () const; - void run (); - void run_one (nano::transaction const &, entry const & candidate); - -private: // Dependencies - optimistic_scheduler_config const & config; - nano::node & node; - nano::ledger & ledger; - nano::active_transactions & active; - nano::network_constants const & network_constants; - nano::stats & stats; - -private: - struct entry - { - nano::account account; - nano::clock::time_point timestamp; - }; - - // clang-format off - class tag_sequenced {}; - class tag_account {}; - - using ordered_candidates = boost::multi_index_container>, - mi::hashed_unique, - mi::member> - >>; - // clang-format on - - /** Accounts eligible for optimistic scheduling */ - ordered_candidates candidates; - - bool stopped{ false }; - nano::condition_variable condition; - mutable nano::mutex mutex; - std::thread thread; -}; -} \ No newline at end of file