diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index bd18d4fd57..4aeddbdefc 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -4453,6 +4453,21 @@ TEST (node, deferred_dependent_elections) } } +TEST (node, default_difficulty) +{ + nano::system system (1); + auto & node (*system.nodes[0]); + auto const & thresholds = nano::network_params{}.network.publish_thresholds; + ASSERT_EQ (thresholds.epoch_1, node.default_difficulty (nano::work_version::work_1)); + ASSERT_EQ (thresholds.epoch_1, node.default_receive_difficulty (nano::work_version::work_1)); + nano::upgrade_epoch (system.work, node.ledger, nano::epoch::epoch_1); + ASSERT_EQ (thresholds.epoch_1, node.default_difficulty (nano::work_version::work_1)); + ASSERT_EQ (thresholds.epoch_1, node.default_receive_difficulty (nano::work_version::work_1)); + nano::upgrade_epoch (system.work, node.ledger, nano::epoch::epoch_2); + ASSERT_EQ (thresholds.epoch_2, node.default_difficulty (nano::work_version::work_1)); + ASSERT_EQ (thresholds.epoch_2_receive, node.default_receive_difficulty (nano::work_version::work_1)); +} + namespace { void add_required_children_node_config_tree (nano::jsonconfig & tree) diff --git a/nano/core_test/websocket.cpp b/nano/core_test/websocket.cpp index de0559d286..913a14a140 100644 --- a/nano/core_test/websocket.cpp +++ b/nano/core_test/websocket.cpp @@ -114,12 +114,22 @@ TEST (websocket, active_difficulty) 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 diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index b753a46db7..c9be8c7e21 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -953,10 +953,14 @@ void nano::json_handler::accounts_pending () void nano::json_handler::active_difficulty () { auto include_trend (request.get ("include_trend", false)); - auto multiplier_active = node.active.active_multiplier (); - auto default_difficulty (node.default_difficulty (nano::work_version::work_1)); + 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) { diff --git a/nano/node/node.cpp b/nano/node/node.cpp index bb62cbb5f7..d625c43e7b 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -260,7 +260,7 @@ node_seq (seq) 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), active_difficulty)); + 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); } }); @@ -1007,6 +1007,20 @@ uint64_t nano::node::default_difficulty (nano::work_version const version_a) con return result; } +uint64_t nano::node::default_receive_difficulty (nano::work_version const version_a) const +{ + uint64_t result{ std::numeric_limits::max () }; + switch (version_a) + { + case nano::work_version::work_1: + result = ledger.cache.epoch_2_started ? network_params.network.publish_thresholds.epoch_2_receive : network_params.network.publish_thresholds.epoch_1; + break; + default: + debug_assert (false && "Invalid version specified to default_receive_difficulty"); + } + return result; +} + uint64_t nano::node::max_work_generate_difficulty (nano::work_version const version_a) const { return nano::difficulty::from_multiplier (config.max_work_generate_multiplier, default_difficulty (version_a)); diff --git a/nano/node/node.hpp b/nano/node/node.hpp index 4e191c6776..946602852c 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -128,6 +128,7 @@ class node final : public std::enable_shared_from_this int price (nano::uint128_t const &, int); // The default difficulty updates to base only when the first epoch_2 block is processed uint64_t default_difficulty (nano::work_version const) const; + uint64_t default_receive_difficulty (nano::work_version const) const; uint64_t max_work_generate_difficulty (nano::work_version const) const; bool local_work_generation_enabled () const; bool work_generation_enabled () const; diff --git a/nano/node/websocket.cpp b/nano/node/websocket.cpp index ab0f59ec7e..d893defb2f 100644 --- a/nano/node/websocket.cpp +++ b/nano/node/websocket.cpp @@ -775,7 +775,7 @@ 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 difficulty_active_a) +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); @@ -783,9 +783,12 @@ nano::websocket::message nano::websocket::message_builder::difficulty_changed (u // 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; diff --git a/nano/node/websocket.hpp b/nano/node/websocket.hpp index f76518fa47..6ed16ea418 100644 --- a/nano/node/websocket.hpp +++ b/nano/node/websocket.hpp @@ -94,7 +94,7 @@ namespace websocket message block_confirmed (std::shared_ptr 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, nano::websocket::confirmation_options const & options_a); message stopped_election (nano::block_hash const & hash_a); message vote_received (std::shared_ptr vote_a, nano::vote_code code_a); - message difficulty_changed (uint64_t publish_threshold_a, uint64_t difficulty_active_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); diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index ed84f2c6a3..e6cc9598a5 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -7966,12 +7966,22 @@ TEST (rpc, active_difficulty) 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