Work multiplier format and RPC work_validate fix for lower difficulties (#1984)
* Format multipliers using fixed and max precision rather than scientific * Fix RPC work_validate returning invalid for difficulty lower than threshold * Move nano::to/from_string_hex to lib/numbers.hpp * Parameter can be const in nano::to_string_hex * Extract nano::to_string method for converting double with fixed and custom precision. Use std streams rather than boost * Fix intermitent failure of rpc.work_generate test * Prevent crash in debug if given difficulty is 0
This commit is contained in:
parent
2174fd737b
commit
e822707d90
7 changed files with 62 additions and 47 deletions
|
|
@ -16,43 +16,6 @@ bool blocks_equal (T const & first, nano::block const & second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string nano::to_string_hex (uint64_t value_a)
|
|
||||||
{
|
|
||||||
std::stringstream stream;
|
|
||||||
stream << std::hex << std::noshowbase << std::setw (16) << std::setfill ('0');
|
|
||||||
stream << value_a;
|
|
||||||
return stream.str ();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::from_string_hex (std::string const & value_a, uint64_t & target_a)
|
|
||||||
{
|
|
||||||
auto error (value_a.empty ());
|
|
||||||
if (!error)
|
|
||||||
{
|
|
||||||
error = value_a.size () > 16;
|
|
||||||
if (!error)
|
|
||||||
{
|
|
||||||
std::stringstream stream (value_a);
|
|
||||||
stream << std::hex << std::noshowbase;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
uint64_t number_l;
|
|
||||||
stream >> number_l;
|
|
||||||
target_a = number_l;
|
|
||||||
if (!stream.eof ())
|
|
||||||
{
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::runtime_error &)
|
|
||||||
{
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string nano::block::to_json () const
|
std::string nano::block::to_json () const
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@
|
||||||
|
|
||||||
namespace nano
|
namespace nano
|
||||||
{
|
{
|
||||||
std::string to_string_hex (uint64_t);
|
|
||||||
bool from_string_hex (std::string const &, uint64_t &);
|
|
||||||
// We operate on streams of uint8_t by convention
|
// We operate on streams of uint8_t by convention
|
||||||
using stream = std::basic_streambuf<uint8_t>;
|
using stream = std::basic_streambuf<uint8_t>;
|
||||||
// Read a raw byte stream the size of `T' and fill value.
|
// Read a raw byte stream the size of `T' and fill value.
|
||||||
|
|
|
||||||
|
|
@ -774,6 +774,51 @@ std::string nano::uint128_union::to_string_dec () const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string nano::to_string_hex (uint64_t const value_a)
|
||||||
|
{
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << std::hex << std::noshowbase << std::setw (16) << std::setfill ('0');
|
||||||
|
stream << value_a;
|
||||||
|
return stream.str ();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nano::from_string_hex (std::string const & value_a, uint64_t & target_a)
|
||||||
|
{
|
||||||
|
auto error (value_a.empty ());
|
||||||
|
if (!error)
|
||||||
|
{
|
||||||
|
error = value_a.size () > 16;
|
||||||
|
if (!error)
|
||||||
|
{
|
||||||
|
std::stringstream stream (value_a);
|
||||||
|
stream << std::hex << std::noshowbase;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
uint64_t number_l;
|
||||||
|
stream >> number_l;
|
||||||
|
target_a = number_l;
|
||||||
|
if (!stream.eof ())
|
||||||
|
{
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::runtime_error &)
|
||||||
|
{
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string nano::to_string (double const value_a, int const precision_a)
|
||||||
|
{
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << std::setprecision (precision_a) << std::fixed;
|
||||||
|
stream << value_a;
|
||||||
|
return stream.str ();
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t nano::difficulty::from_multiplier (double const multiplier_a, uint64_t const base_difficulty_a)
|
uint64_t nano::difficulty::from_multiplier (double const multiplier_a, uint64_t const base_difficulty_a)
|
||||||
{
|
{
|
||||||
assert (multiplier_a > 0.);
|
assert (multiplier_a > 0.);
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,16 @@ bool validate_message_batch (const unsigned char **, size_t *, const unsigned ch
|
||||||
void deterministic_key (nano::uint256_union const &, uint32_t, nano::uint256_union &);
|
void deterministic_key (nano::uint256_union const &, uint32_t, nano::uint256_union &);
|
||||||
nano::public_key pub_key (nano::private_key const &);
|
nano::public_key pub_key (nano::private_key const &);
|
||||||
|
|
||||||
|
/* Conversion methods */
|
||||||
|
std::string to_string_hex (uint64_t const);
|
||||||
|
bool from_string_hex (std::string const &, uint64_t &);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a double to string in fixed format
|
||||||
|
* @param precision_a (optional) use a specific precision (default is the maximum)
|
||||||
|
*/
|
||||||
|
std::string to_string (double const, int const precision_a = std::numeric_limits<double>::digits10);
|
||||||
|
|
||||||
namespace difficulty
|
namespace difficulty
|
||||||
{
|
{
|
||||||
uint64_t from_multiplier (double const, uint64_t const);
|
uint64_t from_multiplier (double const, uint64_t const);
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ void nano::work_pool::loop (uint64_t thread)
|
||||||
{
|
{
|
||||||
// If the ticket matches what we started with, we're the ones that found the solution
|
// If the ticket matches what we started with, we're the ones that found the solution
|
||||||
assert (output >= current_l.difficulty);
|
assert (output >= current_l.difficulty);
|
||||||
assert (work_value (current_l.item, work) == output);
|
assert (current_l.difficulty == 0 || work_value (current_l.item, work) == output);
|
||||||
// Signal other threads to stop their work next time they check ticket
|
// Signal other threads to stop their work next time they check ticket
|
||||||
++ticket;
|
++ticket;
|
||||||
pending.pop_front ();
|
pending.pop_front ();
|
||||||
|
|
|
||||||
|
|
@ -839,7 +839,7 @@ void nano::json_handler::active_difficulty ()
|
||||||
auto difficulty_active = node.active.active_difficulty ();
|
auto difficulty_active = node.active.active_difficulty ();
|
||||||
response_l.put ("difficulty_active", nano::to_string_hex (difficulty_active));
|
response_l.put ("difficulty_active", nano::to_string_hex (difficulty_active));
|
||||||
auto multiplier = nano::difficulty::to_multiplier (difficulty_active, node.network_params.network.publish_threshold);
|
auto multiplier = nano::difficulty::to_multiplier (difficulty_active, node.network_params.network.publish_threshold);
|
||||||
response_l.put ("multiplier", std::to_string (multiplier));
|
response_l.put ("multiplier", nano::to_string (multiplier));
|
||||||
response_errors ();
|
response_errors ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4363,7 +4363,7 @@ void nano::json_handler::work_generate ()
|
||||||
nano::work_validate (hash, work_a.value (), &result_difficulty);
|
nano::work_validate (hash, work_a.value (), &result_difficulty);
|
||||||
response_l.put ("difficulty", nano::to_string_hex (result_difficulty));
|
response_l.put ("difficulty", nano::to_string_hex (result_difficulty));
|
||||||
auto multiplier = nano::difficulty::to_multiplier (result_difficulty, this->node.network_params.network.publish_threshold);
|
auto multiplier = nano::difficulty::to_multiplier (result_difficulty, this->node.network_params.network.publish_threshold);
|
||||||
response_l.put ("multiplier", multiplier);
|
response_l.put ("multiplier", nano::to_string (multiplier));
|
||||||
boost::property_tree::write_json (ostream, response_l);
|
boost::property_tree::write_json (ostream, response_l);
|
||||||
rpc_l->response (ostream.str ());
|
rpc_l->response (ostream.str ());
|
||||||
}
|
}
|
||||||
|
|
@ -4451,12 +4451,11 @@ void nano::json_handler::work_validate ()
|
||||||
if (!ec)
|
if (!ec)
|
||||||
{
|
{
|
||||||
uint64_t result_difficulty (0);
|
uint64_t result_difficulty (0);
|
||||||
bool invalid (nano::work_validate (hash, work, &result_difficulty));
|
nano::work_validate (hash, work, &result_difficulty);
|
||||||
bool valid (!invalid && result_difficulty >= difficulty);
|
response_l.put ("valid", (result_difficulty >= difficulty) ? "1" : "0");
|
||||||
response_l.put ("valid", valid ? "1" : "0");
|
|
||||||
response_l.put ("difficulty", nano::to_string_hex (result_difficulty));
|
response_l.put ("difficulty", nano::to_string_hex (result_difficulty));
|
||||||
auto multiplier = nano::difficulty::to_multiplier (result_difficulty, node.network_params.network.publish_threshold);
|
auto multiplier = nano::difficulty::to_multiplier (result_difficulty, node.network_params.network.publish_threshold);
|
||||||
response_l.put ("multiplier", multiplier);
|
response_l.put ("multiplier", nano::to_string (multiplier));
|
||||||
}
|
}
|
||||||
response_errors ();
|
response_errors ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2462,7 +2462,7 @@ TEST (rpc, work_generate)
|
||||||
ASSERT_FALSE (nano::from_string_hex (response_difficulty_text, response_difficulty));
|
ASSERT_FALSE (nano::from_string_hex (response_difficulty_text, response_difficulty));
|
||||||
ASSERT_EQ (result_difficulty, response_difficulty);
|
ASSERT_EQ (result_difficulty, response_difficulty);
|
||||||
auto multiplier = response.json.get<double> ("multiplier");
|
auto multiplier = response.json.get<double> ("multiplier");
|
||||||
ASSERT_EQ (nano::difficulty::to_multiplier (result_difficulty, node->network_params.network.publish_threshold), multiplier);
|
ASSERT_NEAR (nano::difficulty::to_multiplier (result_difficulty, node->network_params.network.publish_threshold), multiplier, 1e-6);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST (rpc, work_generate_difficulty)
|
TEST (rpc, work_generate_difficulty)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue