From b0812e7f333ec46a113cdfcffa13c4b5681a7f07 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Thu, 26 Mar 2020 17:57:19 +0300 Subject: [PATCH 1/7] Move vote generator to active transactions --- nano/core_test/node.cpp | 6 +++--- nano/node/active_transactions.cpp | 7 +++++-- nano/node/active_transactions.hpp | 2 ++ nano/node/blockprocessor.cpp | 7 +------ nano/node/blockprocessor.hpp | 6 ++---- nano/node/election.cpp | 2 +- nano/node/node.cpp | 2 +- 7 files changed, 15 insertions(+), 17 deletions(-) diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 84b227ae7e..656343a571 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -1213,7 +1213,7 @@ TEST (node, fork_publish) // Wait until the genesis rep activated & makes vote while (election->last_votes_size () != 2) { - node1.block_processor.generator.add (send1->hash ()); + node1.active.generator.add (send1->hash ()); node1.vote_processor.flush (); ASSERT_NO_ERROR (system.poll ()); } @@ -1837,7 +1837,7 @@ TEST (node, rep_self_vote) ASSERT_EQ (nano::process_result::progress, node0->process (*block0).code); auto & active (node0->active); auto election1 = active.insert (block0); - node0->block_processor.generator.add (block0->hash ()); + active.generator.add (block0->hash ()); system.deadline_set (1s); // Wait until representatives are activated & make vote while (election1.election->last_votes_size () != 3) @@ -2876,7 +2876,7 @@ TEST (node, vote_by_hash_bundle) for (int i = 1; i <= 200; i++) { nano::block_hash hash (i); - system.nodes[0]->block_processor.generator.add (hash); + system.nodes[0]->active.generator.add (hash); } // Verify that bundling occurs. While reaching 12 should be common on most hardware in release mode, diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index ebebcaddd4..ad4d761bcb 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -16,6 +16,7 @@ using namespace std::chrono; nano::active_transactions::active_transactions (nano::node & node_a, nano::confirmation_height_processor & confirmation_height_processor_a) : confirmation_height_processor (confirmation_height_processor_a), +generator (node_a.config, node_a.store, node_a.wallets, node_a.vote_processor, node_a.votes_cache, node_a.network), node (node_a), multipliers_cb (20, 1.), trended_active_difficulty (node_a.network_params.network.publish_thresholds.base), @@ -109,7 +110,7 @@ void nano::active_transactions::search_frontiers (nano::transaction const & tran // Calculate votes for local representatives if (election.prioritized && representative) { - this->node.block_processor.generator.add (info.head); + this->generator.add (info.head); } } } @@ -278,7 +279,7 @@ void nano::active_transactions::request_confirm (nano::unique_lock & solicitor.flush (); for (auto const & hash_l : hashes_generation_l) { - node.block_processor.generator.add (hash_l); + generator.add (hash_l); } lock_a.lock (); @@ -482,6 +483,7 @@ void nano::active_transactions::prioritize_frontiers_for_confirmation (nano::tra void nano::active_transactions::stop () { + generator.stop (); nano::unique_lock lock (mutex); if (!started) { @@ -1083,5 +1085,6 @@ std::unique_ptr nano::collect_container_info (ac composite->add_component (std::make_unique (container_info{ "priority_wallet_cementable_frontiers_count", active_transactions.priority_wallet_cementable_frontiers_size (), sizeof (nano::cementable_account) })); composite->add_component (std::make_unique (container_info{ "priority_cementable_frontiers_count", active_transactions.priority_cementable_frontiers_size (), sizeof (nano::cementable_account) })); composite->add_component (std::make_unique (container_info{ "inactive_votes_cache_count", active_transactions.inactive_votes_cache_size (), sizeof (nano::gap_information) })); + composite->add_component (collect_container_info (active_transactions.generator, "generator")); return composite; } diff --git a/nano/node/active_transactions.hpp b/nano/node/active_transactions.hpp index b6071e16b7..8bc14c2243 100644 --- a/nano/node/active_transactions.hpp +++ b/nano/node/active_transactions.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -149,6 +150,7 @@ class active_transactions final 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 &); + nano::vote_generator generator; private: std::mutex election_winner_details_mutex; diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 18124dc042..81328bcd74 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -10,9 +10,6 @@ std::chrono::milliseconds constexpr nano::block_processor::confirmation_request_delay; nano::block_processor::block_processor (nano::node & node_a, nano::write_database_queue & write_database_queue_a) : -generator (node_a.config, node_a.store, node_a.wallets, node_a.vote_processor, node_a.votes_cache, node_a.network), -stopped (false), -active (false), next_log (std::chrono::steady_clock::now ()), node (node_a), write_database_queue (write_database_queue_a), @@ -40,7 +37,6 @@ nano::block_processor::~block_processor () void nano::block_processor::stop () { - generator.stop (); { nano::lock_guard lock (mutex); stopped = true; @@ -295,7 +291,7 @@ void nano::block_processor::process_live (nano::block_hash const & hash_a, std:: if (election.prioritized && node.config.enable_voting && node.wallets.rep_counts ().voting > 0) { // Announce our weighted vote to the network - generator.add (hash_a); + node.active.generator.add (hash_a); } } @@ -501,6 +497,5 @@ std::unique_ptr nano::collect_container_info (bl composite->add_component (collect_container_info (block_processor.state_block_signature_verification, "state_block_signature_verification")); composite->add_component (std::make_unique (container_info{ "blocks", blocks_count, sizeof (decltype (block_processor.blocks)::value_type) })); composite->add_component (std::make_unique (container_info{ "forced", forced_count, sizeof (decltype (block_processor.forced)::value_type) })); - composite->add_component (collect_container_info (block_processor.generator, "generator")); return composite; } diff --git a/nano/node/blockprocessor.hpp b/nano/node/blockprocessor.hpp index e87882c4fa..ca6299ccf5 100644 --- a/nano/node/blockprocessor.hpp +++ b/nano/node/blockprocessor.hpp @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -45,7 +44,6 @@ class block_processor final void process_blocks (); nano::process_return process_one (nano::write_transaction const &, nano::unchecked_info, const bool = false, const bool = false); nano::process_return process_one (nano::write_transaction const &, std::shared_ptr, const bool = false); - nano::vote_generator generator; std::atomic flushing{ false }; // Delay required for average network propagartion before requesting confirmation static std::chrono::milliseconds constexpr confirmation_request_delay{ 1500 }; @@ -56,8 +54,8 @@ class block_processor final void process_live (nano::block_hash const &, std::shared_ptr, const bool = false, const bool = false); 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 &); - bool stopped; - bool active; + bool stopped{ false }; + bool active{ false }; bool awaiting_write{ false }; std::chrono::steady_clock::time_point next_log; std::deque blocks; diff --git a/nano/node/election.cpp b/nano/node/election.cpp index e9b776e718..b7072fcf68 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -357,7 +357,7 @@ void nano::election::confirm_if_quorum () if (node.config.enable_voting && node.wallets.rep_counts ().voting > 0) { node.votes_cache.remove (status_winner_hash_l); - node.block_processor.generator.add (winner_hash_l); + node.active.generator.add (winner_hash_l); } node.block_processor.force (block_l); status.winner = block_l; diff --git a/nano/node/node.cpp b/nano/node/node.cpp index b263d64e7d..9c6e8afded 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -1102,7 +1102,7 @@ void nano::node::block_confirm (std::shared_ptr block_a) // Calculate votes for local representatives if (election.prioritized && config.enable_voting && wallets.rep_counts ().voting > 0 && active.active (*block_a)) { - block_processor.generator.add (block_a->hash ()); + active.generator.add (block_a->hash ()); } } From c5d52ec140c619a68750fbf80303b19ffca2459b Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Fri, 27 Mar 2020 01:02:44 +0300 Subject: [PATCH 2/7] Add generate_votes () function to election --- nano/node/active_transactions.cpp | 7 ++++++- nano/node/blockprocessor.cpp | 4 ++-- nano/node/election.cpp | 10 +++++++++- nano/node/election.hpp | 2 ++ nano/node/node.cpp | 4 ++-- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index aa34b0e61e..7aaa778777 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -110,7 +110,7 @@ void nano::active_transactions::search_frontiers (nano::transaction const & tran // Calculate votes for local representatives if (election.prioritized && representative) { - this->generator.add (info.head); + election.election->generate_votes(); } } } @@ -520,6 +520,11 @@ nano::election_insertion_result nano::active_transactions::insert_impl (std::sha blocks.emplace (hash, result.election); add_adjust_difficulty (hash); result.election->insert_inactive_votes_cache (hash); + // Calculate votes for local representatives + if (result.prioritized) + { + result.election->generate_votes (); + } } } else diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index c9ac8cb613..2f3ad2ea00 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -288,10 +288,10 @@ void nano::block_processor::process_live (nano::block_hash const & hash_a, std:: { node.network.flood_block (block_a, nano::buffer_drop_policy::no_limiter_drop); } - if (election.prioritized && node.config.enable_voting && node.wallets.rep_counts ().voting > 0) + if (election.prioritized) { // Announce our weighted vote to the network - node.active.generator.add (hash_a); + election.election->generate_votes (); } } diff --git a/nano/node/election.cpp b/nano/node/election.cpp index b7072fcf68..ed86370a46 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -357,7 +357,7 @@ void nano::election::confirm_if_quorum () if (node.config.enable_voting && node.wallets.rep_counts ().voting > 0) { node.votes_cache.remove (status_winner_hash_l); - node.active.generator.add (winner_hash_l); + generate_votes (); } node.block_processor.force (block_l); status.winner = block_l; @@ -576,3 +576,11 @@ void nano::election::insert_inactive_votes_cache (nano::block_hash const & hash_ confirm_if_quorum (); } } + +void nano::election::generate_votes () +{ + if (node.config.enable_voting && node.wallets.rep_counts ().voting > 0) + { + node.active.generator.add (status.winner->hash ()); + } +} diff --git a/nano/node/election.hpp b/nano/node/election.hpp index 4d21435f29..3723898a1d 100644 --- a/nano/node/election.hpp +++ b/nano/node/election.hpp @@ -78,6 +78,8 @@ class election final : public std::enable_shared_from_this void update_dependent (); void adjust_dependent_difficulty (); void insert_inactive_votes_cache (nano::block_hash const &); + // Calculate votes for local representatives + void generate_votes (); // Erase all blocks from active and, if not confirmed, clear digests from network filters void cleanup (); diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 7f9c3ba773..7e0515453a 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -1104,9 +1104,9 @@ void nano::node::block_confirm (std::shared_ptr block_a) election.election->transition_active (); } // Calculate votes for local representatives - if (election.prioritized && config.enable_voting && wallets.rep_counts ().voting > 0 && active.active (*block_a)) + if (election.prioritized && active.active (*block_a)) { - active.generator.add (block_a->hash ()); + election.election->generate_votes (); } } From 43e7868eb39281fa20e085509142975148b813f3 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Fri, 27 Mar 2020 01:53:51 +0300 Subject: [PATCH 3/7] Call votes generation only from elections - for started election (also for non-prioritized) - for changed winner --- nano/core_test/node.cpp | 5 +++-- nano/node/active_transactions.cpp | 25 ++----------------------- nano/node/active_transactions.hpp | 3 ++- nano/node/blockprocessor.cpp | 5 ----- nano/node/election.cpp | 20 +++++++++++++------- nano/node/election.hpp | 3 ++- nano/node/node.cpp | 5 ----- 7 files changed, 22 insertions(+), 44 deletions(-) diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index dae8a4ee02..ae3863292b 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -1238,7 +1238,6 @@ TEST (node, fork_publish) // Wait until the genesis rep activated & makes vote while (election->last_votes_size () != 2) { - node1.active.generator.add (send1->hash ()); node1.vote_processor.flush (); ASSERT_NO_ERROR (system.poll ()); } @@ -1886,7 +1885,6 @@ TEST (node, rep_self_vote) ASSERT_EQ (nano::process_result::progress, node0->process (*block0).code); auto & active (node0->active); auto election1 = active.insert (block0); - active.generator.add (block0->hash ()); system.deadline_set (1s); // Wait until representatives are activated & make vote while (election1.election->last_votes_size () != 3) @@ -2905,6 +2903,8 @@ TEST (node, vote_republish) } } +namespace nano +{ TEST (node, vote_by_hash_bundle) { // Keep max_hashes above system to ensure it is kept in scope as votes can be added during system destruction @@ -2936,6 +2936,7 @@ TEST (node, vote_by_hash_bundle) ASSERT_NO_ERROR (system.poll ()); } } +} TEST (node, vote_by_hash_republish) { diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index 7aaa778777..cd380509d0 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -84,7 +84,7 @@ void nano::active_transactions::search_frontiers (nano::transaction const & tran size_t elections_count (0); lk.lock (); - auto start_elections_for_prioritized_frontiers = [&transaction_a, &elections_count, max_elections, &lk, &representative, this](prioritize_num_uncemented & cementable_frontiers) { + auto start_elections_for_prioritized_frontiers = [&transaction_a, &elections_count, max_elections, &lk, this](prioritize_num_uncemented & cementable_frontiers) { while (!cementable_frontiers.empty () && !this->stopped && elections_count < max_elections) { auto cementable_account_front_it = cementable_frontiers.get ().begin (); @@ -107,11 +107,6 @@ void nano::active_transactions::search_frontiers (nano::transaction const & tran { election.election->transition_active (); ++elections_count; - // Calculate votes for local representatives - if (election.prioritized && representative) - { - election.election->generate_votes(); - } } } } @@ -232,8 +227,6 @@ void nano::active_transactions::request_confirm (nano::unique_lock & nano::confirmation_solicitor solicitor (node.network, node.network_params.network); solicitor.prepare (node.rep_crawler.principal_representatives (std::numeric_limits::max (), node.network_params.protocol.tcp_realtime_protocol_version_min)); - bool const representative_l (node.config.enable_voting && node.wallets.rep_counts ().voting > 0); - std::vector hashes_generation_l; auto & sorted_roots_l (roots.get ()); auto const election_ttl_cutoff_l (std::chrono::steady_clock::now () - election_time_to_live); bool const check_all_elections_l (std::chrono::steady_clock::now () - last_check_all_elections > check_all_elections_period); @@ -253,14 +246,9 @@ void nano::active_transactions::request_confirm (nano::unique_lock & auto & election_l (i->election); bool const confirmed_l (election_l->confirmed ()); - // Queue vote generation for newly prioritized elections if (!i->prioritized && unconfirmed_count_l < prioritized_cutoff) { sorted_roots_l.modify (i, [](nano::conflict_info & info_a) { info_a.prioritized = true; }); - if (representative_l && !confirmed_l) - { - hashes_generation_l.push_back (election_l->status.winner->hash ()); - } } unconfirmed_count_l += !confirmed_l; @@ -277,10 +265,6 @@ void nano::active_transactions::request_confirm (nano::unique_lock & } lock_a.unlock (); solicitor.flush (); - for (auto const & hash_l : hashes_generation_l) - { - generator.add (hash_l); - } lock_a.lock (); // This is updated after the loop to ensure slow machines don't do the full check often @@ -483,7 +467,6 @@ void nano::active_transactions::prioritize_frontiers_for_confirmation (nano::tra void nano::active_transactions::stop () { - generator.stop (); nano::unique_lock lock (mutex); if (!started) { @@ -496,6 +479,7 @@ void nano::active_transactions::stop () { thread.join (); } + generator.stop (); lock.lock (); roots.clear (); } @@ -520,11 +504,6 @@ nano::election_insertion_result nano::active_transactions::insert_impl (std::sha blocks.emplace (hash, result.election); add_adjust_difficulty (hash); result.election->insert_inactive_votes_cache (hash); - // Calculate votes for local representatives - if (result.prioritized) - { - result.election->generate_votes (); - } } } else diff --git a/nano/node/active_transactions.hpp b/nano/node/active_transactions.hpp index 8bc14c2243..b411ce0e34 100644 --- a/nano/node/active_transactions.hpp +++ b/nano/node/active_transactions.hpp @@ -150,11 +150,11 @@ class active_transactions final 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 &); - nano::vote_generator generator; private: std::mutex election_winner_details_mutex; std::unordered_map> election_winner_details; + nano::vote_generator generator; // Call action with confirmed block, may be different than what we started with // clang-format off @@ -225,6 +225,7 @@ class active_transactions final friend class confirmation_height_prioritize_frontiers_Test; friend class confirmation_height_prioritize_frontiers_overwrite_Test; friend class active_transactions_confirmation_consistency_Test; + friend class node_vote_by_hash_bundle_Test; friend std::unique_ptr collect_container_info (active_transactions &, const std::string &); }; diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 2f3ad2ea00..1891dbc49a 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -288,11 +288,6 @@ void nano::block_processor::process_live (nano::block_hash const & hash_a, std:: { node.network.flood_block (block_a, nano::buffer_drop_policy::no_limiter_drop); } - if (election.prioritized) - { - // Announce our weighted vote to the network - election.election->generate_votes (); - } } nano::process_return nano::block_processor::process_one (nano::write_transaction const & transaction_a, nano::unchecked_info info_a, const bool watch_work_a, const bool first_publish_a) diff --git a/nano/node/election.cpp b/nano/node/election.cpp index ed86370a46..cc73304a36 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -31,6 +31,7 @@ status ({ block_a, 0, std::chrono::duration_cast (std last_votes.emplace (node.network_params.random.not_an_account, nano::vote_info{ std::chrono::steady_clock::now (), 0, block_a->hash () }); blocks.emplace (block_a->hash (), block_a); update_dependent (); + generate_votes (block_a->hash ()); } void nano::election::confirm_once (nano::election_status_type type_a) @@ -354,11 +355,8 @@ void nano::election::confirm_if_quorum () } if (sum >= node.config.online_weight_minimum.number () && winner_hash_l != status_winner_hash_l) { - if (node.config.enable_voting && node.wallets.rep_counts ().voting > 0) - { - node.votes_cache.remove (status_winner_hash_l); - generate_votes (); - } + remove_votes (status_winner_hash_l); + generate_votes (winner_hash_l); node.block_processor.force (block_l); status.winner = block_l; update_dependent (); @@ -577,10 +575,18 @@ void nano::election::insert_inactive_votes_cache (nano::block_hash const & hash_ } } -void nano::election::generate_votes () +void nano::election::generate_votes (nano::block_hash const & hash_a) +{ + if (node.config.enable_voting && node.wallets.rep_counts ().voting > 0) + { + node.active.generator.add (hash_a); + } +} + +void nano::election::remove_votes (nano::block_hash const & hash_a) { if (node.config.enable_voting && node.wallets.rep_counts ().voting > 0) { - node.active.generator.add (status.winner->hash ()); + node.votes_cache.remove (hash_a); } } diff --git a/nano/node/election.hpp b/nano/node/election.hpp index 3723898a1d..fcd91fd12c 100644 --- a/nano/node/election.hpp +++ b/nano/node/election.hpp @@ -79,7 +79,8 @@ class election final : public std::enable_shared_from_this void adjust_dependent_difficulty (); void insert_inactive_votes_cache (nano::block_hash const &); // Calculate votes for local representatives - void generate_votes (); + void generate_votes (nano::block_hash const &); + void remove_votes (nano::block_hash const &); // Erase all blocks from active and, if not confirmed, clear digests from network filters void cleanup (); diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 7e0515453a..86ced5f114 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -1103,11 +1103,6 @@ void nano::node::block_confirm (std::shared_ptr block_a) { election.election->transition_active (); } - // Calculate votes for local representatives - if (election.prioritized && active.active (*block_a)) - { - election.election->generate_votes (); - } } bool nano::node::block_confirmed_or_being_confirmed (nano::transaction const & transaction_a, nano::block_hash const & hash_a) From 64abe1cf800a6478c6905387445f68ff59e0ed46 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Fri, 27 Mar 2020 14:22:17 +0300 Subject: [PATCH 4/7] Restore elections prioritization --- nano/core_test/active_transactions.cpp | 14 +++++++------- nano/core_test/confirmation_solicitor.cpp | 4 ++-- nano/node/active_transactions.cpp | 10 +++++----- nano/node/active_transactions.hpp | 2 -- nano/node/election.cpp | 22 +++++++++++++++++++--- nano/node/election.hpp | 11 +++++++---- 6 files changed, 40 insertions(+), 23 deletions(-) diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index c477cadafa..249eb94195 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -882,19 +882,19 @@ TEST (active_transactions, insertion_prioritization) node.active.update_active_difficulty (lock); }; - ASSERT_TRUE (node.active.insert (blocks[2]).prioritized); + ASSERT_TRUE (node.active.insert (blocks[2]).election->prioritized ()); update_active_difficulty (); - ASSERT_FALSE (node.active.insert (blocks[3]).prioritized); + ASSERT_FALSE (node.active.insert (blocks[3]).election->prioritized ()); update_active_difficulty (); - ASSERT_TRUE (node.active.insert (blocks[1]).prioritized); + ASSERT_TRUE (node.active.insert (blocks[1]).election->prioritized ()); update_active_difficulty (); - ASSERT_FALSE (node.active.insert (blocks[4]).prioritized); + ASSERT_FALSE (node.active.insert (blocks[4]).election->prioritized ()); update_active_difficulty (); - ASSERT_TRUE (node.active.insert (blocks[0]).prioritized); + ASSERT_TRUE (node.active.insert (blocks[0]).election->prioritized ()); update_active_difficulty (); - ASSERT_FALSE (node.active.insert (blocks[5]).prioritized); + ASSERT_FALSE (node.active.insert (blocks[5]).election->prioritized ()); update_active_difficulty (); - ASSERT_FALSE (node.active.insert (blocks[6]).prioritized); + ASSERT_FALSE (node.active.insert (blocks[6]).election->prioritized ()); } TEST (active_difficulty, less_than_one) diff --git a/nano/core_test/confirmation_solicitor.cpp b/nano/core_test/confirmation_solicitor.cpp index ef97f49d9f..f7dd96c227 100644 --- a/nano/core_test/confirmation_solicitor.cpp +++ b/nano/core_test/confirmation_solicitor.cpp @@ -33,12 +33,12 @@ 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)); + auto election (std::make_shared (node2, send, nullptr, false)); ASSERT_FALSE (solicitor.add (*election)); } ASSERT_EQ (1, solicitor.max_confirm_req_batches); // Reached the maximum amount of requests for the channel - auto election (std::make_shared (node2, send, nullptr)); + auto election (std::make_shared (node2, send, nullptr, false)); 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)); diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index cd380509d0..9a876186f3 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -246,9 +246,9 @@ void nano::active_transactions::request_confirm (nano::unique_lock & auto & election_l (i->election); bool const confirmed_l (election_l->confirmed ()); - if (!i->prioritized && unconfirmed_count_l < prioritized_cutoff) + if (!election_l->prioritized () && unconfirmed_count_l < prioritized_cutoff) { - sorted_roots_l.modify (i, [](nano::conflict_info & info_a) { info_a.prioritized = true; }); + election_l->prioritize_election (); } unconfirmed_count_l += !confirmed_l; @@ -497,10 +497,10 @@ nano::election_insertion_result nano::active_transactions::insert_impl (std::sha { result.inserted = true; auto hash (block_a->hash ()); - result.election = nano::make_shared (node, block_a, confirmation_action_a); auto difficulty (block_a->difficulty ()); - result.prioritized = roots.size () < prioritized_cutoff || difficulty > last_prioritized_difficulty.value_or (0); - roots.get ().emplace (nano::conflict_info{ root, difficulty, difficulty, result.election, result.prioritized }); + bool prioritized = roots.size () < prioritized_cutoff || difficulty > last_prioritized_difficulty.value_or (0); + result.election = nano::make_shared (node, block_a, confirmation_action_a, prioritized); + roots.get ().emplace (nano::conflict_info{ root, difficulty, difficulty, result.election }); blocks.emplace (hash, result.election); add_adjust_difficulty (hash); result.election->insert_inactive_votes_cache (hash); diff --git a/nano/node/active_transactions.hpp b/nano/node/active_transactions.hpp index b411ce0e34..4d96602691 100644 --- a/nano/node/active_transactions.hpp +++ b/nano/node/active_transactions.hpp @@ -38,7 +38,6 @@ class conflict_info final uint64_t difficulty; uint64_t adjusted_difficulty; std::shared_ptr election; - bool prioritized; }; class cementable_account final @@ -71,7 +70,6 @@ class election_insertion_result final public: std::shared_ptr election; bool inserted{ false }; - bool prioritized{ false }; }; // Core class for determining consensus diff --git a/nano/node/election.cpp b/nano/node/election.cpp index cc73304a36..62c5b6445f 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -22,16 +22,20 @@ 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 block_a, std::function)> const & confirmation_action_a) : +nano::election::election (nano::node & node_a, std::shared_ptr block_a, std::function)> const & confirmation_action_a, bool prioritized_a) : confirmation_action (confirmation_action_a), state_start (std::chrono::steady_clock::now ()), 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 }) +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 }), +prioritized_m (prioritized_a) { last_votes.emplace (node.network_params.random.not_an_account, nano::vote_info{ std::chrono::steady_clock::now (), 0, block_a->hash () }); blocks.emplace (block_a->hash (), block_a); update_dependent (); - generate_votes (block_a->hash ()); + if (prioritized_a) + { + generate_votes (block_a->hash ()); + } } void nano::election::confirm_once (nano::election_status_type type_a) @@ -575,6 +579,18 @@ void nano::election::insert_inactive_votes_cache (nano::block_hash const & hash_ } } +bool nano::election::prioritized () +{ + return prioritized_m; +} + +void nano::election::prioritize_election () +{ + debug_assert (!node.active.mutex.try_lock ()); + prioritized_m = true; + generate_votes (status.winner->hash ()); +} + void nano::election::generate_votes (nano::block_hash const & hash_a) { if (node.config.enable_voting && node.wallets.rep_counts ().voting > 0) diff --git a/nano/node/election.hpp b/nano/node/election.hpp index fcd91fd12c..c798456758 100644 --- a/nano/node/election.hpp +++ b/nano/node/election.hpp @@ -62,9 +62,13 @@ class election final : public std::enable_shared_from_this void broadcast_block (nano::confirmation_solicitor &); void send_confirm_req (nano::confirmation_solicitor &); void activate_dependencies (); + // Calculate votes for local representatives + void generate_votes (nano::block_hash const &); + void remove_votes (nano::block_hash const &); + std::atomic prioritized_m = { false }; public: - election (nano::node &, std::shared_ptr, std::function)> const &); + election (nano::node &, std::shared_ptr, std::function)> const &, bool); nano::election_vote_result vote (nano::account, uint64_t, nano::block_hash); nano::tally_t tally (); // Check if we have vote quorum @@ -78,9 +82,8 @@ class election final : public std::enable_shared_from_this void update_dependent (); void adjust_dependent_difficulty (); void insert_inactive_votes_cache (nano::block_hash const &); - // Calculate votes for local representatives - void generate_votes (nano::block_hash const &); - void remove_votes (nano::block_hash const &); + bool prioritized (); + void prioritize_election (); // Erase all blocks from active and, if not confirmed, clear digests from network filters void cleanup (); From a6cc0819d8b2e8bf283f33f790f41a12702502e4 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Tue, 31 Mar 2020 01:37:48 +0300 Subject: [PATCH 5/7] Assert multiple prioritizations --- nano/node/election.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/nano/node/election.cpp b/nano/node/election.cpp index 62c5b6445f..af1a02647b 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -587,6 +587,7 @@ bool nano::election::prioritized () void nano::election::prioritize_election () { debug_assert (!node.active.mutex.try_lock ()); + debug_assert (!prioritized_m); prioritized_m = true; generate_votes (status.winner->hash ()); } From 1a8b8ba91fddca6cfa535a76ce91d6bf7c6d2e5c Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Wed, 1 Apr 2020 01:49:25 +0300 Subject: [PATCH 6/7] Apply Wesley review --- nano/node/election.cpp | 2 +- nano/node/election.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nano/node/election.cpp b/nano/node/election.cpp index af1a02647b..4ec3490c3a 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -579,7 +579,7 @@ void nano::election::insert_inactive_votes_cache (nano::block_hash const & hash_ } } -bool nano::election::prioritized () +bool nano::election::prioritized () const { return prioritized_m; } diff --git a/nano/node/election.hpp b/nano/node/election.hpp index c798456758..0d06e32613 100644 --- a/nano/node/election.hpp +++ b/nano/node/election.hpp @@ -82,7 +82,7 @@ class election final : public std::enable_shared_from_this void update_dependent (); void adjust_dependent_difficulty (); void insert_inactive_votes_cache (nano::block_hash const &); - bool prioritized (); + bool prioritized () const; void prioritize_election (); // Erase all blocks from active and, if not confirmed, clear digests from network filters void cleanup (); From 494b3bcaf1eb399a6a9525558d5207b08bf3c6c9 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Wed, 1 Apr 2020 02:31:01 +0300 Subject: [PATCH 7/7] Remove local votes from election with winner change --- nano/node/election.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/nano/node/election.cpp b/nano/node/election.cpp index 4ec3490c3a..bd6c67c745 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -604,6 +604,13 @@ void nano::election::remove_votes (nano::block_hash const & hash_a) { if (node.config.enable_voting && node.wallets.rep_counts ().voting > 0) { + // Remove votes from election + auto list_generated_votes (node.votes_cache.find (hash_a)); + for (auto const & vote : list_generated_votes) + { + last_votes.erase (vote->account); + } + // Clear votes cache node.votes_cache.remove (hash_a); } }