From 14b844e2eff1cbc55c29b7ff9df37b7f5713bc2d Mon Sep 17 00:00:00 2001 From: Wesley Shillingford Date: Tue, 18 Feb 2020 14:35:03 +0000 Subject: [PATCH] Request telemetry data for local node (#2560) --- nano/node/json_handler.cpp | 27 +++++++++++++-- nano/node/network.cpp | 17 +-------- nano/node/telemetry.cpp | 20 +++++++++++ nano/node/telemetry.hpp | 1 + nano/rpc_test/rpc.cpp | 70 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 19 deletions(-) diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index ced95b6c6..a207b8e71 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -3914,10 +3914,31 @@ void nano::json_handler::telemetry () if (!nano::parse_address (*address_text, address)) { nano::endpoint endpoint (address, port); - channel = node.network.find_channel (nano::transport::map_endpoint_to_v6 (endpoint)); - if (!channel) + if (address.is_loopback () && port == rpc_l->node.network.endpoint ().port ()) { - ec = nano::error_rpc::peer_not_found; + // Requesting telemetry metrics locally + auto telemetry_data = nano::local_telemetry_data (rpc_l->node.ledger.cache, rpc_l->node.network, rpc_l->node.config.bandwidth_limit, rpc_l->node.network_params, rpc_l->node.startup_time); + + nano::jsonconfig config_l; + auto err = telemetry_data.serialize_json (config_l); + config_l.put ("timestamp", std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()).count ()); + auto const & ptree = config_l.get_tree (); + + if (!err) + { + rpc_l->response_l.insert (rpc_l->response_l.begin (), ptree.begin (), ptree.end ()); + } + + rpc_l->response_errors (); + return; + } + else + { + channel = node.network.find_channel (nano::transport::map_endpoint_to_v6 (endpoint)); + if (!channel) + { + ec = nano::error_rpc::peer_not_found; + } } } else diff --git a/nano/node/network.cpp b/nano/node/network.cpp index 7afd39efc..328913262 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -458,22 +458,7 @@ public: nano::telemetry_ack telemetry_ack; if (!node.flags.disable_providing_telemetry_metrics) { - nano::telemetry_data telemetry_data; - telemetry_data.block_count = node.ledger.cache.block_count; - telemetry_data.cemented_count = node.ledger.cache.cemented_count; - telemetry_data.bandwidth_cap = node.config.bandwidth_limit; - telemetry_data.protocol_version = node.network_params.protocol.protocol_version; - telemetry_data.uptime = std::chrono::duration_cast (std::chrono::steady_clock::now () - node.startup_time).count (); - telemetry_data.unchecked_count = node.ledger.cache.unchecked_count; - telemetry_data.genesis_block = node.network_params.ledger.genesis_hash; - telemetry_data.peer_count = node.network.size (); - telemetry_data.account_count = node.ledger.cache.account_count; - telemetry_data.major_version = nano::get_major_node_version (); - telemetry_data.minor_version = nano::get_minor_node_version (); - telemetry_data.patch_version = nano::get_patch_node_version (); - telemetry_data.pre_release_version = nano::get_pre_release_node_version (); - telemetry_data.maker = 0; // 0 Indicates it originated from the NF - + auto telemetry_data = nano::local_telemetry_data (node.ledger.cache, node.network, node.config.bandwidth_limit, node.network_params, node.startup_time); telemetry_ack = nano::telemetry_ack (telemetry_data); } channel->send (telemetry_ack, nullptr, false); diff --git a/nano/node/telemetry.cpp b/nano/node/telemetry.cpp index ed65d6640..2b98a5f35 100644 --- a/nano/node/telemetry.cpp +++ b/nano/node/telemetry.cpp @@ -668,4 +668,24 @@ nano::telemetry_data_time_pair nano::consolidate_telemetry_data_time_pairs (std: auto consolidated_timestamp = boost::numeric_cast (timestamp_sum / size); return telemetry_data_time_pair{ consolidated_data, std::chrono::steady_clock::time_point{}, std::chrono::system_clock::time_point (std::chrono::milliseconds (consolidated_timestamp)) }; +} + +nano::telemetry_data nano::local_telemetry_data (nano::ledger_cache const & ledger_cache_a, nano::network & network_a, uint64_t bandwidth_limit_a, nano::network_params const & network_params_a, std::chrono::steady_clock::time_point statup_time_a) +{ + nano::telemetry_data telemetry_data; + telemetry_data.block_count = ledger_cache_a.block_count; + telemetry_data.cemented_count = ledger_cache_a.cemented_count; + telemetry_data.bandwidth_cap = bandwidth_limit_a; + telemetry_data.protocol_version = network_params_a.protocol.protocol_version; + telemetry_data.uptime = std::chrono::duration_cast (std::chrono::steady_clock::now () - statup_time_a).count (); + telemetry_data.unchecked_count = ledger_cache_a.unchecked_count; + telemetry_data.genesis_block = network_params_a.ledger.genesis_hash; + telemetry_data.peer_count = network_a.size (); + telemetry_data.account_count = ledger_cache_a.account_count; + telemetry_data.major_version = nano::get_major_node_version (); + telemetry_data.minor_version = nano::get_minor_node_version (); + telemetry_data.patch_version = nano::get_patch_node_version (); + telemetry_data.pre_release_version = nano::get_pre_release_node_version (); + telemetry_data.maker = 0; // 0 Indicates it originated from the NF + return telemetry_data; } \ No newline at end of file diff --git a/nano/node/telemetry.hpp b/nano/node/telemetry.hpp index e82d8c18b..0c14defe1 100644 --- a/nano/node/telemetry.hpp +++ b/nano/node/telemetry.hpp @@ -195,4 +195,5 @@ std::unique_ptr collect_container_info (telemetr nano::telemetry_data consolidate_telemetry_data (std::vector const & telemetry_data); nano::telemetry_data_time_pair consolidate_telemetry_data_time_pairs (std::vector const & telemetry_data_time_pairs); +nano::telemetry_data local_telemetry_data (nano::ledger_cache const &, nano::network &, uint64_t, nano::network_params const &, std::chrono::steady_clock::time_point); } \ No newline at end of file diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 4b1580294..8b2278982 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -8037,3 +8037,73 @@ TEST (rpc, node_telemetry_all) ASSERT_EQ (node->network.endpoint ().address ().to_string (), metrics.address); ASSERT_EQ (node->network.endpoint ().port (), metrics.port); } + +// Also tests all forms of ipv4/ipv6 +TEST (rpc, node_telemetry_self) +{ + nano::system system; + auto & node1 = *add_ipc_enabled_node (system); + scoped_io_thread_name_change scoped_thread_name_io; + 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 (); + + // Just to have peer count at 1 + node1.network.udp_channels.insert (nano::endpoint (boost::asio::ip::make_address_v6 ("::1"), nano::get_available_port ()), 0); + + boost::property_tree::ptree request; + request.put ("action", "node_telemetry"); + request.put ("address", "::1"); + request.put ("port", node1.network.endpoint ().port ()); + { + test_response response (request, rpc.config.port, system.io_ctx); + system.deadline_set (10s); + while (response.status == 0) + { + ASSERT_NO_ERROR (system.poll ()); + } + ASSERT_EQ (200, response.status); + compare_default_test_result_data (response, node1); + } + + request.put ("address", "[::1]"); + { + test_response response (request, rpc.config.port, system.io_ctx); + system.deadline_set (10s); + while (response.status == 0) + { + ASSERT_NO_ERROR (system.poll ()); + } + ASSERT_EQ (200, response.status); + compare_default_test_result_data (response, node1); + } + + request.put ("address", "127.0.0.1"); + { + test_response response (request, rpc.config.port, system.io_ctx); + system.deadline_set (10s); + while (response.status == 0) + { + ASSERT_NO_ERROR (system.poll ()); + } + ASSERT_EQ (200, response.status); + compare_default_test_result_data (response, node1); + } + + // Incorrect port should fail + request.put ("port", "0"); + { + test_response response (request, rpc.config.port, system.io_ctx); + system.deadline_set (10s); + while (response.status == 0) + { + ASSERT_NO_ERROR (system.poll ()); + } + ASSERT_EQ (200, response.status); + ASSERT_EQ (std::error_code (nano::error_rpc::peer_not_found).message (), response.json.get ("error")); + } +}