diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index 4b89e6666b..9a481c3397 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -5082,8 +5082,21 @@ void nano::json_handler::work_validate () multiplier_optional_impl (work_version, difficulty); if (!ec) { + /* Transition to epoch_2 difficulty levels breaks previous behavior. + * When difficulty is not given, the default difficulty to validate changes when the first epoch_2 block is seen, breaking previous behavior. + * For this reason, when difficulty is not given, the "valid" field is no longer included in the response to break loudly any client expecting it. + * Instead, use the new fields: + * * valid_all: the work is valid at the current highest difficulty threshold + * * valid_receive: the work is valid for a receive block in an epoch_2 upgraded account + */ + auto result_difficulty (nano::work_difficulty (work_version, hash, work)); - response_l.put ("valid", (result_difficulty >= difficulty) ? "1" : "0"); + if (request.count ("difficulty")) + { + response_l.put ("valid", (result_difficulty >= difficulty) ? "1" : "0"); + } + response_l.put ("valid_all", (result_difficulty >= node.default_difficulty (work_version)) ? "1" : "0"); + response_l.put ("valid_receive", (result_difficulty >= nano::work_threshold (work_version, nano::block_details (nano::epoch::epoch_2, false, true, false))) ? "1" : "0"); response_l.put ("difficulty", nano::to_string_hex (result_difficulty)); auto result_multiplier = nano::difficulty::to_multiplier (result_difficulty, node.default_difficulty (work_version)); response_l.put ("multiplier", nano::to_string (result_multiplier)); diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 7e92190ec8..513eb3cd52 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -4028,8 +4028,9 @@ TEST (rpc, work_validate) ASSERT_NO_ERROR (system.poll ()); } ASSERT_EQ (200, response.status); - std::string validate_text (response.json.get ("valid")); - ASSERT_EQ ("1", validate_text); + ASSERT_EQ (0, response.json.count ("valid")); + ASSERT_TRUE (response.json.get ("valid_all")); + ASSERT_TRUE (response.json.get ("valid_receive")); std::string difficulty_text (response.json.get ("difficulty")); uint64_t difficulty; ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty)); @@ -4047,8 +4048,9 @@ TEST (rpc, work_validate) ASSERT_NO_ERROR (system.poll ()); } ASSERT_EQ (200, response.status); - std::string validate_text (response.json.get ("valid")); - ASSERT_EQ ("0", validate_text); + ASSERT_EQ (0, response.json.count ("valid")); + ASSERT_FALSE (response.json.get ("valid_all")); + ASSERT_FALSE (response.json.get ("valid_receive")); std::string difficulty_text (response.json.get ("difficulty")); uint64_t difficulty; ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty)); @@ -4068,8 +4070,9 @@ TEST (rpc, work_validate) ASSERT_NO_ERROR (system.poll ()); } ASSERT_EQ (200, response.status); - bool validate (response.json.get ("valid")); - ASSERT_TRUE (validate); + ASSERT_TRUE (response.json.get ("valid")); + ASSERT_TRUE (response.json.get ("valid_all")); + ASSERT_TRUE (response.json.get ("valid_receive")); } uint64_t difficulty4 (0xfff0000000000000); request.put ("work", nano::to_string_hex (work1)); @@ -4082,8 +4085,9 @@ TEST (rpc, work_validate) ASSERT_NO_ERROR (system.poll ()); } ASSERT_EQ (200, response.status); - bool validate (response.json.get ("valid")); - ASSERT_EQ (result_difficulty >= difficulty4, validate); + ASSERT_EQ (result_difficulty >= difficulty4, response.json.get ("valid")); + ASSERT_EQ (result_difficulty >= node1.default_difficulty (nano::work_version::work_1), response.json.get ("valid_all")); + ASSERT_EQ (result_difficulty >= node1.network_params.network.publish_thresholds.epoch_2_receive, response.json.get ("valid_all")); } uint64_t work3 (*node1.work_generate_blocking (hash, difficulty4)); request.put ("work", nano::to_string_hex (work3)); @@ -4095,8 +4099,9 @@ TEST (rpc, work_validate) ASSERT_NO_ERROR (system.poll ()); } ASSERT_EQ (200, response.status); - bool validate (response.json.get ("valid")); - ASSERT_TRUE (validate); + ASSERT_TRUE (response.json.get ("valid")); + ASSERT_TRUE (response.json.get ("valid_all")); + ASSERT_TRUE (response.json.get ("valid_receive")); } } @@ -4128,7 +4133,9 @@ TEST (rpc, work_validate_epoch_2) ASSERT_NO_ERROR (system.poll ()); } ASSERT_EQ (200, response.status); - ASSERT_TRUE (response.json.get ("valid")); + ASSERT_EQ (0, response.json.count ("valid")); + ASSERT_TRUE (response.json.get ("valid_all")); + ASSERT_TRUE (response.json.get ("valid_receive")); std::string difficulty_text (response.json.get ("difficulty")); uint64_t difficulty{ 0 }; ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty)); @@ -4147,7 +4154,9 @@ TEST (rpc, work_validate_epoch_2) ASSERT_NO_ERROR (system.poll ()); } ASSERT_EQ (200, response.status); - ASSERT_FALSE (response.json.get ("valid")); + ASSERT_EQ (0, response.json.count ("valid")); + ASSERT_FALSE (response.json.get ("valid_all")); + ASSERT_TRUE (response.json.get ("valid_receive")); std::string difficulty_text (response.json.get ("difficulty")); uint64_t difficulty{ 0 }; ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty));