diff --git a/CMakeLists.txt b/CMakeLists.txt index a67294efd3..e19ba83d6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,7 +170,11 @@ set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) #set(CMAKE_C_EXTENSIONS OFF) -set(CMAKE_CXX_STANDARD 14) +set(NANO_SUPPORTED_CPP_STANDARD "17" CACHE STRING "Supported C++ standard (14 or 17)") +if (CI_BUILD OR CI_TEST) + set(NANO_SUPPORTED_CPP_STANDARD "14") +endif() +set(CMAKE_CXX_STANDARD ${NANO_SUPPORTED_CPP_STANDARD}) set(CMAKE_CXX_STANDARD_REQUIRED ON) #set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index 64eca0e740..ffa3c4938c 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -254,7 +254,6 @@ TEST (active_transactions, keep_local) { ASSERT_NO_ERROR (system.poll ()); } - ASSERT_EQ (0, node.active.dropped_elections_cache_size ()); while (!node.active.empty ()) { nano::lock_guard active_guard (node.active.mutex); @@ -276,7 +275,6 @@ TEST (active_transactions, keep_local) { ASSERT_NO_ERROR (system.poll ()); } - ASSERT_EQ (1, node.active.dropped_elections_cache_size ()); } TEST (active_transactions, prioritize_chains) @@ -571,72 +569,6 @@ TEST (active_transactions, update_difficulty) } } -TEST (active_transactions, restart_dropped) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.enable_voting = false; - node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; - auto & node = *system.add_node (node_config); - nano::genesis genesis; - auto send1 (std::make_shared (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::xrb_ratio, nano::test_genesis_key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ()))); - // Process only in ledger and emulate dropping the election - ASSERT_EQ (nano::process_result::progress, node.process (*send1).code); - { - nano::lock_guard guard (node.active.mutex); - node.active.add_dropped_elections_cache (send1->qualified_root ()); - } - uint64_t difficulty1 (0); - nano::work_validate (*send1, &difficulty1); - // Generate higher difficulty work - auto work2 (*system.work.generate (send1->root (), difficulty1)); - uint64_t difficulty2 (0); - nano::work_validate (send1->root (), work2, &difficulty2); - ASSERT_GT (difficulty2, difficulty1); - // Process the same block with updated work - auto send2 (std::make_shared (*send1)); - send2->block_work_set (work2); - node.process_active (send2); - // Wait until the block is in elections - system.deadline_set (5s); - bool done{ false }; - while (!done) - { - { - nano::lock_guard guard (node.active.mutex); - auto existing (node.active.roots.find (send2->qualified_root ())); - done = existing != node.active.roots.end (); - if (done) - { - ASSERT_EQ (difficulty2, existing->difficulty); - } - } - ASSERT_NO_ERROR (system.poll ()); - } - std::shared_ptr block; - while (block == nullptr) - { - ASSERT_NO_ERROR (system.poll ()); - block = node.store.block_get (node.store.tx_begin_read (), send1->hash ()); - } - ASSERT_EQ (work2, block->block_work ()); - // Drop election - node.active.erase (*send2); - // Try to restart election with the lower difficulty block, should not work since the block as lower work - node.process_active (send1); - system.deadline_set (5s); - while (node.block_processor.size () > 0) - { - ASSERT_NO_ERROR (system.poll ()); - } - ASSERT_TRUE (node.active.empty ()); - // Verify the block was not updated in the ledger - { - auto block (node.store.block_get (node.store.tx_begin_read (), send1->hash ())); - ASSERT_EQ (work2, block->block_work ()); - } -} - TEST (active_transactions, vote_replays) { nano::system system; diff --git a/nano/core_test/block.cpp b/nano/core_test/block.cpp index 082dab5697..0b0670df86 100644 --- a/nano/core_test/block.cpp +++ b/nano/core_test/block.cpp @@ -399,6 +399,15 @@ TEST (state_block, hashing) ASSERT_EQ (hash, block.hash ()); } +TEST (blocks, work_version) +{ + ASSERT_EQ (nano::work_version::work_1, nano::send_block ().work_version ()); + ASSERT_EQ (nano::work_version::work_1, nano::receive_block ().work_version ()); + ASSERT_EQ (nano::work_version::work_1, nano::change_block ().work_version ()); + ASSERT_EQ (nano::work_version::work_1, nano::open_block ().work_version ()); + ASSERT_EQ (nano::work_version::work_1, nano::state_block ().work_version ()); +} + TEST (block_uniquer, null) { nano::block_uniquer uniquer; diff --git a/nano/core_test/confirmation_height.cpp b/nano/core_test/confirmation_height.cpp index 426debef75..5f93aa8eb7 100644 --- a/nano/core_test/confirmation_height.cpp +++ b/nano/core_test/confirmation_height.cpp @@ -1171,9 +1171,6 @@ TEST (confirmation_height, dependent_election) add_callback_stats (*node); - // Prevent the confirmation height processor from doing any processing - node->confirmation_height_processor.pause (); - // Wait until it has been processed node->block_confirm (send2); system.deadline_set (10s); @@ -1182,20 +1179,17 @@ TEST (confirmation_height, dependent_election) ASSERT_NO_ERROR (system.poll ()); } - system.deadline_set (10s); - while (node->confirmation_height_processor.awaiting_processing_size () != 1) - { - ASSERT_NO_ERROR (system.poll ()); - } - { - nano::lock_guard guard (node->confirmation_height_processor.mutex); - ASSERT_EQ (*node->confirmation_height_processor.awaiting_processing.begin (), send2->hash ()); + // The write guard prevents the confirmation height processor doing any writes. + system.deadline_set (10s); + auto write_guard = node->write_database_queue.wait (nano::writer::testing); + while (!node->write_database_queue.contains (nano::writer::confirmation_height)) + { + ASSERT_NO_ERROR (system.poll ()); + } } - // Now put the other block in active so it can be confirmed as a dependent election node->block_confirm (send1); - node->confirmation_height_processor.unpause (); system.deadline_set (10s); while (node->stats.count (nano::stat::type::http_callback, nano::stat::detail::http_callback, nano::stat::dir::out) != 3) diff --git a/nano/core_test/confirmation_solicitor.cpp b/nano/core_test/confirmation_solicitor.cpp index cb4b512249..8be720b051 100644 --- a/nano/core_test/confirmation_solicitor.cpp +++ b/nano/core_test/confirmation_solicitor.cpp @@ -12,15 +12,16 @@ TEST (confirmation_solicitor, batches) nano::node_config node_config (nano::get_available_port (), system.logging); node_config.enable_voting = false; node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; - auto & node1 = *system.add_node (node_config); - auto channel1 (node1.network.udp_channels.create (node1.network.endpoint ())); - // Solicitor will only solicit from this representative - nano::representative representative (nano::test_genesis_key.pub, nano::genesis_amount, channel1); - node_config.peering_port = nano::get_available_port (); nano::node_flags node_flags; + node_flags.disable_udp = false; + auto & node1 = *system.add_node (node_config, node_flags); + node_config.peering_port = nano::get_available_port (); // To prevent races on the solicitor node_flags.disable_request_loop = true; auto & node2 = *system.add_node (node_config, node_flags); + // Solicitor will only solicit from this representative + auto channel1 (node2.network.udp_channels.create (node1.network.endpoint ())); + nano::representative representative (nano::test_genesis_key.pub, nano::genesis_amount, channel1); // Lock active_transactions which uses the solicitor { nano::lock_guard active_guard (node2.active.mutex); @@ -43,6 +44,7 @@ TEST (confirmation_solicitor, batches) // Broadcasting should be immediate ASSERT_EQ (0, node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out)); ASSERT_FALSE (node2.active.solicitor.broadcast (*election)); + system.deadline_set (5s); while (node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out) < 1) { ASSERT_NO_ERROR (system.poll ()); diff --git a/nano/core_test/distributed_work.cpp b/nano/core_test/distributed_work.cpp index 2f1fbe2237..c396b0a532 100644 --- a/nano/core_test/distributed_work.cpp +++ b/nano/core_test/distributed_work.cpp @@ -31,7 +31,7 @@ TEST (distributed_work, no_peers) { ASSERT_NO_ERROR (system.poll ()); } - ASSERT_FALSE (nano::work_validate (hash, *work)); + ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, *work)); // should only be removed after cleanup ASSERT_EQ (1, node->distributed_work.items.size ()); while (!node->distributed_work.items.empty ()) @@ -177,7 +177,7 @@ TEST (distributed_work, peer) { ASSERT_NO_ERROR (system.poll ()); } - ASSERT_FALSE (nano::work_validate (hash, *work)); + ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, *work)); ASSERT_EQ (1, work_peer->generations_good); ASSERT_EQ (0, work_peer->generations_bad); ASSERT_NO_ERROR (system.poll ()); @@ -207,7 +207,7 @@ TEST (distributed_work, peer_malicious) { ASSERT_NO_ERROR (system.poll ()); } - ASSERT_FALSE (nano::work_validate (hash, *work)); + ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, *work)); system.deadline_set (5s); while (malicious_peer->generations_bad < 1) { @@ -265,7 +265,7 @@ TEST (distributed_work, peer_multi) { ASSERT_NO_ERROR (system.poll ()); } - ASSERT_FALSE (nano::work_validate (hash, *work)); + ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, *work)); system.deadline_set (5s); while (slow_peer->cancels < 1) { @@ -304,5 +304,5 @@ TEST (distributed_work, fail_resolve) { ASSERT_NO_ERROR (system.poll ()); } - ASSERT_FALSE (nano::work_validate (hash, *work)); + ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, *work)); } diff --git a/nano/core_test/fakes/work_peer.hpp b/nano/core_test/fakes/work_peer.hpp index 30cc6173fe..a084e52312 100644 --- a/nano/core_test/fakes/work_peer.hpp +++ b/nano/core_test/fakes/work_peer.hpp @@ -36,9 +36,10 @@ class work_peer_connection : public std::enable_shared_from_this on_generation_a, std::function on_cancel_a) : + work_peer_connection (asio::io_context & ioc_a, work_peer_type const type_a, nano::work_version const version_a, nano::work_pool & pool_a, std::function on_generation_a, std::function on_cancel_a) : socket (ioc_a), type (type_a), + version (version_a), work_pool (pool_a), on_generation (on_generation_a), on_cancel (on_cancel_a), @@ -53,6 +54,7 @@ class work_peer_connection : public std::enable_shared_from_this request; @@ -130,10 +132,10 @@ class work_peer_connection : public std::enable_shared_from_this work_a) { + 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 (hash, result, &difficulty); + nano::work_validate (this_l->version, hash, result, &difficulty); static nano::network_params params; ptree::ptree message_l; message_l.put ("work", nano::to_string_hex (result)); @@ -188,12 +190,14 @@ class work_peer_connection : public std::enable_shared_from_this { public: - fake_work_peer (nano::work_pool & pool_a, asio::io_context & ioc_a, unsigned short port_a, work_peer_type const type_a) : + fake_work_peer () = delete; + fake_work_peer (nano::work_pool & pool_a, asio::io_context & ioc_a, unsigned short port_a, work_peer_type const type_a, nano::work_version const version_a = nano::work_version::work_1) : pool (pool_a), endpoint (tcp::v4 (), port_a), ioc (ioc_a), acceptor (ioc_a, endpoint), - type (type_a) + type (type_a), + version (version_a) { } void start () @@ -213,7 +217,7 @@ class fake_work_peer : public std::enable_shared_from_this { std::weak_ptr this_w (shared_from_this ()); auto connection (std::make_shared ( - ioc, type, pool, + ioc, type, version, pool, [this_w](bool const good_generation) { if (auto this_l = this_w.lock ()) { @@ -249,5 +253,6 @@ class fake_work_peer : public std::enable_shared_from_this asio::io_context & ioc; tcp::acceptor acceptor; work_peer_type const type; + nano::work_version version; }; } diff --git a/nano/core_test/node_telemetry.cpp b/nano/core_test/node_telemetry.cpp index 6c528d31cd..c42b396cce 100644 --- a/nano/core_test/node_telemetry.cpp +++ b/nano/core_test/node_telemetry.cpp @@ -16,6 +16,8 @@ void compare_default_test_result_data (nano::telemetry_data const & telemetry_da TEST (node_telemetry, consolidate_data) { + auto time = 1582117035109; + // Pick specific values so that we can check both mode and average are working correctly nano::telemetry_data data; data.account_count = 2; @@ -31,6 +33,7 @@ TEST (node_telemetry, consolidate_data) data.minor_version = 1; data.patch_version = 4; data.pre_release_version = 6; + data.timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (time)); nano::telemetry_data data1; data1.account_count = 5; @@ -47,6 +50,7 @@ TEST (node_telemetry, consolidate_data) data1.patch_version = 3; data1.pre_release_version = 6; data1.maker = 2; + data1.timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (time + 1)); nano::telemetry_data data2; data2.account_count = 3; @@ -62,6 +66,7 @@ TEST (node_telemetry, consolidate_data) data2.minor_version = 1; data2.patch_version = 4; data2.pre_release_version = 6; + data2.timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (time)); std::vector all_data{ data, data1, data2 }; @@ -80,6 +85,7 @@ TEST (node_telemetry, consolidate_data) ASSERT_FALSE (consolidated_telemetry_data.patch_version.is_initialized ()); ASSERT_FALSE (consolidated_telemetry_data.pre_release_version.is_initialized ()); ASSERT_FALSE (consolidated_telemetry_data.maker.is_initialized ()); + ASSERT_EQ (*consolidated_telemetry_data.timestamp, std::chrono::system_clock::time_point (std::chrono::milliseconds (time))); // Modify the metrics which may be either the mode or averages to ensure all are tested. all_data[2].bandwidth_cap = 53; @@ -90,6 +96,7 @@ TEST (node_telemetry, consolidate_data) all_data[2].patch_version = 3; all_data[2].pre_release_version = 6; all_data[2].maker = 2; + all_data[2].timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (time + 2)); auto consolidated_telemetry_data1 = nano::consolidate_telemetry_data (all_data); ASSERT_EQ (consolidated_telemetry_data1.major_version, 10); @@ -100,6 +107,7 @@ TEST (node_telemetry, consolidate_data) ASSERT_TRUE (consolidated_telemetry_data1.protocol_version == 11 || consolidated_telemetry_data1.protocol_version == 12 || consolidated_telemetry_data1.protocol_version == 13); ASSERT_EQ (consolidated_telemetry_data1.bandwidth_cap, 51); ASSERT_EQ (consolidated_telemetry_data1.genesis_block, nano::block_hash (3)); + ASSERT_EQ (*consolidated_telemetry_data1.timestamp, std::chrono::system_clock::time_point (std::chrono::milliseconds (time + 1))); // Test equality operator ASSERT_FALSE (consolidated_telemetry_data == consolidated_telemetry_data1); @@ -108,16 +116,19 @@ TEST (node_telemetry, consolidate_data) TEST (node_telemetry, consolidate_data_optional_data) { + auto time = 1582117035109; nano::telemetry_data data; data.major_version = 20; data.minor_version = 1; data.patch_version = 4; data.pre_release_version = 6; data.maker = 2; + data.timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (time)); nano::telemetry_data missing_minor; missing_minor.major_version = 20; missing_minor.patch_version = 4; + missing_minor.timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (time + 3)); nano::telemetry_data missing_all_optional; @@ -128,6 +139,7 @@ TEST (node_telemetry, consolidate_data_optional_data) ASSERT_EQ (*consolidated_telemetry_data.patch_version, 4); ASSERT_EQ (*consolidated_telemetry_data.pre_release_version, 6); ASSERT_EQ (*consolidated_telemetry_data.maker, 2); + ASSERT_EQ (*consolidated_telemetry_data.timestamp, std::chrono::system_clock::time_point (std::chrono::milliseconds (time + 1))); } TEST (node_telemetry, serialize_deserialize_json_optional) @@ -137,6 +149,7 @@ TEST (node_telemetry, serialize_deserialize_json_optional) data.patch_version = 4; data.pre_release_version = 6; data.maker = 2; + data.timestamp = std::chrono::system_clock::time_point (100ms); nano::jsonconfig config; data.serialize_json (config); @@ -150,6 +163,9 @@ TEST (node_telemetry, serialize_deserialize_json_optional) ASSERT_EQ (val, 6); ASSERT_FALSE (config.get ("maker", val).get_error ()); ASSERT_EQ (val, 2); + uint64_t timestamp; + ASSERT_FALSE (config.get ("timestamp", timestamp).get_error ()); + ASSERT_EQ (timestamp, 100); nano::telemetry_data data1; data1.deserialize_json (config); @@ -157,6 +173,7 @@ TEST (node_telemetry, serialize_deserialize_json_optional) ASSERT_EQ (*data1.patch_version, 4); ASSERT_EQ (*data1.pre_release_version, 6); ASSERT_EQ (*data1.maker, 2); + ASSERT_EQ (*data1.timestamp, std::chrono::system_clock::time_point (100ms)); nano::telemetry_data no_optional_data; nano::jsonconfig config1; @@ -165,6 +182,7 @@ TEST (node_telemetry, serialize_deserialize_json_optional) ASSERT_FALSE (config1.get_optional ("patch_version").is_initialized ()); ASSERT_FALSE (config1.get_optional ("pre_release_version").is_initialized ()); ASSERT_FALSE (config1.get_optional ("maker").is_initialized ()); + ASSERT_FALSE (config1.get_optional ("timestamp").is_initialized ()); nano::telemetry_data no_optional_data1; no_optional_data1.deserialize_json (config1); @@ -172,6 +190,7 @@ TEST (node_telemetry, serialize_deserialize_json_optional) ASSERT_FALSE (no_optional_data1.patch_version.is_initialized ()); ASSERT_FALSE (no_optional_data1.pre_release_version.is_initialized ()); ASSERT_FALSE (no_optional_data1.maker.is_initialized ()); + ASSERT_FALSE (no_optional_data1.timestamp.is_initialized ()); } TEST (node_telemetry, consolidate_data_remove_outliers) @@ -191,6 +210,7 @@ TEST (node_telemetry, consolidate_data_remove_outliers) data.patch_version = 5; data.pre_release_version = 2; data.maker = 1; + data.timestamp = std::chrono::system_clock::time_point (100ms); // Insert 20 of these, and 2 outliers at the lower and upper bounds which should get removed std::vector all_data (20, data); @@ -211,6 +231,7 @@ TEST (node_telemetry, consolidate_data_remove_outliers) outlier_data.patch_version = 1; outlier_data.pre_release_version = 1; outlier_data.maker = 1; + outlier_data.timestamp = std::chrono::system_clock::time_point (1ms); all_data.push_back (outlier_data); all_data.push_back (outlier_data); @@ -229,6 +250,7 @@ TEST (node_telemetry, consolidate_data_remove_outliers) outlier_data1.patch_version = 9; outlier_data1.pre_release_version = 9; outlier_data1.maker = 9; + outlier_data1.timestamp = std::chrono::system_clock::time_point (999ms); all_data.push_back (outlier_data1); all_data.push_back (outlier_data1); @@ -242,7 +264,7 @@ TEST (node_telemetry, no_peers) std::atomic done{ false }; system.nodes[0]->telemetry.get_metrics_peers_async ([&done](nano::telemetry_data_responses const & responses_a) { - ASSERT_TRUE (responses_a.telemetry_data_time_pairs.empty ()); + ASSERT_TRUE (responses_a.telemetry_datas.empty ()); ASSERT_FALSE (responses_a.all_received); done = true; }); @@ -267,12 +289,12 @@ TEST (node_telemetry, basic) wait_peer_connections (system); // Request telemetry metrics - std::unordered_map all_telemetry_data_time_pairs; + std::unordered_map all_telemetry_datas; { std::atomic done{ false }; - node_client->telemetry.get_metrics_peers_async ([&done, &all_telemetry_data_time_pairs](nano::telemetry_data_responses const & responses_a) { + node_client->telemetry.get_metrics_peers_async ([&done, &all_telemetry_datas](nano::telemetry_data_responses const & responses_a) { ASSERT_TRUE (responses_a.all_received); - all_telemetry_data_time_pairs = responses_a.telemetry_data_time_pairs; + all_telemetry_datas = responses_a.telemetry_datas; done = true; }); @@ -284,14 +306,14 @@ TEST (node_telemetry, basic) } // Check the metrics are correct - ASSERT_EQ (all_telemetry_data_time_pairs.size (), 1); - compare_default_test_result_data (all_telemetry_data_time_pairs.begin ()->second.data, *node_server); + ASSERT_EQ (all_telemetry_datas.size (), 1); + compare_default_test_result_data (all_telemetry_datas.begin ()->second, *node_server); // Call again straight away. It should use the cache { std::atomic done{ false }; - node_client->telemetry.get_metrics_peers_async ([&done, &all_telemetry_data_time_pairs](nano::telemetry_data_responses const & responses_a) { - ASSERT_EQ (all_telemetry_data_time_pairs, responses_a.telemetry_data_time_pairs); + node_client->telemetry.get_metrics_peers_async ([&done, &all_telemetry_datas](nano::telemetry_data_responses const & responses_a) { + ASSERT_EQ (all_telemetry_datas, responses_a.telemetry_datas); ASSERT_TRUE (responses_a.all_received); done = true; }); @@ -307,8 +329,8 @@ TEST (node_telemetry, basic) std::this_thread::sleep_for (nano::telemetry_cache_cutoffs::test); std::atomic done{ false }; - node_client->telemetry.get_metrics_peers_async ([&done, &all_telemetry_data_time_pairs](nano::telemetry_data_responses const & responses_a) { - ASSERT_NE (all_telemetry_data_time_pairs, responses_a.telemetry_data_time_pairs); + node_client->telemetry.get_metrics_peers_async ([&done, &all_telemetry_datas](nano::telemetry_data_responses const & responses_a) { + ASSERT_NE (all_telemetry_datas, responses_a.telemetry_datas); ASSERT_TRUE (responses_a.all_received); done = true; }); @@ -350,10 +372,10 @@ TEST (node_telemetry, many_nodes) auto node_client = system.nodes.front (); std::atomic done{ false }; - std::unordered_map all_telemetry_data_time_pairs; - node_client->telemetry.get_metrics_peers_async ([&done, &all_telemetry_data_time_pairs](nano::telemetry_data_responses const & responses_a) { + std::unordered_map all_telemetry_datas; + node_client->telemetry.get_metrics_peers_async ([&done, &all_telemetry_datas](nano::telemetry_data_responses const & responses_a) { ASSERT_TRUE (responses_a.all_received); - all_telemetry_data_time_pairs = responses_a.telemetry_data_time_pairs; + all_telemetry_datas = responses_a.telemetry_datas; done = true; }); @@ -365,9 +387,9 @@ TEST (node_telemetry, many_nodes) // Check the metrics nano::network_params params; - for (auto & telemetry_data_time_pair : all_telemetry_data_time_pairs) + for (auto & telemetry_data : all_telemetry_datas) { - auto & data = telemetry_data_time_pair.second.data; + auto & data = telemetry_data.second; ASSERT_EQ (data.unchecked_count, 0); ASSERT_EQ (data.cemented_count, 1); ASSERT_LE (data.peer_count, 9); @@ -386,10 +408,10 @@ TEST (node_telemetry, many_nodes) } // We gave some nodes different bandwidth caps, confirm they are not all the same - auto bandwidth_cap = all_telemetry_data_time_pairs.begin ()->second.data.bandwidth_cap; - all_telemetry_data_time_pairs.erase (all_telemetry_data_time_pairs.begin ()); - auto all_bandwidth_limits_same = std::all_of (all_telemetry_data_time_pairs.begin (), all_telemetry_data_time_pairs.end (), [bandwidth_cap](auto & telemetry_data_time_pair) { - return telemetry_data_time_pair.second.data.bandwidth_cap == bandwidth_cap; + auto bandwidth_cap = all_telemetry_datas.begin ()->second.bandwidth_cap; + all_telemetry_datas.erase (all_telemetry_datas.begin ()); + auto all_bandwidth_limits_same = std::all_of (all_telemetry_datas.begin (), all_telemetry_datas.end (), [bandwidth_cap](auto & telemetry_data) { + return telemetry_data.second.bandwidth_cap == bandwidth_cap; }); ASSERT_FALSE (all_bandwidth_limits_same); } @@ -416,10 +438,10 @@ TEST (node_telemetry, over_udp) wait_peer_connections (system); std::atomic done{ false }; - std::unordered_map all_telemetry_data_time_pairs; - node_client->telemetry.get_metrics_peers_async ([&done, &all_telemetry_data_time_pairs](nano::telemetry_data_responses const & responses_a) { + std::unordered_map all_telemetry_datas; + node_client->telemetry.get_metrics_peers_async ([&done, &all_telemetry_datas](nano::telemetry_data_responses const & responses_a) { ASSERT_TRUE (responses_a.all_received); - all_telemetry_data_time_pairs = responses_a.telemetry_data_time_pairs; + all_telemetry_datas = responses_a.telemetry_datas; done = true; }); @@ -429,8 +451,8 @@ TEST (node_telemetry, over_udp) ASSERT_NO_ERROR (system.poll ()); } - ASSERT_EQ (all_telemetry_data_time_pairs.size (), 1); - compare_default_test_result_data (all_telemetry_data_time_pairs.begin ()->second.data, *node_server); + ASSERT_EQ (all_telemetry_datas.size (), 1); + compare_default_test_result_data (all_telemetry_datas.begin ()->second, *node_server); // Check channels are indeed udp ASSERT_EQ (1, node_client->network.size ()); @@ -458,14 +480,14 @@ TEST (node_telemetry, single_request) // Request telemetry metrics auto channel = node_client->network.find_channel (node_server->network.endpoint ()); - nano::telemetry_data_time_pair telemetry_data_time_pair; + nano::telemetry_data telemetry_data; { std::atomic done{ false }; - node_client->telemetry.get_metrics_single_peer_async (channel, [&done, &telemetry_data_time_pair, &channel](nano::telemetry_data_response const & response_a) { + node_client->telemetry.get_metrics_single_peer_async (channel, [&done, &telemetry_data, &channel](nano::telemetry_data_response const & response_a) { ASSERT_FALSE (response_a.error); ASSERT_EQ (channel->get_endpoint (), response_a.endpoint); - telemetry_data_time_pair = response_a.telemetry_data_time_pair; + telemetry_data = response_a.telemetry_data; done = true; }); @@ -477,13 +499,13 @@ TEST (node_telemetry, single_request) } // Check the metrics are correct - compare_default_test_result_data (telemetry_data_time_pair.data, *node_server); + compare_default_test_result_data (telemetry_data, *node_server); // Call again straight away. It should use the cache { std::atomic done{ false }; - node_client->telemetry.get_metrics_single_peer_async (channel, [&done, &telemetry_data_time_pair](nano::telemetry_data_response const & response_a) { - ASSERT_EQ (telemetry_data_time_pair, response_a.telemetry_data_time_pair); + node_client->telemetry.get_metrics_single_peer_async (channel, [&done, &telemetry_data](nano::telemetry_data_response const & response_a) { + ASSERT_EQ (telemetry_data, response_a.telemetry_data); ASSERT_FALSE (response_a.error); done = true; }); @@ -499,8 +521,8 @@ TEST (node_telemetry, single_request) std::this_thread::sleep_for (nano::telemetry_cache_cutoffs::test); std::atomic done{ false }; - node_client->telemetry.get_metrics_single_peer_async (channel, [&done, &telemetry_data_time_pair](nano::telemetry_data_response const & response_a) { - ASSERT_NE (telemetry_data_time_pair, response_a.telemetry_data_time_pair); + node_client->telemetry.get_metrics_single_peer_async (channel, [&done, &telemetry_data](nano::telemetry_data_response const & response_a) { + ASSERT_NE (telemetry_data, response_a.telemetry_data); ASSERT_FALSE (response_a.error); done = true; }); @@ -565,13 +587,13 @@ TEST (node_telemetry, blocking_single_and_random) // Blocking version of get_random_metrics_async auto telemetry_data_responses = node_client->telemetry.get_metrics_peers (); ASSERT_TRUE (telemetry_data_responses.all_received); - compare_default_test_result_data (telemetry_data_responses.telemetry_data_time_pairs.begin ()->second.data, *node_server); + compare_default_test_result_data (telemetry_data_responses.telemetry_datas.begin ()->second, *node_server); // Now try single request metric auto telemetry_data_response = node_client->telemetry.get_metrics_single_peer (node_client->network.find_channel (node_server->network.endpoint ())); ASSERT_FALSE (telemetry_data_response.error); - compare_default_test_result_data (telemetry_data_response.telemetry_data_time_pair.data, *node_server); - ASSERT_EQ (telemetry_data_response.telemetry_data_time_pair.last_updated, telemetry_data_responses.telemetry_data_time_pairs.begin ()->second.last_updated); + compare_default_test_result_data (telemetry_data_response.telemetry_data, *node_server); + ASSERT_EQ (*telemetry_data_response.telemetry_data.timestamp, *telemetry_data_responses.telemetry_datas.begin ()->second.timestamp); done = true; promise.get_future ().wait (); @@ -596,10 +618,10 @@ TEST (node_telemetry, multiple_single_request_clearing) auto channel = node_client->network.find_channel (node_server->network.endpoint ()); std::atomic done{ false }; - std::chrono::steady_clock::time_point last_updated; + std::chrono::system_clock::time_point last_updated; node_client->telemetry.get_metrics_single_peer_async (channel, [&done, &last_updated](nano::telemetry_data_response const & response_a) { ASSERT_FALSE (response_a.error); - last_updated = response_a.telemetry_data_time_pair.last_updated; + last_updated = *response_a.telemetry_data.timestamp; done = true; }); @@ -615,12 +637,10 @@ TEST (node_telemetry, multiple_single_request_clearing) system.deadline_set (10s); node_client->telemetry.get_metrics_single_peer_async (channel, [&done, last_updated](nano::telemetry_data_response const & response_a) { ASSERT_FALSE (response_a.error); - ASSERT_EQ (last_updated, response_a.telemetry_data_time_pair.last_updated); + ASSERT_EQ (last_updated, *response_a.telemetry_data.timestamp); done = true; }); - ASSERT_LT (last_updated, node_client->telemetry.single_requests.begin ()->second.last_updated); - system.deadline_set (10s); while (!done) { @@ -631,8 +651,8 @@ TEST (node_telemetry, multiple_single_request_clearing) auto channel1 = node_client->network.find_channel (node_server1->network.endpoint ()); node_client->telemetry.get_metrics_single_peer_async (channel1, [&done, &last_updated](nano::telemetry_data_response const & response_a) { ASSERT_FALSE (response_a.error); - ASSERT_NE (last_updated, response_a.telemetry_data_time_pair.last_updated); - last_updated = response_a.telemetry_data_time_pair.last_updated; + ASSERT_NE (last_updated, *response_a.telemetry_data.timestamp); + last_updated = *response_a.telemetry_data.timestamp; done = true; }); @@ -646,7 +666,7 @@ TEST (node_telemetry, multiple_single_request_clearing) done = false; node_client->telemetry.get_metrics_single_peer_async (channel1, [&done, last_updated](nano::telemetry_data_response const & response_a) { ASSERT_FALSE (response_a.error); - ASSERT_EQ (last_updated, response_a.telemetry_data_time_pair.last_updated); + ASSERT_EQ (last_updated, *response_a.telemetry_data.timestamp); done = true; }); @@ -712,12 +732,12 @@ TEST (node_telemetry, batch_use_single_request_cache) wait_peer_connections (system); // Request telemetry metrics - nano::telemetry_data_time_pair telemetry_data_time_pair; + nano::telemetry_data telemetry_data; { std::atomic done{ false }; auto channel = node_client->network.find_channel (node_server->network.endpoint ()); - node_client->telemetry.get_metrics_single_peer_async (channel, [&done, &telemetry_data_time_pair](nano::telemetry_data_response const & response_a) { - telemetry_data_time_pair = response_a.telemetry_data_time_pair; + node_client->telemetry.get_metrics_single_peer_async (channel, [&done, &telemetry_data](nano::telemetry_data_response const & response_a) { + telemetry_data = response_a.telemetry_data; done = true; }); @@ -730,9 +750,9 @@ TEST (node_telemetry, batch_use_single_request_cache) { std::atomic done{ false }; - node_client->telemetry.get_metrics_peers_async ([&done, &telemetry_data_time_pair](nano::telemetry_data_responses const & responses_a) { + node_client->telemetry.get_metrics_peers_async ([&done, &telemetry_data](nano::telemetry_data_responses const & responses_a) { ASSERT_TRUE (responses_a.all_received); - ASSERT_EQ (telemetry_data_time_pair, responses_a.telemetry_data_time_pairs.begin ()->second); + ASSERT_EQ (telemetry_data, responses_a.telemetry_datas.begin ()->second); done = true; }); @@ -763,7 +783,7 @@ TEST (node_telemetry, batch_use_single_request_cache) system.deadline_set (10s); std::atomic done{ false }; node_client->telemetry.get_metrics_peers_async ([&done](nano::telemetry_data_responses const & responses_a) { - ASSERT_EQ (1, responses_a.telemetry_data_time_pairs.size ()); + ASSERT_EQ (1, responses_a.telemetry_datas.size ()); done = true; }); @@ -792,13 +812,13 @@ TEST (node_telemetry, single_request_use_batch_cache) wait_peer_connections (system); // Request batched metric first - std::unordered_map all_telemetry_data_time_pairs; + std::unordered_map all_telemetry_datas; { std::atomic done{ false }; - node_client->telemetry.get_metrics_peers_async ([&done, &all_telemetry_data_time_pairs](nano::telemetry_data_responses const & responses_a) { + node_client->telemetry.get_metrics_peers_async ([&done, &all_telemetry_datas](nano::telemetry_data_responses const & responses_a) { ASSERT_TRUE (responses_a.all_received); - ASSERT_EQ (1, responses_a.telemetry_data_time_pairs.size ()); - all_telemetry_data_time_pairs = responses_a.telemetry_data_time_pairs; + ASSERT_EQ (1, responses_a.telemetry_datas.size ()); + all_telemetry_datas = responses_a.telemetry_datas; done = true; }); @@ -811,8 +831,8 @@ TEST (node_telemetry, single_request_use_batch_cache) std::atomic done{ false }; auto channel = node_client->network.find_channel (node_server->network.endpoint ()); - node_client->telemetry.get_metrics_single_peer_async (channel, [&done, &all_telemetry_data_time_pairs](nano::telemetry_data_response const & response_a) { - ASSERT_EQ (all_telemetry_data_time_pairs.begin ()->second, response_a.telemetry_data_time_pair); + node_client->telemetry.get_metrics_single_peer_async (channel, [&done, &all_telemetry_datas](nano::telemetry_data_response const & response_a) { + ASSERT_EQ (all_telemetry_datas.begin ()->second, response_a.telemetry_data); ASSERT_FALSE (response_a.error); done = true; }); @@ -958,7 +978,7 @@ TEST (node_telemetry, disable_metrics_single) auto channel1 = node_server->network.find_channel (node_client->network.endpoint ()); node_server->telemetry.get_metrics_single_peer_async (channel1, [&done, node_server](nano::telemetry_data_response const & response_a) { ASSERT_FALSE (response_a.error); - compare_default_test_result_data (response_a.telemetry_data_time_pair.data, *node_server); + compare_default_test_result_data (response_a.telemetry_data, *node_server); done = true; }); @@ -999,7 +1019,7 @@ TEST (node_telemetry, disable_metrics_batch) done = false; node_server->telemetry.get_metrics_peers_async ([&done, node_server](nano::telemetry_data_responses const & responses_a) { ASSERT_TRUE (responses_a.all_received); - compare_default_test_result_data (responses_a.telemetry_data_time_pairs.begin ()->second.data, *node_server); + compare_default_test_result_data (responses_a.telemetry_datas.begin ()->second, *node_server); done = true; }); @@ -1036,12 +1056,13 @@ void compare_default_test_result_data (nano::telemetry_data const & telemetry_da ASSERT_EQ (telemetry_data_a.protocol_version, node_server_a.network_params.protocol.telemetry_protocol_version_min); ASSERT_EQ (telemetry_data_a.unchecked_count, 0); ASSERT_EQ (telemetry_data_a.account_count, 1); + ASSERT_LT (telemetry_data_a.uptime, 100); + ASSERT_EQ (telemetry_data_a.genesis_block, node_server_a.network_params.ledger.genesis_hash); ASSERT_EQ (telemetry_data_a.major_version, nano::get_major_node_version ()); ASSERT_EQ (*telemetry_data_a.minor_version, nano::get_minor_node_version ()); ASSERT_EQ (*telemetry_data_a.patch_version, nano::get_patch_node_version ()); ASSERT_EQ (*telemetry_data_a.pre_release_version, nano::get_pre_release_node_version ()); ASSERT_EQ (*telemetry_data_a.maker, 0); - ASSERT_LT (telemetry_data_a.uptime, 100); - ASSERT_EQ (telemetry_data_a.genesis_block, node_server_a.network_params.ledger.genesis_hash); + ASSERT_GT (*telemetry_data_a.timestamp, std::chrono::system_clock::now () - 100s); } } diff --git a/nano/core_test/wallet.cpp b/nano/core_test/wallet.cpp index 3f71506349..ac7ace30be 100644 --- a/nano/core_test/wallet.cpp +++ b/nano/core_test/wallet.cpp @@ -649,7 +649,7 @@ TEST (wallet, work) uint64_t work (0); if (!wallet->store.work_get (transaction, nano::test_genesis_key.pub, work)) { - done = !nano::work_validate (genesis.hash (), work); + done = !nano::work_validate (genesis.open->work_version (), genesis.hash (), work); } ASSERT_NO_ERROR (system.poll ()); } @@ -669,7 +669,7 @@ TEST (wallet, work_generate) account1 = system.account (transaction, 0); } nano::keypair key; - wallet->send_action (nano::test_genesis_key.pub, key.pub, 100); + auto block (wallet->send_action (nano::test_genesis_key.pub, key.pub, 100)); system.deadline_set (10s); auto transaction (node1.store.tx_begin_read ()); while (node1.ledger.account_balance (transaction, nano::test_genesis_key.pub) == amount1) @@ -683,7 +683,7 @@ TEST (wallet, work_generate) ASSERT_NO_ERROR (system.poll ()); auto block_transaction (node1.store.tx_begin_read ()); auto transaction (system.wallet (0)->wallets.tx_begin_read ()); - again = wallet->store.work_get (transaction, account1, work1) || nano::work_validate (node1.ledger.latest_root (block_transaction, account1), work1); + again = wallet->store.work_get (transaction, account1, work1) || nano::work_validate (block->work_version (), node1.ledger.latest_root (block_transaction, account1), work1); } } @@ -949,7 +949,7 @@ TEST (wallet, no_work) auto block (system.wallet (0)->send_action (nano::test_genesis_key.pub, key2.pub, std::numeric_limits::max (), false)); ASSERT_NE (nullptr, block); ASSERT_NE (0, block->block_work ()); - ASSERT_FALSE (nano::work_validate (block->root (), block->block_work ())); + ASSERT_FALSE (nano::work_validate (*block)); auto transaction (system.wallet (0)->wallets.tx_begin_read ()); uint64_t cached_work (0); system.wallet (0)->store.work_get (transaction, nano::test_genesis_key.pub, cached_work); @@ -1190,7 +1190,7 @@ TEST (wallet, work_watcher_generation_disabled) 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)); - node.wallets.watcher->add (block, nano::work_version::work_1); + 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); diff --git a/nano/core_test/work_pool.cpp b/nano/core_test/work_pool.cpp index b520872040..6a8af34c13 100644 --- a/nano/core_test/work_pool.cpp +++ b/nano/core_test/work_pool.cpp @@ -106,9 +106,9 @@ TEST (work, opencl) for (auto i (0); i < 16; ++i) { nano::random_pool::generate_block (root.bytes.data (), root.bytes.size ()); - auto result (*pool.generate (root, difficulty)); + auto result (*pool.generate (nano::work_version::work_1, root, difficulty)); uint64_t result_difficulty (0); - ASSERT_FALSE (nano::work_validate (root, result, &result_difficulty)); + ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, root, result, &result_difficulty)); ASSERT_GE (result_difficulty, difficulty); difficulty += difficulty_add; } @@ -149,15 +149,15 @@ TEST (work, difficulty) uint64_t nonce1 (0); do { - auto work1 = *pool.generate (root, difficulty1); - nano::work_validate (root, work1, &nonce1); + 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); do { - auto work2 = *pool.generate (root, difficulty2); - nano::work_validate (root, work2, &nonce2); + 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); } @@ -178,8 +178,8 @@ TEST (work, eco_pow) uint64_t nonce (0); do { - auto work = *pool.generate (root, difficulty1); - nano::work_validate (root, work, &nonce); + 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); } diff --git a/nano/lib/blocks.cpp b/nano/lib/blocks.cpp index d4508ec5d2..bcd8ec2bc3 100644 --- a/nano/lib/blocks.cpp +++ b/nano/lib/blocks.cpp @@ -76,6 +76,11 @@ size_t nano::block::size (nano::block_type type_a) return result; } +nano::work_version nano::block::work_version () const +{ + return nano::work_version::work_1; +} + 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 d355ea9030..b6d3b05b68 100644 --- a/nano/lib/blocks.hpp +++ b/nano/lib/blocks.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -58,6 +59,7 @@ class block virtual ~block () = default; virtual bool valid_predecessor (nano::block const &) const = 0; static size_t size (nano::block_type); + virtual nano::work_version work_version () 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 61b9e80da1..daa3c847bf 100644 --- a/nano/lib/work.cpp +++ b/nano/lib/work.cpp @@ -21,9 +21,9 @@ std::string nano::to_string (nano::work_version const version_a) return result; } -bool nano::work_validate (nano::work_version const version_a, nano::block const & block_a, uint64_t * difficulty_a) +bool nano::work_validate (nano::block const & block_a, uint64_t * difficulty_a) { - return nano::work_validate (version_a, block_a.root (), block_a.block_work (), difficulty_a); + return nano::work_validate (block_a.work_version (), block_a.root (), block_a.block_work (), difficulty_a); } bool nano::work_validate (nano::work_version const version_a, nano::root const & root_a, uint64_t const work_a, uint64_t * difficulty_a) @@ -40,18 +40,6 @@ bool nano::work_validate (nano::work_version const version_a, nano::root const & return invalid; } -bool nano::work_validate (nano::block const & block_a, uint64_t * difficulty_a) -{ - return nano::work_validate (block_a.root (), block_a.block_work (), difficulty_a); -} - -bool nano::work_validate (nano::root const & root_a, uint64_t const work_a, uint64_t * difficulty_a) -{ - static nano::network_constants network_constants; - debug_assert (network_constants.is_test_network ()); - return nano::work_validate (nano::work_version::work_1, root_a, work_a, difficulty_a); -} - bool nano::work_v1::validate (nano::root const & root_a, uint64_t work_a, uint64_t * difficulty_a) { static nano::network_constants network_constants; diff --git a/nano/lib/work.hpp b/nano/lib/work.hpp index 2742acdc19..9524e29856 100644 --- a/nano/lib/work.hpp +++ b/nano/lib/work.hpp @@ -21,12 +21,8 @@ enum class work_version std::string to_string (nano::work_version const version_a); class block; -bool work_validate (nano::work_version const, nano::block const &, uint64_t * = nullptr); -bool work_validate (nano::work_version const, nano::root const &, uint64_t const, uint64_t * = nullptr); -// For tests only bool work_validate (nano::block const &, uint64_t * = nullptr); -// For tests only -bool work_validate (nano::root const &, uint64_t const, uint64_t * = nullptr); +bool work_validate (nano::work_version const, nano::root const &, uint64_t const, uint64_t * = nullptr); namespace work_v1 { diff --git a/nano/nano_node/entry.cpp b/nano/nano_node/entry.cpp index eca4a1d0d8..eeb5af6d03 100644 --- a/nano/nano_node/entry.cpp +++ b/nano/nano_node/entry.cpp @@ -1104,7 +1104,7 @@ int main (int argc, char * const * argv) std::cerr << boost::str (boost::format ("Incorrect sideband block details for block %1%\n") % hash.to_string ()); } // Check if block work value is correct - if (nano::work_validate (nano::work_version::work_1, *block)) + if (nano::work_validate (*block)) { std::cerr << boost::str (boost::format ("Invalid work for block %1% value: %2%\n") % hash.to_string () % nano::to_string_hex (block->block_work ())); } diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index 57a0c257cc..be61400ed4 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -323,7 +323,6 @@ void nano::active_transactions::request_confirm (nano::unique_lock & { election_l->stop (); inactive_l.insert (root_l); - add_dropped_elections_cache (root_l); } // Attempt obtaining votes else if (election_l->skip_delay || election_l->election_start < cutoff_l) @@ -581,7 +580,7 @@ std::pair, bool> nano::active_transactions::inse auto hash (block_a->hash ()); result.first = nano::make_shared (node, block_a, skip_delay_a, confirmation_action_a); uint64_t difficulty (0); - release_assert (!nano::work_validate (nano::work_version::work_1, *block_a, &difficulty)); + release_assert (!nano::work_validate (*block_a, &difficulty)); roots.get ().emplace (nano::conflict_info{ root, difficulty, difficulty, result.first }); blocks.emplace (hash, result.first); adjust_difficulty (hash); @@ -672,14 +671,14 @@ bool nano::active_transactions::active (nano::block const & block_a) return active (block_a.qualified_root ()); } -void nano::active_transactions::update_difficulty (std::shared_ptr block_a, boost::optional opt_transaction_a) +void nano::active_transactions::update_difficulty (std::shared_ptr block_a) { nano::unique_lock lock (mutex); auto existing_election (roots.get ().find (block_a->qualified_root ())); if (existing_election != roots.get ().end ()) { uint64_t difficulty; - auto error (nano::work_validate (nano::work_version::work_1, *block_a, &difficulty)); + auto error (nano::work_validate (*block_a, &difficulty)); (void)error; debug_assert (!error); if (difficulty > existing_election->difficulty) @@ -695,41 +694,6 @@ void nano::active_transactions::update_difficulty (std::shared_ptr adjust_difficulty (block_a->hash ()); } } - else if (opt_transaction_a.is_initialized ()) - { - // Only guaranteed to immediately restart the election if the new block is received within 60s of dropping it - constexpr std::chrono::seconds recently_dropped_cutoff{ 60s }; - if (find_dropped_elections_cache (block_a->qualified_root ()) > std::chrono::steady_clock::now () - recently_dropped_cutoff) - { - lock.unlock (); - nano::block_sideband existing_sideband; - auto hash (block_a->hash ()); - auto existing_block (node.store.block_get (*opt_transaction_a, hash, &existing_sideband)); - release_assert (existing_block != nullptr); - nano::confirmation_height_info confirmation_height_info; - release_assert (!node.store.confirmation_height_get (*opt_transaction_a, node.store.block_account (*opt_transaction_a, hash), confirmation_height_info)); - bool confirmed = (confirmation_height_info.height >= existing_sideband.height); - if (!confirmed && existing_block->block_work () != block_a->block_work ()) - { - uint64_t existing_difficulty; - uint64_t new_difficulty; - if (!nano::work_validate (nano::work_version::work_1, *block_a, &new_difficulty) && !nano::work_validate (nano::work_version::work_1, *existing_block, &existing_difficulty)) - { - if (new_difficulty > existing_difficulty) - { - // Re-writing the block is necessary to avoid the same work being received later to force restarting the election - // The existing block is re-written, not the arriving block, as that one might not have gone through a full signature check - existing_block->block_work_set (block_a->block_work ()); - node.store.block_put (*opt_transaction_a, hash, *existing_block, existing_sideband); - - // Restart election for the upgraded block, previously dropped from elections - lock.lock (); - insert_impl (existing_block); - } - } - } - } - } } void nano::active_transactions::adjust_difficulty (nano::block_hash const & hash_a) @@ -1033,7 +997,7 @@ void nano::active_transactions::add_inactive_votes_cache (nano::block_hash const bool start_bootstrap (inactive_votes_bootstrap_check (representative_vector, hash_a, confirmed)); auto & inactive_by_arrival (inactive_votes_cache.get ()); inactive_by_arrival.emplace (nano::inactive_cache_information{ std::chrono::steady_clock::now (), hash_a, representative_vector, start_bootstrap, confirmed }); - if (inactive_votes_cache.size () > inactive_votes_cache_max) + if (inactive_votes_cache.size () > node.flags.inactive_votes_cache_size) { inactive_by_arrival.erase (inactive_by_arrival.begin ()); } @@ -1108,36 +1072,6 @@ bool nano::active_transactions::inactive_votes_bootstrap_check (std::vector guard (mutex); - return dropped_elections_cache.size (); -} - -void nano::active_transactions::add_dropped_elections_cache (nano::qualified_root const & root_a) -{ - debug_assert (!mutex.try_lock ()); - dropped_elections_cache.get ().emplace_back (nano::election_timepoint{ std::chrono::steady_clock::now (), root_a }); - if (dropped_elections_cache.size () > dropped_elections_cache_max) - { - dropped_elections_cache.get ().pop_front (); - } -} - -std::chrono::steady_clock::time_point nano::active_transactions::find_dropped_elections_cache (nano::qualified_root const & root_a) -{ - debug_assert (!mutex.try_lock ()); - auto existing (dropped_elections_cache.get ().find (root_a)); - if (existing != dropped_elections_cache.get ().end ()) - { - return existing->time; - } - else - { - return std::chrono::steady_clock::time_point{}; - } -} - size_t nano::active_transactions::election_winner_details_size () { nano::lock_guard guard (mutex); @@ -1170,6 +1104,5 @@ std::unique_ptr nano::collect_container_info (ac composite->add_component (std::make_unique (container_info{ "priority_wallet_cementable_frontiers_count", active_transactions.priority_wallet_cementable_frontiers_size (), sizeof (nano::cementable_account) })); composite->add_component (std::make_unique (container_info{ "priority_cementable_frontiers_count", active_transactions.priority_cementable_frontiers_size (), sizeof (nano::cementable_account) })); composite->add_component (std::make_unique (container_info{ "inactive_votes_cache_count", active_transactions.inactive_votes_cache_size (), sizeof (nano::gap_information) })); - composite->add_component (std::make_unique (container_info{ "dropped_elections_count", active_transactions.dropped_elections_cache_size (), sizeof (nano::election_timepoint) })); return composite; } diff --git a/nano/node/active_transactions.hpp b/nano/node/active_transactions.hpp index 0ac75f1d3c..82c319327b 100644 --- a/nano/node/active_transactions.hpp +++ b/nano/node/active_transactions.hpp @@ -97,7 +97,7 @@ class active_transactions final // Is the root of this block in the roots container bool active (nano::block const &); bool active (nano::qualified_root const &); - void update_difficulty (std::shared_ptr, boost::optional = boost::none); + void update_difficulty (std::shared_ptr); void adjust_difficulty (nano::block_hash const &); void update_active_difficulty (nano::unique_lock &); uint64_t active_difficulty (); @@ -139,9 +139,6 @@ class active_transactions final size_t inactive_votes_cache_size (); std::unordered_map> election_winner_details; size_t election_winner_details_size (); - void add_dropped_elections_cache (nano::qualified_root const &); - std::chrono::steady_clock::time_point find_dropped_elections_cache (nano::qualified_root const &); - size_t dropped_elections_cache_size (); nano::confirmation_solicitor solicitor; private: @@ -205,16 +202,7 @@ class active_transactions final mi::member>>>; ordered_cache inactive_votes_cache; // clang-format on - static size_t constexpr inactive_votes_cache_max{ 16 * 1024 }; bool inactive_votes_bootstrap_check (std::vector const &, nano::block_hash const &, bool &); - // clang-format off - boost::multi_index_container>, - mi::hashed_unique, - mi::member>>> - dropped_elections_cache; - // clang-format on static size_t constexpr dropped_elections_cache_max{ 32 * 1024 }; boost::thread thread; diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index dd765e9e2b..8a373243e4 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -73,7 +73,7 @@ void nano::block_processor::add (std::shared_ptr block_a, uint64_t void nano::block_processor::add (nano::unchecked_info const & info_a) { - if (!nano::work_validate (nano::work_version::work_1, info_a.block->root (), info_a.block->block_work ())) + if (!nano::work_validate (*info_a.block)) { bool should_notify{ false }; { @@ -300,7 +300,7 @@ void nano::block_processor::process_live (nano::block_hash const & hash_a, std:: // Add to work watcher to prevent dropping the election if (watch_work_a) { - node.wallets.watcher->add (block_a, nano::work_version::work_1); + node.wallets.watcher->add (block_a); } // Start collecting quorum on block @@ -393,7 +393,7 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction node.logger.try_log (boost::str (boost::format ("Old for: %1%") % hash.to_string ())); } queue_unchecked (transaction_a, hash); - node.active.update_difficulty (info_a.block, transaction_a); + node.active.update_difficulty (info_a.block); node.stats.inc (nano::stat::type::ledger, nano::stat::detail::old); break; } diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.cpp b/nano/node/bootstrap/bootstrap_bulk_pull.cpp index f8c8a16a9b..384600ad38 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.cpp @@ -214,7 +214,7 @@ void nano::bulk_pull_client::received_block (boost::system::error_code const & e { nano::bufferstream stream (connection->receive_buffer->data (), size_a); std::shared_ptr block (nano::deserialize_block (stream, type_a)); - if (block != nullptr && !nano::work_validate (nano::work_version::work_1, *block)) + if (block != nullptr && !nano::work_validate (*block)) { auto hash (block->hash ()); if (connection->node->config.logging.bulk_pull_logging ()) diff --git a/nano/node/bootstrap/bootstrap_bulk_push.cpp b/nano/node/bootstrap/bootstrap_bulk_push.cpp index f50d154b7e..fc22904631 100644 --- a/nano/node/bootstrap/bootstrap_bulk_push.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_push.cpp @@ -240,7 +240,7 @@ void nano::bulk_push_server::received_block (boost::system::error_code const & e { nano::bufferstream stream (receive_buffer->data (), size_a); auto block (nano::deserialize_block (stream, type_a)); - if (block != nullptr && !nano::work_validate (nano::work_version::work_1, *block)) + if (block != nullptr && !nano::work_validate (*block)) { connection->node->process_active (std::move (block)); throttled_receive (); diff --git a/nano/node/cli.cpp b/nano/node/cli.cpp index c7cc0f751f..a04eca7515 100644 --- a/nano/node/cli.cpp +++ b/nano/node/cli.cpp @@ -100,7 +100,8 @@ void nano::add_node_flag_options (boost::program_options::options_description & ("batch_size", boost::program_options::value(), "Increase sideband batch size, default 512") ("block_processor_batch_size", boost::program_options::value(), "Increase block processor transaction batch write size, default 0 (limited by config block_processor_batch_max_time), 256k for fast_bootstrap") ("block_processor_full_size", boost::program_options::value(), "Increase block processor allowed blocks queue size before dropping live network packets and holding bootstrap download, default 65536, 1 million for fast_bootstrap") - ("block_processor_verification_size", boost::program_options::value(), "Increase batch signature verification size in block processor, default 0 (limited by config signature_checker_threads), unlimited for fast_bootstrap"); + ("block_processor_verification_size", boost::program_options::value(), "Increase batch signature verification size in block processor, default 0 (limited by config signature_checker_threads), unlimited for fast_bootstrap") + ("inactive_votes_cache_size", boost::program_options::value(), "Increase cached votes without active elections size, default 16384"); // clang-format on } @@ -154,6 +155,11 @@ std::error_code nano::update_flags (nano::node_flags & flags_a, boost::program_o { flags_a.block_processor_verification_size = block_processor_verification_size_it->second.as (); } + auto inactive_votes_cache_size_it = vm.find ("inactive_votes_cache_size"); + if (inactive_votes_cache_size_it != vm.end ()) + { + flags_a.inactive_votes_cache_size = inactive_votes_cache_size_it->second.as (); + } return ec; } diff --git a/nano/node/common.cpp b/nano/node/common.cpp index d4bbf64f02..d57558897e 100644 --- a/nano/node/common.cpp +++ b/nano/node/common.cpp @@ -418,7 +418,7 @@ void nano::message_parser::deserialize_publish (nano::stream & stream_a, nano::m nano::publish incoming (error, stream_a, header_a, &block_uniquer); if (!error && at_end (stream_a)) { - if (!nano::work_validate (nano::work_version::work_1, *incoming.block)) + if (!nano::work_validate (*incoming.block)) { visitor.publish (incoming); } @@ -439,7 +439,7 @@ void nano::message_parser::deserialize_confirm_req (nano::stream & stream_a, nan nano::confirm_req incoming (error, stream_a, header_a, &block_uniquer); if (!error && at_end (stream_a)) { - if (incoming.block == nullptr || !nano::work_validate (nano::work_version::work_1, *incoming.block)) + if (incoming.block == nullptr || !nano::work_validate (*incoming.block)) { visitor.confirm_req (incoming); } @@ -465,7 +465,7 @@ void nano::message_parser::deserialize_confirm_ack (nano::stream & stream_a, nan if (!vote_block.which ()) { auto block (boost::get> (vote_block)); - if (nano::work_validate (nano::work_version::work_1, *block)) + if (nano::work_validate (*block)) { status = parse_status::insufficient_work; break; @@ -1117,6 +1117,7 @@ void nano::telemetry_ack::serialize (nano::stream & stream_a) const write (stream_a, *data.patch_version); write (stream_a, *data.pre_release_version); write (stream_a, *data.maker); + write (stream_a, std::chrono::duration_cast (data.timestamp->time_since_epoch ()).count ()); } } @@ -1151,6 +1152,13 @@ bool nano::telemetry_ack::deserialize (nano::stream & stream_a) read (stream_a, out); data.maker = out; } + + if (header.extensions.to_ulong () > telemetry_data::size_v1) + { + uint64_t timestamp; + read (stream_a, timestamp); + data.timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (timestamp)); + } } } catch (std::runtime_error const &) @@ -1209,6 +1217,10 @@ nano::error nano::telemetry_data::serialize_json (nano::jsonconfig & json) const { json.put ("maker", *maker); } + if (timestamp.is_initialized ()) + { + json.put ("timestamp", std::chrono::duration_cast (timestamp->time_since_epoch ()).count ()); + } return json.get_error (); } @@ -1236,13 +1248,18 @@ nano::error nano::telemetry_data::deserialize_json (nano::jsonconfig & json) patch_version = json.get_optional ("patch_version"); pre_release_version = json.get_optional ("pre_release_version"); maker = json.get_optional ("maker"); + auto timestamp_l = json.get_optional ("timestamp"); + if (timestamp_l.is_initialized ()) + { + timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (*timestamp_l)); + } return json.get_error (); } bool nano::telemetry_data::operator== (nano::telemetry_data const & data_a) const { - return (block_count == data_a.block_count && cemented_count == data_a.cemented_count && unchecked_count == data_a.unchecked_count && account_count == data_a.account_count && bandwidth_cap == data_a.bandwidth_cap && uptime == data_a.uptime && peer_count == data_a.peer_count && protocol_version == data_a.protocol_version && genesis_block == data_a.genesis_block && major_version == data_a.major_version && minor_version == data_a.minor_version && patch_version == data_a.patch_version && pre_release_version == data_a.pre_release_version && maker == data_a.maker); + return (block_count == data_a.block_count && cemented_count == data_a.cemented_count && unchecked_count == data_a.unchecked_count && account_count == data_a.account_count && bandwidth_cap == data_a.bandwidth_cap && uptime == data_a.uptime && peer_count == data_a.peer_count && protocol_version == data_a.protocol_version && genesis_block == data_a.genesis_block && major_version == data_a.major_version && minor_version == data_a.minor_version && patch_version == data_a.patch_version && pre_release_version == data_a.pre_release_version && maker == data_a.maker && timestamp == data_a.timestamp); } bool nano::telemetry_data::operator!= (nano::telemetry_data const & data_a) const diff --git a/nano/node/common.hpp b/nano/node/common.hpp index 9464ba803c..4cf7273208 100644 --- a/nano/node/common.hpp +++ b/nano/node/common.hpp @@ -349,6 +349,7 @@ class telemetry_data boost::optional patch_version; boost::optional pre_release_version; boost::optional maker; // 0 for NF node + boost::optional timestamp; nano::error serialize_json (nano::jsonconfig & json) const; nano::error deserialize_json (nano::jsonconfig & json); @@ -356,7 +357,8 @@ class telemetry_data bool operator!= (nano::telemetry_data const &) const; static auto constexpr size_v0 = sizeof (block_count) + sizeof (cemented_count) + sizeof (unchecked_count) + sizeof (account_count) + sizeof (bandwidth_cap) + sizeof (peer_count) + sizeof (protocol_version) + sizeof (uptime) + sizeof (genesis_block) + sizeof (major_version); - static auto constexpr size = size_v0 + sizeof (decltype (minor_version)::value_type) + sizeof (decltype (patch_version)::value_type) + sizeof (decltype (pre_release_version)::value_type) + sizeof (decltype (maker)::value_type); + static auto constexpr size_v1 = size_v0 + sizeof (decltype (minor_version)::value_type) + sizeof (decltype (patch_version)::value_type) + sizeof (decltype (pre_release_version)::value_type) + sizeof (decltype (maker)::value_type); + static auto constexpr size = size_v1 + sizeof (uint64_t); }; class telemetry_req final : public message { diff --git a/nano/node/election.cpp b/nano/node/election.cpp index 775a21dc73..5e7b9c335f 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -108,19 +108,22 @@ void nano::election::confirm_if_quorum () debug_assert (!tally_l.empty ()); auto winner (tally_l.begin ()); auto block_l (winner->second); + auto winner_hash_l (block_l->hash ()); status.tally = winner->first; + auto status_winner_hash_l (status.winner->hash ()); nano::uint128_t sum (0); for (auto & i : tally_l) { sum += i.first; } - if (sum >= node.config.online_weight_minimum.number () && block_l->hash () != status.winner->hash ()) + if (sum >= node.config.online_weight_minimum.number () && winner_hash_l != status_winner_hash_l) { - auto node_l (node.shared ()); - node_l->block_processor.force (block_l); + node.votes_cache.remove (status_winner_hash_l); + node.block_processor.generator.add (winner_hash_l); + node.block_processor.force (block_l); status.winner = block_l; update_dependent (); - node_l->active.adjust_difficulty (block_l->hash ()); + node.active.adjust_difficulty (winner_hash_l); } if (have_quorum (tally_l, sum)) { diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index e96ae81797..b2bf0ce243 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -2126,7 +2126,7 @@ void epoch_upgrader (std::shared_ptr node_a, nano::private_key const .work (node_a->work_generate_blocking (nano::work_version::work_1, info.head).value_or (0)) .build (); bool valid_signature (!nano::validate_message (signer, epoch->hash (), epoch->block_signature ())); - bool valid_work (!nano::work_validate (nano::work_version::work_1, *epoch.get ())); + bool valid_work (!nano::work_validate (*epoch.get ())); nano::process_result result (nano::process_result::old); if (valid_signature && valid_work) { @@ -2185,7 +2185,7 @@ void epoch_upgrader (std::shared_ptr node_a, nano::private_key const .work (node_a->work_generate_blocking (nano::work_version::work_1, key.account).value_or (0)) .build (); bool valid_signature (!nano::validate_message (signer, epoch->hash (), epoch->block_signature ())); - bool valid_work (!nano::work_validate (nano::work_version::work_1, *epoch.get ())); + bool valid_work (!nano::work_validate (*epoch.get ())); nano::process_result result (nano::process_result::old); if (valid_signature && valid_work) { @@ -3252,7 +3252,7 @@ void nano::json_handler::process () } if (!rpc_l->ec) { - if (!nano::work_validate (nano::work_version::work_1, *block)) + if (!nano::work_validate (*block)) { auto result (rpc_l->node.process_local (block, watch_work_l)); switch (result.code) @@ -3941,7 +3941,6 @@ void nano::json_handler::telemetry () nano::jsonconfig config_l; auto err = telemetry_data.serialize_json (config_l); - config_l.put ("timestamp", std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()).count ()); auto const & ptree = config_l.get_tree (); if (!err) @@ -3979,12 +3978,11 @@ void nano::json_handler::telemetry () if (!ec) { debug_assert (channel); - node.telemetry.get_metrics_single_peer_async (channel, [rpc_l](auto const & single_telemetry_metric_a) { - if (!single_telemetry_metric_a.error) + node.telemetry.get_metrics_single_peer_async (channel, [rpc_l](auto const & telemetry_response_a) { + if (!telemetry_response_a.error) { nano::jsonconfig config_l; - auto err = single_telemetry_metric_a.telemetry_data_time_pair.data.serialize_json (config_l); - config_l.put ("timestamp", std::chrono::duration_cast (single_telemetry_metric_a.telemetry_data_time_pair.system_last_updated.time_since_epoch ()).count ()); + auto err = telemetry_response_a.telemetry_data.serialize_json (config_l); auto const & ptree = config_l.get_tree (); if (!err) @@ -4015,15 +4013,14 @@ void nano::json_handler::telemetry () // setting "raw" to true returns metrics from all nodes requested. auto raw = request.get_optional ("raw"); auto output_raw = raw.value_or (false); - node.telemetry.get_metrics_peers_async ([rpc_l, output_raw](auto const & batched_telemetry_metrics_a) { + node.telemetry.get_metrics_peers_async ([rpc_l, output_raw](telemetry_data_responses const & telemetry_responses_a) { if (output_raw) { boost::property_tree::ptree metrics; - for (auto & telemetry_metrics : batched_telemetry_metrics_a.telemetry_data_time_pairs) + for (auto & telemetry_metrics : telemetry_responses_a.telemetry_datas) { nano::jsonconfig config_l; - auto err = telemetry_metrics.second.data.serialize_json (config_l); - config_l.put ("timestamp", std::chrono::duration_cast (telemetry_metrics.second.system_last_updated.time_since_epoch ()).count ()); + auto err = telemetry_metrics.second.serialize_json (config_l); config_l.put ("address", telemetry_metrics.first.address ()); config_l.put ("port", telemetry_metrics.first.port ()); if (!err) @@ -4041,15 +4038,14 @@ void nano::json_handler::telemetry () else { nano::jsonconfig config_l; - std::vector telemetry_data_time_pairs; - telemetry_data_time_pairs.reserve (batched_telemetry_metrics_a.telemetry_data_time_pairs.size ()); - std::transform (batched_telemetry_metrics_a.telemetry_data_time_pairs.begin (), batched_telemetry_metrics_a.telemetry_data_time_pairs.end (), std::back_inserter (telemetry_data_time_pairs), [](auto const & telemetry_data_time_pair_a) { - return telemetry_data_time_pair_a.second; + std::vector telemetry_datas; + telemetry_datas.reserve (telemetry_responses_a.telemetry_datas.size ()); + std::transform (telemetry_responses_a.telemetry_datas.begin (), telemetry_responses_a.telemetry_datas.end (), std::back_inserter (telemetry_datas), [](auto const & endpoint_telemetry_data) { + return endpoint_telemetry_data.second; }); - auto average_telemetry_metrics = nano::consolidate_telemetry_data_time_pairs (telemetry_data_time_pairs); - auto err = average_telemetry_metrics.data.serialize_json (config_l); - config_l.put ("timestamp", std::chrono::duration_cast (average_telemetry_metrics.system_last_updated.time_since_epoch ()).count ()); + auto average_telemetry_metrics = nano::consolidate_telemetry_data (telemetry_datas); + auto err = average_telemetry_metrics.serialize_json (config_l); auto const & ptree = config_l.get_tree (); if (!err) @@ -4100,7 +4096,7 @@ void nano::json_handler::unchecked_clear () { auto rpc_l (shared_from_this ()); node.worker.push_task ([rpc_l]() { - auto transaction (rpc_l->node.store.tx_begin_write ()); + auto transaction (rpc_l->node.store.tx_begin_write ({ tables::unchecked })); rpc_l->node.store.unchecked_clear (transaction); rpc_l->node.ledger.cache.unchecked_count = 0; rpc_l->response_l.put ("success", ""); diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 6b3b5d578a..8cac941ada 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -343,7 +343,7 @@ startup_time (std::chrono::steady_clock::now ()) if (!is_initialized) { release_assert (!flags.read_only); - auto transaction (store.tx_begin_write ()); + auto transaction (store.tx_begin_write ({ tables::accounts, tables::cached_counts, tables::confirmation_height, tables::frontiers, tables::open_blocks })); // Store was empty meaning we just created it, add the genesis block store.initialize (transaction, genesis, ledger.cache); } @@ -417,7 +417,7 @@ startup_time (std::chrono::steady_clock::now ()) // Drop unchecked blocks if initial bootstrap is completed if (!flags.disable_unchecked_drop && !use_bootstrap_weight && !flags.read_only) { - auto transaction (store.tx_begin_write ()); + auto transaction (store.tx_begin_write ({ tables::unchecked })); store.unchecked_clear (transaction); ledger.cache.unchecked_count = 0; logger.always_log ("Dropping unchecked blocks"); @@ -602,7 +602,7 @@ nano::process_return nano::node::process_local (std::shared_ptr blo // Notify block processor to release write lock block_processor.wait_write (); // Process block - auto transaction (store.tx_begin_write ()); + auto transaction (store.tx_begin_write ({ tables::accounts, tables::cached_counts, tables::change_blocks, tables::frontiers, tables::open_blocks, tables::pending, tables::receive_blocks, tables::representation, tables::send_blocks, tables::state_blocks }, { tables::confirmation_height })); return block_processor.process_one (transaction, info, work_watcher_a); } @@ -756,7 +756,7 @@ nano::uint128_t nano::node::minimum_principal_weight (nano::uint128_t const & on void nano::node::long_inactivity_cleanup () { bool perform_cleanup = false; - auto transaction (store.tx_begin_write ()); + auto transaction (store.tx_begin_write ({ tables::online_weight, tables::peers })); if (store.online_weight_count (transaction) > 0) { auto i (store.online_weight_begin (transaction)); @@ -926,7 +926,7 @@ void nano::node::unchecked_cleanup () while (!cleaning_list.empty ()) { size_t deleted_count (0); - auto transaction (store.tx_begin_write ()); + auto transaction (store.tx_begin_write ({ tables::unchecked })); while (deleted_count++ < 2 * 1024 && !cleaning_list.empty ()) { auto key (cleaning_list.front ()); @@ -982,14 +982,14 @@ bool nano::node::work_generation_enabled (std::vector nano::node::work_generate_blocking (nano::work_version const version_a, nano::block & block_a) +boost::optional nano::node::work_generate_blocking (nano::block & block_a) { - return work_generate_blocking (version_a, block_a, network_params.network.publish_threshold); + return work_generate_blocking (block_a, network_params.network.publish_threshold); } -boost::optional nano::node::work_generate_blocking (nano::work_version const version_a, nano::block & block_a, uint64_t difficulty_a) +boost::optional nano::node::work_generate_blocking (nano::block & block_a, uint64_t difficulty_a) { - auto opt_work_l (work_generate_blocking (version_a, block_a.root (), difficulty_a, block_a.account ())); + auto opt_work_l (work_generate_blocking (block_a.work_version (), block_a.root (), difficulty_a, block_a.account ())); if (opt_work_l.is_initialized ()) { block_a.block_work_set (*opt_work_l); @@ -1028,18 +1028,6 @@ boost::optional nano::node::work_generate_blocking (nano::work_version return promise.get_future ().get (); } -boost::optional nano::node::work_generate_blocking (nano::block & block_a) -{ - debug_assert (network_params.network.is_test_network ()); - return work_generate_blocking (block_a, network_params.network.publish_threshold); -} - -boost::optional nano::node::work_generate_blocking (nano::block & block_a, uint64_t difficulty_a) -{ - debug_assert (network_params.network.is_test_network ()); - return work_generate_blocking (nano::work_version::work_1, block_a, difficulty_a); -} - boost::optional nano::node::work_generate_blocking (nano::root const & root_a) { debug_assert (network_params.network.is_test_network ()); diff --git a/nano/node/node.hpp b/nano/node/node.hpp index cfaaf0174c..79c2534d27 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -128,8 +128,8 @@ class node final : public std::enable_shared_from_this bool local_work_generation_enabled () const; bool work_generation_enabled () const; bool work_generation_enabled (std::vector> const &) const; - boost::optional work_generate_blocking (nano::work_version const, nano::block &, uint64_t); - boost::optional work_generate_blocking (nano::work_version const, nano::block &); + boost::optional work_generate_blocking (nano::block &, uint64_t); + boost::optional work_generate_blocking (nano::block &); boost::optional work_generate_blocking (nano::work_version const, nano::root const &, uint64_t, boost::optional const & = boost::none); boost::optional work_generate_blocking (nano::work_version const, nano::root const &, boost::optional const & = boost::none); void work_generate (nano::work_version const, nano::root const &, std::function)>, uint64_t, boost::optional const & = boost::none, bool const = false); @@ -193,11 +193,6 @@ class node final : public std::enable_shared_from_this std::atomic stopped{ false }; static double constexpr price_max = 16.0; static double constexpr free_cutoff = 1024.0; - - // For tests only - boost::optional work_generate_blocking (nano::block &, uint64_t); - // For tests only - boost::optional work_generate_blocking (nano::block &); // For tests only boost::optional work_generate_blocking (nano::root const &, uint64_t); // For tests only diff --git a/nano/node/nodeconfig.hpp b/nano/node/nodeconfig.hpp index f08daf1269..0640b89e2b 100644 --- a/nano/node/nodeconfig.hpp +++ b/nano/node/nodeconfig.hpp @@ -136,5 +136,6 @@ class node_flags final size_t block_processor_batch_size{ 0 }; size_t block_processor_full_size{ 65536 }; size_t block_processor_verification_size{ 0 }; + size_t inactive_votes_cache_size{ 16 * 1024 }; }; } diff --git a/nano/node/online_reps.cpp b/nano/node/online_reps.cpp index dee84dcc6f..11d8e0517d 100644 --- a/nano/node/online_reps.cpp +++ b/nano/node/online_reps.cpp @@ -26,7 +26,7 @@ void nano::online_reps::observe (nano::account const & rep_a) void nano::online_reps::sample () { - auto transaction (ledger.store.tx_begin_write ()); + auto transaction (ledger.store.tx_begin_write ({ tables::online_weight })); // Discard oldest entries while (ledger.store.online_weight_count (transaction) >= network_params.node.max_weight_samples) { diff --git a/nano/node/telemetry.cpp b/nano/node/telemetry.cpp index 1554ffdd09..a9e506610a 100644 --- a/nano/node/telemetry.cpp +++ b/nano/node/telemetry.cpp @@ -20,7 +20,7 @@ worker (worker_a), batch_request (std::make_shared (network, alarm, worker)) { // Before callbacks are called with the batch request, check if any of the single request data can be appended to give - batch_request->pre_callback_callback = [this](std::unordered_map & data_a, std::mutex & mutex_a) { + batch_request->pre_callback_callback = [this](std::unordered_map & datas_a, std::mutex & mutex_a) { nano::lock_guard guard (this->mutex); for (auto & single_request : single_requests) { @@ -35,7 +35,7 @@ batch_request (std::make_shared (network, alarm, worker)) } else { - data_a.emplace (single_request.first, single_request.second.impl->cached_telemetry_data.begin ()->second); + datas_a.emplace (single_request.first, single_request.second.impl->cached_telemetry_data.begin ()->second.data); } } } @@ -50,7 +50,7 @@ batch_request (std::make_shared (network, alarm, worker)) } else { - data_a.emplace (pending.first, pending.second); + datas_a.emplace (pending.first, pending.second.data); } } finished_single_requests.clear (); @@ -195,7 +195,7 @@ void nano::telemetry::get_metrics_single_peer_async (std::shared_ptrget_network_version () >= network_params.protocol.telemetry_protocol_version_min)) { - auto add_callback_async = [& worker = this->worker, &callback_a](telemetry_data_time_pair const & telemetry_data_time_pair_a, nano::endpoint const & endpoint_a) { - telemetry_data_response telemetry_data_response_l{ telemetry_data_time_pair_a, endpoint_a, false }; + auto add_callback_async = [& worker = this->worker, &callback_a](telemetry_data const & telemetry_data_a, nano::endpoint const & endpoint_a) { + telemetry_data_response telemetry_data_response_l{ telemetry_data_a, endpoint_a, false }; worker.push_task ([telemetry_data_response_l, callback_a]() { callback_a (telemetry_data_response_l); }); @@ -217,7 +217,7 @@ void nano::telemetry::get_metrics_single_peer_async (std::shared_ptrcached_telemetry_data.find (channel_a->get_endpoint ()); if (it != batch_request->cached_telemetry_data.cend ()) { - add_callback_async (it->second, it->first); + add_callback_async (it->second.data, it->first); return; } } @@ -225,7 +225,7 @@ void nano::telemetry::get_metrics_single_peer_async (std::shared_ptrget_endpoint ()); if (it != finished_single_requests.cend ()) { - add_callback_async (it->second, it->first); + add_callback_async (it->second.data, it->first); return; } @@ -238,13 +238,13 @@ void nano::telemetry::get_metrics_single_peer_async (std::shared_ptrsecond, it->first, error }); } else { - callback_a ({ nano::telemetry_data_time_pair{}, channel_a->get_endpoint (), error }); + callback_a ({ nano::telemetry_data{}, channel_a->get_endpoint (), error }); } }); } @@ -357,7 +357,7 @@ void nano::telemetry_impl::add (nano::telemetry_data const & telemetry_data_a, n if (!is_empty_a) { - current_telemetry_data_responses[endpoint_a] = { telemetry_data_a, std::chrono::steady_clock::now (), std::chrono::system_clock::now () }; + current_telemetry_data_responses[endpoint_a] = { telemetry_data_a, std::chrono::steady_clock::now () }; } channel_processed (lk, endpoint_a); } @@ -366,12 +366,16 @@ void nano::telemetry_impl::invoke_callbacks () { decltype (callbacks) callbacks_l; bool all_received; - decltype (cached_telemetry_data) cached_telemetry_data_l; + std::unordered_map cached_responses_l; { // Copy callbacks so that they can be called outside of holding the lock nano::lock_guard guard (mutex); callbacks_l = callbacks; - cached_telemetry_data_l = cached_telemetry_data; + cached_responses_l.reserve (cached_telemetry_data.size ()); + std::transform (cached_telemetry_data.begin (), cached_telemetry_data.end (), std::inserter (cached_responses_l, cached_responses_l.end ()), [](auto const & endpoint_telemetry_data) { + return std::pair{ endpoint_telemetry_data.first, endpoint_telemetry_data.second.data }; + }); + current_telemetry_data_responses.clear (); callbacks.clear (); all_received = failed.empty (); @@ -379,13 +383,13 @@ void nano::telemetry_impl::invoke_callbacks () if (pre_callback_callback) { - pre_callback_callback (cached_telemetry_data_l, mutex); + pre_callback_callback (cached_responses_l, mutex); } // Need to account for nodes which disable telemetry data in responses - bool all_received_l = !cached_telemetry_data_l.empty () && all_received; + bool all_received_l = !cached_responses_l.empty () && all_received; for (auto & callback : callbacks_l) { - callback ({ cached_telemetry_data_l, all_received_l }); + callback ({ cached_responses_l, all_received_l }); } } @@ -511,24 +515,14 @@ nano::telemetry_data nano::consolidate_telemetry_data (std::vector telemetry_data_time_pairs; telemetry_data_time_pairs.reserve (telemetry_datas.size ()); - std::transform (telemetry_datas.begin (), telemetry_datas.end (), std::back_inserter (telemetry_data_time_pairs), [](nano::telemetry_data const & telemetry_data_a) { - // Don't care about the timestamps here - return nano::telemetry_data_time_pair{ telemetry_data_a, {}, {} }; - }); - - return consolidate_telemetry_data_time_pairs (telemetry_data_time_pairs).data; -} - -nano::telemetry_data_time_pair nano::consolidate_telemetry_data_time_pairs (std::vector const & telemetry_data_time_pairs_a) -{ - if (telemetry_data_time_pairs_a.empty ()) + if (telemetry_datas.empty ()) { return {}; } - else if (telemetry_data_time_pairs_a.size () == 1) + else if (telemetry_datas.size () == 1) { // Only 1 element in the collection, so just return it. - return telemetry_data_time_pairs_a.front (); + return telemetry_datas.front (); } std::unordered_map protocol_versions; @@ -542,13 +536,12 @@ nano::telemetry_data_time_pair nano::consolidate_telemetry_data_time_pairs (std: std::multiset cemented_counts; std::multiset peer_counts; std::multiset unchecked_counts; - std::multiset uptime_counts; - std::multiset bandwidth_counts; - std::multiset timestamp_counts; + std::multiset uptimes; + std::multiset bandwidths; + std::multiset timestamps; - for (auto const & telemetry_data_time_pair : telemetry_data_time_pairs_a) + for (auto const & telemetry_data : telemetry_datas) { - auto & telemetry_data = telemetry_data_time_pair.data; account_counts.insert (telemetry_data.account_count); block_counts.insert (telemetry_data.block_count); cemented_counts.insert (telemetry_data.cemented_count); @@ -572,25 +565,28 @@ nano::telemetry_data_time_pair nano::consolidate_telemetry_data_time_pairs (std: } } + if (telemetry_data.timestamp.is_initialized ()) + { + timestamps.insert (std::chrono::duration_cast (telemetry_data.timestamp->time_since_epoch ()).count ()); + } + ++vendor_versions[ss.str ()]; ++protocol_versions[telemetry_data.protocol_version]; peer_counts.insert (telemetry_data.peer_count); unchecked_counts.insert (telemetry_data.unchecked_count); - uptime_counts.insert (telemetry_data.uptime); + uptimes.insert (telemetry_data.uptime); // 0 has a special meaning (unlimited), don't include it in the average as it will be heavily skewed if (telemetry_data.bandwidth_cap != 0) { - bandwidth_counts.insert (telemetry_data.bandwidth_cap); + bandwidths.insert (telemetry_data.bandwidth_cap); } ++bandwidth_caps[telemetry_data.bandwidth_cap]; ++genesis_blocks[telemetry_data.genesis_block]; - - timestamp_counts.insert (std::chrono::time_point_cast (telemetry_data_time_pair.system_last_updated).time_since_epoch ().count ()); } // Remove 10% of the results from the lower and upper bounds to catch any outliers. Need at least 10 responses before any are removed. - auto num_either_side_to_remove = telemetry_data_time_pairs_a.size () / 10; + auto num_either_side_to_remove = telemetry_datas.size () / 10; auto strip_outliers_and_sum = [num_either_side_to_remove](auto & counts) { counts.erase (counts.begin (), std::next (counts.begin (), num_either_side_to_remove)); @@ -605,11 +601,11 @@ nano::telemetry_data_time_pair nano::consolidate_telemetry_data_time_pairs (std: auto cemented_sum = strip_outliers_and_sum (cemented_counts); auto peer_sum = strip_outliers_and_sum (peer_counts); auto unchecked_sum = strip_outliers_and_sum (unchecked_counts); - auto uptime_sum = strip_outliers_and_sum (uptime_counts); - auto bandwidth_sum = strip_outliers_and_sum (bandwidth_counts); + auto uptime_sum = strip_outliers_and_sum (uptimes); + auto bandwidth_sum = strip_outliers_and_sum (bandwidths); nano::telemetry_data consolidated_data; - auto size = telemetry_data_time_pairs_a.size () - num_either_side_to_remove * 2; + auto size = telemetry_datas.size () - num_either_side_to_remove * 2; consolidated_data.account_count = boost::numeric_cast (account_sum / size); consolidated_data.block_count = boost::numeric_cast (block_sum / size); consolidated_data.cemented_count = boost::numeric_cast (cemented_sum / size); @@ -617,6 +613,12 @@ nano::telemetry_data_time_pair nano::consolidate_telemetry_data_time_pairs (std: consolidated_data.uptime = boost::numeric_cast (uptime_sum / size); consolidated_data.unchecked_count = boost::numeric_cast (unchecked_sum / size); + if (!timestamps.empty ()) + { + auto timestamp_sum = strip_outliers_and_sum (timestamps); + consolidated_data.timestamp = std::chrono::system_clock::time_point (std::chrono::milliseconds (boost::numeric_cast (timestamp_sum / timestamps.size ()))); + } + auto set_mode_or_average = [](auto const & collection, auto & var, auto const & sum, size_t size) { auto max = std::max_element (collection.begin (), collection.end (), [](auto const & lhs, auto const & rhs) { return lhs.second < rhs.second; @@ -668,11 +670,7 @@ nano::telemetry_data_time_pair nano::consolidate_telemetry_data_time_pairs (std: consolidated_data.maker = boost::lexical_cast (version_fragments[4]); } - // Consolidate timestamps - auto timestamp_sum = strip_outliers_and_sum (timestamp_counts); - auto consolidated_timestamp = boost::numeric_cast (timestamp_sum / size); - - return telemetry_data_time_pair{ consolidated_data, std::chrono::steady_clock::time_point{}, std::chrono::system_clock::time_point (std::chrono::milliseconds (consolidated_timestamp)) }; + return consolidated_data; } nano::telemetry_data nano::local_telemetry_data (nano::ledger_cache const & ledger_cache_a, nano::network & network_a, uint64_t bandwidth_limit_a, nano::network_params const & network_params_a, std::chrono::steady_clock::time_point statup_time_a) @@ -692,5 +690,6 @@ nano::telemetry_data nano::local_telemetry_data (nano::ledger_cache const & ledg telemetry_data.patch_version = nano::get_patch_node_version (); telemetry_data.pre_release_version = nano::get_pre_release_node_version (); telemetry_data.maker = 0; // 0 Indicates it originated from the NF + telemetry_data.timestamp = std::chrono::system_clock::now (); return telemetry_data; } diff --git a/nano/node/telemetry.hpp b/nano/node/telemetry.hpp index 093c996bcc..4406e7cd24 100644 --- a/nano/node/telemetry.hpp +++ b/nano/node/telemetry.hpp @@ -23,7 +23,6 @@ class telemetry_data_time_pair public: nano::telemetry_data data; std::chrono::steady_clock::time_point last_updated; - std::chrono::system_clock::time_point system_last_updated; bool operator== (telemetry_data_time_pair const &) const; bool operator!= (telemetry_data_time_pair const &) const; }; @@ -34,7 +33,7 @@ class telemetry_data_time_pair class telemetry_data_response { public: - nano::telemetry_data_time_pair telemetry_data_time_pair; + nano::telemetry_data telemetry_data; nano::endpoint endpoint; bool error{ true }; }; @@ -45,7 +44,7 @@ class telemetry_data_response class telemetry_data_responses { public: - std::unordered_map telemetry_data_time_pairs; + std::unordered_map telemetry_datas; bool all_received{ false }; }; @@ -88,7 +87,7 @@ class telemetry_impl : public std::enable_shared_from_this nano::alarm & alarm; nano::worker & worker; - std::function & data_a, std::mutex &)> pre_callback_callback; + std::function & data_a, std::mutex &)> pre_callback_callback; void invoke_callbacks (); void channel_processed (nano::unique_lock & lk_a, nano::endpoint const & endpoint_a); diff --git a/nano/node/transport/tcp.hpp b/nano/node/transport/tcp.hpp index e4a2eee1b5..29525bb72b 100644 --- a/nano/node/transport/tcp.hpp +++ b/nano/node/transport/tcp.hpp @@ -78,7 +78,7 @@ namespace transport class tcp_channels final { friend class nano::transport::channel_tcp; - friend class node_telemetry_simultaneous_single_and_random_requests_Test; + friend class node_telemetry_simultaneous_single_and_all_requests_Test; public: tcp_channels (nano::node &); diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index 18cfd8cdc7..08e3a9ddd8 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1134,10 +1134,10 @@ bool nano::wallet::action_complete (std::shared_ptr const & block_a bool error{ false }; if (block_a != nullptr) { - if (nano::work_validate (nano::work_version::work_1, *block_a)) + if (nano::work_validate (*block_a)) { wallets.node.logger.try_log (boost::str (boost::format ("Cached or provided work for block %1% account %2% is invalid, regenerating") % block_a->hash ().to_string () % account_a.to_account ())); - error = !wallets.node.work_generate_blocking (nano::work_version::work_1, *block_a, wallets.node.active.limited_active_difficulty ()).is_initialized (); + error = !wallets.node.work_generate_blocking (*block_a, wallets.node.active.limited_active_difficulty ()).is_initialized (); } if (!error) { @@ -1401,7 +1401,7 @@ void nano::work_watcher::stop () stopped = true; } -void nano::work_watcher::add (std::shared_ptr block_a, nano::work_version const work_version_a) +void nano::work_watcher::add (std::shared_ptr block_a) { auto block_l (std::dynamic_pointer_cast (block_a)); if (!stopped && block_l != nullptr) @@ -1410,7 +1410,7 @@ void nano::work_watcher::add (std::shared_ptr block_a, nano::work_v nano::unique_lock lock (mutex); watched[root_l] = block_l; lock.unlock (); - watching (work_version_a, root_l, block_l); + watching (root_l, block_l); } } @@ -1420,10 +1420,10 @@ void nano::work_watcher::update (nano::qualified_root const & root_a, std::share watched[root_a] = block_a; } -void nano::work_watcher::watching (nano::work_version const version_a, nano::qualified_root const & root_a, std::shared_ptr block_a) +void nano::work_watcher::watching (nano::qualified_root const & root_a, std::shared_ptr block_a) { std::weak_ptr watcher_w (shared_from_this ()); - node.alarm.add (std::chrono::steady_clock::now () + node.config.work_watcher_period, [block_a, version_a, root_a, watcher_w]() { + node.alarm.add (std::chrono::steady_clock::now () + node.config.work_watcher_period, [block_a, root_a, watcher_w]() { auto watcher_l = watcher_w.lock (); if (watcher_l && !watcher_l->stopped && block_a != nullptr) { @@ -1432,8 +1432,7 @@ void nano::work_watcher::watching (nano::work_version const version_a, nano::qua { lock.unlock (); uint64_t difficulty (0); - auto root_l (block_a->root ()); - nano::work_validate (version_a, root_l, block_a->block_work (), &difficulty); + 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 @@ -1442,7 +1441,7 @@ void nano::work_watcher::watching (nano::work_version const version_a, nano::qua if (active_difficulty > difficulty && watcher_l->node.work_generation_enabled ()) { watcher_l->node.work_generate ( - version_a, root_l, [watcher_l, block_a, version_a, root_a](boost::optional work_a) { + block_a->work_version (), block_a->root (), [watcher_l, block_a, root_a](boost::optional work_a) { if (block_a != nullptr && watcher_l != nullptr && !watcher_l->stopped) { bool updated_l{ false }; @@ -1457,12 +1456,12 @@ void nano::work_watcher::watching (nano::work_version const version_a, nano::qua watcher_l->node.active.update_difficulty (block); watcher_l->update (root_a, block); updated_l = true; - watcher_l->watching (version_a, root_a, block); + watcher_l->watching (root_a, block); } } if (!updated_l) { - watcher_l->watching (version_a, root_a, block_a); + watcher_l->watching (root_a, block_a); } } }, @@ -1470,7 +1469,7 @@ void nano::work_watcher::watching (nano::work_version const version_a, nano::qua } else { - watcher_l->watching (version_a, root_a, block_a); + watcher_l->watching (root_a, block_a); } } } diff --git a/nano/node/wallet.hpp b/nano/node/wallet.hpp index c447c86056..dd8de020ea 100644 --- a/nano/node/wallet.hpp +++ b/nano/node/wallet.hpp @@ -168,9 +168,9 @@ class work_watcher final : public std::enable_shared_from_this, nano::work_version const); + void add (std::shared_ptr); void update (nano::qualified_root const &, std::shared_ptr); - void watching (work_version const, nano::qualified_root const &, std::shared_ptr); + void watching (nano::qualified_root const &, std::shared_ptr); void remove (std::shared_ptr); bool is_watched (nano::qualified_root const &); size_t size (); diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index d179eafa2d..4813d71821 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -2229,7 +2229,7 @@ void nano_qt::block_creation::create_send () (void)error; debug_assert (!error); nano::state_block send (account_l, info.head, info.representative, balance - amount_l.number (), destination_l, key, account_l, 0); - if (wallet.node.work_generate_blocking (nano::work_version::work_1, send).is_initialized ()) + if (wallet.node.work_generate_blocking (send).is_initialized ()) { std::string block_l; send.serialize_json (block_l); @@ -2308,7 +2308,7 @@ void nano_qt::block_creation::create_receive () if (!error) { nano::state_block receive (pending_key.account, info.head, info.representative, info.balance.number () + pending.amount.number (), source_l, key, pending_key.account, 0); - if (wallet.node.work_generate_blocking (nano::work_version::work_1, receive).is_initialized ()) + if (wallet.node.work_generate_blocking (receive).is_initialized ()) { std::string block_l; receive.serialize_json (block_l); @@ -2387,7 +2387,7 @@ void nano_qt::block_creation::create_change () if (!error) { nano::state_block change (account_l, info.head, representative_l, info.balance, 0, key, account_l, 0); - if (wallet.node.work_generate_blocking (nano::work_version::work_1, change).is_initialized ()) + if (wallet.node.work_generate_blocking (change).is_initialized ()) { std::string block_l; change.serialize_json (block_l); @@ -2464,7 +2464,7 @@ void nano_qt::block_creation::create_open () if (!error) { nano::state_block open (pending_key.account, 0, representative_l, pending.amount, source_l, key, pending_key.account, 0); - if (wallet.node.work_generate_blocking (nano::work_version::work_1, open).is_initialized ()) + if (wallet.node.work_generate_blocking (open).is_initialized ()) { std::string block_l; open.serialize_json (block_l); diff --git a/nano/qt_test/qt.cpp b/nano/qt_test/qt.cpp index f37c3ed6e6..8e3c83b8e9 100644 --- a/nano/qt_test/qt.cpp +++ b/nano/qt_test/qt.cpp @@ -727,7 +727,7 @@ TEST (wallet, seed_work_generation) ASSERT_NO_ERROR (ec); } auto transaction (system.nodes[0]->store.tx_begin_read ()); - ASSERT_FALSE (nano::work_validate (system.nodes[0]->ledger.latest_root (transaction, pub), work)); + ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, system.nodes[0]->ledger.latest_root (transaction, pub), work)); } TEST (wallet, backup_seed) diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 52dee8be2e..f8e01b15ba 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -2222,13 +2222,13 @@ TEST (rpc, payment_begin_end) root1 = node1->ledger.latest_root (transaction, account); } uint64_t work (0); - while (!nano::work_validate (root1, work)) + while (!nano::work_validate (nano::work_version::work_1, root1, work)) { ++work; ASSERT_LT (work, 50); } system.deadline_set (10s); - while (nano::work_validate (root1, work)) + while (nano::work_validate (nano::work_version::work_1, root1, work)) { auto ec = system.poll (); auto transaction (wallet->wallets.tx_begin_read ()); @@ -2832,7 +2832,7 @@ TEST (rpc, work_generate) auto work_text (response.json.get ("work")); uint64_t work, result_difficulty; ASSERT_FALSE (nano::from_string_hex (work_text, work)); - ASSERT_FALSE (nano::work_validate (hash, work, &result_difficulty)); + ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, work, &result_difficulty)); auto response_difficulty_text (response.json.get ("difficulty")); uint64_t response_difficulty; ASSERT_FALSE (nano::from_string_hex (response_difficulty_text, response_difficulty)); @@ -2877,7 +2877,7 @@ TEST (rpc, work_generate_difficulty) uint64_t work; ASSERT_FALSE (nano::from_string_hex (work_text, work)); uint64_t result_difficulty; - ASSERT_FALSE (nano::work_validate (hash, work, &result_difficulty)); + ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, work, &result_difficulty)); auto response_difficulty_text (response.json.get ("difficulty")); uint64_t response_difficulty; ASSERT_FALSE (nano::from_string_hex (response_difficulty_text, response_difficulty)); @@ -2901,7 +2901,7 @@ TEST (rpc, work_generate_difficulty) uint64_t work; ASSERT_FALSE (nano::from_string_hex (work_text, work)); uint64_t result_difficulty; - ASSERT_FALSE (nano::work_validate (hash, work, &result_difficulty)); + ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, work, &result_difficulty)); ASSERT_GE (result_difficulty, difficulty); } { @@ -2954,7 +2954,7 @@ TEST (rpc, work_generate_multiplier) uint64_t work; ASSERT_FALSE (nano::from_string_hex (work_text, work)); uint64_t result_difficulty; - ASSERT_FALSE (nano::work_validate (hash, work, &result_difficulty)); + ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, work, &result_difficulty)); auto response_difficulty_text (response.json.get ("difficulty")); uint64_t response_difficulty; ASSERT_FALSE (nano::from_string_hex (response_difficulty_text, response_difficulty)); @@ -3050,7 +3050,7 @@ TEST (rpc, work_peer_bad) work = *work_a; }); system.deadline_set (5s); - while (nano::work_validate (hash1, work)) + while (nano::work_validate (nano::work_version::work_1, hash1, work)) { ASSERT_NO_ERROR (system.poll ()); } @@ -3080,7 +3080,7 @@ TEST (rpc, work_peer_one) work = *work_a; }); system.deadline_set (5s); - while (nano::work_validate (key1.pub, work)) + while (nano::work_validate (nano::work_version::work_1, key1.pub, work)) { ASSERT_NO_ERROR (system.poll ()); } @@ -3125,7 +3125,7 @@ TEST (rpc, work_peer_many) node1.work_generate (nano::work_version::work_1, key1.pub, [& work = works[i]](boost::optional work_a) { work = *work_a; }); - while (nano::work_validate (key1.pub, works[i])) + while (nano::work_validate (nano::work_version::work_1, key1.pub, works[i])) { system1.poll (); system2.poll (); @@ -3842,7 +3842,7 @@ TEST (rpc, work_validate) ASSERT_NEAR (multiplier, nano::difficulty::to_multiplier (difficulty, params.network.publish_threshold), 1e-6); } uint64_t result_difficulty; - ASSERT_FALSE (nano::work_validate (hash, work1, &result_difficulty)); + ASSERT_FALSE (nano::work_validate (nano::work_version::work_1, hash, work1, &result_difficulty)); 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)); @@ -7874,7 +7874,7 @@ void compare_default_test_result_data (test_response & response, nano::node cons ASSERT_EQ (nano::get_patch_node_version (), response.json.get ("patch_version")); ASSERT_EQ (nano::get_pre_release_node_version (), response.json.get ("pre_release_version")); ASSERT_EQ (0, response.json.get ("maker")); - ASSERT_GE (std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()).count (), response.json.get ("timestamp")); + ASSERT_GE (std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()).count (), response.json.get ("timestamp")); } } @@ -8069,7 +8069,7 @@ TEST (rpc, node_telemetry_all) ASSERT_EQ (nano::get_patch_node_version (), metrics.patch_version); ASSERT_EQ (nano::get_pre_release_node_version (), metrics.pre_release_version); ASSERT_EQ (0, metrics.maker); - ASSERT_GE (std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()).count (), metrics.timestamp); + ASSERT_GE (std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()).count (), metrics.timestamp); ASSERT_EQ (node->network.endpoint ().address ().to_string (), metrics.address); ASSERT_EQ (node->network.endpoint ().port (), metrics.port); } diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index 75e78dfcaf..18c083c9c1 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -754,7 +754,7 @@ nano::uint128_t nano::ledger::account_pending (nano::transaction const & transac nano::process_return nano::ledger::process (nano::write_transaction const & transaction_a, nano::block const & block_a, nano::signature_verification verification) { - debug_assert (!nano::work_validate (nano::work_version::work_1, block_a)); + debug_assert (!nano::work_validate (block_a)); ledger_processor processor (*this, transaction_a, verification); block_a.visit (processor); if (processor.result.code == nano::process_result::progress) diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 523082d6ae..1f0202b9bf 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -846,7 +846,7 @@ class data std::atomic awaiting_cache{ false }; std::atomic keep_requesting_metrics{ true }; std::shared_ptr node; - std::chrono::steady_clock::time_point orig_time; + std::chrono::system_clock::time_point orig_time; std::atomic_flag orig_time_set = ATOMIC_FLAG_INIT; }; class shared_data @@ -859,7 +859,7 @@ class shared_data }; template -void callback_process (shared_data & shared_data_a, data & data, T & all_node_data_a, std::chrono::steady_clock::time_point last_updated) +void callback_process (shared_data & shared_data_a, data & data, T & all_node_data_a, std::chrono::system_clock::time_point last_updated) { if (!data.orig_time_set.test_and_set ()) { @@ -921,7 +921,7 @@ TEST (node_telemetry, ongoing_requests) } } -TEST (node_telemetry, simultaneous_random_requests) +TEST (node_telemetry, simultaneous_all_requests) { const auto num_nodes = 4; nano::system system (num_nodes); @@ -954,7 +954,7 @@ TEST (node_telemetry, simultaneous_random_requests) { ++shared_data.count; data.node->telemetry.get_metrics_peers_async ([&shared_data, &data, &all_data](nano::telemetry_data_responses const & responses_a) { - callback_process (shared_data, data, all_data, responses_a.telemetry_data_time_pairs.begin ()->second.last_updated); + callback_process (shared_data, data, all_data, *responses_a.telemetry_datas.begin ()->second.timestamp); }); } std::this_thread::sleep_for (1ms); @@ -982,7 +982,7 @@ namespace nano { namespace transport { - TEST (node_telemetry, simultaneous_single_and_random_requests) + TEST (node_telemetry, simultaneous_single_and_all_requests) { const auto num_nodes = 4; nano::system system (num_nodes); @@ -993,21 +993,21 @@ namespace transport const auto num_threads = 4; std::array node_data_single{}; - std::array node_data_random{}; + std::array node_data_all{}; for (auto i = 0; i < num_nodes; ++i) { node_data_single[i].node = system.nodes[i]; - node_data_random[i].node = system.nodes[i]; + node_data_all[i].node = system.nodes[i]; } shared_data shared_data_single; - shared_data shared_data_random; + shared_data shared_data_all; // Create a few threads where each node sends out telemetry request messages to all other nodes continuously, until the cache it reached and subsequently expired. // The test waits until all telemetry_ack messages have been received. for (int i = 0; i < num_threads; ++i) { - threads.emplace_back ([&node_data_single, &node_data_random, &shared_data_single, &shared_data_random]() { + threads.emplace_back ([&node_data_single, &node_data_all, &shared_data_single, &shared_data_all]() { auto func = [](auto & all_node_data_a, shared_data & shared_data_a, bool single_a) { while (std::any_of (all_node_data_a.cbegin (), all_node_data_a.cend (), [](auto const & data) { return data.keep_requesting_metrics.load (); })) { @@ -1023,13 +1023,13 @@ namespace transport // Pick first peer to be consistent auto peer = data.node->network.tcp_channels.channels[0].channel; data.node->telemetry.get_metrics_single_peer_async (peer, [&shared_data_a, &data, &all_node_data_a](nano::telemetry_data_response const & telemetry_data_response_a) { - callback_process (shared_data_a, data, all_node_data_a, telemetry_data_response_a.telemetry_data_time_pair.last_updated); + callback_process (shared_data_a, data, all_node_data_a, *telemetry_data_response_a.telemetry_data.timestamp); }); } else { data.node->telemetry.get_metrics_peers_async ([&shared_data_a, &data, &all_node_data_a](nano::telemetry_data_responses const & telemetry_data_responses_a) { - callback_process (shared_data_a, data, all_node_data_a, telemetry_data_responses_a.telemetry_data_time_pairs.begin ()->second.last_updated); + callback_process (shared_data_a, data, all_node_data_a, *telemetry_data_responses_a.telemetry_datas.begin ()->second.timestamp); }); } } @@ -1042,12 +1042,12 @@ namespace transport }; func (node_data_single, shared_data_single, true); - func (node_data_random, shared_data_random, false); + func (node_data_all, shared_data_all, false); }); } system.deadline_set (30s); - while (!shared_data_random.done || !shared_data_single.done) + while (!shared_data_all.done || !shared_data_single.done) { ASSERT_NO_ERROR (system.poll ()); }