From 9976d8a5c7bc8c677ad87343ffbe0ba2d2397e11 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Fri, 30 Apr 2021 15:26:15 +0300 Subject: [PATCH 1/9] Remove active transactions difficulty sorting (draft in progress) --- nano/core_test/active_transactions.cpp | 83 +---------- nano/lib/stats.cpp | 7 +- nano/lib/stats.hpp | 3 +- nano/node/active_transactions.cpp | 191 ++----------------------- nano/node/active_transactions.hpp | 31 +--- nano/node/blockprocessor.cpp | 9 -- nano/node/election.cpp | 24 +--- nano/node/election.hpp | 5 +- nano/node/json_handler.cpp | 30 +--- nano/node/json_handler.hpp | 1 - nano/node/network.cpp | 2 +- 11 files changed, 26 insertions(+), 360 deletions(-) diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index bd8f36522c..94bd9773ee 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -511,85 +511,6 @@ TEST (active_transactions, inactive_votes_cache_election_start) ASSERT_TIMELY (5s, 13 == node.ledger.cache.cemented_count); } -TEST (active_transactions, DISABLED_update_difficulty) -{ - nano::system system (2); - auto & node1 = *system.nodes[0]; - auto & node2 = *system.nodes[1]; - nano::genesis genesis; - nano::keypair key1; - // Generate blocks & start elections - nano::state_block_builder builder; - auto send1 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (genesis.hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 100) - .link (key1.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (genesis.hash ())) - .build_shared (); - auto difficulty1 (send1->difficulty ()); - auto multiplier1 (nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty1, nano::work_threshold (send1->work_version (), nano::block_details (nano::epoch::epoch_0, true, false, false))), node1.network_params.network.publish_thresholds.epoch_1)); - auto send2 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (send1->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 200) - .link (key1.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send1->hash ())) - .build_shared (); - auto difficulty2 (send2->difficulty ()); - auto multiplier2 (nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty2, nano::work_threshold (send2->work_version (), nano::block_details (nano::epoch::epoch_0, true, false, false))), node1.network_params.network.publish_thresholds.epoch_1)); - node1.process_active (send1); - node1.process_active (send2); - node1.block_processor.flush (); - ASSERT_NO_ERROR (system.poll_until_true (10s, [&node1, &node2] { return node1.active.size () == 2 && node2.active.size () == 2; })); - // Update work with higher difficulty - auto work1 = node1.work_generate_blocking (send1->root (), difficulty1 + 1); - auto work2 = node1.work_generate_blocking (send2->root (), difficulty2 + 1); - - std::error_code ec; - send1 = builder.make_block ().from (*send1).work (*work1).build_shared (ec); - send2 = builder.make_block ().from (*send2).work (*work2).build_shared (ec); - ASSERT_FALSE (ec); - - node1.process_active (send1); - node1.process_active (send2); - node1.block_processor.flush (); - node1.scheduler.flush (); - // Share the updated blocks - node1.network.flood_block (send1); - node1.network.flood_block (send2); - - system.deadline_set (10s); - bool done (false); - while (!done) - { - { - // node1 - nano::lock_guard guard1 (node1.active.mutex); - auto const existing1 (node1.active.roots.find (send1->qualified_root ())); - ASSERT_NE (existing1, node1.active.roots.end ()); - auto const existing2 (node1.active.roots.find (send2->qualified_root ())); - ASSERT_NE (existing2, node1.active.roots.end ()); - // node2 - nano::lock_guard guard2 (node2.active.mutex); - auto const existing3 (node2.active.roots.find (send1->qualified_root ())); - ASSERT_NE (existing3, node2.active.roots.end ()); - auto const existing4 (node2.active.roots.find (send2->qualified_root ())); - ASSERT_NE (existing4, node2.active.roots.end ()); - auto updated1 = existing1->multiplier > multiplier1; - auto updated2 = existing2->multiplier > multiplier2; - auto propagated1 = existing3->multiplier > multiplier1; - auto propagated2 = existing4->multiplier > multiplier2; - done = updated1 && updated2 && propagated1 && propagated2; - } - ASSERT_NO_ERROR (system.poll ()); - } -} - namespace nano { TEST (active_transactions, vote_replays) @@ -1160,8 +1081,8 @@ TEST (active_transactions, insertion_prioritization) node.scheduler.flush (); ASSERT_FALSE (node.active.election (blocks[6]->qualified_root ())->prioritized ()); - ASSERT_EQ (4, node.stats.count (nano::stat::type::election, nano::stat::detail::election_non_priority)); - ASSERT_EQ (3, node.stats.count (nano::stat::type::election, nano::stat::detail::election_priority)); + ASSERT_EQ (4, node.stats.count (nano::stat::type::election, nano::stat::detail::election_start)); + ASSERT_EQ (3, node.stats.count (nano::stat::type::election, nano::stat::detail::election_start)); } TEST (active_multiplier, less_than_one) diff --git a/nano/lib/stats.cpp b/nano/lib/stats.cpp index 1732d428a4..e250af97e5 100644 --- a/nano/lib/stats.cpp +++ b/nano/lib/stats.cpp @@ -730,11 +730,8 @@ std::string nano::stat::detail_to_string (uint32_t key) case nano::stat::detail::late_block_seconds: res = "late_block_seconds"; break; - case nano::stat::detail::election_non_priority: - res = "election_non_priority"; - break; - case nano::stat::detail::election_priority: - res = "election_priority"; + case nano::stat::detail::election_start: + res = "election_start"; break; case nano::stat::detail::election_block_conflict: res = "election_block_conflict"; diff --git a/nano/lib/stats.hpp b/nano/lib/stats.hpp index 14412abdab..566e7a073e 100644 --- a/nano/lib/stats.hpp +++ b/nano/lib/stats.hpp @@ -315,8 +315,7 @@ class stat final vote_cached, late_block, late_block_seconds, - election_non_priority, - election_priority, + election_start, election_block_conflict, election_difficulty_update, election_drop, diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index fbb2ff5126..b72cab4ed8 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -22,12 +22,8 @@ nano::active_transactions::active_transactions (nano::node & node_a, nano::confi scheduler{ node_a.scheduler }, // Move dependencies requiring this circular reference confirmation_height_processor{ confirmation_height_processor_a }, node{ node_a }, - multipliers_cb{ 20, 1. }, - trended_active_multiplier{ 1.0 }, generator{ node_a.config, node_a.ledger, node_a.wallets, node_a.vote_processor, node_a.history, node_a.network, node_a.stats }, - check_all_elections_period{ node_a.network_params.network.is_dev_network () ? 10ms : 5s }, election_time_to_live{ node_a.network_params.network.is_dev_network () ? 0s : 2s }, - prioritized_cutoff{ std::max (1, node_a.config.active_elections_size / 10) }, thread ([this] () { nano::thread_role::set (nano::thread_role::name::request_loop); request_loop (); @@ -291,8 +287,7 @@ void nano::active_transactions::request_confirm (nano::unique_lock { debug_assert (lock_a.owns_lock ()); - bool const check_all_elections_l (std::chrono::steady_clock::now () - last_check_all_elections > check_all_elections_period); - size_t const this_loop_target_l (check_all_elections_l ? roots.size () : prioritized_cutoff); + size_t const this_loop_target_l (roots.size ()); auto const elections_l{ list_active_impl (this_loop_target_l) }; lock_a.unlock (); @@ -320,11 +315,6 @@ void nano::active_transactions::request_confirm (nano::unique_lock { bool const confirmed_l (election_l->confirmed ()); - if (!election_l->prioritized () && unconfirmed_count_l < prioritized_cutoff) - { - election_l->prioritize (generator_session); - } - unconfirmed_count_l += !confirmed_l; bool const overflow_l (unconfirmed_count_l > node.config.active_elections_size && election_l->election_start < election_ttl_cutoff_l && !is_watched (election_l->qualified_root)); if (overflow_l || election_l->transition_time (solicitor)) @@ -348,14 +338,9 @@ void nano::active_transactions::request_confirm (nano::unique_lock generator_session.flush (); lock_a.lock (); - // This is updated after the loop to ensure slow machines don't do the full check often - if (check_all_elections_l) + if (node.config.logging.timing_logging ()) { - last_check_all_elections = std::chrono::steady_clock::now (); - if (node.config.logging.timing_logging () && this_loop_target_l > prioritized_cutoff) - { - node.logger.try_log (boost::str (boost::format ("Processed %1% elections (%2% were already confirmed) in %3% %4%") % this_loop_target_l % (this_loop_target_l - unconfirmed_count_l) % elapsed.value ().count () % elapsed.unit ())); - } + node.logger.try_log (boost::str (boost::format ("Processed %1% elections (%2% were already confirmed) in %3% %4%") % this_loop_target_l % (this_loop_target_l - unconfirmed_count_l) % elapsed.value ().count () % elapsed.unit ())); } } @@ -405,7 +390,7 @@ std::vector> nano::active_transactions::list_act std::vector> result_l; result_l.reserve (std::min (max_a, roots.size ())); { - auto & sorted_roots_l (roots.get ()); + auto & sorted_roots_l (roots.get ()); size_t count_l{ 0 }; for (auto i = sorted_roots_l.begin (), n = sorted_roots_l.end (); i != n && count_l < max_a; ++i, ++count_l) { @@ -591,7 +576,6 @@ void nano::active_transactions::request_loop () const auto stamp_l = std::chrono::steady_clock::now (); - update_active_multiplier (lock); request_confirm (lock); if (!stopped) @@ -826,20 +810,18 @@ nano::election_insertion_result nano::active_transactions::insert_impl (nano::un previous_balance = node.ledger.balance (transaction, block_a->previous ()); } } - double multiplier (normalized_multiplier (*block_a)); - bool prioritized = roots.size () < prioritized_cutoff || multiplier > last_prioritized_multiplier.value_or (0); result.election = nano::make_shared ( node, block_a, confirmation_action_a, [&node = node] (auto const & rep_a) { // Representative is defined as online if replying to live votes or rep_crawler queries node.online_reps.observe (rep_a); }, - prioritized, election_behavior_a); - roots.get ().emplace (nano::active_transactions::conflict_info{ root, multiplier, result.election, epoch, previous_balance }); + election_behavior_a); + roots.get ().emplace (nano::active_transactions::conflict_info{ root, result.election, epoch, previous_balance }); blocks.emplace (hash, result.election); auto const cache = find_inactive_votes_cache_impl (hash); lock_a.unlock (); result.election->insert_inactive_votes_cache (cache); - node.stats.inc (nano::stat::type::election, prioritized ? nano::stat::detail::election_priority : nano::stat::detail::election_non_priority); + node.stats.inc (nano::stat::type::election, nano::stat::detail::election_start); vacancy_update (); } } @@ -853,9 +835,8 @@ nano::election_insertion_result nano::active_transactions::insert_impl (nano::un lock_a.unlock (); } - // Votes are generated for inserted or ongoing elections if they're prioritized - // Non-priority elections generate votes when they gain priority in the future - if (result.election && result.election->prioritized ()) + // Votes are generated for inserted or ongoing elections + if (result.election) { result.election->generate_votes (); } @@ -979,39 +960,6 @@ std::shared_ptr nano::active_transactions::winner (nano::block_hash return result; } -bool nano::active_transactions::update_difficulty (std::shared_ptr const & block_a, bool flood_update) -{ - nano::unique_lock lock (mutex); - auto existing_election (roots.get ().find (block_a->qualified_root ())); - bool error = existing_election == roots.get ().end () || update_difficulty_impl (existing_election, *block_a); - // Update election and flood block - if (!error && flood_update) - { - lock.unlock (); - existing_election->election->publish (block_a); - } - return error; -} - -bool nano::active_transactions::update_difficulty_impl (nano::active_transactions::roots_iterator const & root_it_a, nano::block const & block_a) -{ - debug_assert (!mutex.try_lock ()); - double multiplier (normalized_multiplier (block_a, root_it_a)); - bool error = multiplier <= root_it_a->multiplier; - if (!error) - { - if (node.config.logging.active_update_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Election %1% difficulty updated with block %2% from multiplier %3% to %4%") % root_it_a->root.to_string () % block_a.hash ().to_string () % root_it_a->multiplier % multiplier)); - } - roots.get ().modify (root_it_a, [multiplier] (nano::active_transactions::conflict_info & info_a) { - info_a.multiplier = multiplier; - }); - node.stats.inc (nano::stat::type::election, nano::stat::detail::election_difficulty_update); - } - return error; -} - void nano::active_transactions::restart (nano::transaction const & transaction_a, std::shared_ptr const & block_a) { auto hash (block_a->hash ()); @@ -1040,120 +988,6 @@ void nano::active_transactions::restart (nano::transaction const & transaction_a } } -double nano::active_transactions::normalized_multiplier (nano::block const & block_a, boost::optional const & root_it_a) const -{ - debug_assert (!mutex.try_lock ()); - auto difficulty (block_a.difficulty ()); - uint64_t threshold (0); - bool sideband_not_found (false); - if (block_a.has_sideband ()) - { - threshold = nano::work_threshold (block_a.work_version (), block_a.sideband ().details); - } - else if (root_it_a.is_initialized ()) - { - auto election (*root_it_a); - debug_assert (election != roots.end ()); - // This is one of few places where both the active mutex and election mutexes are held - if (auto election_block = election->election->find (block_a.hash ()); election_block && election_block->has_sideband ()) - { - threshold = nano::work_threshold (block_a.work_version (), election_block->sideband ().details); - } - else - { - // This can have incorrect results during an epoch upgrade, but it only affects prioritization - bool is_send = election->previous_balance > block_a.balance ().number (); - bool is_receive = election->previous_balance < block_a.balance ().number (); - nano::block_details details (election->epoch, is_send, is_receive, false); - - threshold = nano::work_threshold (block_a.work_version (), details); - sideband_not_found = true; - } - } - double multiplier (nano::difficulty::to_multiplier (difficulty, threshold)); - debug_assert (multiplier >= 1 || sideband_not_found); - if (multiplier >= 1) - { - multiplier = nano::normalized_multiplier (multiplier, threshold); - } - else - { - // Inferred threshold was incorrect - multiplier = 1; - } - return multiplier; -} - -void nano::active_transactions::update_active_multiplier (nano::unique_lock & lock_a) -{ - debug_assert (!mutex.try_lock ()); - last_prioritized_multiplier.reset (); - double multiplier (1.); - // Heurestic to filter out non-saturated network and frontier confirmation - if (roots.size () >= prioritized_cutoff || (node.network_params.network.is_dev_network () && !roots.empty ())) - { - auto & sorted_roots = roots.get (); - std::vector prioritized; - prioritized.reserve (std::min (sorted_roots.size (), prioritized_cutoff)); - for (auto it (sorted_roots.begin ()), end (sorted_roots.end ()); it != end && prioritized.size () < prioritized_cutoff; ++it) - { - if (!it->election->confirmed ()) - { - prioritized.push_back (it->multiplier); - } - } - if (prioritized.size () > 10 || (node.network_params.network.is_dev_network () && !prioritized.empty ())) - { - multiplier = prioritized[prioritized.size () / 2]; - } - if (!prioritized.empty ()) - { - last_prioritized_multiplier = prioritized.back (); - } - } - debug_assert (multiplier >= nano::difficulty::to_multiplier (node.network_params.network.publish_thresholds.entry, node.network_params.network.publish_thresholds.base)); - multipliers_cb.push_front (multiplier); - auto sum (std::accumulate (multipliers_cb.begin (), multipliers_cb.end (), double (0))); - double avg_multiplier (sum / multipliers_cb.size ()); - auto difficulty = nano::difficulty::from_multiplier (avg_multiplier, node.default_difficulty (nano::work_version::work_1)); - debug_assert (difficulty >= node.network_params.network.publish_thresholds.entry); - - trended_active_multiplier = avg_multiplier; - lock_a.unlock (); - node.observers.difficulty.notify (difficulty); - lock_a.lock (); -} - -uint64_t nano::active_transactions::active_difficulty () -{ - return nano::difficulty::from_multiplier (active_multiplier (), node.default_difficulty (nano::work_version::work_1)); -} - -uint64_t nano::active_transactions::limited_active_difficulty (nano::block const & block_a) -{ - uint64_t threshold (0); - if (block_a.has_sideband ()) - { - threshold = nano::work_threshold (block_a.work_version (), block_a.sideband ().details); - } - else - { - threshold = node.default_difficulty (block_a.work_version ()); - } - return limited_active_difficulty (block_a.work_version (), threshold); -} - -uint64_t nano::active_transactions::limited_active_difficulty (nano::work_version const version_a, uint64_t const threshold_a) -{ - auto difficulty (nano::difficulty::from_multiplier (nano::denormalized_multiplier (active_multiplier (), threshold_a), threshold_a)); - return std::min (difficulty, node.max_work_generate_difficulty (version_a)); -} - -double nano::active_transactions::active_multiplier () -{ - return trended_active_multiplier.load (); -} - std::deque nano::active_transactions::list_recently_cemented () { nano::lock_guard lock (mutex); @@ -1240,7 +1074,6 @@ bool nano::active_transactions::publish (std::shared_ptr const & bl auto result (true); if (existing != roots.get ().end ()) { - update_difficulty_impl (existing, *block_a); auto election (existing->election); lock.unlock (); result = election->publish (block_a); @@ -1309,12 +1142,6 @@ size_t nano::active_transactions::priority_wallet_cementable_frontiers_size () return priority_wallet_cementable_frontiers.size (); } -boost::circular_buffer nano::active_transactions::difficulty_trend () -{ - nano::lock_guard guard (mutex); - return multipliers_cb; -} - size_t nano::active_transactions::inactive_votes_cache_size () { nano::lock_guard guard (mutex); diff --git a/nano/node/active_transactions.hpp b/nano/node/active_transactions.hpp index de96d7ca8e..6fe40913a2 100644 --- a/nano/node/active_transactions.hpp +++ b/nano/node/active_transactions.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -121,7 +122,6 @@ class active_transactions final { public: nano::qualified_root root; - double multiplier; std::shared_ptr election; nano::epoch epoch; nano::uint128_t previous_balance; @@ -131,7 +131,7 @@ class active_transactions final // clang-format off class tag_account {}; - class tag_difficulty {}; + class tag_random_access {}; class tag_root {}; class tag_sequence {}; class tag_uncemented {}; @@ -145,11 +145,9 @@ class active_transactions final // clang-format off using ordered_roots = boost::multi_index_container>, mi::hashed_unique, - mi::member>, - mi::ordered_non_unique, - mi::member, - std::greater>>>; + mi::member>>>; // clang-format on ordered_roots roots; using roots_iterator = active_transactions::ordered_roots::index_iterator::type; @@ -163,18 +161,10 @@ class active_transactions final bool active (nano::qualified_root const &); std::shared_ptr election (nano::qualified_root const &) const; std::shared_ptr winner (nano::block_hash const &) const; - // Returns false if the election difficulty was updated - bool update_difficulty (std::shared_ptr const &, bool); // Returns false if the election was restarted void restart (nano::transaction const &, std::shared_ptr const &); // Returns a list of elections sorted by difficulty std::vector> list_active (size_t = std::numeric_limits::max ()); - double normalized_multiplier (nano::block const &, boost::optional const & = boost::none) const; - void update_active_multiplier (nano::unique_lock &); - uint64_t active_difficulty (); - uint64_t limited_active_difficulty (nano::block const &); - uint64_t limited_active_difficulty (nano::work_version const, uint64_t const); - double active_multiplier (); void erase (nano::block const &); void erase_hash (nano::block_hash const &); bool empty (); @@ -188,7 +178,6 @@ class active_transactions final int64_t vacancy () const; std::function vacancy_update{ [] () {} }; - boost::optional last_prioritized_multiplier{ boost::none }; std::unordered_map> blocks; std::deque list_recently_cemented (); std::deque recently_cemented; @@ -205,11 +194,8 @@ class active_transactions final nano::confirmation_height_processor & confirmation_height_processor; nano::node & node; mutable nano::mutex mutex{ mutex_identifier (mutexes::active) }; - boost::circular_buffer multipliers_cb; - std::atomic trended_active_multiplier; size_t priority_cementable_frontiers_size (); size_t priority_wallet_cementable_frontiers_size (); - boost::circular_buffer difficulty_trend (); size_t inactive_votes_cache_size (); size_t election_winner_details_size (); void add_election_winner_details (nano::block_hash const &, std::shared_ptr const &); @@ -241,8 +227,6 @@ class active_transactions final // clang-format off nano::election_insertion_result insert_impl (nano::unique_lock &, std::shared_ptr const&, boost::optional const & = boost::none, nano::election_behavior = nano::election_behavior::normal, std::functionconst&)> const & = nullptr); // clang-format on - // Returns false if the election difficulty was updated - bool update_difficulty_impl (roots_iterator const &, nano::block const &); void request_loop (); void request_confirm (nano::unique_lock &); void erase (nano::qualified_root const &); @@ -255,16 +239,9 @@ class active_transactions final bool started{ false }; std::atomic stopped{ false }; - // Periodically check all elections - std::chrono::milliseconds const check_all_elections_period; - std::chrono::steady_clock::time_point last_check_all_elections{}; - // Maximum time an election can be kept active if it is extending the container std::chrono::seconds const election_time_to_live; - // Elections above this position in the queue are prioritized - size_t const prioritized_cutoff; - static size_t constexpr recently_confirmed_size{ 65536 }; using recent_confirmation = std::pair; // clang-format off diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 1a1ba60005..4d6ee1611c 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -563,15 +563,6 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction void nano::block_processor::process_old (nano::transaction const & transaction_a, std::shared_ptr const & block_a, nano::block_origin const origin_a) { node.active.restart (transaction_a, block_a); - // First try to update election difficulty, then attempt to restart an election - if (!node.active.update_difficulty (block_a, true)) - { - // Let others know about the difficulty update - if (origin_a == nano::block_origin::local) - { - node.network.flood_block_initial (block_a); - } - } } void nano::block_processor::queue_unchecked (nano::write_transaction const & transaction_a, nano::hash_or_account const & hash_or_account_a) diff --git a/nano/node/election.cpp b/nano/node/election.cpp index 5b1fee6b41..e65122d2e7 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -18,10 +18,9 @@ nano::election_vote_result::election_vote_result (bool replay_a, bool processed_ processed = processed_a; } -nano::election::election (nano::node & node_a, std::shared_ptr const & block_a, std::function const &)> const & confirmation_action_a, std::function const & live_vote_action_a, bool prioritized_a, nano::election_behavior election_behavior_a) : +nano::election::election (nano::node & node_a, std::shared_ptr const & block_a, std::function const &)> const & confirmation_action_a, std::function const & live_vote_action_a, nano::election_behavior election_behavior_a) : confirmation_action (confirmation_action_a), live_vote_action (live_vote_action_a), - prioritized_m (prioritized_a), behavior (election_behavior_a), node (node_a), status ({ block_a, 0, std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()), std::chrono::duration_values::zero (), 0, 1, 0, nano::election_status_type::ongoing }), @@ -31,6 +30,10 @@ nano::election::election (nano::node & node_a, std::shared_ptr cons { last_votes.emplace (node.network_params.random.not_an_account, nano::vote_info{ std::chrono::steady_clock::now (), 0, block_a->hash () }); last_blocks.emplace (block_a->hash (), block_a); + if (node.config.enable_voting && node.wallets.reps ().voting > 0) + { + node.active.generator.add (root, block_a->hash ()); + } } void nano::election::confirm_once (nano::unique_lock & lock_a, nano::election_status_type type_a) @@ -454,28 +457,11 @@ size_t nano::election::insert_inactive_votes_cache (nano::inactive_cache_informa return cache_a.voters.size (); } -bool nano::election::prioritized () const -{ - return prioritized_m; -} - bool nano::election::optimistic () const { return behavior == nano::election_behavior::optimistic; } -void nano::election::prioritize (nano::vote_generator_session & generator_session_a) -{ - debug_assert (!prioritized_m); - if (!prioritized_m.exchange (true)) - { - if (node.config.enable_voting && node.wallets.reps ().voting > 0) - { - node.active.generator.add (root, winner ()->hash ()); - } - } -} - nano::election_extended_status nano::election::current_status () const { nano::lock_guard guard (mutex); diff --git a/nano/node/election.hpp b/nano/node/election.hpp index b638d25a36..3584a10379 100644 --- a/nano/node/election.hpp +++ b/nano/node/election.hpp @@ -88,7 +88,6 @@ class election final : public std::enable_shared_from_this bool valid_change (nano::election::state_t, nano::election::state_t) const; bool state_change (nano::election::state_t, nano::election::state_t); - std::atomic prioritized_m = { false }; public: // State transitions bool transition_time (nano::confirmation_solicitor &); @@ -97,7 +96,6 @@ class election final : public std::enable_shared_from_this public: // Status bool confirmed () const; bool failed () const; - bool prioritized () const; bool optimistic () const; nano::election_extended_status current_status () const; std::shared_ptr winner () const; @@ -111,14 +109,13 @@ class election final : public std::enable_shared_from_this nano::election_status status; public: // Interface - election (nano::node &, std::shared_ptr const &, std::function const &)> const &, std::function const &, bool, nano::election_behavior); + election (nano::node &, std::shared_ptr const &, std::function const &)> const &, std::function const &, nano::election_behavior); std::shared_ptr find (nano::block_hash const &) const; nano::election_vote_result vote (nano::account const &, uint64_t, nano::block_hash const &); bool publish (std::shared_ptr const & block_a); size_t insert_inactive_votes_cache (nano::inactive_cache_information const &); // Confirm this block if quorum is met void confirm_if_quorum (nano::unique_lock &); - void prioritize (nano::vote_generator_session &); nano::election_cleanup_info cleanup_info () const; public: // Information diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index b76b802001..a6716ecd1d 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -1009,33 +1009,6 @@ void nano::json_handler::accounts_pending () response_errors (); } -void nano::json_handler::active_difficulty () -{ - auto include_trend (request.get ("include_trend", false)); - auto const multiplier_active = node.active.active_multiplier (); - auto const default_difficulty (node.default_difficulty (nano::work_version::work_1)); - auto const default_receive_difficulty (node.default_receive_difficulty (nano::work_version::work_1)); - auto const receive_current_denormalized (nano::denormalized_multiplier (multiplier_active, node.network_params.network.publish_thresholds.epoch_2_receive)); - response_l.put ("network_minimum", nano::to_string_hex (default_difficulty)); - response_l.put ("network_receive_minimum", nano::to_string_hex (default_receive_difficulty)); - response_l.put ("network_current", nano::to_string_hex (nano::difficulty::from_multiplier (multiplier_active, default_difficulty))); - response_l.put ("network_receive_current", nano::to_string_hex (nano::difficulty::from_multiplier (receive_current_denormalized, default_receive_difficulty))); - response_l.put ("multiplier", multiplier_active); - if (include_trend) - { - boost::property_tree::ptree trend_entry_l; - auto trend_l (node.active.difficulty_trend ()); - for (auto multiplier_l : trend_l) - { - boost::property_tree::ptree entry; - entry.put ("", nano::to_string (multiplier_l)); - trend_entry_l.push_back (std::make_pair ("", entry)); - } - response_l.add_child ("difficulty_trend", trend_entry_l); - } - response_errors (); -} - void nano::json_handler::available_supply () { auto genesis_balance (node.balance (node.network_params.ledger.genesis_account)); // Cold storage genesis @@ -3790,7 +3763,7 @@ void nano::json_handler::telemetry () if (address.is_loopback () && port == rpc_l->node.network.endpoint ().port ()) { // Requesting telemetry metrics locally - auto telemetry_data = nano::local_telemetry_data (rpc_l->node.ledger, rpc_l->node.network, rpc_l->node.config.bandwidth_limit, rpc_l->node.network_params, rpc_l->node.startup_time, rpc_l->node.active.active_difficulty (), rpc_l->node.node_id); + auto telemetry_data = nano::local_telemetry_data (rpc_l->node.ledger, rpc_l->node.network, rpc_l->node.config.bandwidth_limit, rpc_l->node.network_params, rpc_l->node.startup_time, rpc_l->node.default_difficulty (nano::work_version::work_1), rpc_l->node.node_id); nano::jsonconfig config_l; auto const should_ignore_identification_metrics = false; @@ -5077,7 +5050,6 @@ ipc_json_handler_no_arg_func_map create_ipc_json_handler_no_arg_func_map () no_arg_funcs.emplace ("accounts_create", &nano::json_handler::accounts_create); no_arg_funcs.emplace ("accounts_frontiers", &nano::json_handler::accounts_frontiers); no_arg_funcs.emplace ("accounts_pending", &nano::json_handler::accounts_pending); - no_arg_funcs.emplace ("active_difficulty", &nano::json_handler::active_difficulty); no_arg_funcs.emplace ("available_supply", &nano::json_handler::available_supply); no_arg_funcs.emplace ("block_info", &nano::json_handler::block_info); no_arg_funcs.emplace ("block", &nano::json_handler::block_info); diff --git a/nano/node/json_handler.hpp b/nano/node/json_handler.hpp index 67c6380110..ba229634e7 100644 --- a/nano/node/json_handler.hpp +++ b/nano/node/json_handler.hpp @@ -43,7 +43,6 @@ class json_handler : public std::enable_shared_from_this void accounts_create (); void accounts_frontiers (); void accounts_pending (); - void active_difficulty (); void available_supply (); void block_info (); void block_confirm (); diff --git a/nano/node/network.cpp b/nano/node/network.cpp index 93b7556456..2a8b53aefa 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -505,7 +505,7 @@ class network_message_visitor : public nano::message_visitor nano::telemetry_ack telemetry_ack; if (!node.flags.disable_providing_telemetry_metrics) { - auto telemetry_data = nano::local_telemetry_data (node.ledger, node.network, node.config.bandwidth_limit, node.network_params, node.startup_time, node.active.active_difficulty (), node.node_id); + auto telemetry_data = nano::local_telemetry_data (node.ledger, node.network, node.config.bandwidth_limit, node.network_params, node.startup_time, node.default_difficulty (nano::work_version::work_1), node.node_id); telemetry_ack = nano::telemetry_ack (telemetry_data); } channel->send (telemetry_ack, nullptr, nano::buffer_drop_policy::no_socket_drop); From 519714fc3cb5ebabd58bec8c406a3cb37e2cd7c8 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Fri, 30 Apr 2021 16:10:59 +0300 Subject: [PATCH 2/9] Remove active transactions difficulty sorting (draft in progress) --- nano/lib/threading.cpp | 3 - nano/lib/threading.hpp | 1 - nano/node/active_transactions.cpp | 6 +- nano/node/blockprocessor.cpp | 47 +++---- nano/node/blockprocessor.hpp | 14 +- nano/node/json_handler.cpp | 5 +- nano/node/node.cpp | 8 +- nano/node/node.hpp | 4 +- nano/node/nodeconfig.cpp | 21 +-- nano/node/nodeconfig.hpp | 1 - .../state_block_signature_verification.cpp | 8 +- .../state_block_signature_verification.hpp | 4 +- nano/node/testing.cpp | 1 - nano/node/wallet.cpp | 122 +----------------- nano/node/wallet.hpp | 23 ---- 15 files changed, 45 insertions(+), 223 deletions(-) diff --git a/nano/lib/threading.cpp b/nano/lib/threading.cpp index e1f474162e..df17fda901 100644 --- a/nano/lib/threading.cpp +++ b/nano/lib/threading.cpp @@ -48,9 +48,6 @@ std::string nano::thread_role::get_string (nano::thread_role::name role) case nano::thread_role::name::wallet_actions: thread_role_name_string = "Wallet actions"; break; - case nano::thread_role::name::work_watcher: - thread_role_name_string = "Work watcher"; - break; case nano::thread_role::name::bootstrap_initiator: thread_role_name_string = "Bootstrap init"; break; diff --git a/nano/lib/threading.hpp b/nano/lib/threading.hpp index 3d9c5ddb33..dd7112bd90 100644 --- a/nano/lib/threading.hpp +++ b/nano/lib/threading.hpp @@ -32,7 +32,6 @@ namespace thread_role signature_checking, rpc_request_processor, rpc_process_container, - work_watcher, confirmation_height_processing, worker, request_aggregator, diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index b72cab4ed8..3b53117c82 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -300,10 +300,6 @@ void nano::active_transactions::request_confirm (nano::unique_lock size_t unconfirmed_count_l (0); nano::timer elapsed (nano::timer_state::started); - auto const is_watched = [watched = node.wallets.watcher->list_watched ()] (nano::qualified_root const & root_a) -> bool { - return watched.find (root_a) != watched.end (); - }; - /* * Loop through active elections in descending order of proof-of-work difficulty, requesting confirmation * @@ -316,7 +312,7 @@ void nano::active_transactions::request_confirm (nano::unique_lock bool const confirmed_l (election_l->confirmed ()); unconfirmed_count_l += !confirmed_l; - bool const overflow_l (unconfirmed_count_l > node.config.active_elections_size && election_l->election_start < election_ttl_cutoff_l && !is_watched (election_l->qualified_root)); + bool const overflow_l (unconfirmed_count_l > node.config.active_elections_size && election_l->election_start < election_ttl_cutoff_l); if (overflow_l || election_l->transition_time (solicitor)) { if (election_l->optimistic () && election_l->failed ()) diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 4d6ee1611c..3ab98637b6 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -31,7 +31,7 @@ nano::block_processor::block_processor (nano::node & node_a, nano::write_databas write_database_queue (write_database_queue_a), state_block_signature_verification (node.checker, node.ledger.network_params.ledger.epochs, node.config, node.logger, node.flags.block_processor_verification_size) { - state_block_signature_verification.blocks_verified_callback = [this] (std::deque> & items, std::vector const & verifications, std::vector const & hashes, std::vector const & blocks_signatures) { + state_block_signature_verification.blocks_verified_callback = [this] (std::deque & items, std::vector const & verifications, std::vector const & hashes, std::vector const & blocks_signatures) { this->process_verified_state_blocks (items, verifications, hashes, blocks_signatures); }; state_block_signature_verification.transition_inactive_callback = [this] () { @@ -109,7 +109,7 @@ void nano::block_processor::add (nano::unchecked_info const & info_a, const bool bool quarter_full (size () > node.flags.block_processor_full_size / 4); if (info_a.verified == nano::signature_verification::unknown && (info_a.block->type () == nano::block_type::state || info_a.block->type () == nano::block_type::open || !info_a.account.is_zero ())) { - state_block_signature_verification.add (info_a, false); + state_block_signature_verification.add (info_a); } else if (push_front_preference_a && !quarter_full) { @@ -118,7 +118,7 @@ void nano::block_processor::add (nano::unchecked_info const & info_a, const bool If deque is a quarter full then push back to allow other blocks processing. */ { nano::lock_guard guard (mutex); - blocks.emplace_front (info_a, false); + blocks.emplace_front (info_a); } condition.notify_all (); } @@ -126,17 +126,17 @@ void nano::block_processor::add (nano::unchecked_info const & info_a, const bool { { nano::lock_guard guard (mutex); - blocks.emplace_front (info_a, false); + blocks.emplace_front (info_a); } condition.notify_all (); } } -void nano::block_processor::add_local (nano::unchecked_info const & info_a, bool const watch_work_a) +void nano::block_processor::add_local (nano::unchecked_info const & info_a) { release_assert (info_a.verified == nano::signature_verification::unknown && (info_a.block->type () == nano::block_type::state || !info_a.account.is_zero ())); debug_assert (!nano::work_validate_entry (*info_a.block)); - state_block_signature_verification.add (info_a, watch_work_a); + state_block_signature_verification.add (info_a); } void nano::block_processor::force (std::shared_ptr const & block_a) @@ -208,34 +208,34 @@ bool nano::block_processor::have_blocks () return have_blocks_ready () || state_block_signature_verification.size () != 0; } -void nano::block_processor::process_verified_state_blocks (std::deque> & items, std::vector const & verifications, std::vector const & hashes, std::vector const & blocks_signatures) +void nano::block_processor::process_verified_state_blocks (std::deque & items, std::vector const & verifications, std::vector const & hashes, std::vector const & blocks_signatures) { { nano::unique_lock lk (mutex); for (auto i (0); i < verifications.size (); ++i) { debug_assert (verifications[i] == 1 || verifications[i] == 0); - auto & [item, watch_work] = items.front (); + auto & item = items.front (); if (!item.block->link ().is_zero () && node.ledger.is_epoch_link (item.block->link ())) { // Epoch blocks if (verifications[i] == 1) { item.verified = nano::signature_verification::valid_epoch; - blocks.emplace_back (std::move (item), watch_work); + blocks.emplace_back (std::move (item)); } else { // Possible regular state blocks with epoch link (send subtype) item.verified = nano::signature_verification::unknown; - blocks.emplace_back (std::move (item), watch_work); + blocks.emplace_back (std::move (item)); } } else if (verifications[i] == 1) { // Non epoch blocks item.verified = nano::signature_verification::valid; - blocks.emplace_back (std::move (item), watch_work); + blocks.emplace_back (std::move (item)); } else { @@ -266,7 +266,6 @@ void nano::block_processor::process_batch (nano::unique_lock & lock { node.logger.always_log (boost::str (boost::format ("%1% blocks (+ %2% state blocks) (+ %3% forced, %4% updates) in processing queue") % blocks.size () % state_block_signature_verification.size () % forced.size () % updates.size ())); } - bool watch_work{ false }; if (!updates.empty ()) { auto block (updates.front ()); @@ -286,7 +285,7 @@ void nano::block_processor::process_batch (nano::unique_lock & lock bool force (false); if (forced.empty ()) { - std::tie (info, watch_work) = blocks.front (); + info = blocks.front (); blocks.pop_front (); hash = info.block->hash (); } @@ -318,11 +317,10 @@ void nano::block_processor::process_batch (nano::unique_lock & lock { node.logger.always_log (boost::str (boost::format ("%1% blocks rolled back") % rollback_list.size ())); } - // Deleting from votes cache & wallet work watcher, stop active transaction + // Deleting from votes cache, stop active transaction for (auto & i : rollback_list) { node.history.erase (i->root ()); - node.wallets.watcher->remove (*i); // Stop all rolled back active transactions except initial if (i->hash () != successor->hash ()) { @@ -332,7 +330,7 @@ void nano::block_processor::process_batch (nano::unique_lock & lock } } number_of_blocks_processed++; - process_one (transaction, post_events, info, watch_work, force); + process_one (transaction, post_events, info, force); } lock_a.lock (); } @@ -345,16 +343,11 @@ void nano::block_processor::process_batch (nano::unique_lock & lock } } -void nano::block_processor::process_live (nano::transaction const & transaction_a, nano::block_hash const & hash_a, std::shared_ptr const & block_a, nano::process_return const & process_return_a, const bool watch_work_a, nano::block_origin const origin_a) +void nano::block_processor::process_live (nano::transaction const & transaction_a, nano::block_hash const & hash_a, std::shared_ptr const & block_a, nano::process_return const & process_return_a, nano::block_origin const origin_a) { - // Add to work watcher to prevent dropping the election - if (watch_work_a) - { - node.wallets.watcher->add (block_a); - } // Start collecting quorum on block - if (watch_work_a || node.ledger.dependents_confirmed (transaction_a, *block_a)) + if (node.ledger.dependents_confirmed (transaction_a, *block_a)) { auto account = block_a->account ().is_zero () ? block_a->sideband ().account : block_a->account (); node.scheduler.activate (account, transaction_a); @@ -376,7 +369,7 @@ void nano::block_processor::process_live (nano::transaction const & transaction_ } } -nano::process_return nano::block_processor::process_one (nano::write_transaction const & transaction_a, block_post_events & events_a, nano::unchecked_info info_a, const bool watch_work_a, const bool forced_a, nano::block_origin const origin_a) +nano::process_return nano::block_processor::process_one (nano::write_transaction const & transaction_a, block_post_events & events_a, nano::unchecked_info info_a, const bool forced_a, nano::block_origin const origin_a) { nano::process_return result; auto block (info_a.block); @@ -395,7 +388,7 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction } if ((info_a.modified > nano::seconds_since_epoch () - 300 && node.block_arrival.recent (hash)) || forced_a) { - events_a.events.emplace_back ([this, hash, block = info_a.block, result, watch_work_a, origin_a] (nano::transaction const & post_event_transaction_a) { process_live (post_event_transaction_a, hash, block, result, watch_work_a, origin_a); }); + events_a.events.emplace_back ([this, hash, block = info_a.block, result, origin_a] (nano::transaction const & post_event_transaction_a) { process_live (post_event_transaction_a, hash, block, result, origin_a); }); } queue_unchecked (transaction_a, hash); /* For send blocks check epoch open unchecked (gap pending). @@ -553,10 +546,10 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction return result; } -nano::process_return nano::block_processor::process_one (nano::write_transaction const & transaction_a, block_post_events & events_a, std::shared_ptr const & block_a, const bool watch_work_a) +nano::process_return nano::block_processor::process_one (nano::write_transaction const & transaction_a, block_post_events & events_a, std::shared_ptr const & block_a) { nano::unchecked_info info (block_a, block_a->account (), 0, nano::signature_verification::unknown); - auto result (process_one (transaction_a, events_a, info, watch_work_a)); + auto result (process_one (transaction_a, events_a, info)); return result; } diff --git a/nano/node/blockprocessor.hpp b/nano/node/blockprocessor.hpp index 59dbaf784a..63eee40738 100644 --- a/nano/node/blockprocessor.hpp +++ b/nano/node/blockprocessor.hpp @@ -54,8 +54,8 @@ class block_processor final size_t size (); bool full (); bool half_full (); - void add_local (nano::unchecked_info const & info_a, bool const = false); - void add (nano::unchecked_info const &, bool const = false); + void add_local (nano::unchecked_info const & info_a); + void add (nano::unchecked_info const &, const bool = false); void add (std::shared_ptr const &, uint64_t = 0); void force (std::shared_ptr const &); void update (std::shared_ptr const &); @@ -64,8 +64,8 @@ class block_processor final bool have_blocks_ready (); bool have_blocks (); void process_blocks (); - nano::process_return process_one (nano::write_transaction const &, block_post_events &, nano::unchecked_info, const bool = false, const bool = false, nano::block_origin const = nano::block_origin::remote); - nano::process_return process_one (nano::write_transaction const &, block_post_events &, std::shared_ptr const &, const bool = false); + nano::process_return process_one (nano::write_transaction const &, block_post_events &, nano::unchecked_info, const bool = false, nano::block_origin const = nano::block_origin::remote); + nano::process_return process_one (nano::write_transaction const &, block_post_events &, std::shared_ptr const &); std::atomic flushing{ false }; // Delay required for average network propagartion before requesting confirmation static std::chrono::milliseconds constexpr confirmation_request_delay{ 1500 }; @@ -73,15 +73,15 @@ class block_processor final private: void queue_unchecked (nano::write_transaction const &, nano::hash_or_account const &); void process_batch (nano::unique_lock &); - void process_live (nano::transaction const &, nano::block_hash const &, std::shared_ptr const &, nano::process_return const &, const bool = false, nano::block_origin const = nano::block_origin::remote); + void process_live (nano::transaction const &, nano::block_hash const &, std::shared_ptr const &, nano::process_return const &, nano::block_origin const = nano::block_origin::remote); void process_old (nano::transaction const &, std::shared_ptr const &, nano::block_origin const); void requeue_invalid (nano::block_hash const &, nano::unchecked_info const &); - void process_verified_state_blocks (std::deque> &, std::vector const &, std::vector const &, std::vector const &); + void process_verified_state_blocks (std::deque &, std::vector const &, std::vector const &, std::vector const &); bool stopped{ false }; bool active{ false }; bool awaiting_write{ false }; std::chrono::steady_clock::time_point next_log; - std::deque> blocks; + std::deque blocks; std::deque> forced; std::deque> updates; nano::condition_variable condition; diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index a6716ecd1d..9fea70fc3d 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -2960,7 +2960,6 @@ void nano::json_handler::pending_exists () void nano::json_handler::process () { node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { - const bool watch_work_l = rpc_l->request.get ("watch_work", true); const bool is_async = rpc_l->request.get ("async", false); auto block (rpc_l->block_impl (true)); @@ -3037,7 +3036,7 @@ void nano::json_handler::process () { if (!is_async) { - auto result (rpc_l->node.process_local (block, watch_work_l)); + auto result (rpc_l->node.process_local (block)); switch (result.code) { case nano::process_result::progress: @@ -3122,7 +3121,7 @@ void nano::json_handler::process () { if (block->type () == nano::block_type::state) { - rpc_l->node.process_local_async (block, watch_work_l); + rpc_l->node.process_local_async (block); rpc_l->response_l.put ("started", "1"); } else diff --git a/nano/node/node.cpp b/nano/node/node.cpp index d9db6639e0..5f9033fbe1 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -573,7 +573,7 @@ nano::process_return nano::node::process (nano::block & block_a) return result; } -nano::process_return nano::node::process_local (std::shared_ptr const & block_a, bool const work_watcher_a) +nano::process_return nano::node::process_local (std::shared_ptr const & block_a) { // Add block hash as recently arrived to trigger automatic rebroadcast and election block_arrival.add (block_a->hash ()); @@ -584,16 +584,16 @@ nano::process_return nano::node::process_local (std::shared_ptr con // Process block block_post_events post_events ([&store = store] { return store.tx_begin_read (); }); auto transaction (store.tx_begin_write ({ tables::accounts, tables::blocks, tables::frontiers, tables::pending })); - return block_processor.process_one (transaction, post_events, info, work_watcher_a, false, nano::block_origin::local); + return block_processor.process_one (transaction, post_events, info, false, nano::block_origin::local); } -void nano::node::process_local_async (std::shared_ptr const & block_a, bool const work_watcher_a) +void nano::node::process_local_async (std::shared_ptr const & block_a) { // Add block hash as recently arrived to trigger automatic rebroadcast and election block_arrival.add (block_a->hash ()); // Set current time to trigger automatic rebroadcast and election nano::unchecked_info info (block_a, block_a->account (), nano::seconds_since_epoch (), nano::signature_verification::unknown); - block_processor.add_local (info, work_watcher_a); + block_processor.add_local (info); } void nano::node::start () diff --git a/nano/node/node.hpp b/nano/node/node.hpp index 31ae3ac053..4d97785445 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -104,8 +104,8 @@ class node final : public std::enable_shared_from_this void process_confirmed (nano::election_status const &, uint64_t = 0); void process_active (std::shared_ptr const &); nano::process_return process (nano::block &); - nano::process_return process_local (std::shared_ptr const &, bool const = false); - void process_local_async (std::shared_ptr const &, bool const = false); + nano::process_return process_local (std::shared_ptr const &); + void process_local_async (std::shared_ptr const &); void keepalive_preconfigured (std::vector const &); nano::block_hash latest (nano::account const &); nano::uint128_t balance (nano::account const &); diff --git a/nano/node/nodeconfig.cpp b/nano/node/nodeconfig.cpp index 03cb9f312c..e2b2df364a 100644 --- a/nano/node/nodeconfig.cpp +++ b/nano/node/nodeconfig.cpp @@ -107,7 +107,6 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const toml.put ("bandwidth_limit_burst_ratio", bandwidth_limit_burst_ratio, "Burst ratio for outbound traffic shaping.\ntype:double"); toml.put ("conf_height_processor_batch_min_time", conf_height_processor_batch_min_time.count (), "Minimum write batching time when there are blocks pending confirmation height.\ntype:milliseconds"); toml.put ("backup_before_upgrade", backup_before_upgrade, "Backup the ledger database before performing upgrades.\nWarning: uses more disk storage and increases startup time when upgrading.\ntype:bool"); - toml.put ("work_watcher_period", work_watcher_period.count (), "Time between checks for confirmation and re-generating higher difficulty work if unconfirmed, for blocks in the work watcher.\ntype:seconds"); toml.put ("max_work_generate_multiplier", max_work_generate_multiplier, "Maximum allowed difficulty multiplier for work generation.\ntype:double,[1..]"); toml.put ("frontiers_confirmation", serialize_frontiers_confirmation (frontiers_confirmation), "Mode controlling frontier confirmation rate.\ntype:string,{auto,always,disabled}"); toml.put ("max_queued_requests", max_queued_requests, "Limit for number of queued confirmation requests for one channel, after which new requests are dropped until the queue drops below this value.\ntype:uint32"); @@ -363,10 +362,6 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml) toml.get ("bandwidth_limit_burst_ratio", bandwidth_limit_burst_ratio); toml.get ("backup_before_upgrade", backup_before_upgrade); - auto work_watcher_period_l = work_watcher_period.count (); - toml.get ("work_watcher_period", work_watcher_period_l); - work_watcher_period = std::chrono::seconds (work_watcher_period_l); - auto conf_height_processor_batch_min_time_l (conf_height_processor_batch_min_time.count ()); toml.get ("conf_height_processor_batch_min_time", conf_height_processor_batch_min_time_l); conf_height_processor_batch_min_time = std::chrono::milliseconds (conf_height_processor_batch_min_time_l); @@ -425,10 +420,6 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml) { toml.get_error ().set ("vote_generator_threshold must be a number between 1 and 11"); } - if (work_watcher_period < std::chrono::seconds (1)) - { - toml.get_error ().set ("work_watcher_period must be equal or larger than 1"); - } if (max_work_generate_multiplier < 1) { toml.get_error ().set ("max_work_generate_multiplier must be greater than or equal to 1"); @@ -531,7 +522,7 @@ nano::error nano::node_config::serialize_json (nano::jsonconfig & json) const json.put ("active_elections_size", active_elections_size); json.put ("bandwidth_limit", bandwidth_limit); json.put ("backup_before_upgrade", backup_before_upgrade); - json.put ("work_watcher_period", work_watcher_period.count ()); + json.put ("work_watcher_period", 5); return json.get_error (); } @@ -563,7 +554,7 @@ bool nano::node_config::upgrade_json (unsigned version_a, nano::jsonconfig & jso json.put ("active_elections_size", 10000); // Update value json.put ("vote_generator_delay", 100); // Update value json.put ("backup_before_upgrade", backup_before_upgrade); - json.put ("work_watcher_period", work_watcher_period.count ()); + json.put ("work_watcher_period", 5); } case 18: break; @@ -707,10 +698,6 @@ nano::error nano::node_config::deserialize_json (bool & upgraded_a, nano::jsonco json.get ("bandwidth_limit", bandwidth_limit); json.get ("backup_before_upgrade", backup_before_upgrade); - auto work_watcher_period_l = work_watcher_period.count (); - json.get ("work_watcher_period", work_watcher_period_l); - work_watcher_period = std::chrono::seconds (work_watcher_period_l); - auto conf_height_processor_batch_min_time_l (conf_height_processor_batch_min_time.count ()); json.get ("conf_height_processor_batch_min_time", conf_height_processor_batch_min_time_l); conf_height_processor_batch_min_time = std::chrono::milliseconds (conf_height_processor_batch_min_time_l); @@ -737,10 +724,6 @@ nano::error nano::node_config::deserialize_json (bool & upgraded_a, nano::jsonco { json.get_error ().set ("vote_generator_threshold must be a number between 1 and 11"); } - if (work_watcher_period < std::chrono::seconds (1)) - { - json.get_error ().set ("work_watcher_period must be equal or larger than 1"); - } } catch (std::runtime_error const & ex) { diff --git a/nano/node/nodeconfig.hpp b/nano/node/nodeconfig.hpp index b8070ccc30..4620795a60 100644 --- a/nano/node/nodeconfig.hpp +++ b/nano/node/nodeconfig.hpp @@ -97,7 +97,6 @@ class node_config double bandwidth_limit_burst_ratio{ 3. }; std::chrono::milliseconds conf_height_processor_batch_min_time{ 50 }; bool backup_before_upgrade{ false }; - std::chrono::seconds work_watcher_period{ std::chrono::seconds (5) }; double max_work_generate_multiplier{ 64. }; uint32_t max_queued_requests{ 512 }; /** Maximum amount of confirmation requests (batches) to be sent to each channel */ diff --git a/nano/node/state_block_signature_verification.cpp b/nano/node/state_block_signature_verification.cpp index 6e14dd0584..94a49b0387 100644 --- a/nano/node/state_block_signature_verification.cpp +++ b/nano/node/state_block_signature_verification.cpp @@ -74,11 +74,11 @@ bool nano::state_block_signature_verification::is_active () return active; } -void nano::state_block_signature_verification::add (nano::unchecked_info const & info_a, bool watch_work_a) +void nano::state_block_signature_verification::add (nano::unchecked_info const & info_a) { { nano::lock_guard guard (mutex); - state_blocks.emplace_back (info_a, watch_work_a); + state_blocks.emplace_back (info_a); } condition.notify_one (); } @@ -89,7 +89,7 @@ size_t nano::state_block_signature_verification::size () return state_blocks.size (); } -std::deque> nano::state_block_signature_verification::setup_items (size_t max_count) +std::deque nano::state_block_signature_verification::setup_items (size_t max_count) { std::deque> items; if (state_blocks.size () <= max_count) @@ -131,7 +131,7 @@ void nano::state_block_signature_verification::verify_state_blocks (std::deque verifications; verifications.resize (size, 0); - for ([[maybe_unused]] auto & [item, watch_work] : items) + for (auto & item : items) { hashes.push_back (item.block->hash ()); messages.push_back (hashes.back ().bytes.data ()); diff --git a/nano/node/state_block_signature_verification.hpp b/nano/node/state_block_signature_verification.hpp index 8a486f56db..a69d1dd22b 100644 --- a/nano/node/state_block_signature_verification.hpp +++ b/nano/node/state_block_signature_verification.hpp @@ -19,12 +19,12 @@ class state_block_signature_verification public: state_block_signature_verification (nano::signature_checker &, nano::epochs &, nano::node_config &, nano::logger_mt &, uint64_t); ~state_block_signature_verification (); - void add (nano::unchecked_info const & info_a, bool watch_work_a); + void add (nano::unchecked_info const & info_a); size_t size (); void stop (); bool is_active (); - std::function> &, std::vector const &, std::vector const &, std::vector const &)> blocks_verified_callback; + std::function &, std::vector const &, std::vector const &, std::vector const &)> blocks_verified_callback; std::function transition_inactive_callback; private: diff --git a/nano/node/testing.cpp b/nano/node/testing.cpp index 78fb6d1e13..c0e8341bf2 100644 --- a/nano/node/testing.cpp +++ b/nano/node/testing.cpp @@ -340,7 +340,6 @@ void nano::system::generate_rollback (nano::node & node_a, std::vectorremove (*i); node_a.active.erase (*i); } } diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index cededd746b..d1b5f5ed89 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1049,8 +1049,7 @@ bool nano::wallet::action_complete (std::shared_ptr const & block_a { wallets.node.logger.try_log (boost::str (boost::format ("Cached or provided work for block %1% account %2% is invalid, regenerating") % block_a->hash ().to_string () % account_a.to_account ())); debug_assert (required_difficulty <= wallets.node.max_work_generate_difficulty (block_a->work_version ())); - auto target_difficulty = std::max (required_difficulty, wallets.node.active.limited_active_difficulty (block_a->work_version (), required_difficulty)); - error = !wallets.node.work_generate_blocking (*block_a, target_difficulty).is_initialized (); + error = !wallets.node.work_generate_blocking (*block_a, required_difficulty).is_initialized (); } if (!error) { @@ -1319,121 +1318,6 @@ void nano::wallet::work_cache_blocking (nano::account const & account_a, nano::r } } -nano::work_watcher::work_watcher (nano::node & node_a) : - node (node_a), - stopped (false) -{ - node.observers.blocks.add ([this] (nano::election_status const & status_a, std::vector const & votes_a, nano::account const & account_a, nano::amount const & amount_a, bool is_state_send_a) { - this->remove (*status_a.winner); - }); -} - -nano::work_watcher::~work_watcher () -{ - stop (); -} - -void nano::work_watcher::stop () -{ - nano::unique_lock lock (mutex); - watched.clear (); - stopped = true; -} - -void nano::work_watcher::add (std::shared_ptr const & block_a) -{ - auto block_l (std::dynamic_pointer_cast (block_a)); - if (!stopped && block_l != nullptr) - { - auto root_l (block_l->qualified_root ()); - nano::unique_lock lock (mutex); - watched[root_l] = block_l; - lock.unlock (); - watching (root_l, block_l); - } -} - -void nano::work_watcher::update (nano::qualified_root const & root_a, std::shared_ptr const & block_a) -{ - nano::lock_guard guard (mutex); - watched[root_a] = block_a; -} - -void nano::work_watcher::watching (nano::qualified_root const & root_a, std::shared_ptr const & block_a) -{ - std::weak_ptr watcher_w (shared_from_this ()); - node.workers.add_timed_task (std::chrono::steady_clock::now () + node.config.work_watcher_period, [block_a, root_a, watcher_w] () { - auto watcher_l = watcher_w.lock (); - if (watcher_l && !watcher_l->stopped && watcher_l->is_watched (root_a)) - { - auto active_difficulty (watcher_l->node.active.limited_active_difficulty (*block_a)); - /* - * Work watcher should still watch blocks even without work generation, although no rework is done - * Functionality may be added in the future that does not require updating work - */ - if (active_difficulty > block_a->difficulty () && watcher_l->node.work_generation_enabled ()) - { - watcher_l->node.work_generate ( - block_a->work_version (), block_a->root (), active_difficulty, [watcher_l, block_a, root_a] (boost::optional work_a) { - if (watcher_l->is_watched (root_a)) - { - if (work_a.is_initialized ()) - { - debug_assert (nano::work_difficulty (block_a->work_version (), block_a->root (), *work_a) > block_a->difficulty ()); - nano::state_block_builder builder; - std::error_code ec; - std::shared_ptr block (builder.from (*block_a).work (*work_a).build (ec)); - if (!ec) - { - watcher_l->node.network.flood_block_initial (block); - watcher_l->node.active.update_difficulty (block, false); - watcher_l->update (root_a, block); - } - } - watcher_l->watching (root_a, block_a); - } - }, - block_a->account ()); - } - else - { - watcher_l->watching (root_a, block_a); - } - } - }); -} - -void nano::work_watcher::remove (nano::block const & block_a) -{ - nano::unique_lock lock (mutex); - auto existing (watched.find (block_a.qualified_root ())); - if (existing != watched.end ()) - { - watched.erase (existing); - lock.unlock (); - node.observers.work_cancel.notify (block_a.root ()); - } -} - -bool nano::work_watcher::is_watched (nano::qualified_root const & root_a) -{ - nano::lock_guard guard (mutex); - auto exists (watched.find (root_a)); - return exists != watched.end (); -} - -auto nano::work_watcher::list_watched () -> decltype (watched) -{ - nano::lock_guard guard (mutex); - return watched; -} - -size_t nano::work_watcher::size () -{ - nano::lock_guard guard (mutex); - return watched.size (); -} - void nano::wallets::do_wallet_actions () { nano::unique_lock action_lock (action_mutex); @@ -1466,7 +1350,6 @@ nano::wallets::wallets (bool error_a, nano::node & node_a) : node (node_a), env (boost::polymorphic_downcast (node_a.wallets_store_impl.get ())->environment), stopped (false), - watcher (std::make_shared (node_a)), thread ([this] () { nano::thread_role::set (nano::thread_role::name::wallet_actions); do_wallet_actions (); @@ -1731,7 +1614,6 @@ void nano::wallets::stop () { thread.join (); } - watcher->stop (); } nano::write_transaction nano::wallets::tx_begin_write () @@ -1961,10 +1843,8 @@ std::unique_ptr nano::collect_container_info (wa auto sizeof_item_element = sizeof (decltype (wallets.items)::value_type); auto sizeof_actions_element = sizeof (decltype (wallets.actions)::value_type); - auto sizeof_watcher_element = sizeof (decltype (wallets.watcher->list_watched ())::value_type); auto composite = std::make_unique (name); composite->add_component (std::make_unique (container_info{ "items", items_count, sizeof_item_element })); composite->add_component (std::make_unique (container_info{ "actions", actions_count, sizeof_actions_element })); - composite->add_component (std::make_unique (container_info{ "work_watcher", wallets.watcher->size (), sizeof_watcher_element })); return composite; } diff --git a/nano/node/wallet.hpp b/nano/node/wallet.hpp index 7ff706a675..c52f5f600d 100644 --- a/nano/node/wallet.hpp +++ b/nano/node/wallet.hpp @@ -161,28 +161,6 @@ class wallet final : public std::enable_shared_from_this std::unordered_set representatives; }; -class work_watcher final : public std::enable_shared_from_this -{ - std::unordered_map> watched; - -public: - work_watcher (nano::node &); - ~work_watcher (); - void stop (); - void add (std::shared_ptr const &); - void update (nano::qualified_root const &, std::shared_ptr const &); - void watching (nano::qualified_root const &, std::shared_ptr const &); - void remove (nano::block const &); - bool is_watched (nano::qualified_root const &); - decltype (watched) list_watched (); - size_t size (); - -private: - nano::mutex mutex; - nano::node & node; - std::atomic stopped; -}; - class wallet_representatives { public: @@ -247,7 +225,6 @@ class wallets final nano::node & node; nano::mdb_env & env; std::atomic stopped; - std::shared_ptr watcher; std::thread thread; static nano::uint128_t const generate_priority; static nano::uint128_t const high_priority; From 7880f866cfea1e5a2e55f29e3998bceab2a6abd0 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Fri, 30 Apr 2021 16:54:05 +0300 Subject: [PATCH 3/9] Remove active transactions difficulty sorting (draft in progress) --- nano/node/state_block_signature_verification.cpp | 4 ++-- nano/node/state_block_signature_verification.hpp | 6 +++--- nano/node/wallet.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/nano/node/state_block_signature_verification.cpp b/nano/node/state_block_signature_verification.cpp index 94a49b0387..a8e61035fc 100644 --- a/nano/node/state_block_signature_verification.cpp +++ b/nano/node/state_block_signature_verification.cpp @@ -91,7 +91,7 @@ size_t nano::state_block_signature_verification::size () std::deque nano::state_block_signature_verification::setup_items (size_t max_count) { - std::deque> items; + std::deque items; if (state_blocks.size () <= max_count) { items.swap (state_blocks); @@ -108,7 +108,7 @@ std::deque nano::state_block_signature_verification::setup return items; } -void nano::state_block_signature_verification::verify_state_blocks (std::deque> & items) +void nano::state_block_signature_verification::verify_state_blocks (std::deque & items) { if (!items.empty ()) { diff --git a/nano/node/state_block_signature_verification.hpp b/nano/node/state_block_signature_verification.hpp index a69d1dd22b..05e66d801f 100644 --- a/nano/node/state_block_signature_verification.hpp +++ b/nano/node/state_block_signature_verification.hpp @@ -36,13 +36,13 @@ class state_block_signature_verification nano::mutex mutex{ mutex_identifier (mutexes::state_block_signature_verification) }; bool stopped{ false }; bool active{ false }; - std::deque> state_blocks; + std::deque state_blocks; nano::condition_variable condition; std::thread thread; void run (uint64_t block_processor_verification_size); - std::deque> setup_items (size_t); - void verify_state_blocks (std::deque> &); + std::deque setup_items (size_t); + void verify_state_blocks (std::deque &); }; std::unique_ptr collect_container_info (state_block_signature_verification & state_block_signature_verification, std::string const & name); diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index d1b5f5ed89..58ca89f1af 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1053,7 +1053,7 @@ bool nano::wallet::action_complete (std::shared_ptr const & block_a } if (!error) { - error = wallets.node.process_local (block_a, true).code != nano::process_result::progress; + error = wallets.node.process_local (block_a).code != nano::process_result::progress; debug_assert (error || block_a->sideband ().details == details_a); } if (!error && generate_work_a) From bf8de8399e377f56dad6aafccb2486e8e37a2286 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Fri, 30 Apr 2021 17:30:07 +0300 Subject: [PATCH 4/9] Fix core_test build --- nano/core_test/CMakeLists.txt | 1 - nano/core_test/active_transactions.cpp | 379 +--------------------- nano/core_test/confirmation_solicitor.cpp | 10 +- nano/core_test/conflicts.cpp | 33 -- nano/core_test/node.cpp | 56 +--- nano/core_test/telemetry.cpp | 10 +- nano/core_test/toml.cpp | 3 - nano/core_test/wallet.cpp | 38 --- nano/core_test/websocket.cpp | 72 +--- nano/core_test/work_watcher.cpp | 320 ------------------ 10 files changed, 21 insertions(+), 901 deletions(-) delete mode 100644 nano/core_test/work_watcher.cpp diff --git a/nano/core_test/CMakeLists.txt b/nano/core_test/CMakeLists.txt index 500576a456..51b55a32c6 100644 --- a/nano/core_test/CMakeLists.txt +++ b/nano/core_test/CMakeLists.txt @@ -45,7 +45,6 @@ add_executable( wallet.cpp wallets.cpp websocket.cpp - work_watcher.cpp work_pool.cpp) target_compile_definitions( diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index 94bd9773ee..14f291cd8f 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -967,381 +967,6 @@ TEST (active_transactions, confirmation_consistency) } } -TEST (active_transactions, insertion_prioritization) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - // 10% of elections (1) are prioritized - node_config.active_elections_size = 10; - nano::node_flags node_flags; - node_flags.disable_request_loop = true; - auto & node = *system.add_node (node_config, node_flags); - nano::state_block_builder builder; - auto send1 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (nano::genesis_hash) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 10 * nano::xrb_ratio) - .link (nano::public_key ()) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (nano::genesis_hash)) - .build_shared (); - auto send2 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (send1->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 20 * nano::xrb_ratio) - .link (nano::public_key ()) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send1->hash ())) - .build_shared (); - auto send3 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (send2->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 30 * nano::xrb_ratio) - .link (nano::public_key ()) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send2->hash ())) - .build_shared (); - auto send4 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (send3->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 40 * nano::xrb_ratio) - .link (nano::public_key ()) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send3->hash ())) - .build_shared (); - auto send5 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (send4->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 50 * nano::xrb_ratio) - .link (nano::public_key ()) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send4->hash ())) - .build_shared (); - auto send6 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (send5->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 60 * nano::xrb_ratio) - .link (nano::public_key ()) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send5->hash ())) - .build_shared (); - auto send7 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (send6->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 70 * nano::xrb_ratio) - .link (nano::public_key ()) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send6->hash ())) - .build_shared (); - // Sort by difficulty, descending - std::vector> blocks{ send1, send2, send3, send4, send5, send6, send7 }; - for (auto const & block : blocks) - { - ASSERT_EQ (nano::process_result::progress, node.process (*block).code); - } - std::sort (blocks.begin (), blocks.end (), [] (auto const & blockl, auto const & blockr) { return blockl->difficulty () > blockr->difficulty (); }); - - auto update_active_multiplier = [&node] { - nano::unique_lock lock (node.active.mutex); - node.active.update_active_multiplier (lock); - }; - - node.block_confirm (blocks[2]); - node.scheduler.flush (); - ASSERT_TRUE (node.active.election (blocks[2]->qualified_root ())->prioritized ()); - update_active_multiplier (); - node.block_confirm (blocks[3]); - node.scheduler.flush (); - ASSERT_FALSE (node.active.election (blocks[3]->qualified_root ())->prioritized ()); - update_active_multiplier (); - node.block_confirm (blocks[1]); - node.scheduler.flush (); - ASSERT_TRUE (node.active.election (blocks[1]->qualified_root ())->prioritized ()); - update_active_multiplier (); - node.block_confirm (blocks[4]); - node.scheduler.flush (); - ASSERT_FALSE (node.active.election (blocks[4]->qualified_root ())->prioritized ()); - update_active_multiplier (); - node.block_confirm (blocks[0]); - node.scheduler.flush (); - ASSERT_TRUE (node.active.election (blocks[0]->qualified_root ())->prioritized ()); - update_active_multiplier (); - node.block_confirm (blocks[5]); - node.scheduler.flush (); - ASSERT_FALSE (node.active.election (blocks[5]->qualified_root ())->prioritized ()); - update_active_multiplier (); - node.block_confirm (blocks[6]); - node.scheduler.flush (); - ASSERT_FALSE (node.active.election (blocks[6]->qualified_root ())->prioritized ()); - - ASSERT_EQ (4, node.stats.count (nano::stat::type::election, nano::stat::detail::election_start)); - ASSERT_EQ (3, node.stats.count (nano::stat::type::election, nano::stat::detail::election_start)); -} - -TEST (active_multiplier, less_than_one) -{ - nano::system system (1); - auto & node (*system.nodes[0]); - nano::unique_lock lock (node.active.mutex); - auto base_active_difficulty = node.network_params.network.publish_thresholds.epoch_1; - auto base_active_multiplier = 1.0; - auto min_active_difficulty = node.network_params.network.publish_thresholds.entry; - auto min_multiplier = nano::difficulty::to_multiplier (min_active_difficulty, base_active_difficulty); - ASSERT_EQ (node.active.trended_active_multiplier.load (), base_active_multiplier); - for (int i = 0; i < node.active.multipliers_cb.size () - 1; ++i) - { - node.active.multipliers_cb.push_front (min_multiplier); - } - auto sum (std::accumulate (node.active.multipliers_cb.begin (), node.active.multipliers_cb.end (), 0.)); - auto multiplier = sum / node.active.multipliers_cb.size (); - node.active.multipliers_cb.push_front (min_multiplier); - node.active.update_active_multiplier (lock); - ASSERT_EQ (node.active.trended_active_multiplier.load (), multiplier); -} - -TEST (active_multiplier, normalization) -{ - nano::system system (1); - auto & node (*system.nodes[0]); - // Check normalization for epoch 1 - double multiplier1 (1.0); - ASSERT_LT (nano::difficulty::from_multiplier (multiplier1, node.network_params.network.publish_thresholds.epoch_1), nano::difficulty::from_multiplier (1.0, node.network_params.network.publish_thresholds.epoch_2)); - auto norm_multiplier1 (nano::normalized_multiplier (multiplier1, node.network_params.network.publish_thresholds.epoch_1)); - ASSERT_NEAR (1.0, norm_multiplier1, 1e-10); - ASSERT_NEAR (nano::denormalized_multiplier (norm_multiplier1, node.network_params.network.publish_thresholds.epoch_1), multiplier1, 1e-10); - double multiplier2 (5.0); - ASSERT_LT (nano::difficulty::from_multiplier (multiplier2, node.network_params.network.publish_thresholds.epoch_1), nano::difficulty::from_multiplier (1.5, node.network_params.network.publish_thresholds.epoch_2)); - auto norm_multiplier2 (nano::normalized_multiplier (multiplier2, node.network_params.network.publish_thresholds.epoch_1)); - ASSERT_NEAR (1.5, norm_multiplier2, 1e-10); - ASSERT_NEAR (nano::denormalized_multiplier (norm_multiplier2, node.network_params.network.publish_thresholds.epoch_1), multiplier2, 1e-10); - double multiplier3 (9.0); - ASSERT_LT (nano::difficulty::from_multiplier (multiplier3, node.network_params.network.publish_thresholds.epoch_1), nano::difficulty::from_multiplier (2.0, node.network_params.network.publish_thresholds.epoch_2)); - auto norm_multiplier3 (nano::normalized_multiplier (multiplier3, node.network_params.network.publish_thresholds.epoch_1)); - ASSERT_NEAR (2.0, norm_multiplier3, 1e-10); - ASSERT_NEAR (nano::denormalized_multiplier (norm_multiplier3, node.network_params.network.publish_thresholds.epoch_1), multiplier3, 1e-10); - double multiplier4 (17.0); - ASSERT_LT (nano::difficulty::from_multiplier (multiplier4, node.network_params.network.publish_thresholds.epoch_1), nano::difficulty::from_multiplier (3.0, node.network_params.network.publish_thresholds.epoch_2)); - auto norm_multiplier4 (nano::normalized_multiplier (multiplier4, node.network_params.network.publish_thresholds.epoch_1)); - ASSERT_NEAR (3.0, norm_multiplier4, 1e-10); - ASSERT_NEAR (nano::denormalized_multiplier (norm_multiplier4, node.network_params.network.publish_thresholds.epoch_1), multiplier4, 1e-10); - double multiplier5 (25.0); - ASSERT_LT (nano::difficulty::from_multiplier (multiplier5, node.network_params.network.publish_thresholds.epoch_1), nano::difficulty::from_multiplier (4.0, node.network_params.network.publish_thresholds.epoch_2)); - auto norm_multiplier5 (nano::normalized_multiplier (multiplier5, node.network_params.network.publish_thresholds.epoch_1)); - ASSERT_NEAR (4.0, norm_multiplier5, 1e-10); - ASSERT_NEAR (nano::denormalized_multiplier (norm_multiplier5, node.network_params.network.publish_thresholds.epoch_1), multiplier5, 1e-10); - double multiplier6 (57.0); - ASSERT_LT (nano::difficulty::from_multiplier (multiplier6, node.network_params.network.publish_thresholds.epoch_1), nano::difficulty::from_multiplier (8.0, node.network_params.network.publish_thresholds.epoch_2)); - auto norm_multiplier6 (nano::normalized_multiplier (multiplier6, node.network_params.network.publish_thresholds.epoch_1)); - ASSERT_NEAR (8.0, norm_multiplier6, 1e-10); - ASSERT_NEAR (nano::denormalized_multiplier (norm_multiplier6, node.network_params.network.publish_thresholds.epoch_1), multiplier6, 1e-10); - // Check normalization for epoch 2 receive - double multiplier10 (1.0); - ASSERT_LT (nano::difficulty::from_multiplier (multiplier10, node.network_params.network.publish_thresholds.epoch_2_receive), nano::difficulty::from_multiplier (1.0, node.network_params.network.publish_thresholds.epoch_2)); - auto norm_multiplier10 (nano::normalized_multiplier (multiplier10, node.network_params.network.publish_thresholds.epoch_2_receive)); - ASSERT_NEAR (1.0, norm_multiplier10, 1e-10); - ASSERT_NEAR (nano::denormalized_multiplier (norm_multiplier10, node.network_params.network.publish_thresholds.epoch_2_receive), multiplier10, 1e-10); - double multiplier11 (33.0); - ASSERT_LT (nano::difficulty::from_multiplier (multiplier11, node.network_params.network.publish_thresholds.epoch_2_receive), nano::difficulty::from_multiplier (1.5, node.network_params.network.publish_thresholds.epoch_2)); - auto norm_multiplier11 (nano::normalized_multiplier (multiplier11, node.network_params.network.publish_thresholds.epoch_2_receive)); - ASSERT_NEAR (1.5, norm_multiplier11, 1e-10); - ASSERT_NEAR (nano::denormalized_multiplier (norm_multiplier11, node.network_params.network.publish_thresholds.epoch_2_receive), multiplier11, 1e-10); - double multiplier12 (65.0); - ASSERT_LT (nano::difficulty::from_multiplier (multiplier12, node.network_params.network.publish_thresholds.epoch_2_receive), nano::difficulty::from_multiplier (2.0, node.network_params.network.publish_thresholds.epoch_2)); - auto norm_multiplier12 (nano::normalized_multiplier (multiplier12, node.network_params.network.publish_thresholds.epoch_2_receive)); - ASSERT_NEAR (2.0, norm_multiplier12, 1e-10); - ASSERT_NEAR (nano::denormalized_multiplier (norm_multiplier12, node.network_params.network.publish_thresholds.epoch_2_receive), multiplier12, 1e-10); - double multiplier13 (129.0); - ASSERT_LT (nano::difficulty::from_multiplier (multiplier13, node.network_params.network.publish_thresholds.epoch_2_receive), nano::difficulty::from_multiplier (3.0, node.network_params.network.publish_thresholds.epoch_2)); - auto norm_multiplier13 (nano::normalized_multiplier (multiplier13, node.network_params.network.publish_thresholds.epoch_2_receive)); - ASSERT_NEAR (3.0, norm_multiplier13, 1e-10); - ASSERT_NEAR (nano::denormalized_multiplier (norm_multiplier13, node.network_params.network.publish_thresholds.epoch_2_receive), multiplier13, 1e-10); - double multiplier14 (193.0); - ASSERT_LT (nano::difficulty::from_multiplier (multiplier14, node.network_params.network.publish_thresholds.epoch_2_receive), nano::difficulty::from_multiplier (4.0, node.network_params.network.publish_thresholds.epoch_2)); - auto norm_multiplier14 (nano::normalized_multiplier (multiplier14, node.network_params.network.publish_thresholds.epoch_2_receive)); - ASSERT_NEAR (4.0, norm_multiplier14, 1e-10); - ASSERT_NEAR (nano::denormalized_multiplier (norm_multiplier14, node.network_params.network.publish_thresholds.epoch_2_receive), multiplier14, 1e-10); - double multiplier15 (961.0); - ASSERT_LT (nano::difficulty::from_multiplier (multiplier15, node.network_params.network.publish_thresholds.epoch_2_receive), nano::difficulty::from_multiplier (16.0, node.network_params.network.publish_thresholds.epoch_2)); - auto norm_multiplier15 (nano::normalized_multiplier (multiplier15, node.network_params.network.publish_thresholds.epoch_2_receive)); - ASSERT_NEAR (16.0, norm_multiplier15, 1e-10); - ASSERT_NEAR (nano::denormalized_multiplier (norm_multiplier15, node.network_params.network.publish_thresholds.epoch_2_receive), multiplier15, 1e-10); -} - -TEST (active_transactions, election_difficulty_update_old) -{ - nano::system system; - nano::node_flags node_flags; - node_flags.disable_request_loop = true; - auto & node = *system.add_node (node_flags); - nano::genesis genesis; - nano::keypair key; - nano::state_block_builder builder; - auto send1 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (genesis.hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 10 * nano::xrb_ratio) - .link (key.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (genesis.hash ())) - .build_shared (); - auto send1_copy = builder.make_block ().from (*send1).build_shared (); - node.process_active (send1); - node.block_processor.flush (); - node.scheduler.flush (); - ASSERT_EQ (1, node.active.size ()); - auto multiplier = node.active.roots.begin ()->multiplier; - { - nano::lock_guard guard (node.active.mutex); - ASSERT_EQ (node.active.normalized_multiplier (*send1), multiplier); - } - // Should not update with a lower difficulty - send1_copy->block_work_set (0); - ASSERT_EQ (nano::process_result::old, node.process (*send1_copy).code); - ASSERT_FALSE (send1_copy->has_sideband ()); - node.process_active (send1); - node.block_processor.flush (); - ASSERT_EQ (1, node.active.size ()); - ASSERT_EQ (node.active.roots.begin ()->multiplier, multiplier); - // Update work, even without a sideband it should find the block in the election and update the election multiplier - ASSERT_TRUE (node.work_generate_blocking (*send1_copy, send1->difficulty () + 1).is_initialized ()); - node.process_active (send1_copy); - node.block_processor.flush (); - ASSERT_EQ (1, node.active.size ()); - ASSERT_GT (node.active.roots.begin ()->multiplier, multiplier); - - ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::election_difficulty_update)); -} - -TEST (active_transactions, election_difficulty_update_fork) -{ - nano::system system; - nano::node_flags node_flags; - node_flags.disable_request_loop = true; - auto & node = *system.add_node (node_flags); - - ASSERT_NE (nullptr, system.upgrade_genesis_epoch (node, nano::epoch::epoch_1)); - auto epoch2 = system.upgrade_genesis_epoch (node, nano::epoch::epoch_2); - ASSERT_NE (nullptr, epoch2); - nano::keypair key; - nano::state_block_builder builder; - auto send1 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (epoch2->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - nano::Gxrb_ratio) - .link (key.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (epoch2->hash ())) - .build_shared (); - auto open1 = builder.make_block () - .account (key.pub) - .previous (0) - .representative (key.pub) - .balance (nano::Gxrb_ratio) - .link (send1->hash ()) - .sign (key.prv, key.pub) - .work (*system.work.generate (key.pub)) - .build_shared (); - auto send2 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (send1->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 2 * nano::Gxrb_ratio) - .link (key.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send1->hash ())) - .build_shared (); - ASSERT_EQ (nano::process_result::progress, node.process (*send1).code); - ASSERT_EQ (nano::process_result::progress, node.process (*open1).code); - ASSERT_EQ (nano::process_result::progress, node.process (*send2).code); - // Confirm blocks so far to allow starting elections for upcoming blocks - for (auto block : { open1, send2 }) - { - node.block_confirm (block); - auto election = node.active.election (block->qualified_root ()); - ASSERT_NE (nullptr, election); - election->force_confirm (); - ASSERT_TIMELY (2s, node.block_confirmed (block->hash ())); - node.active.erase (*block); - } - - // Verify an election with multiple blocks is correctly updated on arrival of another block - // Each subsequent block has difficulty at least higher than the previous one - auto fork_change = builder.make_block () - .account (key.pub) - .previous (open1->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::Gxrb_ratio) - .link (0) - .sign (key.prv, key.pub) - .work (*system.work.generate (open1->hash ())) - .build_shared (); - auto fork_send = builder.make_block () - .account (key.pub) - .previous (open1->hash ()) - .representative (key.pub) - .balance (0) - .link (key.pub) - .sign (key.prv, key.pub) - .work (*system.work.generate (open1->hash (), fork_change->difficulty ())) - .build_shared (); - auto fork_receive = builder.make_block () - .account (key.pub) - .previous (open1->hash ()) - .representative (key.pub) - .balance (2 * nano::Gxrb_ratio) - .link (send2->hash ()) - .sign (key.prv, key.pub) - .work (*system.work.generate (open1->hash (), fork_send->difficulty ())) - .build_shared (); - ASSERT_GT (fork_send->difficulty (), fork_change->difficulty ()); - ASSERT_GT (fork_receive->difficulty (), fork_send->difficulty ()); - - node.process_active (fork_change); - node.block_processor.flush (); - node.scheduler.flush (); - ASSERT_EQ (1, node.active.size ()); - auto multiplier_change = node.active.roots.begin ()->multiplier; - node.process_active (fork_send); - node.block_processor.flush (); - ASSERT_EQ (1, node.active.size ()); - ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::election_block_conflict)); - ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::election_difficulty_update)); - auto multiplier_send = node.active.roots.begin ()->multiplier; - node.process_active (fork_receive); - node.block_processor.flush (); - ASSERT_EQ (1, node.active.size ()); - ASSERT_EQ (2, node.stats.count (nano::stat::type::election, nano::stat::detail::election_block_conflict)); - ASSERT_EQ (2, node.stats.count (nano::stat::type::election, nano::stat::detail::election_difficulty_update)); - auto multiplier_receive = node.active.roots.begin ()->multiplier; - - ASSERT_GT (multiplier_send, multiplier_change); - ASSERT_GT (multiplier_receive, multiplier_send); - - EXPECT_FALSE (fork_receive->has_sideband ()); - auto threshold = nano::work_threshold (fork_receive->work_version (), nano::block_details (nano::epoch::epoch_2, false, true, false)); - auto denormalized = nano::denormalized_multiplier (multiplier_receive, threshold); - ASSERT_NEAR (nano::difficulty::to_multiplier (fork_receive->difficulty (), threshold), denormalized, 1e-10); - - // Ensure a fork with updated difficulty will also update the election difficulty - fork_receive->block_work_set (*system.work.generate (fork_receive->root (), fork_receive->difficulty () + 1)); - node.process_active (fork_receive); - node.block_processor.flush (); - ASSERT_EQ (1, node.active.size ()); - ASSERT_EQ (2, node.stats.count (nano::stat::type::election, nano::stat::detail::election_block_conflict)); - ASSERT_EQ (3, node.stats.count (nano::stat::type::election, nano::stat::detail::election_difficulty_update)); - auto multiplier_receive_updated = node.active.roots.begin ()->multiplier; - ASSERT_GT (multiplier_receive_updated, multiplier_receive); -} - TEST (active_transactions, confirm_new) { nano::system system (1); @@ -1692,9 +1317,9 @@ TEST (active_transactions, pessimistic_elections) // Make dummy election with winner. { nano::election election1 ( - node, send, [] (auto const &) {}, [] (auto const &) {}, false, nano::election_behavior::normal); + node, send, [] (auto const &) {}, [] (auto const &) {}, nano::election_behavior::normal); nano::election election2 ( - node, open, [] (auto const &) {}, [] (auto const &) {}, false, nano::election_behavior::normal); + node, open, [] (auto const &) {}, [] (auto const &) {}, nano::election_behavior::normal); node.active.add_expired_optimistic_election (election1); node.active.add_expired_optimistic_election (election2); } diff --git a/nano/core_test/confirmation_solicitor.cpp b/nano/core_test/confirmation_solicitor.cpp index 1c384547d9..907ef5fede 100644 --- a/nano/core_test/confirmation_solicitor.cpp +++ b/nano/core_test/confirmation_solicitor.cpp @@ -34,11 +34,11 @@ TEST (confirmation_solicitor, batches) nano::lock_guard guard (node2.active.mutex); for (size_t i (0); i < nano::network::confirm_req_hashes_max; ++i) { - auto election (std::make_shared (node2, send, nullptr, nullptr, false, nano::election_behavior::normal)); + auto election (std::make_shared (node2, send, nullptr, nullptr, nano::election_behavior::normal)); ASSERT_FALSE (solicitor.add (*election)); } // Reached the maximum amount of requests for the channel - auto election (std::make_shared (node2, send, nullptr, nullptr, false, nano::election_behavior::normal)); + auto election (std::make_shared (node2, send, nullptr, nullptr, nano::election_behavior::normal)); ASSERT_TRUE (solicitor.add (*election)); // Broadcasting should be immediate ASSERT_EQ (0, node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out)); @@ -74,7 +74,7 @@ TEST (confirmation_solicitor, different_hash) ASSERT_TIMELY (3s, node2.network.size () == 1); auto send (std::make_shared (nano::genesis_hash, nano::keypair ().pub, nano::genesis_amount - 100, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (nano::genesis_hash))); send->sideband_set ({}); - auto election (std::make_shared (node2, send, nullptr, nullptr, false, nano::election_behavior::normal)); + auto election (std::make_shared (node2, send, nullptr, nullptr, nano::election_behavior::normal)); // Add a vote for something else, not the winner election->last_votes[representative.account] = { std::chrono::steady_clock::now (), 1, 1 }; // Ensure the request and broadcast goes through @@ -110,7 +110,7 @@ TEST (confirmation_solicitor, bypass_max_requests_cap) ASSERT_TIMELY (3s, node2.network.size () == 1); auto send (std::make_shared (nano::genesis_hash, nano::keypair ().pub, nano::genesis_amount - 100, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (nano::genesis_hash))); send->sideband_set ({}); - auto election (std::make_shared (node2, send, nullptr, nullptr, false, nano::election_behavior::normal)); + auto election (std::make_shared (node2, send, nullptr, nullptr, nano::election_behavior::normal)); // Add a vote for something else, not the winner for (auto const & rep : representatives) { @@ -124,7 +124,7 @@ TEST (confirmation_solicitor, bypass_max_requests_cap) ASSERT_EQ (max_representatives + 1, node2.stats.count (nano::stat::type::message, nano::stat::detail::confirm_req, nano::stat::dir::out)); solicitor.prepare (representatives); - auto election2 (std::make_shared (node2, send, nullptr, nullptr, false, nano::election_behavior::normal)); + auto election2 (std::make_shared (node2, send, nullptr, nullptr, nano::election_behavior::normal)); ASSERT_FALSE (solicitor.add (*election2)); ASSERT_FALSE (solicitor.broadcast (*election2)); diff --git a/nano/core_test/conflicts.cpp b/nano/core_test/conflicts.cpp index a8889d0b6f..2fe1ce8349 100644 --- a/nano/core_test/conflicts.cpp +++ b/nano/core_test/conflicts.cpp @@ -156,36 +156,3 @@ TEST (vote_uniquer, cleanup) ASSERT_LT (iterations++, 200); } } - -TEST (conflicts, reprioritize) -{ - nano::system system (1); - auto & node1 (*system.nodes[0]); - nano::genesis genesis; - nano::keypair key1; - auto send1 (std::make_shared (genesis.hash (), key1.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); - node1.work_generate_blocking (*send1); - auto difficulty1 (send1->difficulty ()); - auto multiplier1 (nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty1, nano::work_threshold (send1->work_version (), nano::block_details (nano::epoch::epoch_0, false /* unused */, false /* unused */, false /* unused */))), node1.network_params.network.publish_thresholds.epoch_1)); - nano::send_block send1_copy (*send1); - node1.process_active (send1); - node1.block_processor.flush (); - node1.scheduler.flush (); - { - nano::lock_guard guard (node1.active.mutex); - auto existing1 (node1.active.roots.find (send1->qualified_root ())); - ASSERT_NE (node1.active.roots.end (), existing1); - ASSERT_EQ (multiplier1, existing1->multiplier); - } - node1.work_generate_blocking (send1_copy, difficulty1); - auto difficulty2 (send1_copy.difficulty ()); - auto multiplier2 (nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty2, nano::work_threshold (send1_copy.work_version (), nano::block_details (nano::epoch::epoch_0, false /* unused */, false /* unused */, false /* unused */))), node1.network_params.network.publish_thresholds.epoch_1)); - node1.process_active (std::make_shared (send1_copy)); - node1.block_processor.flush (); - { - nano::lock_guard guard (node1.active.mutex); - auto existing2 (node1.active.roots.find (send1->qualified_root ())); - ASSERT_NE (node1.active.roots.end (), existing2); - ASSERT_EQ (multiplier2, existing2->multiplier); - } -} diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 5701286c63..39cd4af85b 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -780,7 +780,6 @@ TEST (node_config, v18_values) tree.put ("active_elections_size", 10000); tree.put ("vote_generator_delay", 100); tree.put ("backup_before_upgrade", true); - tree.put ("work_watcher_period", 5); } config.deserialize_json (upgraded, tree); @@ -788,13 +787,11 @@ TEST (node_config, v18_values) ASSERT_EQ (config.active_elections_size, 10000); ASSERT_EQ (config.vote_generator_delay.count (), 100); ASSERT_EQ (config.backup_before_upgrade, true); - ASSERT_EQ (config.work_watcher_period.count (), 5); // Check config is correct with other values tree.put ("active_elections_size", 5); tree.put ("vote_generator_delay", std::numeric_limits::max () - 100); tree.put ("backup_before_upgrade", false); - tree.put ("work_watcher_period", 999); upgraded = false; config.deserialize_json (upgraded, tree); @@ -802,7 +799,6 @@ TEST (node_config, v18_values) ASSERT_EQ (config.active_elections_size, 5); ASSERT_EQ (config.vote_generator_delay.count (), std::numeric_limits::max () - 100); ASSERT_EQ (config.backup_before_upgrade, false); - ASSERT_EQ (config.work_watcher_period.count (), 999); } // Regression test to ensure that deserializing includes changes node via get_required_child @@ -3921,7 +3917,7 @@ TEST (node, aggressive_flooding) .build (); } // Processing locally goes through the aggressive block flooding path - node1.process_local (block, false); + node1.process_local (block); auto all_have_block = [&nodes_wallets] (nano::block_hash const & hash_a) { return std::all_of (nodes_wallets.begin (), nodes_wallets.end (), [hash = hash_a] (auto const & node_wallet) { @@ -3940,42 +3936,6 @@ TEST (node, aggressive_flooding) ASSERT_EQ (1 + 2 * nodes_wallets.size () + 2, node1.ledger.cache.block_count); } -TEST (active_difficulty, recalculate_work) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.enable_voting = false; - auto & node1 = *system.add_node (node_config); - nano::genesis genesis; - nano::keypair key1; - ASSERT_EQ (node1.network_params.network.publish_thresholds.epoch_2, node1.active.active_difficulty ()); - auto send1 = nano::send_block_builder () - .previous (genesis.hash ()) - .destination (key1.pub) - .balance (0) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (genesis.hash ())) - .build_shared (); - auto multiplier1 = nano::difficulty::to_multiplier (send1->difficulty (), node1.network_params.network.publish_thresholds.epoch_2); - // Process as local block - node1.process_active (send1); - ASSERT_TIMELY (2s, !node1.active.empty ()); - auto sum (std::accumulate (node1.active.multipliers_cb.begin (), node1.active.multipliers_cb.end (), double (0))); - ASSERT_EQ (node1.active.active_difficulty (), nano::difficulty::from_multiplier (sum / node1.active.multipliers_cb.size (), node1.network_params.network.publish_thresholds.epoch_2)); - nano::unique_lock lock (node1.active.mutex); - // Fake history records to force work recalculation - for (auto i (0); i < node1.active.multipliers_cb.size (); i++) - { - node1.active.multipliers_cb.push_back (multiplier1 * (1 + i / 100.)); - } - node1.work_generate_blocking (*send1); - node1.process_active (send1); - node1.active.update_active_multiplier (lock); - sum = std::accumulate (node1.active.multipliers_cb.begin (), node1.active.multipliers_cb.end (), double (0)); - ASSERT_EQ (node1.active.trended_active_multiplier.load (), sum / node1.active.multipliers_cb.size ()); - lock.unlock (); -} - TEST (node, node_sequence) { nano::system system (3); @@ -4498,8 +4458,8 @@ TEST (node, deferred_dependent_elections) ASSERT_NE (nullptr, election_send1); // Should process and republish but not start an election for any dependent blocks - node.process_local (open, false); - node.process_local (send2, false); + node.process_local (open); + node.process_local (send2); node.block_processor.flush (); ASSERT_TRUE (node.block (open->hash ())); ASSERT_TRUE (node.block (send2->hash ())); @@ -4510,7 +4470,7 @@ TEST (node, deferred_dependent_elections) // Re-processing older blocks with updated work also does not start an election node.work_generate_blocking (*open, open->difficulty () + 1); - node.process_local (open, false); + node.process_local (open); node.block_processor.flush (); ASSERT_FALSE (node.active.active (open->qualified_root ())); /// However, work is still updated @@ -4525,7 +4485,7 @@ TEST (node, deferred_dependent_elections) /// The election was dropped but it's still not possible to restart it node.work_generate_blocking (*open, open->difficulty () + 1); ASSERT_FALSE (node.active.active (open->qualified_root ())); - node.process_local (open, false); + node.process_local (open); node.block_processor.flush (); ASSERT_FALSE (node.active.active (open->qualified_root ())); /// However, work is still updated @@ -4564,14 +4524,14 @@ TEST (node, deferred_dependent_elections) ASSERT_FALSE (node.active.active (receive->qualified_root ())); ASSERT_FALSE (node.ledger.rollback (node.store.tx_begin_write (), receive->hash ())); ASSERT_FALSE (node.block (receive->hash ())); - node.process_local (receive, false); + node.process_local (receive); node.block_processor.flush (); ASSERT_TRUE (node.block (receive->hash ())); ASSERT_FALSE (node.active.active (receive->qualified_root ())); // Processing a fork will also not start an election ASSERT_EQ (nano::process_result::fork, node.process (*fork).code); - node.process_local (fork, false); + node.process_local (fork); node.block_processor.flush (); ASSERT_FALSE (node.active.active (receive->qualified_root ())); @@ -4582,7 +4542,7 @@ TEST (node, deferred_dependent_elections) node.active.erase (*receive); ASSERT_FALSE (node.active.active (receive->qualified_root ())); node.work_generate_blocking (*receive, receive->difficulty () + 1); - node.process_local (receive, false); + node.process_local (receive); node.block_processor.flush (); ASSERT_TRUE (node.active.active (receive->qualified_root ())); } diff --git a/nano/core_test/telemetry.cpp b/nano/core_test/telemetry.cpp index 669e4fc85f..1ad42c4e73 100644 --- a/nano/core_test/telemetry.cpp +++ b/nano/core_test/telemetry.cpp @@ -253,7 +253,7 @@ TEST (telemetry, basic) } // Check the metrics are correct - nano::compare_default_telemetry_response_data (telemetry_data, node_server->network_params, node_server->config.bandwidth_limit, node_server->active.active_difficulty (), node_server->node_id); + nano::compare_default_telemetry_response_data (telemetry_data, node_server->network_params, node_server->config.bandwidth_limit, node_server->default_difficulty (nano::work_version::work_1), node_server->node_id); // Call again straight away. It should use the cache { @@ -305,7 +305,7 @@ TEST (telemetry, over_udp) auto channel = node_client->network.find_channel (node_server->network.endpoint ()); node_client->telemetry->get_metrics_single_peer_async (channel, [&done, &node_server] (nano::telemetry_data_response const & response_a) { ASSERT_FALSE (response_a.error); - nano::compare_default_telemetry_response_data (response_a.telemetry_data, node_server->network_params, node_server->config.bandwidth_limit, node_server->active.active_difficulty (), node_server->node_id); + nano::compare_default_telemetry_response_data (response_a.telemetry_data, node_server->network_params, node_server->config.bandwidth_limit, node_server->default_difficulty (nano::work_version::work_1), node_server->node_id); done = true; }); @@ -370,7 +370,7 @@ TEST (telemetry, blocking_request) // Now try single request metric auto telemetry_data_response = node_client->telemetry->get_metrics_single_peer (node_client->network.find_channel (node_server->network.endpoint ())); ASSERT_FALSE (telemetry_data_response.error); - nano::compare_default_telemetry_response_data (telemetry_data_response.telemetry_data, node_server->network_params, node_server->config.bandwidth_limit, node_server->active.active_difficulty (), node_server->node_id); + nano::compare_default_telemetry_response_data (telemetry_data_response.telemetry_data, node_server->network_params, node_server->config.bandwidth_limit, node_server->default_difficulty (nano::work_version::work_1), node_server->node_id); done = true; promise.get_future ().wait (); @@ -513,7 +513,7 @@ TEST (telemetry, disable_metrics) auto channel1 = node_server->network.find_channel (node_client->network.endpoint ()); node_server->telemetry->get_metrics_single_peer_async (channel1, [&done, node_client] (nano::telemetry_data_response const & response_a) { ASSERT_FALSE (response_a.error); - nano::compare_default_telemetry_response_data (response_a.telemetry_data, node_client->network_params, node_client->config.bandwidth_limit, node_client->active.active_difficulty (), node_client->node_id); + nano::compare_default_telemetry_response_data (response_a.telemetry_data, node_client->network_params, node_client->config.bandwidth_limit, node_client->default_difficulty (nano::work_version::work_1), node_client->node_id); done = true; }); @@ -628,7 +628,7 @@ TEST (telemetry, remove_peer_invalid_signature) // (Implementation detail) So that messages are not just discarded when requests were not sent. node->telemetry->recent_or_initial_request_telemetry_data.emplace (channel->get_endpoint (), nano::telemetry_data (), std::chrono::steady_clock::now (), true); - auto telemetry_data = nano::local_telemetry_data (node->ledger, node->network, node->config.bandwidth_limit, node->network_params, node->startup_time, node->active.active_difficulty (), node->node_id); + auto telemetry_data = nano::local_telemetry_data (node->ledger, node->network, node->config.bandwidth_limit, node->network_params, node->startup_time, node->default_difficulty (nano::work_version::work_1), node->node_id); // Change anything so that the signed message is incorrect telemetry_data.block_count = 0; auto telemetry_ack = nano::telemetry_ack (telemetry_data); diff --git a/nano/core_test/toml.cpp b/nano/core_test/toml.cpp index f2854e0cc2..fff7bccfb2 100644 --- a/nano/core_test/toml.cpp +++ b/nano/core_test/toml.cpp @@ -167,7 +167,6 @@ TEST (toml, daemon_config_deserialize_defaults) ASSERT_EQ (conf.node.max_work_generate_multiplier, defaults.node.max_work_generate_multiplier); ASSERT_EQ (conf.node.network_threads, defaults.node.network_threads); ASSERT_EQ (conf.node.secondary_work_peers, defaults.node.secondary_work_peers); - ASSERT_EQ (conf.node.work_watcher_period, defaults.node.work_watcher_period); ASSERT_EQ (conf.node.online_weight_minimum, defaults.node.online_weight_minimum); ASSERT_EQ (conf.node.election_hint_weight_percent, defaults.node.election_hint_weight_percent); ASSERT_EQ (conf.node.password_fanout, defaults.node.password_fanout); @@ -423,7 +422,6 @@ TEST (toml, daemon_config_deserialize_no_defaults) vote_minimum = "999" work_peers = ["dev.org:999"] work_threads = 999 - work_watcher_period = 999 max_work_generate_multiplier = 1.0 max_queued_requests = 999 frontiers_confirmation = "always" @@ -573,7 +571,6 @@ TEST (toml, daemon_config_deserialize_no_defaults) ASSERT_NE (conf.node.secondary_work_peers, defaults.node.secondary_work_peers); ASSERT_NE (conf.node.max_pruning_age, defaults.node.max_pruning_age); ASSERT_NE (conf.node.max_pruning_depth, defaults.node.max_pruning_depth); - ASSERT_NE (conf.node.work_watcher_period, defaults.node.work_watcher_period); ASSERT_NE (conf.node.online_weight_minimum, defaults.node.online_weight_minimum); ASSERT_NE (conf.node.election_hint_weight_percent, defaults.node.election_hint_weight_percent); ASSERT_NE (conf.node.password_fanout, defaults.node.password_fanout); diff --git a/nano/core_test/wallet.cpp b/nano/core_test/wallet.cpp index d3b2bf3bfb..e77a23f515 100644 --- a/nano/core_test/wallet.cpp +++ b/nano/core_test/wallet.cpp @@ -996,34 +996,6 @@ TEST (wallet, deterministic_restore) ASSERT_TRUE (wallet->exists (pub)); } -// Ensure the minimum limited difficulty is enough for the highest threshold -TEST (wallet, limited_difficulty) -{ - nano::system system; - nano::genesis genesis; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.max_work_generate_multiplier = 1; - nano::node_flags node_flags; - node_flags.disable_request_loop = true; - auto & node = *system.add_node (node_config, node_flags); - auto & wallet (*system.wallet (0)); - // Upgrade the genesis account to epoch 2 - ASSERT_NE (nullptr, system.upgrade_genesis_epoch (node, nano::epoch::epoch_1)); - ASSERT_NE (nullptr, system.upgrade_genesis_epoch (node, nano::epoch::epoch_2)); - ASSERT_EQ (nano::epoch::epoch_2, node.store.block_version (node.store.tx_begin_read (), node.latest (nano::dev_genesis_key.pub))); - wallet.insert_adhoc (nano::dev_genesis_key.prv, false); - { - // Force active difficulty to an impossibly high value - nano::lock_guard guard (node.active.mutex); - node.active.trended_active_multiplier = 1024 * 1024 * 1024; - } - ASSERT_EQ (node.max_work_generate_difficulty (nano::work_version::work_1), node.active.limited_active_difficulty (*genesis.open)); - auto send = wallet.send_action (nano::dev_genesis_key.pub, nano::keypair ().pub, 1, 1); - ASSERT_NE (nullptr, send); - ASSERT_EQ (nano::epoch::epoch_2, send->sideband ().details.epoch); - ASSERT_EQ (nano::epoch::epoch_0, send->sideband ().source_epoch); // Not used for send state blocks -} - TEST (wallet, epoch_2_validation) { nano::system system (1); @@ -1100,11 +1072,6 @@ TEST (wallet, epoch_2_receive_propagation) auto send2 = wallet.send_action (nano::dev_genesis_key.pub, key.pub, amount, 1); ASSERT_NE (nullptr, send2); - // Receiving should use the lower difficulty - { - nano::lock_guard guard (node.active.mutex); - node.active.trended_active_multiplier = 1.0; - } auto receive2 = wallet.receive_action (send2->hash (), key.pub, amount, send2->link ().as_account (), 1); ASSERT_NE (nullptr, receive2); if (receive2->difficulty () < node.network_params.network.publish_thresholds.base) @@ -1150,11 +1117,6 @@ TEST (wallet, epoch_2_receive_unopened) wallet.insert_adhoc (key.prv, false); - // Receiving should use the lower difficulty - { - nano::lock_guard guard (node.active.mutex); - node.active.trended_active_multiplier = 1.0; - } auto receive1 = wallet.receive_action (send1->hash (), key.pub, amount, send1->link ().as_account (), 1); ASSERT_NE (nullptr, receive1); if (receive1->difficulty () < node.network_params.network.publish_thresholds.base) diff --git a/nano/core_test/websocket.cpp b/nano/core_test/websocket.cpp index f815cfc1d4..d3c58814a1 100644 --- a/nano/core_test/websocket.cpp +++ b/nano/core_test/websocket.cpp @@ -48,76 +48,6 @@ TEST (websocket, subscription_edge) ASSERT_TIMELY (5s, future.wait_for (0s) == std::future_status::ready); } -// Test client subscribing to changes in active_multiplier -TEST (websocket, active_difficulty) -{ - nano::system system; - nano::node_config config (nano::get_available_port (), system.logging); - config.websocket_config.enabled = true; - config.websocket_config.port = nano::get_available_port (); - nano::node_flags node_flags; - // Disable auto-updating active difficulty (multiplier) to prevent intermittent failures - node_flags.disable_request_loop = true; - auto node1 (system.add_node (config, node_flags)); - - ASSERT_EQ (node1->default_difficulty (nano::work_version::work_1), node1->network_params.network.publish_thresholds.epoch_2); - - ASSERT_EQ (0, node1->websocket_server->subscriber_count (nano::websocket::topic::active_difficulty)); - - std::atomic ack_ready{ false }; - auto task = ([&ack_ready, config, &node1] () { - fake_websocket_client client (config.websocket_config.port); - client.send_message (R"json({"action": "subscribe", "topic": "active_difficulty", "ack": true})json"); - client.await_ack (); - ack_ready = true; - EXPECT_EQ (1, node1->websocket_server->subscriber_count (nano::websocket::topic::active_difficulty)); - return client.get_response (); - }); - auto future = std::async (std::launch::async, task); - - ASSERT_TIMELY (5s, ack_ready); - - // Fake history records and force a trended_active_multiplier change - { - nano::unique_lock lock (node1->active.mutex); - node1->active.multipliers_cb.push_front (10.); - node1->active.update_active_multiplier (lock); - } - - ASSERT_TIMELY (5s, future.wait_for (0s) == std::future_status::ready); - - // Check active_difficulty response - boost::optional response = future.get (); - ASSERT_TRUE (response); - std::stringstream stream; - stream << response; - boost::property_tree::ptree event; - boost::property_tree::read_json (stream, event); - ASSERT_EQ (event.get ("topic"), "active_difficulty"); - - auto message_contents = event.get_child ("message"); - uint64_t network_minimum; - nano::from_string_hex (message_contents.get ("network_minimum"), network_minimum); - ASSERT_EQ (network_minimum, node1->default_difficulty (nano::work_version::work_1)); - - uint64_t network_receive_minimum; - nano::from_string_hex (message_contents.get ("network_receive_minimum"), network_receive_minimum); - ASSERT_EQ (network_receive_minimum, node1->default_receive_difficulty (nano::work_version::work_1)); - - uint64_t network_current; - nano::from_string_hex (message_contents.get ("network_current"), network_current); - ASSERT_EQ (network_current, node1->active.active_difficulty ()); - - double multiplier = message_contents.get ("multiplier"); - ASSERT_NEAR (multiplier, nano::difficulty::to_multiplier (node1->active.active_difficulty (), node1->default_difficulty (nano::work_version::work_1)), 1e-6); - - uint64_t network_receive_current; - nano::from_string_hex (message_contents.get ("network_receive_current"), network_receive_current); - auto network_receive_current_multiplier (nano::difficulty::to_multiplier (network_receive_current, network_receive_minimum)); - auto network_receive_current_normalized_multiplier (nano::normalized_multiplier (network_receive_current_multiplier, network_receive_minimum)); - ASSERT_NEAR (network_receive_current_normalized_multiplier, multiplier, 1e-6); -} - // Subscribes to block confirmations, confirms a block and then awaits websocket notification TEST (websocket, confirmation) { @@ -950,7 +880,7 @@ TEST (websocket, telemetry) nano::jsonconfig telemetry_contents (contents); nano::telemetry_data telemetry_data; telemetry_data.deserialize_json (telemetry_contents, false); - compare_default_telemetry_response_data (telemetry_data, node2->network_params, node2->config.bandwidth_limit, node2->active.active_difficulty (), node2->node_id); + compare_default_telemetry_response_data (telemetry_data, node2->network_params, node2->config.bandwidth_limit, node2->default_difficulty (nano::work_version::work_1), node2->node_id); ASSERT_EQ (contents.get ("address"), node2->network.endpoint ().address ().to_string ()); ASSERT_EQ (contents.get ("port"), node2->network.endpoint ().port ()); diff --git a/nano/core_test/work_watcher.cpp b/nano/core_test/work_watcher.cpp deleted file mode 100644 index 0ce203260e..0000000000 --- a/nano/core_test/work_watcher.cpp +++ /dev/null @@ -1,320 +0,0 @@ -#include -#include - -#include - -using namespace std::chrono_literals; - -TEST (work_watcher, DISABLED_update) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.enable_voting = false; - node_config.work_watcher_period = 1s; - node_config.max_work_generate_multiplier = 1e6; - nano::node_flags node_flags; - node_flags.disable_request_loop = true; - auto & node = *system.add_node (node_config, node_flags); - auto & wallet = *system.wallet (0); - wallet.insert_adhoc (nano::dev_genesis_key.prv); - nano::keypair key; - auto const block1 = wallet.send_action (nano::dev_genesis_key.pub, key.pub, 100); - auto difficulty1 = block1->difficulty (); - auto multiplier1 = nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty1, nano::work_threshold (block1->work_version (), nano::block_details (nano::epoch::epoch_0, true, false, false))), node.network_params.network.publish_thresholds.epoch_1); - auto const block2 = wallet.send_action (nano::dev_genesis_key.pub, key.pub, 200); - auto difficulty2 = block2->difficulty (); - auto multiplier2 = nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty2, nano::work_threshold (block2->work_version (), nano::block_details (nano::epoch::epoch_0, true, false, false))), node.network_params.network.publish_thresholds.epoch_1); - node.block_processor.flush (); - node.scheduler.flush (); - double updated_multiplier1{ multiplier1 }, updated_multiplier2{ multiplier2 }, target_multiplier{ std::max (multiplier1, multiplier2) + 1e-6 }; - { - nano::lock_guard guard (node.active.mutex); - node.active.trended_active_multiplier = target_multiplier; - } - system.deadline_set (20s); - while (updated_multiplier1 == multiplier1 || updated_multiplier2 == multiplier2) - { - { - nano::lock_guard guard (node.active.mutex); - { - auto const existing = node.active.roots.find (block1->qualified_root ()); - //if existing is junk the block has been confirmed already - ASSERT_NE (existing, node.active.roots.end ()); - updated_multiplier1 = existing->multiplier; - } - { - auto const existing = node.active.roots.find (block2->qualified_root ()); - //if existing is junk the block has been confirmed already - ASSERT_NE (existing, node.active.roots.end ()); - updated_multiplier2 = existing->multiplier; - } - } - ASSERT_NO_ERROR (system.poll ()); - } - ASSERT_GT (updated_multiplier1, multiplier1); - ASSERT_GT (updated_multiplier2, multiplier2); -} - -TEST (work_watcher, propagate) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.enable_voting = false; - node_config.work_watcher_period = 1s; - node_config.max_work_generate_multiplier = 1e6; - nano::node_flags node_flags; - node_flags.disable_request_loop = true; - auto & node = *system.add_node (node_config, node_flags); - auto & wallet (*system.wallet (0)); - wallet.insert_adhoc (nano::dev_genesis_key.prv); - node_config.peering_port = nano::get_available_port (); - auto & node_passive = *system.add_node (node_config); - nano::keypair key; - auto const block (wallet.send_action (nano::dev_genesis_key.pub, key.pub, 100)); - ASSERT_TIMELY (5s, node_passive.ledger.block_exists (block->hash ())); - auto const multiplier (nano::normalized_multiplier (nano::difficulty::to_multiplier (block->difficulty (), nano::work_threshold (block->work_version (), nano::block_details (nano::epoch::epoch_0, false, false, false))), node.network_params.network.publish_thresholds.epoch_1)); - auto updated_multiplier{ multiplier }; - auto propagated_multiplier{ multiplier }; - { - nano::lock_guard guard (node.active.mutex); - node.active.trended_active_multiplier = multiplier * 1.001; - } - bool updated{ false }; - bool propagated{ false }; - system.deadline_set (10s); - while (!(updated && propagated)) - { - { - nano::lock_guard guard (node.active.mutex); - { - auto const existing (node.active.roots.find (block->qualified_root ())); - ASSERT_NE (existing, node.active.roots.end ()); - updated_multiplier = existing->multiplier; - } - } - { - nano::lock_guard guard (node_passive.active.mutex); - { - auto const existing (node_passive.active.roots.find (block->qualified_root ())); - ASSERT_NE (existing, node_passive.active.roots.end ()); - propagated_multiplier = existing->multiplier; - } - } - updated = updated_multiplier != multiplier; - propagated = propagated_multiplier != multiplier; - ASSERT_NO_ERROR (system.poll ()); - } - ASSERT_GT (updated_multiplier, multiplier); - ASSERT_EQ (propagated_multiplier, updated_multiplier); -} - -TEST (work_watcher, removed_after_win) -{ - nano::system system (1); - auto & node (*system.nodes[0]); - auto & wallet (*system.wallet (0)); - wallet.insert_adhoc (nano::dev_genesis_key.prv); - nano::keypair key; - ASSERT_EQ (0, wallet.wallets.watcher->size ()); - auto const block1 (wallet.send_action (nano::dev_genesis_key.pub, key.pub, 100)); - ASSERT_EQ (1, wallet.wallets.watcher->size ()); - ASSERT_TIMELY (5s, !node.wallets.watcher->is_watched (block1->qualified_root ())); - ASSERT_EQ (0, node.wallets.watcher->size ()); -} - -TEST (work_watcher, removed_after_lose) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - nano::state_block_builder builder; - node_config.enable_voting = false; - node_config.work_watcher_period = 1s; - auto & node = *system.add_node (node_config); - auto & wallet (*system.wallet (0)); - wallet.insert_adhoc (nano::dev_genesis_key.prv); - nano::keypair key; - auto const block1 (wallet.send_action (nano::dev_genesis_key.pub, key.pub, 100)); - ASSERT_TRUE (node.wallets.watcher->is_watched (block1->qualified_root ())); - nano::genesis genesis; - auto fork1 = builder - .account (nano::dev_genesis_key.pub) - .previous (genesis.hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - nano::xrb_ratio) - .link (nano::dev_genesis_key.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (genesis.hash ())) - .build_shared (); - - node.process_active (fork1); - node.block_processor.flush (); - auto vote (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, fork1)); - nano::confirm_ack message (vote); - node.network.process_message (message, std::make_shared (node)); - ASSERT_TIMELY (5s, !node.wallets.watcher->is_watched (block1->qualified_root ())); - ASSERT_EQ (0, node.wallets.watcher->size ()); -} - -TEST (work_watcher, generation_disabled) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - nano::state_block_builder builder; - node_config.enable_voting = false; - node_config.work_watcher_period = 1s; - node_config.work_threads = 0; - nano::node_flags node_flags; - node_flags.disable_request_loop = true; - auto & node = *system.add_node (node_config); - ASSERT_FALSE (node.work_generation_enabled ()); - nano::work_pool pool (std::numeric_limits::max ()); - nano::genesis genesis; - nano::keypair key; - auto block = builder - .account (nano::dev_genesis_key.pub) - .previous (genesis.hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - nano::Mxrb_ratio) - .link (key.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*pool.generate (genesis.hash ())) - .build_shared (); - - auto difficulty (block->difficulty ()); - node.wallets.watcher->add (block); - ASSERT_FALSE (node.process_local (block).code != nano::process_result::progress); - ASSERT_TRUE (node.wallets.watcher->is_watched (block->qualified_root ())); - auto multiplier = nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty, nano::work_threshold (block->work_version (), nano::block_details (nano::epoch::epoch_0, true, false, false))), node.network_params.network.publish_thresholds.epoch_1); - double updated_multiplier{ multiplier }; - { - nano::lock_guard guard (node.active.mutex); - node.active.trended_active_multiplier = multiplier * 10; - } - std::this_thread::sleep_for (2s); - ASSERT_TRUE (node.wallets.watcher->is_watched (block->qualified_root ())); - { - nano::lock_guard guard (node.active.mutex); - auto const existing (node.active.roots.find (block->qualified_root ())); - ASSERT_NE (existing, node.active.roots.end ()); - updated_multiplier = existing->multiplier; - } - ASSERT_EQ (updated_multiplier, multiplier); - ASSERT_EQ (0, node.distributed_work.size ()); -} - -TEST (work_watcher, cancel) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.work_watcher_period = 1s; - node_config.max_work_generate_multiplier = 1e6; - node_config.enable_voting = false; - auto & node = *system.add_node (node_config); - auto & wallet (*system.wallet (0)); - wallet.insert_adhoc (nano::dev_genesis_key.prv, false); - nano::keypair key; - auto work1 (node.work_generate_blocking (nano::dev_genesis_key.pub)); - auto const block1 (wallet.send_action (nano::dev_genesis_key.pub, key.pub, 100, *work1, false)); - { - nano::unique_lock lock (node.active.mutex); - // Prevent active difficulty repopulating multipliers - node.network_params.network.request_interval_ms = 10000; - // Fill multipliers_cb and update active difficulty; - for (auto i (0); i < node.active.multipliers_cb.size (); i++) - { - node.active.multipliers_cb.push_back (node.config.max_work_generate_multiplier); - } - node.active.update_active_multiplier (lock); - } - // Wait for work generation to start - ASSERT_TIMELY (5s, 0 != node.work.size ()); - // Cancel the ongoing work - ASSERT_EQ (1, node.work.size ()); - node.work.cancel (block1->root ()); - ASSERT_EQ (0, node.work.size ()); - { - auto watched = wallet.wallets.watcher->list_watched (); - auto existing = watched.find (block1->qualified_root ()); - ASSERT_NE (watched.end (), existing); - auto block2 (existing->second); - // Block must be the same - ASSERT_NE (nullptr, block1); - ASSERT_NE (nullptr, block2); - ASSERT_EQ (*block1, *block2); - // but should still be under watch - ASSERT_TRUE (wallet.wallets.watcher->is_watched (block1->qualified_root ())); - } -} - -TEST (work_watcher, confirm_while_generating) -{ - // Ensure proper behavior when confirmation happens during work generation - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.work_threads = 1; - node_config.work_watcher_period = 1s; - node_config.max_work_generate_multiplier = 1e6; - node_config.enable_voting = false; - auto & node = *system.add_node (node_config); - auto & wallet (*system.wallet (0)); - wallet.insert_adhoc (nano::dev_genesis_key.prv, false); - nano::keypair key; - auto work1 (node.work_generate_blocking (nano::dev_genesis_key.pub)); - auto const block1 (wallet.send_action (nano::dev_genesis_key.pub, key.pub, 100, *work1, false)); - { - nano::unique_lock lock (node.active.mutex); - // Prevent active difficulty repopulating multipliers - node.network_params.network.request_interval_ms = 10000; - // Fill multipliers_cb and update active difficulty; - for (auto i (0); i < node.active.multipliers_cb.size (); i++) - { - node.active.multipliers_cb.push_back (node.config.max_work_generate_multiplier); - } - node.active.update_active_multiplier (lock); - } - // Wait for work generation to start - ASSERT_TIMELY (5s, 0 != node.work.size ()); - // Attach a callback to work cancellations - std::atomic notified{ false }; - node.observers.work_cancel.add ([¬ified, &block1] (nano::root const & root_a) { - EXPECT_EQ (root_a, block1->root ()); - notified = true; - }); - // Confirm the block - ASSERT_EQ (1, node.active.size ()); - auto election (node.active.election (block1->qualified_root ())); - ASSERT_NE (nullptr, election); - election->force_confirm (); - // Verify post conditions - ASSERT_NO_ERROR (system.poll_until_true (10s, [&node, ¬ified, &block1] { - return node.block_confirmed (block1->hash ()) && node.work.size () == 0 && notified && !node.wallets.watcher->is_watched (block1->qualified_root ()); - })); -} - -TEST (work_watcher, list_watched) -{ - nano::system system; - nano::node_config config (nano::get_available_port (), system.logging); - config.enable_voting = false; - system.add_node (config); - auto & wallet = *system.wallet (0); - nano::keypair key; - wallet.insert_adhoc (nano::dev_genesis_key.prv); - ASSERT_TRUE (wallet.wallets.watcher->list_watched ().empty ()); - auto const block1 (wallet.send_action (nano::dev_genesis_key.pub, key.pub, 100)); - auto watched1 = wallet.wallets.watcher->list_watched (); - ASSERT_EQ (1, watched1.size ()); - ASSERT_NE (watched1.end (), watched1.find (block1->qualified_root ())); - auto const block2 (wallet.send_action (nano::dev_genesis_key.pub, key.pub, 100)); - auto watched2 = wallet.wallets.watcher->list_watched (); - ASSERT_EQ (2, watched2.size ()); - ASSERT_NE (watched2.end (), watched2.find (block1->qualified_root ())); - ASSERT_NE (watched2.end (), watched2.find (block2->qualified_root ())); - wallet.wallets.watcher->remove (*block1); - auto watched3 = wallet.wallets.watcher->list_watched (); - ASSERT_EQ (1, watched3.size ()); - ASSERT_NE (watched3.end (), watched3.find (block2->qualified_root ())); - wallet.wallets.watcher->remove (*block2); - auto watched4 = wallet.wallets.watcher->list_watched (); - ASSERT_TRUE (watched4.empty ()); -} From 0a3e06be59df91263f4bec9f79868db491a0c2cf Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Fri, 30 Apr 2021 17:39:51 +0300 Subject: [PATCH 5/9] Fix rpc_test & slow_test build --- nano/rpc_test/rpc.cpp | 296 +--------------------------------------- nano/slow_test/node.cpp | 3 +- 2 files changed, 7 insertions(+), 292 deletions(-) diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 3ef4a48e3c..c8cd046cc4 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -1833,91 +1833,6 @@ TEST (rpc, process_json_block) } } -TEST (rpc, process_block_with_work_watcher) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.enable_voting = false; - node_config.work_watcher_period = 1s; - node_config.max_work_generate_multiplier = 1e6; - auto & node1 = *add_ipc_enabled_node (system, node_config); - nano::keypair key; - auto latest (node1.latest (nano::dev_genesis_key.pub)); - auto send (std::make_shared (nano::dev_genesis_key.pub, latest, nano::dev_genesis_key.pub, nano::genesis_amount - 100, nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (latest))); - auto difficulty1 (send->difficulty ()); - auto multiplier1 = nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty1, node1.network_params.network.publish_thresholds.epoch_1), node1.network_params.network.publish_thresholds.epoch_1); - nano::node_rpc_config node_rpc_config; - nano::ipc::ipc_server ipc_server (node1, node_rpc_config); - nano::rpc_config rpc_config (nano::get_available_port (), true); - rpc_config.rpc_process.ipc_port = node1.config.ipc_config.transport_tcp.port; - nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config); - nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor); - rpc.start (); - boost::property_tree::ptree request; - request.put ("action", "process"); - request.put ("watch_work", true); - std::string json; - send->serialize_json (json); - request.put ("block", json); - test_response response (request, rpc.config.port, system.io_ctx); - ASSERT_TIMELY (5s, response.status != 0); - ASSERT_EQ (200, response.status); - ASSERT_TIMELY (10s, node1.latest (nano::dev_genesis_key.pub) == send->hash ()); - system.deadline_set (10s); - auto updated (false); - double updated_multiplier; - while (!updated) - { - nano::unique_lock lock (node1.active.mutex); - //fill multipliers_cb and update active difficulty; - for (auto i (0); i < node1.active.multipliers_cb.size (); i++) - { - node1.active.multipliers_cb.push_back (multiplier1 * (1 + i / 100.)); - } - node1.active.update_active_multiplier (lock); - auto const existing (node1.active.roots.find (send->qualified_root ())); - //if existing is junk the block has been confirmed already - ASSERT_NE (existing, node1.active.roots.end ()); - updated = existing->multiplier != multiplier1; - updated_multiplier = existing->multiplier; - lock.unlock (); - ASSERT_NO_ERROR (system.poll ()); - } - ASSERT_GT (updated_multiplier, multiplier1); - - // Try without enable_control which watch_work requires if set to true - { - nano::rpc_config rpc_config (nano::get_available_port (), false); - rpc_config.rpc_process.ipc_port = node1.config.ipc_config.transport_tcp.port; - nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config); - nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor); - rpc.start (); - boost::property_tree::ptree request; - request.put ("action", "process"); - request.put ("watch_work", true); - std::string json; - send->serialize_json (json); - request.put ("block", json); - { - test_response response (request, rpc.config.port, system.io_ctx); - ASSERT_TIMELY (5s, response.status != 0); - ASSERT_EQ (200, response.status); - std::error_code ec (nano::error_rpc::rpc_control_disabled); - ASSERT_EQ (ec.message (), response.json.get ("error")); - } - - // Check no enable_control error message is present when not watching work - request.put ("watch_work", false); - { - test_response response (request, rpc.config.port, system.io_ctx); - ASSERT_TIMELY (5s, response.status != 0); - ASSERT_EQ (200, response.status); - std::error_code ec (nano::error_rpc::rpc_control_disabled); - ASSERT_NE (ec.message (), response.json.get ("error")); - } - } -} - TEST (rpc, process_block_async) { nano::system system; @@ -1969,62 +1884,6 @@ TEST (rpc, process_block_async) } } -TEST (rpc, process_block_async_work_watcher) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.enable_voting = false; - node_config.work_watcher_period = 1s; - node_config.max_work_generate_multiplier = 1e6; - auto & node1 = *add_ipc_enabled_node (system, node_config); - nano::keypair key; - auto latest (node1.latest (nano::dev_genesis_key.pub)); - auto send (std::make_shared (nano::dev_genesis_key.pub, latest, nano::dev_genesis_key.pub, nano::genesis_amount - 100, nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (latest))); - auto difficulty1 (send->difficulty ()); - auto multiplier1 = nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty1, node1.network_params.network.publish_thresholds.epoch_1), node1.network_params.network.publish_thresholds.epoch_1); - nano::node_rpc_config node_rpc_config; - nano::ipc::ipc_server ipc_server (node1, node_rpc_config); - nano::rpc_config rpc_config (nano::get_available_port (), true); - rpc_config.rpc_process.ipc_port = node1.config.ipc_config.transport_tcp.port; - nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config); - nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor); - rpc.start (); - boost::property_tree::ptree request; - request.put ("action", "process"); - request.put ("async", "true"); - request.put ("watch_work", true); - std::string json; - send->serialize_json (json); - request.put ("block", json); - { - test_response response (request, rpc.config.port, system.io_ctx); - ASSERT_TIMELY (5s, response.status != 0); - ASSERT_EQ (200, response.status); - ASSERT_EQ ("1", response.json.get ("started")); - ASSERT_TIMELY (10s, node1.latest (nano::dev_genesis_key.pub) == send->hash ()); - } - - auto updated (false); - double updated_multiplier; - while (!updated) - { - nano::unique_lock lock (node1.active.mutex); - // Fill multipliers_cb and update active difficulty - for (auto i (0); i < node1.active.multipliers_cb.size (); i++) - { - node1.active.multipliers_cb.push_back (multiplier1 * (1 + i / 100.)); - } - node1.active.update_active_multiplier (lock); - auto const existing (node1.active.roots.find (send->qualified_root ())); - // If existing is junk the block has been confirmed already - ASSERT_NE (existing, node1.active.roots.end ()); - updated = existing->multiplier != multiplier1; - updated_multiplier = existing->multiplier; - lock.unlock (); - ASSERT_NO_ERROR (system.poll ()); - } -} - TEST (rpc, process_block_no_work) { nano::system system; @@ -2241,74 +2100,6 @@ TEST (rpc, process_ledger_insufficient_work) ASSERT_EQ (response.json.get ("error"), ec.message ()); } -// Ensure that processing an old block with updated work floods it to peers -TEST (rpc, process_difficulty_update_flood) -{ - nano::system system (1); - auto & node_passive = *system.nodes[0]; - auto & node = *add_ipc_enabled_node (system); - - auto latest (node.latest (nano::dev_genesis_key.pub)); - nano::state_block send (nano::genesis_account, latest, nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node.work_generate_blocking (latest)); - - scoped_io_thread_name_change scoped_thread_name_io; - nano::node_rpc_config node_rpc_config; - nano::ipc::ipc_server ipc_server (node, node_rpc_config); - nano::rpc_config rpc_config (nano::get_available_port (), true); - - rpc_config.rpc_process.ipc_port = node.config.ipc_config.transport_tcp.port; - nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config); - nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor); - rpc.start (); - - boost::property_tree::ptree request; - request.put ("action", "process"); - // Must not watch work, otherwise the work watcher could update the block and flood it, whereas we want to ensure flooding happens on demand, without the work watcher - request.put ("watch_work", false); - { - std::string json; - send.serialize_json (json); - request.put ("block", json); - test_response response (request, rpc.config.port, system.io_ctx); - ASSERT_TIMELY (5s, response.status != 0); - ASSERT_EQ (200, response.status); - ASSERT_EQ (0, response.json.count ("error")); - } - - ASSERT_TIMELY (5s, node_passive.active.size () == 1 && node_passive.block (send.hash ()) != nullptr); - - // Update block work - node.work_generate_blocking (send, send.difficulty ()); - auto expected_multiplier = nano::normalized_multiplier (nano::difficulty::to_multiplier (send.difficulty (), nano::work_threshold (send.work_version (), nano::block_details (nano::epoch::epoch_0, true, false, false))), node.network_params.network.publish_thresholds.epoch_1); - - { - std::string json; - send.serialize_json (json); - request.put ("block", json); - std::error_code ec (nano::error_process::old); - test_response response (request, rpc.config.port, system.io_ctx); - ASSERT_TIMELY (5s, response.status != 0); - ASSERT_EQ (200, response.status); - ASSERT_EQ (response.json.get ("error"), ec.message ()); - } - - // Ensure the difficulty update occurs in both nodes - ASSERT_NO_ERROR (system.poll_until_true (5s, [&node, &node_passive, &send, expected_multiplier] { - nano::lock_guard guard (node.active.mutex); - auto const existing (node.active.roots.find (send.qualified_root ())); - EXPECT_NE (existing, node.active.roots.end ()); - - nano::lock_guard guard_passive (node_passive.active.mutex); - auto const existing_passive (node_passive.active.roots.find (send.qualified_root ())); - EXPECT_NE (existing_passive, node_passive.active.roots.end ()); - - bool updated = existing->multiplier == expected_multiplier; - bool updated_passive = existing_passive->multiplier == expected_multiplier; - - return updated && updated_passive; - })); -} - TEST (rpc, keepalive) { nano::system system; @@ -7116,81 +6907,6 @@ TEST (rpc, database_txn_tracker) thread.join (); } -TEST (rpc, active_difficulty) -{ - nano::system system; - auto node = add_ipc_enabled_node (system); - ASSERT_EQ (node->default_difficulty (nano::work_version::work_1), node->network_params.network.publish_thresholds.epoch_2); - scoped_io_thread_name_change scoped_thread_name_io; - nano::node_rpc_config node_rpc_config; - nano::ipc::ipc_server ipc_server (*node, node_rpc_config); - nano::rpc_config rpc_config (nano::get_available_port (), true); - rpc_config.rpc_process.ipc_port = node->config.ipc_config.transport_tcp.port; - nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config); - nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor); - rpc.start (); - boost::property_tree::ptree request; - request.put ("action", "active_difficulty"); - nano::unique_lock lock (node->active.mutex); - node->active.multipliers_cb.push_front (1.5); - node->active.multipliers_cb.push_front (4.2); - // Also pushes 1.0 to the front of multipliers_cb - node->active.update_active_multiplier (lock); - lock.unlock (); - auto trend_size (node->active.multipliers_cb.size ()); - ASSERT_NE (0, trend_size); - auto expected_multiplier{ (1.5 + 4.2 + (trend_size - 2) * 1) / trend_size }; - { - test_response response (request, rpc.config.port, system.io_ctx); - ASSERT_TIMELY (5s, response.status != 0); - ASSERT_EQ (200, response.status); - auto network_minimum_text (response.json.get ("network_minimum")); - uint64_t network_minimum; - ASSERT_FALSE (nano::from_string_hex (network_minimum_text, network_minimum)); - ASSERT_EQ (node->default_difficulty (nano::work_version::work_1), network_minimum); - auto network_receive_minimum_text (response.json.get ("network_receive_minimum")); - uint64_t network_receive_minimum; - ASSERT_FALSE (nano::from_string_hex (network_receive_minimum_text, network_receive_minimum)); - ASSERT_EQ (node->default_receive_difficulty (nano::work_version::work_1), network_receive_minimum); - auto multiplier (response.json.get ("multiplier")); - ASSERT_NEAR (expected_multiplier, multiplier, 1e-6); - auto network_current_text (response.json.get ("network_current")); - uint64_t network_current; - ASSERT_FALSE (nano::from_string_hex (network_current_text, network_current)); - ASSERT_EQ (nano::difficulty::from_multiplier (expected_multiplier, node->default_difficulty (nano::work_version::work_1)), network_current); - auto network_receive_current_text (response.json.get ("network_receive_current")); - uint64_t network_receive_current; - ASSERT_FALSE (nano::from_string_hex (network_receive_current_text, network_receive_current)); - auto network_receive_current_multiplier (nano::difficulty::to_multiplier (network_receive_current, network_receive_minimum)); - auto network_receive_current_normalized_multiplier (nano::normalized_multiplier (network_receive_current_multiplier, network_receive_minimum)); - ASSERT_NEAR (network_receive_current_normalized_multiplier, multiplier, 1e-6); - ASSERT_EQ (response.json.not_found (), response.json.find ("difficulty_trend")); - } - // Test include_trend optional - request.put ("include_trend", true); - { - test_response response (request, rpc.config.port, system.io_ctx); - ASSERT_TIMELY (5s, response.status != 0); - auto trend_opt (response.json.get_child_optional ("difficulty_trend")); - ASSERT_TRUE (trend_opt.is_initialized ()); - auto & trend (trend_opt.get ()); - ASSERT_EQ (trend_size, trend.size ()); - - system.deadline_set (5s); - bool done = false; - while (!done) - { - // Look for the sequence 4.2, 1.5; we don't know where as the active transaction request loop may prepend values concurrently - double values[2]{ 4.2, 1.5 }; - auto it = std::search (trend.begin (), trend.end (), values, values + 2, [] (auto a, double b) { - return a.second.template get ("") == b; - }); - done = it != trend.end (); - ASSERT_NO_ERROR (system.poll ()); - } - } -} - // This is mainly to check for threading issues with TSAN TEST (rpc, simultaneous_calls) { @@ -7895,7 +7611,7 @@ TEST (rpc, telemetry_single) nano::telemetry_data telemetry_data; auto const should_ignore_identification_metrics = false; ASSERT_FALSE (telemetry_data.deserialize_json (config, should_ignore_identification_metrics)); - nano::compare_default_telemetry_response_data (telemetry_data, node->network_params, node->config.bandwidth_limit, node->active.active_difficulty (), node->node_id); + nano::compare_default_telemetry_response_data (telemetry_data, node->network_params, node->config.bandwidth_limit, node->default_difficulty (nano::work_version::work_1), node->node_id); } } @@ -7934,7 +7650,7 @@ TEST (rpc, telemetry_all) nano::telemetry_data telemetry_data; auto const should_ignore_identification_metrics = true; ASSERT_FALSE (telemetry_data.deserialize_json (config, should_ignore_identification_metrics)); - nano::compare_default_telemetry_response_data_excluding_signature (telemetry_data, node->network_params, node->config.bandwidth_limit, node->active.active_difficulty ()); + nano::compare_default_telemetry_response_data_excluding_signature (telemetry_data, node->network_params, node->config.bandwidth_limit, node->default_difficulty (nano::work_version::work_1)); ASSERT_FALSE (response.json.get_optional ("node_id").is_initialized ()); ASSERT_FALSE (response.json.get_optional ("signature").is_initialized ()); } @@ -7953,7 +7669,7 @@ TEST (rpc, telemetry_all) nano::telemetry_data data; auto const should_ignore_identification_metrics = false; ASSERT_FALSE (data.deserialize_json (config, should_ignore_identification_metrics)); - nano::compare_default_telemetry_response_data (data, node->network_params, node->config.bandwidth_limit, node->active.active_difficulty (), node->node_id); + nano::compare_default_telemetry_response_data (data, node->network_params, node->config.bandwidth_limit, node->default_difficulty (nano::work_version::work_1), node->node_id); ASSERT_EQ (node->network.endpoint ().address ().to_string (), metrics.get ("address")); ASSERT_EQ (node->network.endpoint ().port (), metrics.get ("port")); @@ -7989,7 +7705,7 @@ TEST (rpc, telemetry_self) nano::telemetry_data data; nano::jsonconfig config (response.json); ASSERT_FALSE (data.deserialize_json (config, should_ignore_identification_metrics)); - nano::compare_default_telemetry_response_data (data, node1.network_params, node1.config.bandwidth_limit, node1.active.active_difficulty (), node1.node_id); + nano::compare_default_telemetry_response_data (data, node1.network_params, node1.config.bandwidth_limit, node1.default_difficulty (nano::work_version::work_1), node1.node_id); } request.put ("address", "[::1]"); @@ -8000,7 +7716,7 @@ TEST (rpc, telemetry_self) nano::telemetry_data data; nano::jsonconfig config (response.json); ASSERT_FALSE (data.deserialize_json (config, should_ignore_identification_metrics)); - nano::compare_default_telemetry_response_data (data, node1.network_params, node1.config.bandwidth_limit, node1.active.active_difficulty (), node1.node_id); + nano::compare_default_telemetry_response_data (data, node1.network_params, node1.config.bandwidth_limit, node1.default_difficulty (nano::work_version::work_1), node1.node_id); } request.put ("address", "127.0.0.1"); @@ -8011,7 +7727,7 @@ TEST (rpc, telemetry_self) nano::telemetry_data data; nano::jsonconfig config (response.json); ASSERT_FALSE (data.deserialize_json (config, should_ignore_identification_metrics)); - nano::compare_default_telemetry_response_data (data, node1.network_params, node1.config.bandwidth_limit, node1.active.active_difficulty (), node1.node_id); + nano::compare_default_telemetry_response_data (data, node1.network_params, node1.config.bandwidth_limit, node1.default_difficulty (nano::work_version::work_1), node1.node_id); } // Incorrect port should fail diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index cd6ba78a0c..7ad25a278f 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -37,7 +37,6 @@ TEST (system, generate_mass_activity_long) nano::node_config node_config (nano::get_available_port (), system.logging); node_config.enable_voting = false; // Prevent blocks cementing auto node = system.add_node (node_config); - system.wallet (0)->wallets.watcher->stop (); // Stop work watcher nano::thread_runner runner (system.io_ctx, system.nodes[0]->config.io_threads); system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); uint32_t count (1000000000); @@ -1500,7 +1499,7 @@ TEST (telemetry, many_nodes) ASSERT_LT (data.uptime, 100); ASSERT_EQ (data.genesis_block, genesis.hash ()); ASSERT_LE (data.timestamp, std::chrono::system_clock::now ()); - ASSERT_EQ (data.active_difficulty, system.nodes.front ()->active.active_difficulty ()); + ASSERT_EQ (data.active_difficulty, system.nodes.front ()->default_difficulty (nano::work_version::work_1)); } // We gave some nodes different bandwidth caps, confirm they are not all the same From a569e2e1443f10aef2fb56651bcfeccd7a253033 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Fri, 30 Apr 2021 17:47:51 +0300 Subject: [PATCH 6/9] Remove "active_difficulty" websocket --- nano/core_test/active_transactions.cpp | 13 ------------- nano/node/node.cpp | 9 --------- nano/node/node_observers.hpp | 1 - nano/node/websocket.cpp | 27 -------------------------- nano/node/websocket.hpp | 3 --- 5 files changed, 53 deletions(-) diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index 14f291cd8f..9e2117d54e 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -1251,19 +1251,6 @@ TEST (active_transactions, activate_inactive) ASSERT_FALSE (node.active.active (open->qualified_root ()) || node.block_confirmed_or_being_confirmed (node.store.tx_begin_read (), open->hash ())); } -TEST (active_transactions, difficulty_update_observer) -{ - nano::system system (1); - auto & node (*system.nodes[0]); - std::atomic update_received (false); - node.observers.difficulty.add ([&mutex = node.active.mutex, &update_received] (uint64_t difficulty_a) { - nano::unique_lock lock (mutex, std::defer_lock); - EXPECT_TRUE (lock.try_lock ()); - update_received = true; - }); - ASSERT_TIMELY (3s, update_received); -} - namespace nano { TEST (active_transactions, pessimistic_elections) diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 5f9033fbe1..b340abfbca 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -249,15 +249,6 @@ nano::node::node (boost::asio::io_context & io_ctx_a, boost::filesystem::path co } }); - observers.difficulty.add ([this] (uint64_t active_difficulty) { - if (this->websocket_server->any_subscriber (nano::websocket::topic::active_difficulty)) - { - nano::websocket::message_builder builder; - auto msg (builder.difficulty_changed (this->default_difficulty (nano::work_version::work_1), this->default_receive_difficulty (nano::work_version::work_1), active_difficulty)); - this->websocket_server->broadcast (msg); - } - }); - observers.telemetry.add ([this] (nano::telemetry_data const & telemetry_data, nano::endpoint const & endpoint) { if (this->websocket_server->any_subscriber (nano::websocket::topic::telemetry)) { diff --git a/nano/node/node_observers.hpp b/nano/node/node_observers.hpp index 8262c85300..78c0f0e032 100644 --- a/nano/node/node_observers.hpp +++ b/nano/node/node_observers.hpp @@ -19,7 +19,6 @@ class node_observers final nano::observer_set account_balance; nano::observer_set> endpoint; nano::observer_set<> disconnect; - nano::observer_set difficulty; nano::observer_set work_cancel; nano::observer_set telemetry; }; diff --git a/nano/node/websocket.cpp b/nano/node/websocket.cpp index f4e0831b9d..1e8bbab9b4 100644 --- a/nano/node/websocket.cpp +++ b/nano/node/websocket.cpp @@ -377,10 +377,6 @@ nano::websocket::topic to_topic (std::string const & topic_a) { topic = nano::websocket::topic::ack; } - else if (topic_a == "active_difficulty") - { - topic = nano::websocket::topic::active_difficulty; - } else if (topic_a == "work") { topic = nano::websocket::topic::work; @@ -420,10 +416,6 @@ std::string from_topic (nano::websocket::topic topic_a) { topic = "ack"; } - else if (topic_a == nano::websocket::topic::active_difficulty) - { - topic = "active_difficulty"; - } else if (topic_a == nano::websocket::topic::work) { topic = "work"; @@ -792,25 +784,6 @@ nano::websocket::message nano::websocket::message_builder::vote_received (std::s return message_l; } -nano::websocket::message nano::websocket::message_builder::difficulty_changed (uint64_t publish_threshold_a, uint64_t receive_threshold_a, uint64_t difficulty_active_a) -{ - nano::websocket::message message_l (nano::websocket::topic::active_difficulty); - set_common_fields (message_l); - - // Active difficulty information - boost::property_tree::ptree difficulty_l; - difficulty_l.put ("network_minimum", nano::to_string_hex (publish_threshold_a)); - difficulty_l.put ("network_receive_minimum", nano::to_string_hex (receive_threshold_a)); - difficulty_l.put ("network_current", nano::to_string_hex (difficulty_active_a)); - auto multiplier = nano::difficulty::to_multiplier (difficulty_active_a, publish_threshold_a); - difficulty_l.put ("multiplier", nano::to_string (multiplier)); - auto const receive_current_denormalized (nano::denormalized_multiplier (multiplier, nano::network_params{}.network.publish_thresholds.epoch_2_receive)); - difficulty_l.put ("network_receive_current", nano::to_string_hex (nano::difficulty::from_multiplier (receive_current_denormalized, receive_threshold_a))); - - message_l.contents.add_child ("message", difficulty_l); - return message_l; -} - nano::websocket::message nano::websocket::message_builder::work_generation (nano::work_version const version_a, nano::block_hash const & root_a, uint64_t work_a, uint64_t difficulty_a, uint64_t publish_threshold_a, std::chrono::milliseconds const & duration_a, std::string const & peer_a, std::vector const & bad_peers_a, bool completed_a, bool cancelled_a) { nano::websocket::message message_l (nano::websocket::topic::work); diff --git a/nano/node/websocket.hpp b/nano/node/websocket.hpp index a2084c7da0..1da806ee7b 100644 --- a/nano/node/websocket.hpp +++ b/nano/node/websocket.hpp @@ -55,8 +55,6 @@ namespace websocket stopped_election, /** A vote message **/ vote, - /** An active difficulty message */ - active_difficulty, /** Work generation message */ work, /** A bootstrap message */ @@ -95,7 +93,6 @@ namespace websocket message block_confirmed (std::shared_ptr const & block_a, nano::account const & account_a, nano::amount const & amount_a, std::string subtype, bool include_block, nano::election_status const & election_status_a, std::vector const & election_votes_a, nano::websocket::confirmation_options const & options_a); message stopped_election (nano::block_hash const & hash_a); message vote_received (std::shared_ptr const & vote_a, nano::vote_code code_a); - message difficulty_changed (uint64_t publish_threshold_a, uint64_t receive_threshold_a, uint64_t difficulty_active_a); message work_generation (nano::work_version const version_a, nano::block_hash const & root_a, uint64_t const work_a, uint64_t const difficulty_a, uint64_t const publish_threshold_a, std::chrono::milliseconds const & duration_a, std::string const & peer_a, std::vector const & bad_peers_a, bool const completed_a = true, bool const cancelled_a = false); message work_cancelled (nano::work_version const version_a, nano::block_hash const & root_a, uint64_t const difficulty_a, uint64_t const publish_threshold_a, std::chrono::milliseconds const & duration_a, std::vector const & bad_peers_a); message work_failed (nano::work_version const version_a, nano::block_hash const & root_a, uint64_t const difficulty_a, uint64_t const publish_threshold_a, std::chrono::milliseconds const & duration_a, std::vector const & bad_peers_a); From 844baac1360f72424b82a1ce988676c33808adc2 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Fri, 30 Apr 2021 17:58:18 +0300 Subject: [PATCH 7/9] Fix active_transaction.list_active test --- nano/core_test/active_transactions.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index 9e2117d54e..f1c65decad 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -1448,11 +1448,6 @@ TEST (active_transactions, list_active) ASSERT_EQ (3, node.active.list_active ().size ()); auto active = node.active.list_active (); - - auto difficulty_cmp = [] (std::shared_ptr const & election_l, std::shared_ptr const & election_r) { - return election_l->winner ()->difficulty () >= election_r->winner ()->difficulty (); - }; - ASSERT_TRUE (std::is_sorted (active.cbegin (), active.cend (), difficulty_cmp)); } TEST (active_transactions, vacancy) From 99c2db190ce08175d67858f366dd5cbfe46280d6 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Tue, 4 May 2021 15:55:05 +0300 Subject: [PATCH 8/9] Remove "watch_work" enabled control check --- nano/rpc/rpc_handler.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nano/rpc/rpc_handler.cpp b/nano/rpc/rpc_handler.cpp index e9379e14c8..313418e2eb 100644 --- a/nano/rpc/rpc_handler.cpp +++ b/nano/rpc/rpc_handler.cpp @@ -94,8 +94,7 @@ void nano::rpc_handler::process_request (nano::rpc_handler_request_params const else if (action == "process") { auto force = request.get_optional ("force").value_or (false); - auto watch_work = request.get_optional ("watch_work").value_or (true); - if ((force || watch_work) && !rpc_config.enable_control) + if (force && !rpc_config.enable_control) { json_error_response (response, rpc_control_disabled_ec.message ()); error = true; From 25e8a925209572899c5f6563072b608791c14cb1 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Tue, 4 May 2021 13:48:28 +0100 Subject: [PATCH 9/9] Waiting 2s in test since the populate_backlog function operates on a 1s loop in test. --- nano/core_test/node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 24572bf54c..7aa8cd243d 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -2655,7 +2655,7 @@ TEST (node, confirm_quorum) .build_shared (); ASSERT_EQ (nano::process_result::progress, node1.process (*send1).code); system.wallet (0)->send_action (nano::dev_genesis_key.pub, nano::dev_genesis_key.pub, new_balance.number ()); - ASSERT_TIMELY (1s, node1.active.election (send1->qualified_root ())); + ASSERT_TIMELY (2s, node1.active.election (send1->qualified_root ())); auto election = node1.active.election (send1->qualified_root ()); ASSERT_NE (nullptr, election); ASSERT_FALSE (election->confirmed ());