From 41ce708a552838845cf12e5a395cd037313b00db Mon Sep 17 00:00:00 2001 From: Guilherme Lawless Date: Thu, 9 Apr 2020 10:54:53 +0100 Subject: [PATCH] Remove "valid" from RPC work_validate if difficulty is not explicit (#2689) This is a semantics change for RPC `work_validate`, due to the transition to new work levels with epoch 2. Two new fields are added: - `valid_all` , true if the work is valid at the **current default difficulty** (updated to epoch_2 levels after the first epoch_2 block is processed) - `valid_receive` , true if the work is valid at the lower epoch_2 receive difficulty If difficulty is not explicitly given, then the `valid` field is not included in the response, to break integrations loudly. --- nano/node/json_handler.cpp | 15 ++++++++++++++- nano/rpc_test/rpc.cpp | 33 +++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index e85e5c55..c0961a28 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -5117,8 +5117,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 79eb8984..5b41e425 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -4029,8 +4029,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)); @@ -4048,8 +4049,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)); @@ -4069,8 +4071,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)); @@ -4083,8 +4086,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)); @@ -4096,8 +4100,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")); } } @@ -4129,7 +4134,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)); @@ -4148,7 +4155,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));