From b58ee7f420448b533215380773f25b6c816e859c Mon Sep 17 00:00:00 2001 From: Guilherme Lawless Date: Thu, 5 Dec 2019 19:08:21 +0000 Subject: [PATCH] Add block and voters count in election information (#2414) * Add block and voters count in election information * Blocks already included in confirmation_info * Status is not yet updated before the election is finished --- nano/core_test/websocket.cpp | 2 ++ nano/node/active_transactions.cpp | 2 +- nano/node/active_transactions.hpp | 2 ++ nano/node/election.cpp | 8 +++++++- nano/node/json_handler.cpp | 11 +++++++---- nano/node/websocket.cpp | 4 +++- nano/rpc_test/rpc.cpp | 2 ++ 7 files changed, 24 insertions(+), 7 deletions(-) diff --git a/nano/core_test/websocket.cpp b/nano/core_test/websocket.cpp index 199547d8..9789ac1f 100644 --- a/nano/core_test/websocket.cpp +++ b/nano/core_test/websocket.cpp @@ -467,6 +467,8 @@ TEST (websocket, confirmation_options) // Duration and request count may be zero on testnet, so we only check that they're present ASSERT_EQ (1, election_info.count ("duration")); ASSERT_EQ (1, election_info.count ("request_count")); + ASSERT_EQ (1, election_info.count ("voters")); + ASSERT_GE (1, election_info.get ("blocks")); // Make sure tally and time are non-zero. ASSERT_NE ("0", tally); ASSERT_NE ("0", time); diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index 1cce71c6..ccdd3203 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -114,7 +114,7 @@ void nano::active_transactions::post_confirmation_height_set (nano::transaction bool is_state_send (false); nano::account pending_account (0); node.process_confirmed_data (transaction_a, block_a, block_a->hash (), sideband_a, account, amount, is_state_send, pending_account); - node.observers.blocks.notify (nano::election_status{ block_a, 0, std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()), std::chrono::duration_values::zero (), 0, nano::election_status_type::inactive_confirmation_height }, account, amount, is_state_send); + node.observers.blocks.notify (nano::election_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::inactive_confirmation_height }, account, amount, is_state_send); } else { diff --git a/nano/node/active_transactions.hpp b/nano/node/active_transactions.hpp index 4e4dcd81..e39e68d2 100644 --- a/nano/node/active_transactions.hpp +++ b/nano/node/active_transactions.hpp @@ -56,6 +56,8 @@ public: std::chrono::milliseconds election_end; std::chrono::milliseconds election_duration; unsigned confirmation_request_count; + unsigned block_count; + unsigned voter_count; election_status_type type; }; diff --git a/nano/node/election.cpp b/nano/node/election.cpp index 1b269544..9944f226 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -13,7 +13,7 @@ nano::election::election (nano::node & node_a, std::shared_ptr bloc confirmation_action (confirmation_action_a), node (node_a), election_start (std::chrono::steady_clock::now ()), -status ({ block_a, 0, std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()), std::chrono::duration_values::zero (), 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 }), skip_delay (skip_delay_a), confirmed (false), stopped (false) @@ -36,11 +36,14 @@ void nano::election::compute_rep_votes (nano::transaction const & transaction_a) void nano::election::confirm_once (nano::election_status_type type_a) { + assert (!node.active.mutex.try_lock ()); if (!confirmed.exchange (true)) { status.election_end = std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()); status.election_duration = std::chrono::duration_cast (std::chrono::steady_clock::now () - election_start); status.confirmation_request_count = confirmation_request_count; + status.block_count = blocks.size (); + status.voter_count = last_votes.size (); status.type = type_a; auto status_l (status); auto node_l (node.shared ()); @@ -59,12 +62,15 @@ void nano::election::confirm_once (nano::election_status_type type_a) void nano::election::stop () { + assert (!node.active.mutex.try_lock ()); if (!stopped && !confirmed) { stopped = true; status.election_end = std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()); status.election_duration = std::chrono::duration_cast (std::chrono::steady_clock::now () - election_start); status.confirmation_request_count = confirmation_request_count; + status.block_count = blocks.size (); + status.voter_count = last_votes.size (); status.type = nano::election_status_type::stopped; } } diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index 118842c5..e1ff088b 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -1011,7 +1011,7 @@ void nano::json_handler::block_confirm () else { // Add record in confirmation history for confirmed block - nano::election_status status{ block_l, 0, std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()), std::chrono::duration_values::zero (), 0, nano::election_status_type::active_confirmation_height }; + nano::election_status status{ block_l, 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::active_confirmation_height }; { nano::lock_guard lock (node.active.mutex); node.active.confirmed.push_back (status); @@ -1806,7 +1806,9 @@ void nano::json_handler::confirmation_history () election.put ("duration", i->election_duration.count ()); election.put ("time", i->election_end.count ()); election.put ("tally", i->tally.to_string_dec ()); - election.put ("request_count", i->confirmation_request_count); + election.put ("blocks", std::to_string (i->block_count)); + election.put ("voters", std::to_string (i->voter_count)); + election.put ("request_count", std::to_string (i->confirmation_request_count)); elections.push_back (std::make_pair ("", election)); } running_total += i->election_duration; @@ -1835,10 +1837,11 @@ void nano::json_handler::confirmation_info () auto conflict_info (node.active.roots.find (root)); if (conflict_info != node.active.roots.end ()) { - response_l.put ("announcements", std::to_string (conflict_info->election->confirmation_request_count)); auto election (conflict_info->election); - nano::uint128_t total (0); + response_l.put ("announcements", std::to_string (election->confirmation_request_count)); + response_l.put ("voters", std::to_string (election->last_votes.size ())); response_l.put ("last_winner", election->status.winner->hash ().to_string ()); + nano::uint128_t total (0); auto tally_l (election->tally ()); boost::property_tree::ptree blocks; for (auto i (tally_l.begin ()), n (tally_l.end ()); i != n; ++i) diff --git a/nano/node/websocket.cpp b/nano/node/websocket.cpp index db72d191..c45c7d12 100644 --- a/nano/node/websocket.cpp +++ b/nano/node/websocket.cpp @@ -634,7 +634,9 @@ nano::websocket::message nano::websocket::message_builder::block_confirmed (std: election_node_l.add ("duration", election_status_a.election_duration.count ()); election_node_l.add ("time", election_status_a.election_end.count ()); election_node_l.add ("tally", election_status_a.tally.to_string_dec ()); - election_node_l.add ("request_count", election_status_a.confirmation_request_count); + election_node_l.add ("blocks", std::to_string (election_status_a.block_count)); + election_node_l.add ("voters", std::to_string (election_status_a.voter_count)); + election_node_l.add ("request_count", std::to_string (election_status_a.confirmation_request_count)); message_node_l.add_child ("election_info", election_node_l); } diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 4c6383d3..09df3174 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -6148,6 +6148,8 @@ TEST (rpc, confirmation_history) ASSERT_EQ (1, item->second.count ("duration")); ASSERT_EQ (1, item->second.count ("time")); ASSERT_EQ (1, item->second.count ("request_count")); + ASSERT_EQ (1, item->second.count ("voters")); + ASSERT_GE (1, item->second.get ("blocks")); ASSERT_EQ (block->hash ().to_string (), hash); nano::amount tally_num; tally_num.decode_dec (tally);