From d3ed8e112529c20d232eb99a0971a9f9fd75f71d Mon Sep 17 00:00:00 2001 From: Guilherme Lawless Date: Thu, 27 Feb 2020 08:28:25 +0000 Subject: [PATCH] Block difficulty and work validation cleanup (#2601) Blocks now have a method to calculate and return the difficulty based on their work value, work version, and root. Work validation has been cleaned up, removing optional output difficulty from all methods, and with new work_difficulty and work_threshold methods. These are now used where they make sense, such as when previously work_validate was done even though we only wanted to compare the resulting difficulty. Functionally the same, but much less verbose. Without changing the interface, we can decide to cache the difficulty in the block in the future, if it ever shows up in profiling. Further changes will be required when a new work version is added, especially if the proof is larger than 8 bytes, but these changes are a step forward in that directtion. --- nano/core_test/active_transactions.cpp | 12 +++----- nano/core_test/block.cpp | 6 ++++ nano/core_test/conflicts.cpp | 10 ++---- nano/core_test/fakes/work_peer.hpp | 5 ++- nano/core_test/node.cpp | 6 +--- nano/core_test/wallet.cpp | 14 +++------ nano/core_test/work_pool.cpp | 39 ++++++++++-------------- nano/lib/blocks.cpp | 5 +++ nano/lib/blocks.hpp | 1 + nano/lib/work.cpp | 42 +++++++++++++++++--------- nano/lib/work.hpp | 11 ++++--- nano/node/active_transactions.cpp | 10 ++---- nano/node/distributed_work.cpp | 5 ++- nano/node/json_handler.cpp | 10 +++--- nano/node/openclwork.cpp | 3 +- nano/node/wallet.cpp | 4 +-- nano/node/websocket.cpp | 7 ++--- nano/rpc_test/rpc.cpp | 21 +++++-------- 18 files changed, 99 insertions(+), 112 deletions(-) diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index ffa3c493..15b74bc1 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -297,10 +297,8 @@ TEST (active_transactions, prioritize_chains) auto send5 (std::make_shared (nano::test_genesis_key.pub, send1->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 20 * nano::xrb_ratio, key2.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send1->hash ()))); auto send6 (std::make_shared (nano::test_genesis_key.pub, send5->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 30 * nano::xrb_ratio, key3.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send5->hash ()))); auto open2 (std::make_shared (key2.pub, 0, key2.pub, 10 * nano::xrb_ratio, send5->hash (), key2.prv, key2.pub, *system.work.generate (key2.pub, nano::difficulty::from_multiplier (50., node1.network_params.network.publish_threshold)))); - uint64_t difficulty1 (0); - nano::work_validate (*open2, &difficulty1); - uint64_t difficulty2 (0); - nano::work_validate (*send6, &difficulty2); + auto difficulty1 (open2->difficulty ()); + auto difficulty2 (send6->difficulty ()); node1.process_active (send1); node1.process_active (open1); @@ -517,11 +515,9 @@ TEST (active_transactions, update_difficulty) nano::keypair key1; // Generate blocks & start elections auto send1 (std::make_shared (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - 100, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ()))); - uint64_t difficulty1 (0); - nano::work_validate (*send1, &difficulty1); + auto difficulty1 (send1->difficulty ()); auto send2 (std::make_shared (nano::test_genesis_key.pub, send1->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 200, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send1->hash ()))); - uint64_t difficulty2 (0); - nano::work_validate (*send2, &difficulty2); + auto difficulty2 (send2->difficulty ()); node1.process_active (send1); node1.process_active (send2); node1.block_processor.flush (); diff --git a/nano/core_test/block.cpp b/nano/core_test/block.cpp index 0b0670df..827a68d8 100644 --- a/nano/core_test/block.cpp +++ b/nano/core_test/block.cpp @@ -309,6 +309,12 @@ TEST (block, publish_req_serialization) ASSERT_EQ (*req.block, *req2.block); } +TEST (block, difficulty) +{ + nano::send_block block (0, 1, 2, nano::keypair ().prv, 4, 5); + ASSERT_EQ (block.difficulty (), nano::work_difficulty (block.work_version (), block.root (), block.block_work ())); +} + TEST (state_block, serialization) { nano::keypair key1; diff --git a/nano/core_test/conflicts.cpp b/nano/core_test/conflicts.cpp index ee6357f3..33094355 100644 --- a/nano/core_test/conflicts.cpp +++ b/nano/core_test/conflicts.cpp @@ -165,8 +165,7 @@ TEST (conflicts, reprioritize) nano::keypair key1; auto send1 (std::make_shared (genesis.hash (), key1.pub, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0)); node1.work_generate_blocking (*send1); - uint64_t difficulty1; - nano::work_validate (*send1, &difficulty1); + auto difficulty1 (send1->difficulty ()); nano::send_block send1_copy (*send1); node1.process_active (send1); node1.block_processor.flush (); @@ -177,8 +176,7 @@ TEST (conflicts, reprioritize) ASSERT_EQ (difficulty1, existing1->difficulty); } node1.work_generate_blocking (send1_copy, difficulty1); - uint64_t difficulty2; - nano::work_validate (send1_copy, &difficulty2); + auto difficulty2 (send1_copy.difficulty ()); node1.process_active (std::make_shared (send1_copy)); node1.block_processor.flush (); { @@ -277,9 +275,7 @@ TEST (conflicts, adjusted_difficulty) // Independent elections can have higher difficulty than adjusted tree nano::keypair key4; auto open_epoch2 (std::make_shared (key4.pub, 0, 0, 0, node1.ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (key4.pub, adjusted_difficulties.find (send1->hash ())->second))); - uint64_t difficulty; - ASSERT_FALSE (nano::work_validate (*open_epoch2, &difficulty)); - ASSERT_GT (difficulty, adjusted_difficulties.find (send1->hash ())->second); + ASSERT_GT (open_epoch2->difficulty (), adjusted_difficulties.find (send1->hash ())->second); node1.process_active (open_epoch2); node1.block_processor.flush (); system.deadline_set (3s); diff --git a/nano/core_test/fakes/work_peer.hpp b/nano/core_test/fakes/work_peer.hpp index a084e523..cec4456e 100644 --- a/nano/core_test/fakes/work_peer.hpp +++ b/nano/core_test/fakes/work_peer.hpp @@ -134,13 +134,12 @@ private: auto this_l (shared_from_this ()); work_pool.generate (version, hash, [this_l, hash](boost::optional work_a) { auto result = work_a.value_or (0); - uint64_t difficulty; - nano::work_validate (this_l->version, hash, result, &difficulty); + auto difficulty (nano::work_difficulty (this_l->version, hash, result)); static nano::network_params params; ptree::ptree message_l; message_l.put ("work", nano::to_string_hex (result)); message_l.put ("difficulty", nano::to_string_hex (difficulty)); - message_l.put ("multiplier", nano::to_string (nano::difficulty::to_multiplier (difficulty, params.network.publish_threshold))); + message_l.put ("multiplier", nano::to_string (nano::difficulty::to_multiplier (difficulty, nano::work_threshold (this_l->version)))); message_l.put ("hash", hash.to_string ()); std::stringstream ostream; ptree::write_json (ostream, message_l); diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 60537aef..65bc68cd 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -3702,9 +3702,7 @@ TEST (active_difficulty, recalculate_work) ASSERT_EQ (node1.network_params.network.publish_threshold, node1.active.active_difficulty ()); auto send1 (std::make_shared (genesis.hash (), key1.pub, 0, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0)); node1.work_generate_blocking (*send1); - uint64_t difficulty1; - nano::work_validate (*send1, &difficulty1); - auto multiplier1 = nano::difficulty::to_multiplier (difficulty1, node1.network_params.network.publish_threshold); + auto multiplier1 = nano::difficulty::to_multiplier (send1->difficulty (), nano::work_threshold (send1->work_version ())); // Process as local block node1.process_active (send1); system.deadline_set (2s); @@ -3721,8 +3719,6 @@ TEST (active_difficulty, recalculate_work) node1.active.multipliers_cb.push_back (multiplier1 * (1 + i / 100.)); } node1.work_generate_blocking (*send1); - uint64_t difficulty2; - nano::work_validate (*send1, &difficulty2); node1.process_active (send1); node1.active.update_active_difficulty (lock); sum = std::accumulate (node1.active.multipliers_cb.begin (), node1.active.multipliers_cb.end (), double(0)); diff --git a/nano/core_test/wallet.cpp b/nano/core_test/wallet.cpp index ac7ace30..b9a912eb 100644 --- a/nano/core_test/wallet.cpp +++ b/nano/core_test/wallet.cpp @@ -1134,11 +1134,9 @@ TEST (wallet, work_watcher_update) wallet.insert_adhoc (nano::test_genesis_key.prv); nano::keypair key; auto const block1 (wallet.send_action (nano::test_genesis_key.pub, key.pub, 100)); - uint64_t difficulty1 (0); - nano::work_validate (*block1, &difficulty1); + auto difficulty1 (block1->difficulty ()); auto const block2 (wallet.send_action (nano::test_genesis_key.pub, key.pub, 200)); - uint64_t difficulty2 (0); - nano::work_validate (*block2, &difficulty2); + auto difficulty2 (block2->difficulty ()); auto multiplier = nano::difficulty::to_multiplier (std::max (difficulty1, difficulty2), node.network_params.network.publish_threshold); uint64_t updated_difficulty1{ difficulty1 }, updated_difficulty2{ difficulty2 }; { @@ -1188,12 +1186,11 @@ TEST (wallet, work_watcher_generation_disabled) nano::genesis genesis; nano::keypair key; auto block (std::make_shared (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Mxrb_ratio, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (genesis.hash ()))); - uint64_t difficulty (0); - ASSERT_FALSE (nano::work_validate (*block, &difficulty)); + auto difficulty (block->difficulty ()); node.wallets.watcher->add (block); ASSERT_FALSE (node.process_local (block).code != nano::process_result::progress); ASSERT_TRUE (node.wallets.watcher->is_watched (block->qualified_root ())); - auto multiplier = nano::difficulty::to_multiplier (difficulty, node.network_params.network.publish_threshold); + auto multiplier = nano::difficulty::to_multiplier (difficulty, nano::work_threshold (block->work_version ())); uint64_t updated_difficulty{ difficulty }; { nano::unique_lock lock (node.active.mutex); @@ -1254,8 +1251,7 @@ TEST (wallet, work_watcher_cancel) nano::keypair key; auto work1 (node.work_generate_blocking (nano::test_genesis_key.pub)); auto const block1 (wallet.send_action (nano::test_genesis_key.pub, key.pub, 100, *work1, false)); - uint64_t difficulty1 (0); - nano::work_validate (*block1, &difficulty1); + auto difficulty1 (block1->difficulty ()); { nano::unique_lock lock (node.active.mutex); // Prevent active difficulty repopulating multipliers diff --git a/nano/core_test/work_pool.cpp b/nano/core_test/work_pool.cpp index 6a8af34c..87970f58 100644 --- a/nano/core_test/work_pool.cpp +++ b/nano/core_test/work_pool.cpp @@ -20,9 +20,7 @@ TEST (work, one) nano::work_pool pool (std::numeric_limits::max ()); nano::change_block block (1, 1, nano::keypair ().prv, 3, 4); block.block_work_set (*pool.generate (block.root ())); - uint64_t difficulty; - ASSERT_FALSE (nano::work_validate (block, &difficulty)); - ASSERT_LT (network_constants.publish_threshold, difficulty); + ASSERT_LT (nano::work_threshold (block.work_version ()), block.difficulty ()); } TEST (work, disabled) @@ -38,12 +36,9 @@ TEST (work, validate) nano::network_constants network_constants; nano::work_pool pool (std::numeric_limits::max ()); nano::send_block send_block (1, 1, 2, nano::keypair ().prv, 4, 6); - uint64_t difficulty; - ASSERT_TRUE (nano::work_validate (send_block, &difficulty)); - ASSERT_LT (difficulty, network_constants.publish_threshold); + ASSERT_LT (send_block.difficulty (), nano::work_threshold (send_block.work_version ())); send_block.block_work_set (*pool.generate (send_block.root ())); - ASSERT_FALSE (nano::work_validate (send_block, &difficulty)); - ASSERT_LT (network_constants.publish_threshold, difficulty); + ASSERT_LT (nano::work_threshold (send_block.work_version ()), send_block.difficulty ()); } TEST (work, cancel) @@ -107,9 +102,7 @@ TEST (work, opencl) { nano::random_pool::generate_block (root.bytes.data (), root.bytes.size ()); auto result (*pool.generate (nano::work_version::work_1, root, difficulty)); - uint64_t result_difficulty (0); - ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, root, result, &result_difficulty)); - ASSERT_GE (result_difficulty, difficulty); + ASSERT_GE (nano::work_difficulty (nano::work_version::work_1, root, result), difficulty); difficulty += difficulty_add; } } @@ -146,20 +139,20 @@ TEST (work, difficulty) uint64_t difficulty1 (0xff00000000000000); uint64_t difficulty2 (0xfff0000000000000); uint64_t difficulty3 (0xffff000000000000); - uint64_t nonce1 (0); + uint64_t result_difficulty1 (0); do { auto work1 = *pool.generate (nano::work_version::work_1, root, difficulty1); - nano::work_validate (nano::work_version::work_1, root, work1, &nonce1); - } while (nonce1 > difficulty2); - ASSERT_GT (nonce1, difficulty1); - uint64_t nonce2 (0); + result_difficulty1 = nano::work_difficulty (nano::work_version::work_1, root, work1); + } while (result_difficulty1 > difficulty2); + ASSERT_GT (result_difficulty1, difficulty1); + uint64_t result_difficulty2 (0); do { auto work2 = *pool.generate (nano::work_version::work_1, root, difficulty2); - nano::work_validate (nano::work_version::work_1, root, work2, &nonce2); - } while (nonce2 > difficulty3); - ASSERT_GT (nonce2, difficulty2); + result_difficulty2 = nano::work_difficulty (nano::work_version::work_1, root, work2); + } while (result_difficulty2 > difficulty3); + ASSERT_GT (result_difficulty2, difficulty2); } TEST (work, eco_pow) @@ -175,13 +168,13 @@ TEST (work, eco_pow) nano::root root (1); uint64_t difficulty1 (0xff00000000000000); uint64_t difficulty2 (0xfff0000000000000); - uint64_t nonce (0); + uint64_t result_difficulty (0); do { auto work = *pool.generate (nano::work_version::work_1, root, difficulty1); - nano::work_validate (nano::work_version::work_1, root, work, &nonce); - } while (nonce > difficulty2); - ASSERT_GT (nonce, difficulty1); + result_difficulty = nano::work_difficulty (nano::work_version::work_1, root, work); + } while (result_difficulty > difficulty2); + ASSERT_GT (result_difficulty, difficulty1); } promise.set_value_at_thread_exit (timer.stop ()); diff --git a/nano/lib/blocks.cpp b/nano/lib/blocks.cpp index bcd8ec2b..0907e376 100644 --- a/nano/lib/blocks.cpp +++ b/nano/lib/blocks.cpp @@ -81,6 +81,11 @@ nano::work_version nano::block::work_version () const return nano::work_version::work_1; } +uint64_t nano::block::difficulty () const +{ + return nano::work_difficulty (this->work_version (), this->root (), this->block_work ()); +} + nano::block_hash nano::block::generate_hash () const { nano::block_hash result; diff --git a/nano/lib/blocks.hpp b/nano/lib/blocks.hpp index b6d3b05b..16053bea 100644 --- a/nano/lib/blocks.hpp +++ b/nano/lib/blocks.hpp @@ -60,6 +60,7 @@ public: virtual bool valid_predecessor (nano::block const &) const = 0; static size_t size (nano::block_type); virtual nano::work_version work_version () const; + uint64_t difficulty () const; // If there are any changes to the hashables, call this to update the cached hash void refresh (); diff --git a/nano/lib/work.cpp b/nano/lib/work.cpp index daa3c847..2983d39e 100644 --- a/nano/lib/work.cpp +++ b/nano/lib/work.cpp @@ -21,34 +21,48 @@ std::string nano::to_string (nano::work_version const version_a) return result; } -bool nano::work_validate (nano::block const & block_a, uint64_t * difficulty_a) +bool nano::work_validate (nano::block const & block_a) { - return nano::work_validate (block_a.work_version (), block_a.root (), block_a.block_work (), difficulty_a); + return block_a.difficulty () < nano::work_threshold (block_a.work_version ()); } -bool nano::work_validate (nano::work_version const version_a, nano::root const & root_a, uint64_t const work_a, uint64_t * difficulty_a) +bool nano::work_validate (nano::work_version const version_a, nano::root const & root_a, uint64_t const work_a) { - bool invalid (true); + return nano::work_difficulty (version_a, root_a, work_a) < nano::work_threshold (version_a); +} + +uint64_t nano::work_difficulty (nano::work_version const version_a, nano::root const & root_a, uint64_t const work_a) +{ + uint64_t result{ 0 }; switch (version_a) { case nano::work_version::work_1: - invalid = nano::work_v1::validate (root_a, work_a, difficulty_a); + result = nano::work_v1::value (root_a, work_a); break; default: - debug_assert (false && "Invalid version specified to work_validate"); + debug_assert (false && "Invalid version specified to work_difficulty"); } - return invalid; + return result; } -bool nano::work_v1::validate (nano::root const & root_a, uint64_t work_a, uint64_t * difficulty_a) +uint64_t nano::work_threshold (nano::work_version const version_a) +{ + uint64_t result{ std::numeric_limits::max () }; + switch (version_a) + { + case nano::work_version::work_1: + result = nano::work_v1::threshold (); + break; + default: + debug_assert (false && "Invalid version specified to work_threshold"); + } + return result; +} + +uint64_t nano::work_v1::threshold () { static nano::network_constants network_constants; - auto work_value (value (root_a, work_a)); - if (difficulty_a != nullptr) - { - *difficulty_a = work_value; - } - return work_value < network_constants.publish_threshold; + return network_constants.publish_threshold; } #ifndef NANO_FUZZER_TEST diff --git a/nano/lib/work.hpp b/nano/lib/work.hpp index 9524e298..b64ff8ad 100644 --- a/nano/lib/work.hpp +++ b/nano/lib/work.hpp @@ -21,13 +21,16 @@ enum class work_version std::string to_string (nano::work_version const version_a); class block; -bool work_validate (nano::block const &, uint64_t * = nullptr); -bool work_validate (nano::work_version const, nano::root const &, uint64_t const, uint64_t * = nullptr); +bool work_validate (nano::block const &); +bool work_validate (nano::work_version const, nano::root const &, uint64_t const); + +uint64_t work_difficulty (nano::work_version const, nano::root const &, uint64_t const); +uint64_t work_threshold (nano::work_version const); namespace work_v1 { - bool validate (nano::root const &, uint64_t const, uint64_t * = nullptr); - uint64_t value (nano::root const &, uint64_t); + uint64_t value (nano::root const & root_a, uint64_t work_a); + uint64_t threshold (); } class opencl_work; class work_item final diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index b61acd5e..7e9923d5 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -580,10 +580,7 @@ std::pair, bool> nano::active_transactions::inse result.second = true; auto hash (block_a->hash ()); result.first = nano::make_shared (node, block_a, skip_delay_a, confirmation_action_a); - uint64_t difficulty (0); - auto error (nano::work_validate (*block_a, &difficulty)); - (void)error; - debug_assert (!error); + auto difficulty (block_a->difficulty ()); roots.get ().emplace (nano::conflict_info{ root, difficulty, difficulty, result.first }); blocks.emplace (hash, result.first); adjust_difficulty (hash); @@ -680,10 +677,7 @@ void nano::active_transactions::update_difficulty (std::shared_ptr auto existing_election (roots.get ().find (block_a->qualified_root ())); if (existing_election != roots.get ().end ()) { - uint64_t difficulty; - auto error (nano::work_validate (*block_a, &difficulty)); - (void)error; - debug_assert (!error); + auto difficulty (block_a->difficulty ()); if (difficulty > existing_election->difficulty) { if (node.config.logging.active_update_logging ()) diff --git a/nano/node/distributed_work.cpp b/nano/node/distributed_work.cpp index 0e09d116..33ee1815 100644 --- a/nano/node/distributed_work.cpp +++ b/nano/node/distributed_work.cpp @@ -241,8 +241,7 @@ void nano::distributed_work::success (std::string const & body_a, nano::tcp_endp uint64_t work; if (!nano::from_string_hex (work_text, work)) { - uint64_t result_difficulty (0); - if (!nano::work_validate (request.version, request.root, work, &result_difficulty) && result_difficulty >= request.difficulty) + if (nano::work_difficulty (request.version, request.root, work) >= request.difficulty) { error = false; node.unresponsive_work_peers = false; @@ -324,7 +323,7 @@ void nano::distributed_work::set_once (uint64_t const work_a, std::string const if (node.config.logging.work_generation_time ()) { boost::format unformatted_l ("Work generation for %1%, with a threshold difficulty of %2% (multiplier %3%x) complete: %4% ms"); - auto multiplier_text_l (nano::to_string (nano::difficulty::to_multiplier (request.difficulty, node.network_params.network.publish_threshold), 2)); + auto multiplier_text_l (nano::to_string (nano::difficulty::to_multiplier (request.difficulty, nano::work_threshold (request.version)), 2)); node.logger.try_log (boost::str (unformatted_l % request.root.to_string () % nano::to_string_hex (request.difficulty) % multiplier_text_l % elapsed.value ().count ())); } } diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index b2bf0ce2..699c46c7 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -4938,10 +4938,9 @@ void nano::json_handler::work_generate () uint64_t work (work_a.value ()); response_l.put ("work", nano::to_string_hex (work)); std::stringstream ostream; - uint64_t result_difficulty; - nano::work_validate (work_version, hash, work, &result_difficulty); + auto result_difficulty (nano::work_difficulty (work_version, hash, work)); response_l.put ("difficulty", nano::to_string_hex (result_difficulty)); - auto result_multiplier = nano::difficulty::to_multiplier (result_difficulty, this->node.network_params.network.publish_threshold); + auto result_multiplier = nano::difficulty::to_multiplier (result_difficulty, nano::work_threshold (work_version)); response_l.put ("multiplier", nano::to_string (result_multiplier)); boost::property_tree::write_json (ostream, response_l); rpc_l->response (ostream.str ()); @@ -5053,11 +5052,10 @@ void nano::json_handler::work_validate () auto work_version (work_version_optional_impl (nano::work_version::work_1)); if (!ec) { - uint64_t result_difficulty (0); - nano::work_validate (work_version, hash, work, &result_difficulty); + auto result_difficulty (nano::work_difficulty (work_version, hash, work)); response_l.put ("valid", (result_difficulty >= difficulty) ? "1" : "0"); response_l.put ("difficulty", nano::to_string_hex (result_difficulty)); - auto result_multiplier = nano::difficulty::to_multiplier (result_difficulty, node.network_params.network.publish_threshold); + auto result_multiplier = nano::difficulty::to_multiplier (result_difficulty, nano::work_threshold (work_version)); response_l.put ("multiplier", nano::to_string (result_multiplier)); } response_errors (); diff --git a/nano/node/openclwork.cpp b/nano/node/openclwork.cpp index bce14c3f..39c3d466 100644 --- a/nano/node/openclwork.cpp +++ b/nano/node/openclwork.cpp @@ -699,10 +699,9 @@ boost::optional nano::opencl_work::generate_work (nano::work_version c bool error (false); int ticket_l (ticket_a); uint64_t result (0); - uint64_t computed_difficulty (0); unsigned thread_count (config.threads); size_t work_size[] = { thread_count, 0, 0 }; - while ((nano::work_validate (version_a, root_a, result, &computed_difficulty) || computed_difficulty < difficulty_a) && !error && ticket_a == ticket_l) + while (nano::work_difficulty (version_a, root_a, result) < difficulty_a && !error && ticket_a == ticket_l) { result = rand.next (); cl_int write_error1 = clEnqueueWriteBuffer (queue, attempt_buffer, false, 0, sizeof (uint64_t), &result, 0, nullptr, nullptr); diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index 6541dcf2..0a705dd2 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1431,14 +1431,12 @@ void nano::work_watcher::watching (nano::qualified_root const & root_a, std::sha if (watcher_l->watched.find (root_a) != watcher_l->watched.end ()) // not yet confirmed or cancelled { lock.unlock (); - uint64_t difficulty (0); - nano::work_validate (*block_a, &difficulty); auto active_difficulty (watcher_l->node.active.limited_active_difficulty ()); /* * Work watcher should still watch blocks even without work generation, although no rework is done * Functionality may be added in the future that does not require updating work */ - if (active_difficulty > difficulty && watcher_l->node.work_generation_enabled ()) + if (active_difficulty > block_a->difficulty () && watcher_l->node.work_generation_enabled ()) { watcher_l->node.work_generate ( block_a->work_version (), block_a->root (), [watcher_l, block_a, root_a](boost::optional work_a) { diff --git a/nano/node/websocket.cpp b/nano/node/websocket.cpp index 7bfb1e74..4cb686e7 100644 --- a/nano/node/websocket.cpp +++ b/nano/node/websocket.cpp @@ -788,7 +788,7 @@ nano::websocket::message nano::websocket::message_builder::work_generation (nano request_l.put ("version", nano::to_string (version_a)); request_l.put ("hash", root_a.to_string ()); request_l.put ("difficulty", nano::to_string_hex (difficulty_a)); - auto request_multiplier_l (nano::difficulty::to_multiplier (difficulty_a, publish_threshold_a)); + auto request_multiplier_l (nano::difficulty::to_multiplier (difficulty_a, nano::work_threshold (version_a))); request_l.put ("multiplier", nano::to_string (request_multiplier_l)); work_l.add_child ("request", request_l); @@ -797,10 +797,9 @@ nano::websocket::message nano::websocket::message_builder::work_generation (nano boost::property_tree::ptree result_l; result_l.put ("source", peer_a); result_l.put ("work", nano::to_string_hex (work_a)); - uint64_t result_difficulty_l; - nano::work_validate (version_a, root_a, work_a, &result_difficulty_l); + auto result_difficulty_l (nano::work_difficulty (version_a, root_a, work_a)); result_l.put ("difficulty", nano::to_string_hex (result_difficulty_l)); - auto result_multiplier_l (nano::difficulty::to_multiplier (result_difficulty_l, publish_threshold_a)); + auto result_multiplier_l (nano::difficulty::to_multiplier (result_difficulty_l, nano::work_threshold (version_a))); result_l.put ("multiplier", nano::to_string (result_multiplier_l)); work_l.add_child ("result", result_l); } diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index f8e01b15..9c891973 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -1788,9 +1788,8 @@ TEST (rpc, process_block_with_work_watcher) nano::keypair key; auto latest (node1.latest (nano::test_genesis_key.pub)); auto send (std::make_shared (nano::test_genesis_key.pub, latest, nano::test_genesis_key.pub, nano::genesis_amount - 100, nano::test_genesis_key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (latest))); - uint64_t difficulty1 (0); - nano::work_validate (*send, &difficulty1); - auto multiplier1 = nano::difficulty::to_multiplier (difficulty1, node1.network_params.network.publish_threshold); + auto difficulty1 (send->difficulty ()); + auto multiplier1 = nano::difficulty::to_multiplier (difficulty1, nano::work_threshold (send->work_version ())); nano::node_rpc_config node_rpc_config; nano::ipc::ipc_server ipc_server (node1, node_rpc_config); nano::rpc_config rpc_config (nano::get_available_port (), true); @@ -2830,9 +2829,9 @@ TEST (rpc, work_generate) ASSERT_EQ (200, response.status); ASSERT_EQ (hash.to_string (), response.json.get ("hash")); auto work_text (response.json.get ("work")); - uint64_t work, result_difficulty; + uint64_t work; ASSERT_FALSE (nano::from_string_hex (work_text, work)); - ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, work, &result_difficulty)); + auto result_difficulty (nano::work_difficulty (nano::work_version::work_1, hash, work)); auto response_difficulty_text (response.json.get ("difficulty")); uint64_t response_difficulty; ASSERT_FALSE (nano::from_string_hex (response_difficulty_text, response_difficulty)); @@ -2876,8 +2875,7 @@ TEST (rpc, work_generate_difficulty) auto work_text (response.json.get ("work")); uint64_t work; ASSERT_FALSE (nano::from_string_hex (work_text, work)); - uint64_t result_difficulty; - ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, work, &result_difficulty)); + auto result_difficulty (nano::work_difficulty (nano::work_version::work_1, hash, work)); auto response_difficulty_text (response.json.get ("difficulty")); uint64_t response_difficulty; ASSERT_FALSE (nano::from_string_hex (response_difficulty_text, response_difficulty)); @@ -2900,8 +2898,7 @@ TEST (rpc, work_generate_difficulty) auto work_text (response.json.get ("work")); uint64_t work; ASSERT_FALSE (nano::from_string_hex (work_text, work)); - uint64_t result_difficulty; - ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, work, &result_difficulty)); + auto result_difficulty (nano::work_difficulty (nano::work_version::work_1, hash, work)); ASSERT_GE (result_difficulty, difficulty); } { @@ -2953,8 +2950,7 @@ TEST (rpc, work_generate_multiplier) auto work_text (response.json.get ("work")); uint64_t work; ASSERT_FALSE (nano::from_string_hex (work_text, work)); - uint64_t result_difficulty; - ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, work, &result_difficulty)); + auto result_difficulty (nano::work_difficulty (nano::work_version::work_1, hash, work)); auto response_difficulty_text (response.json.get ("difficulty")); uint64_t response_difficulty; ASSERT_FALSE (nano::from_string_hex (response_difficulty_text, response_difficulty)); @@ -3841,8 +3837,7 @@ TEST (rpc, work_validate) double multiplier (response.json.get ("multiplier")); ASSERT_NEAR (multiplier, nano::difficulty::to_multiplier (difficulty, params.network.publish_threshold), 1e-6); } - uint64_t result_difficulty; - ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, work1, &result_difficulty)); + auto result_difficulty (nano::work_difficulty (nano::work_version::work_1, hash, work1)); ASSERT_GE (result_difficulty, params.network.publish_threshold); request.put ("work", nano::to_string_hex (work1)); request.put ("difficulty", nano::to_string_hex (result_difficulty));