Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change response for RPC work_validate with implicit difficulty #2689

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion nano/node/json_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
33 changes: 21 additions & 12 deletions nano/rpc_test/rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string> ("valid"));
ASSERT_EQ ("1", validate_text);
ASSERT_EQ (0, response.json.count ("valid"));
ASSERT_TRUE (response.json.get<bool> ("valid_all"));
ASSERT_TRUE (response.json.get<bool> ("valid_receive"));
std::string difficulty_text (response.json.get<std::string> ("difficulty"));
uint64_t difficulty;
ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty));
Expand All @@ -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<std::string> ("valid"));
ASSERT_EQ ("0", validate_text);
ASSERT_EQ (0, response.json.count ("valid"));
ASSERT_FALSE (response.json.get<bool> ("valid_all"));
ASSERT_FALSE (response.json.get<bool> ("valid_receive"));
std::string difficulty_text (response.json.get<std::string> ("difficulty"));
uint64_t difficulty;
ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty));
Expand All @@ -4068,8 +4070,9 @@ TEST (rpc, work_validate)
ASSERT_NO_ERROR (system.poll ());
}
ASSERT_EQ (200, response.status);
bool validate (response.json.get<bool> ("valid"));
ASSERT_TRUE (validate);
ASSERT_TRUE (response.json.get<bool> ("valid"));
ASSERT_TRUE (response.json.get<bool> ("valid_all"));
ASSERT_TRUE (response.json.get<bool> ("valid_receive"));
}
uint64_t difficulty4 (0xfff0000000000000);
request.put ("work", nano::to_string_hex (work1));
Expand All @@ -4082,8 +4085,9 @@ TEST (rpc, work_validate)
ASSERT_NO_ERROR (system.poll ());
}
ASSERT_EQ (200, response.status);
bool validate (response.json.get<bool> ("valid"));
ASSERT_EQ (result_difficulty >= difficulty4, validate);
ASSERT_EQ (result_difficulty >= difficulty4, response.json.get<bool> ("valid"));
ASSERT_EQ (result_difficulty >= node1.default_difficulty (nano::work_version::work_1), response.json.get<bool> ("valid_all"));
ASSERT_EQ (result_difficulty >= node1.network_params.network.publish_thresholds.epoch_2_receive, response.json.get<bool> ("valid_all"));
}
uint64_t work3 (*node1.work_generate_blocking (hash, difficulty4));
request.put ("work", nano::to_string_hex (work3));
Expand All @@ -4095,8 +4099,9 @@ TEST (rpc, work_validate)
ASSERT_NO_ERROR (system.poll ());
}
ASSERT_EQ (200, response.status);
bool validate (response.json.get<bool> ("valid"));
ASSERT_TRUE (validate);
ASSERT_TRUE (response.json.get<bool> ("valid"));
ASSERT_TRUE (response.json.get<bool> ("valid_all"));
ASSERT_TRUE (response.json.get<bool> ("valid_receive"));
}
}

Expand Down Expand Up @@ -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<bool> ("valid"));
ASSERT_EQ (0, response.json.count ("valid"));
ASSERT_TRUE (response.json.get<bool> ("valid_all"));
ASSERT_TRUE (response.json.get<bool> ("valid_receive"));
std::string difficulty_text (response.json.get<std::string> ("difficulty"));
uint64_t difficulty{ 0 };
ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty));
Expand All @@ -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<bool> ("valid"));
ASSERT_EQ (0, response.json.count ("valid"));
ASSERT_FALSE (response.json.get<bool> ("valid_all"));
ASSERT_TRUE (response.json.get<bool> ("valid_receive"));
std::string difficulty_text (response.json.get<std::string> ("difficulty"));
uint64_t difficulty{ 0 };
ASSERT_FALSE (nano::from_string_hex (difficulty_text, difficulty));
Expand Down