From aa1c493165cb573ec803d3eefec9c3615aac2c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Thu, 9 May 2024 12:53:18 +0200 Subject: [PATCH 1/6] Document message headers --- nano/node/messages.hpp | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/nano/node/messages.hpp b/nano/node/messages.hpp index 11d96d6bad..27acb3024d 100644 --- a/nano/node/messages.hpp +++ b/nano/node/messages.hpp @@ -60,6 +60,18 @@ enum class bulk_pull_account_flags : uint8_t class message_visitor; +/* + * Common Header Binary Format: + * [2 bytes] Network (big endian) + * [1 byte] Maximum protocol version + * [1 byte] Protocol version currently in use + * [1 byte] Minimum protocol version + * [1 byte] Message type + * [2 bytes] Extensions (message-specific flags and properties) + * + * Notes: + * - The structure and bit usage of the `extensions` field vary by message type. + */ class message_header final { public: @@ -140,6 +152,14 @@ class message virtual void operator() (nano::object_stream &) const; }; +/* + * Binary Format: + * [message_header] Common message header + * [8x (16 bytes (IP) + 2 bytes (port)] Array of 8 peers + * + * Header extensions: + * - No specific bits from the `extensions` field are used for `keepalive`. + */ class keepalive final : public message { public: @@ -156,6 +176,14 @@ class keepalive final : public message void operator() (nano::object_stream &) const override; }; +/* + * Binary Format: + * [message_header] Common message header + * [variable] Block (serialized according to the block type specified in the header) + * + * Header extensions: + * - [0x0f00] Block type: Identifies the specific type of the block. + */ class publish final : public message { public: @@ -172,6 +200,19 @@ class publish final : public message void operator() (nano::object_stream &) const override; }; +/* + * Binary Format: + * [message_header] Common message header + * [N x (32 bytes (block hash) + 32 bytes (root))] Pairs of (block_hash, root) + * - The count is determined by the header's count bits. + * + * Header extensions: + * - [0xf000] Count (for V1 protocol) + * - [0x0f00] Block type + * - Not used anymore (V25.1+), but still present and set to `not_a_block = 0x1` for backwards compatibility + * - [0xf000 (high), 0x00f0 (low)] Count V2 (for V2 protocol) + * - [0x0001] Confirm V2 flag + */ class confirm_req final : public message { public: @@ -197,6 +238,20 @@ class confirm_req final : public message void operator() (nano::object_stream &) const override; }; +/* + * Binary Format: + * [message_header] Common message header + * [variable] Vote + * - Serialized/deserialized by the `nano::vote` class. + * + * Header extensions: + * - [0xf000] Count (for V1 protocol) + * - [0x0f00] Block type + * - Not used anymore (V25.1+), but still present and set to `not_a_block = 0x1` for backwards compatibility + * - [0xf000 (high), 0x00f0 (low)] Count V2 masks (for V2 protocol) + * - [0x0001] Confirm V2 flag + * - [0x0002] Rebroadcasted flag + */ class confirm_ack final : public message { public: From 7173b75170709f9478b03af6bc5a38ac55c737d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Sat, 11 May 2024 23:29:42 +0200 Subject: [PATCH 2/6] Add `is_rebroadcasted` flag --- nano/core_test/message.cpp | 23 +++++++++++++++++++++++ nano/node/messages.cpp | 8 +++++++- nano/node/messages.hpp | 9 +++++++-- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/nano/core_test/message.cpp b/nano/core_test/message.cpp index 3053bbf04c..1e9728b65f 100644 --- a/nano/core_test/message.cpp +++ b/nano/core_test/message.cpp @@ -182,6 +182,7 @@ TEST (message, confirm_ack_hash_serialization) ASSERT_EQ (hashes, con2.vote->hashes); ASSERT_FALSE (header.confirm_is_v2 ()); ASSERT_EQ (header.count_get (), hashes.size ()); + ASSERT_FALSE (con2.is_rebroadcasted ()); } TEST (message, confirm_ack_hash_serialization_v2) @@ -223,6 +224,28 @@ TEST (message, confirm_ack_hash_serialization_v2) ASSERT_EQ (hashes, con2.vote->hashes); ASSERT_TRUE (header.confirm_is_v2 ()); ASSERT_EQ (header.count_v2_get (), hashes.size ()); + ASSERT_FALSE (con2.is_rebroadcasted ()); +} + +TEST (message, confirm_ack_rebroadcasted_flag) +{ + nano::keypair representative1; + auto vote = nano::test::make_vote (representative1, std::vector (), 0, 0); + nano::confirm_ack con1{ nano::dev::network_params.network, vote, /* rebroadcasted */ true }; + ASSERT_TRUE (con1.is_rebroadcasted ()); + std::vector bytes; + { + nano::vectorstream stream1 (bytes); + con1.serialize (stream1); + } + nano::bufferstream stream2 (bytes.data (), bytes.size ()); + bool error (false); + nano::message_header header (error, stream2); + nano::confirm_ack con2 (error, stream2, header); + ASSERT_FALSE (error); + ASSERT_EQ (con1, con2); + ASSERT_TRUE (con2.vote->hashes.empty ()); + ASSERT_TRUE (con2.is_rebroadcasted ()); } TEST (message, confirm_req_hash_serialization) diff --git a/nano/node/messages.cpp b/nano/node/messages.cpp index 5a7bb54996..ac82d67b27 100644 --- a/nano/node/messages.cpp +++ b/nano/node/messages.cpp @@ -616,13 +616,14 @@ nano::confirm_ack::confirm_ack (bool & error_a, nano::stream & stream_a, nano::m } } -nano::confirm_ack::confirm_ack (nano::network_constants const & constants, std::shared_ptr const & vote_a) : +nano::confirm_ack::confirm_ack (nano::network_constants const & constants, std::shared_ptr const & vote_a, bool rebroadcasted_a) : message (constants, nano::message_type::confirm_ack), vote (vote_a) { debug_assert (vote->hashes.size () < 256); header.block_type_set (nano::block_type::not_a_block); + header.flag_set (rebroadcasted_flag, rebroadcasted_a); if (vote->hashes.size () >= 16) { @@ -671,6 +672,11 @@ std::size_t nano::confirm_ack::size (const nano::message_header & header) return nano::vote::size (count); } +bool nano::confirm_ack::is_rebroadcasted () const +{ + return header.flag_test (rebroadcasted_flag); +} + void nano::confirm_ack::operator() (nano::object_stream & obs) const { nano::message::operator() (obs); // Write common data diff --git a/nano/node/messages.hpp b/nano/node/messages.hpp index 27acb3024d..5046eae812 100644 --- a/nano/node/messages.hpp +++ b/nano/node/messages.hpp @@ -212,6 +212,7 @@ class publish final : public message * - Not used anymore (V25.1+), but still present and set to `not_a_block = 0x1` for backwards compatibility * - [0xf000 (high), 0x00f0 (low)] Count V2 (for V2 protocol) * - [0x0001] Confirm V2 flag + * - [0x0002] Reserved for V3+ versioning */ class confirm_req final : public message { @@ -250,13 +251,14 @@ class confirm_req final : public message * - Not used anymore (V25.1+), but still present and set to `not_a_block = 0x1` for backwards compatibility * - [0xf000 (high), 0x00f0 (low)] Count V2 masks (for V2 protocol) * - [0x0001] Confirm V2 flag - * - [0x0002] Rebroadcasted flag + * - [0x0002] Reserved for V3+ versioning + * - [0x0004] Rebroadcasted flag */ class confirm_ack final : public message { public: confirm_ack (bool & error, nano::stream &, nano::message_header const &, nano::vote_uniquer * = nullptr); - confirm_ack (nano::network_constants const & constants, std::shared_ptr const &); + confirm_ack (nano::network_constants const & constants, std::shared_ptr const &, bool rebroadcasted = false); void serialize (nano::stream &) const override; void visit (nano::message_visitor &) const override; @@ -264,6 +266,9 @@ class confirm_ack final : public message static std::size_t size (nano::message_header const &); + static uint8_t constexpr rebroadcasted_flag = 2; // 0x0004 + bool is_rebroadcasted () const; + private: static uint8_t hash_count (nano::message_header const &); From 403cc664ae5c4c98f46bf00e09a61aff45da998a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Mon, 13 May 2024 19:34:13 +0200 Subject: [PATCH 3/6] Mark rebroadcasted votes --- nano/node/network.cpp | 8 ++++---- nano/node/network.hpp | 4 ++-- nano/node/node.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/nano/node/network.cpp b/nano/node/network.cpp index bd4c77bc2a..f741aa7f2f 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -266,18 +266,18 @@ void nano::network::flood_block_initial (std::shared_ptr const & bl } } -void nano::network::flood_vote (std::shared_ptr const & vote_a, float scale) +void nano::network::flood_vote (std::shared_ptr const & vote, float scale, bool rebroadcasted) { - nano::confirm_ack message{ node.network_params.network, vote_a }; + nano::confirm_ack message{ node.network_params.network, vote, rebroadcasted }; for (auto & i : list (fanout (scale))) { i->send (message, nullptr); } } -void nano::network::flood_vote_pr (std::shared_ptr const & vote_a) +void nano::network::flood_vote_pr (std::shared_ptr const & vote, bool rebroadcasted) { - nano::confirm_ack message{ node.network_params.network, vote_a }; + nano::confirm_ack message{ node.network_params.network, vote, rebroadcasted }; for (auto const & i : node.rep_crawler.principal_representatives ()) { i.channel->send (message, nullptr, nano::transport::buffer_drop_policy::no_limiter_drop); diff --git a/nano/node/network.hpp b/nano/node/network.hpp index efabbc253e..14de706800 100644 --- a/nano/node/network.hpp +++ b/nano/node/network.hpp @@ -88,8 +88,8 @@ class network final void flood_message (nano::message &, nano::transport::buffer_drop_policy const = nano::transport::buffer_drop_policy::limiter, float const = 1.0f); void flood_keepalive (float const scale_a = 1.0f); void flood_keepalive_self (float const scale_a = 0.5f); - void flood_vote (std::shared_ptr const &, float scale); - void flood_vote_pr (std::shared_ptr const &); + void flood_vote (std::shared_ptr const &, float scale, bool rebroadcasted = false); + void flood_vote_pr (std::shared_ptr const &, bool rebroadcasted = false); // Flood block to all PRs and a random selection of non-PRs void flood_block_initial (std::shared_ptr const &); // Flood block to a random selection of peers diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 58ec072dae..677ec57f26 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -251,7 +251,7 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy auto const reps = wallets.reps (); if (!reps.have_half_rep () && !reps.exists (vote->account)) { - network.flood_vote (vote, 0.5f); + network.flood_vote (vote, 0.5f, /* rebroadcasted */ true); } } }); From 6fedf7114e79059232c6f43578c407d07570d1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Mon, 13 May 2024 20:32:29 +0200 Subject: [PATCH 4/6] Ignore rebroadcasted votes in rep crawler --- nano/core_test/node.cpp | 2 +- nano/lib/stats_enums.hpp | 2 ++ nano/node/election.cpp | 8 +++++--- nano/node/message_processor.cpp | 2 +- nano/node/node.cpp | 14 +++++++++----- nano/node/node_observers.hpp | 3 ++- nano/node/vote_cache.cpp | 2 +- nano/node/vote_processor.cpp | 15 ++++++++------- nano/node/vote_processor.hpp | 8 +++++--- nano/node/vote_router.hpp | 1 + nano/node/websocket.cpp | 2 +- 11 files changed, 36 insertions(+), 23 deletions(-) diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index d5fa67fcfb..f40dd6ccc0 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -2166,7 +2166,7 @@ TEST (node, vote_by_hash_bundle) nano::keypair key1; system.wallet (0)->insert_adhoc (key1.prv); - system.nodes[0]->observers.vote.add ([&max_hashes] (std::shared_ptr const & vote_a, std::shared_ptr const &, nano::vote_code) { + system.nodes[0]->observers.vote.add ([&max_hashes] (std::shared_ptr const & vote_a, std::shared_ptr const &, nano::vote_source, nano::vote_code) { if (vote_a->hashes.size () > max_hashes) { max_hashes = vote_a->hashes.size (); diff --git a/nano/lib/stats_enums.hpp b/nano/lib/stats_enums.hpp index 22ea06e2b6..7b8a864cc6 100644 --- a/nano/lib/stats_enums.hpp +++ b/nano/lib/stats_enums.hpp @@ -27,6 +27,7 @@ enum class type vote_processor_tier, vote_processor_overfill, election, + election_vote, http_callback, ipc, tcp, @@ -109,6 +110,7 @@ enum class detail success, unknown, cache, + rebroadcast, queue_overflow, // processing queue diff --git a/nano/node/election.cpp b/nano/node/election.cpp index 02d6a0cb1a..40f1f2b864 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -460,7 +460,7 @@ nano::vote_code nano::election::vote (nano::account const & rep, uint64_t timest auto max_vote = timestamp_a == std::numeric_limits::max () && last_vote_l.timestamp < timestamp_a; bool past_cooldown = true; - if (vote_source_a == vote_source::live) // Only cooldown live votes + if (vote_source_a != vote_source::cache) // Only cooldown live votes { const auto cooldown = cooldown_time (weight); past_cooldown = last_vote_l.time <= std::chrono::steady_clock::now () - cooldown; @@ -473,12 +473,14 @@ nano::vote_code nano::election::vote (nano::account const & rep, uint64_t timest } last_votes[rep] = { std::chrono::steady_clock::now (), timestamp_a, block_hash_a }; - if (vote_source_a == vote_source::live) + if (vote_source_a != vote_source::cache) { live_vote_action (rep); } - node.stats.inc (nano::stat::type::election, vote_source_a == vote_source::live ? nano::stat::detail::vote_new : nano::stat::detail::vote_cached); + node.stats.inc (nano::stat::type::election, nano::stat::detail::vote); + node.stats.inc (nano::stat::type::election_vote, to_stat_detail (vote_source_a)); + node.logger.trace (nano::log::type::election, nano::log::detail::vote_processed, nano::log::arg{ "id", id }, nano::log::arg{ "qualified_root", qualified_root }, diff --git a/nano/node/message_processor.cpp b/nano/node/message_processor.cpp index 16606f594c..89902b43f4 100644 --- a/nano/node/message_processor.cpp +++ b/nano/node/message_processor.cpp @@ -209,7 +209,7 @@ class process_visitor : public nano::message_visitor { if (!message.vote->account.is_zero ()) { - node.vote_processor.vote (message.vote, channel); + node.vote_processor.vote (message.vote, channel, message.is_rebroadcasted () ? nano::vote_source::rebroadcast : nano::vote_source::live); } } diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 677ec57f26..cde6186b10 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -358,18 +358,22 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy this->network.send_keepalive_self (channel_a); }); - observers.vote.add ([this] (std::shared_ptr vote, std::shared_ptr const & channel, nano::vote_code code) { + observers.vote.add ([this] (std::shared_ptr vote, std::shared_ptr const & channel, nano::vote_source source, nano::vote_code code) { debug_assert (vote != nullptr); debug_assert (code != nano::vote_code::invalid); if (channel == nullptr) { return; // Channel expired when waiting for vote to be processed } - bool active_in_rep_crawler = rep_crawler.process (vote, channel); - if (active_in_rep_crawler) + // Ignore republished votes + if (source == nano::vote_source::live) { - // Representative is defined as online if replying to live votes or rep_crawler queries - online_reps.observe (vote->account); + bool active_in_rep_crawler = rep_crawler.process (vote, channel); + if (active_in_rep_crawler) + { + // Representative is defined as online if replying to live votes or rep_crawler queries + online_reps.observe (vote->account); + } } }); diff --git a/nano/node/node_observers.hpp b/nano/node/node_observers.hpp index 00220e67de..be18e25df7 100644 --- a/nano/node/node_observers.hpp +++ b/nano/node/node_observers.hpp @@ -7,6 +7,7 @@ namespace nano { +enum class vote_source; class election_status; class telemetry; enum class vote_code; @@ -24,7 +25,7 @@ class node_observers final using blocks_t = nano::observer_set const &, nano::account const &, nano::uint128_t const &, bool, bool>; blocks_t blocks; // Notification upon election completion or cancellation nano::observer_set wallet; - nano::observer_set, std::shared_ptr, nano::vote_code> vote; + nano::observer_set, std::shared_ptr, nano::vote_source, nano::vote_code> vote; nano::observer_set active_started; nano::observer_set active_stopped; nano::observer_set account_balance; diff --git a/nano/node/vote_cache.cpp b/nano/node/vote_cache.cpp index a2210b14e5..5fbf905099 100644 --- a/nano/node/vote_cache.cpp +++ b/nano/node/vote_cache.cpp @@ -130,7 +130,7 @@ nano::vote_cache::vote_cache (vote_cache_config const & config_a, nano::stats & void nano::vote_cache::observe (const std::shared_ptr & vote, nano::vote_source source, std::unordered_map results) { - if (source == nano::vote_source::live) + if (source != nano::vote_source::cache) { insert (vote, [&results] (nano::block_hash const & hash) { // This filters which hashes should be included in the vote cache diff --git a/nano/node/vote_processor.cpp b/nano/node/vote_processor.cpp index 7f0e602594..ebf96af0b9 100644 --- a/nano/node/vote_processor.cpp +++ b/nano/node/vote_processor.cpp @@ -91,7 +91,7 @@ void nano::vote_processor::stop () threads.clear (); } -bool nano::vote_processor::vote (std::shared_ptr const & vote, std::shared_ptr const & channel) +bool nano::vote_processor::vote (std::shared_ptr const & vote, std::shared_ptr const & channel, nano::vote_source source) { debug_assert (channel != nullptr); @@ -100,7 +100,7 @@ bool nano::vote_processor::vote (std::shared_ptr const & vote, std:: bool added = false; { nano::lock_guard guard{ mutex }; - added = queue.push (vote, { tier, channel }); + added = queue.push ({ vote, source }, { tier, channel }); } if (added) { @@ -150,9 +150,10 @@ void nano::vote_processor::run_batch (nano::unique_lock & lock) lock.unlock (); - for (auto const & [vote, origin] : batch) + for (auto const & [item, origin] : batch) { - vote_blocking (vote, origin.channel); + auto const & [vote, source] = item; + vote_blocking (vote, origin.channel, source); } total_processed += batch.size (); @@ -166,12 +167,12 @@ void nano::vote_processor::run_batch (nano::unique_lock & lock) } } -nano::vote_code nano::vote_processor::vote_blocking (std::shared_ptr const & vote, std::shared_ptr const & channel) +nano::vote_code nano::vote_processor::vote_blocking (std::shared_ptr const & vote, std::shared_ptr const & channel, nano::vote_source source) { auto result = nano::vote_code::invalid; if (!vote->validate ()) // false => valid vote { - auto vote_results = vote_router.vote (vote); + auto vote_results = vote_router.vote (vote, source); // Aggregate results for individual hashes bool replay = false; @@ -183,7 +184,7 @@ nano::vote_code nano::vote_processor::vote_blocking (std::shared_ptr } result = replay ? nano::vote_code::replay : (processed ? nano::vote_code::vote : nano::vote_code::indeterminate); - observers.vote.notify (vote, channel, result); + observers.vote.notify (vote, channel, source, result); } stats.inc (nano::stat::type::vote, to_stat_detail (result)); diff --git a/nano/node/vote_processor.hpp b/nano/node/vote_processor.hpp index 7c56f4ac1c..592afff297 100644 --- a/nano/node/vote_processor.hpp +++ b/nano/node/vote_processor.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -64,8 +65,8 @@ class vote_processor final void stop (); /** @returns true if the vote was queued for processing */ - bool vote (std::shared_ptr const &, std::shared_ptr const &); - nano::vote_code vote_blocking (std::shared_ptr const &, std::shared_ptr const &); + bool vote (std::shared_ptr const &, std::shared_ptr const &, nano::vote_source = nano::vote_source::live); + nano::vote_code vote_blocking (std::shared_ptr const &, std::shared_ptr const &, nano::vote_source = nano::vote_source::live); std::size_t size () const; bool empty () const; @@ -91,7 +92,8 @@ class vote_processor final void run_batch (nano::unique_lock &); private: - nano::fair_queue, nano::rep_tier> queue; + using entry_t = std::pair, nano::vote_source>; + nano::fair_queue queue; private: bool stopped{ false }; diff --git a/nano/node/vote_router.hpp b/nano/node/vote_router.hpp index 98003d2183..c66b6ade36 100644 --- a/nano/node/vote_router.hpp +++ b/nano/node/vote_router.hpp @@ -32,6 +32,7 @@ nano::stat::detail to_stat_detail (vote_code); enum class vote_source { live, + rebroadcast, cache, }; diff --git a/nano/node/websocket.cpp b/nano/node/websocket.cpp index 68afbeb267..0d15ca1367 100644 --- a/nano/node/websocket.cpp +++ b/nano/node/websocket.cpp @@ -1061,7 +1061,7 @@ nano::websocket_server::websocket_server (nano::websocket::config & config_a, na } }); - observers.vote.add ([this] (std::shared_ptr vote_a, std::shared_ptr const & channel_a, nano::vote_code code_a) { + observers.vote.add ([this] (std::shared_ptr vote_a, std::shared_ptr const & channel_a, nano::vote_source source_a, nano::vote_code code_a) { debug_assert (vote_a != nullptr); if (server->any_subscriber (nano::websocket::topic::vote)) { From 6040d8b2d4a52aedd7a75aca69bd0755a6bdc0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 14 May 2024 17:02:17 +0200 Subject: [PATCH 5/6] Test that rebroadcasted votes are ignored by rep crawler --- nano/core_test/rep_crawler.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/nano/core_test/rep_crawler.cpp b/nano/core_test/rep_crawler.cpp index e775c2338e..1fbe024b74 100644 --- a/nano/core_test/rep_crawler.cpp +++ b/nano/core_test/rep_crawler.cpp @@ -299,3 +299,32 @@ TEST (rep_crawler, two_reps_one_node) ASSERT_TRUE (nano::dev::genesis_key.pub == reps[0].account || nano::dev::genesis_key.pub == reps[1].account); ASSERT_TRUE (second_rep.pub == reps[0].account || second_rep.pub == reps[1].account); } + +TEST (rep_crawler, ignore_rebroadcasted) +{ + nano::test::system system; + auto & node1 = *system.add_node (); + auto & node2 = *system.add_node (); + + auto channel1to2 = node1.network.find_node_id (node2.node_id.pub); + ASSERT_NE (nullptr, channel1to2); + + node1.rep_crawler.force_query (nano::dev::genesis->hash (), channel1to2); + ASSERT_ALWAYS_EQ (100ms, node1.rep_crawler.representative_count (), 0); + + // Now we spam the vote for genesis, so it appears as a rebroadcasted vote + auto vote = nano::test::make_vote (nano::dev::genesis_key, { nano::dev::genesis->hash () }, 0); + + auto channel2to1 = node2.network.find_node_id (node1.node_id.pub); + ASSERT_NE (nullptr, channel2to1); + + node1.rep_crawler.force_query (nano::dev::genesis->hash (), channel1to2); + + auto tick = [&] () { + nano::confirm_ack msg{ nano::dev::network_params.network, vote, /* rebroadcasted */ true }; + channel2to1->send (msg, nullptr, nano::transport::buffer_drop_policy::no_socket_drop); + return false; + }; + + ASSERT_NEVER (1s, tick () || node1.rep_crawler.representative_count () > 0); +} \ No newline at end of file From f21adde24f38c232938b4312744b8c9428905742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 14 May 2024 18:57:24 +0200 Subject: [PATCH 6/6] Fix tests --- nano/core_test/active_elections.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/nano/core_test/active_elections.cpp b/nano/core_test/active_elections.cpp index 29cd87f70e..692bcae8fc 100644 --- a/nano/core_test/active_elections.cpp +++ b/nano/core_test/active_elections.cpp @@ -249,7 +249,7 @@ TEST (inactive_votes_cache, basic) ASSERT_TIMELY_EQ (5s, node.vote_cache.size (), 1); node.process_active (send); ASSERT_TIMELY (5s, node.ledger.confirmed.block_exists_or_pruned (node.ledger.tx_begin_read (), send->hash ())); - ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_cached)); + ASSERT_EQ (1, node.stats.count (nano::stat::type::election_vote, nano::stat::detail::cache)); } /** @@ -276,7 +276,7 @@ TEST (inactive_votes_cache, non_final) node.process_active (send); std::shared_ptr election; ASSERT_TIMELY (5s, election = node.active.election (send->qualified_root ())); - ASSERT_TIMELY_EQ (5s, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_cached), 1); + ASSERT_TIMELY_EQ (5s, node.stats.count (nano::stat::type::election_vote, nano::stat::detail::cache), 1); ASSERT_TIMELY_EQ (5s, nano::dev::constants.genesis_amount - 100, election->tally ().begin ()->first); ASSERT_FALSE (election->confirmed ()); } @@ -318,7 +318,7 @@ TEST (inactive_votes_cache, fork) node.process_active (send1); ASSERT_TIMELY_EQ (5s, election->blocks ().size (), 2); ASSERT_TIMELY (5s, node.block_confirmed (send1->hash ())); - ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_cached)); + ASSERT_EQ (1, node.stats.count (nano::stat::type::election_vote, nano::stat::detail::cache)); } TEST (inactive_votes_cache, existing_vote) @@ -354,7 +354,7 @@ TEST (inactive_votes_cache, existing_vote) auto vote1 = nano::test::make_vote (key, { send }, nano::vote::timestamp_min * 1, 0); node.vote_processor.vote (vote1, std::make_shared (node, node)); ASSERT_TIMELY_EQ (5s, election->votes ().size (), 2); - ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_new)); + ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::vote)); auto last_vote1 (election->votes ()[key.pub]); ASSERT_EQ (send->hash (), last_vote1.hash); ASSERT_EQ (nano::vote::timestamp_min * 1, last_vote1.timestamp); @@ -372,7 +372,7 @@ TEST (inactive_votes_cache, existing_vote) ASSERT_EQ (last_vote1.hash, last_vote2.hash); ASSERT_EQ (last_vote1.timestamp, last_vote2.timestamp); ASSERT_EQ (last_vote1.time, last_vote2.time); - ASSERT_EQ (0, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_cached)); + ASSERT_EQ (0, node.stats.count (nano::stat::type::election_vote, nano::stat::detail::cache)); } TEST (inactive_votes_cache, multiple_votes) @@ -425,7 +425,7 @@ TEST (inactive_votes_cache, multiple_votes) ASSERT_EQ (1, node.vote_cache.size ()); auto election = nano::test::start_election (system, node, send1->hash ()); ASSERT_TIMELY_EQ (5s, 3, election->votes ().size ()); // 2 votes and 1 default not_an_acount - ASSERT_EQ (2, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_cached)); + ASSERT_EQ (2, node.stats.count (nano::stat::type::election_vote, nano::stat::detail::cache)); } TEST (inactive_votes_cache, election_start)