From 7914c7c55de6930bc820b7e7b1baa61958fcc529 Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Sat, 5 Oct 2024 22:05:17 +0200 Subject: [PATCH 01/48] Removed waiting on vote_generator_threshold --- nano/core_test/toml.cpp | 3 --- nano/node/nodeconfig.cpp | 7 ------- nano/node/nodeconfig.hpp | 1 - nano/node/vote_generator.cpp | 7 ++----- 4 files changed, 2 insertions(+), 16 deletions(-) diff --git a/nano/core_test/toml.cpp b/nano/core_test/toml.cpp index 617f655af..45107a370 100644 --- a/nano/core_test/toml.cpp +++ b/nano/core_test/toml.cpp @@ -191,7 +191,6 @@ TEST (toml, daemon_config_deserialize_defaults) ASSERT_EQ (conf.node.unchecked_cutoff_time, defaults.node.unchecked_cutoff_time); ASSERT_EQ (conf.node.use_memory_pools, defaults.node.use_memory_pools); ASSERT_EQ (conf.node.vote_generator_delay, defaults.node.vote_generator_delay); - ASSERT_EQ (conf.node.vote_generator_threshold, defaults.node.vote_generator_threshold); ASSERT_EQ (conf.node.vote_minimum, defaults.node.vote_minimum); ASSERT_EQ (conf.node.work_peers, defaults.node.work_peers); ASSERT_EQ (conf.node.work_threads, defaults.node.work_threads); @@ -456,7 +455,6 @@ TEST (toml, daemon_config_deserialize_no_defaults) unchecked_cutoff_time = 999 use_memory_pools = false vote_generator_delay = 999 - vote_generator_threshold = 9 vote_minimum = "999" work_peers = ["dev.org:999"] work_threads = 999 @@ -700,7 +698,6 @@ TEST (toml, daemon_config_deserialize_no_defaults) ASSERT_NE (conf.node.unchecked_cutoff_time, defaults.node.unchecked_cutoff_time); ASSERT_NE (conf.node.use_memory_pools, defaults.node.use_memory_pools); ASSERT_NE (conf.node.vote_generator_delay, defaults.node.vote_generator_delay); - ASSERT_NE (conf.node.vote_generator_threshold, defaults.node.vote_generator_threshold); ASSERT_NE (conf.node.vote_minimum, defaults.node.vote_minimum); ASSERT_NE (conf.node.work_peers, defaults.node.work_peers); ASSERT_NE (conf.node.work_threads, defaults.node.work_threads); diff --git a/nano/node/nodeconfig.cpp b/nano/node/nodeconfig.cpp index ee2d8b3c8..5ceb3a6fa 100644 --- a/nano/node/nodeconfig.cpp +++ b/nano/node/nodeconfig.cpp @@ -120,7 +120,6 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const toml.put ("allow_local_peers", allow_local_peers, "Enable or disable local host peering.\ntype:bool"); toml.put ("vote_minimum", vote_minimum.to_string_dec (), "Local representatives do not vote if the delegated weight is under this threshold. Saves on system resources.\ntype:string,amount,raw"); toml.put ("vote_generator_delay", vote_generator_delay.count (), "Delay before votes are sent to allow for efficient bundling of hashes in votes.\ntype:milliseconds"); - toml.put ("vote_generator_threshold", vote_generator_threshold, "Number of bundled hashes required for an additional generator delay.\ntype:uint64,[1..11]"); toml.put ("unchecked_cutoff_time", unchecked_cutoff_time.count (), "Number of seconds before deleting an unchecked entry.\nWarning: lower values (e.g., 3600 seconds, or 1 hour) may result in unsuccessful bootstraps, especially a bootstrap from scratch.\ntype:seconds"); toml.put ("tcp_io_timeout", tcp_io_timeout.count (), "Timeout for TCP connect-, read- and write operations.\nWarning: a low value (e.g., below 5 seconds) may result in TCP connections failing.\ntype:seconds"); toml.put ("pow_sleep_interval", pow_sleep_interval.count (), "Time to sleep between batch work generation attempts. Reduces max CPU usage at the expense of a longer generation time.\ntype:nanoseconds"); @@ -484,8 +483,6 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml) toml.get ("vote_generator_delay", delay_l); vote_generator_delay = std::chrono::milliseconds (delay_l); - toml.get ("vote_generator_threshold", vote_generator_threshold); - auto block_processor_batch_max_time_l = block_processor_batch_max_time.count (); toml.get ("block_processor_batch_max_time", block_processor_batch_max_time_l); block_processor_batch_max_time = std::chrono::milliseconds (block_processor_batch_max_time_l); @@ -600,10 +597,6 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml) { toml.get_error ().set ("bandwidth_limit unbounded = 0, default = 10485760, max = 18446744073709551615"); } - if (vote_generator_threshold < 1 || vote_generator_threshold > 11) - { - toml.get_error ().set ("vote_generator_threshold must be a number between 1 and 11"); - } if (max_work_generate_multiplier < 1) { toml.get_error ().set ("max_work_generate_multiplier must be greater than or equal to 1"); diff --git a/nano/node/nodeconfig.hpp b/nano/node/nodeconfig.hpp index 269203049..c25700d85 100644 --- a/nano/node/nodeconfig.hpp +++ b/nano/node/nodeconfig.hpp @@ -73,7 +73,6 @@ public: nano::amount vote_minimum{ nano::Knano_ratio }; // 1000 nano nano::amount rep_crawler_weight_minimum{ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" }; std::chrono::milliseconds vote_generator_delay{ std::chrono::milliseconds (100) }; - unsigned vote_generator_threshold{ 3 }; nano::amount online_weight_minimum{ 60000 * nano::Knano_ratio }; // 60 million nano /* * The minimum vote weight that a representative must have for its vote to be counted. diff --git a/nano/node/vote_generator.cpp b/nano/node/vote_generator.cpp index 00947ccec..6f2e996a6 100644 --- a/nano/node/vote_generator.cpp +++ b/nano/node/vote_generator.cpp @@ -293,7 +293,7 @@ void nano::vote_generator::run () { broadcast (lock); } - else if (!requests.empty ()) + if (!requests.empty ()) { auto request (requests.front ()); requests.pop_front (); @@ -302,10 +302,7 @@ void nano::vote_generator::run () else { condition.wait_for (lock, config.vote_generator_delay, [this] () { return this->candidates.size () >= nano::network::confirm_ack_hashes_max; }); - if (candidates.size () >= config.vote_generator_threshold && candidates.size () < nano::network::confirm_ack_hashes_max) - { - condition.wait_for (lock, config.vote_generator_delay, [this] () { return this->candidates.size () >= nano::network::confirm_ack_hashes_max; }); - } + if (!candidates.empty ()) { broadcast (lock); From b7b0395a03e1c1a8ff51b842e5ab9e975c0c569a Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Mon, 7 Oct 2024 22:13:54 +0200 Subject: [PATCH 02/48] Simplified vote_generator logic --- nano/node/vote_generator.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/nano/node/vote_generator.cpp b/nano/node/vote_generator.cpp index 6f2e996a6..00dccfd57 100644 --- a/nano/node/vote_generator.cpp +++ b/nano/node/vote_generator.cpp @@ -289,25 +289,19 @@ void nano::vote_generator::run () nano::unique_lock lock{ mutex }; while (!stopped) { - if (candidates.size () >= nano::network::confirm_ack_hashes_max) + condition.wait_for (lock, config.vote_generator_delay, [this] () { return this->candidates.size () >= nano::network::confirm_ack_hashes_max || !requests.empty (); }); + + if (!candidates.empty ()) { broadcast (lock); } + if (!requests.empty ()) { auto request (requests.front ()); requests.pop_front (); reply (lock, std::move (request)); } - else - { - condition.wait_for (lock, config.vote_generator_delay, [this] () { return this->candidates.size () >= nano::network::confirm_ack_hashes_max; }); - - if (!candidates.empty ()) - { - broadcast (lock); - } - } } } From d30dcea56b29301164f3a096007de2d1395c40ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Fri, 3 May 2024 11:44:28 +0200 Subject: [PATCH 03/48] Dead code `tcp_channels::modify` --- nano/core_test/peer_container.cpp | 8 ++------ nano/node/transport/tcp_channels.cpp | 12 ------------ nano/node/transport/tcp_channels.hpp | 1 - 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/nano/core_test/peer_container.cpp b/nano/core_test/peer_container.cpp index 5418ba98c..44f7993b7 100644 --- a/nano/core_test/peer_container.cpp +++ b/nano/core_test/peer_container.cpp @@ -79,16 +79,12 @@ TEST (peer_container, tcp_channel_cleanup_works) ASSERT_NE (nullptr, channel1); // set the last packet sent for channel1 only to guarantee it contains a value. // it won't be necessarily the same use by the cleanup cutoff time - node1.network.tcp_channels.modify (channel1, [&now] (auto channel) { - channel->set_last_packet_sent (now - std::chrono::seconds (5)); - }); + channel1->set_last_packet_sent (now - std::chrono::seconds (5)); auto channel2 = nano::test::establish_tcp (system, node1, outer_node2->network.endpoint ()); ASSERT_NE (nullptr, channel2); // set the last packet sent for channel2 only to guarantee it contains a value. // it won't be necessarily the same use by the cleanup cutoff time - node1.network.tcp_channels.modify (channel2, [&now] (auto channel) { - channel->set_last_packet_sent (now + std::chrono::seconds (1)); - }); + channel2->set_last_packet_sent (now + std::chrono::seconds (1)); ASSERT_EQ (2, node1.network.size ()); ASSERT_EQ (2, node1.network.tcp_channels.size ()); diff --git a/nano/node/transport/tcp_channels.cpp b/nano/node/transport/tcp_channels.cpp index 7a4128056..2d1f147f0 100644 --- a/nano/node/transport/tcp_channels.cpp +++ b/nano/node/transport/tcp_channels.cpp @@ -417,18 +417,6 @@ void nano::transport::tcp_channels::list (std::deque const & channel_a, std::function const &)> modify_callback_a) -{ - nano::lock_guard lock{ mutex }; - auto existing (channels.get ().find (channel_a->get_tcp_endpoint ())); - if (existing != channels.get ().end ()) - { - channels.get ().modify (existing, [modify_callback = std::move (modify_callback_a)] (channel_entry & wrapper_a) { - modify_callback (wrapper_a.channel); - }); - } -} - void nano::transport::tcp_channels::start_tcp (nano::endpoint const & endpoint) { node.tcp_listener.connect (endpoint.address (), endpoint.port ()); diff --git a/nano/node/transport/tcp_channels.hpp b/nano/node/transport/tcp_channels.hpp index 7afd89fc7..0e18d75e8 100644 --- a/nano/node/transport/tcp_channels.hpp +++ b/nano/node/transport/tcp_channels.hpp @@ -50,7 +50,6 @@ public: bool track_reachout (nano::endpoint const &); void purge (std::chrono::steady_clock::time_point cutoff_deadline); void list (std::deque> &, uint8_t = 0, bool = true); - void modify (std::shared_ptr const &, std::function const &)>); void keepalive (); std::optional sample_keepalive (); From 28bc44d95019b7efc9c812cb20b4b269ad47f53d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Fri, 3 May 2024 11:41:29 +0200 Subject: [PATCH 04/48] Cleanup channel endpoints --- nano/core_test/network.cpp | 5 ++--- nano/core_test/node.cpp | 8 ++++---- nano/core_test/request_aggregator.cpp | 2 +- nano/core_test/telemetry.cpp | 18 +++++++++--------- nano/core_test/websocket.cpp | 2 +- nano/node/bootstrap/bootstrap_connections.cpp | 4 ++-- nano/node/bootstrap/bootstrap_legacy.cpp | 2 +- nano/node/json_handler.cpp | 2 +- nano/node/message_processor.cpp | 2 +- nano/node/network.cpp | 4 ++-- nano/node/repcrawler.cpp | 2 +- nano/node/telemetry.cpp | 2 +- nano/node/transport/channel.cpp | 17 ++++++++--------- nano/node/transport/channel.hpp | 6 +++--- nano/node/transport/fake.hpp | 7 +------ nano/node/transport/inproc.hpp | 7 +------ nano/node/transport/tcp_channel.cpp | 6 +++--- nano/node/transport/tcp_channel.hpp | 11 +++-------- nano/node/transport/tcp_channels.cpp | 4 ++-- nano/node/transport/tcp_channels.hpp | 2 +- nano/node/websocket.cpp | 2 +- nano/qt/qt.cpp | 2 +- nano/rpc_test/rpc.cpp | 2 +- nano/slow_test/node.cpp | 8 ++++---- 24 files changed, 55 insertions(+), 72 deletions(-) diff --git a/nano/core_test/network.cpp b/nano/core_test/network.cpp index eb4713f94..9254e8cd1 100644 --- a/nano/core_test/network.cpp +++ b/nano/core_test/network.cpp @@ -1024,14 +1024,13 @@ TEST (network, loopback_channel) auto & node2 = *system.nodes[1]; nano::transport::inproc::channel channel1 (node1, node1); ASSERT_EQ (channel1.get_type (), nano::transport::transport_type::loopback); - ASSERT_EQ (channel1.get_endpoint (), node1.network.endpoint ()); - ASSERT_EQ (channel1.get_tcp_endpoint (), nano::transport::map_endpoint_to_tcp (node1.network.endpoint ())); + ASSERT_EQ (channel1.get_remote_endpoint (), node1.network.endpoint ()); ASSERT_EQ (channel1.get_network_version (), node1.network_params.network.protocol_version); ASSERT_EQ (channel1.get_node_id (), node1.node_id.pub); ASSERT_EQ (channel1.get_node_id_optional ().value_or (0), node1.node_id.pub); nano::transport::inproc::channel channel2 (node2, node2); ++node1.network.port; - ASSERT_NE (channel1.get_endpoint (), node1.network.endpoint ()); + ASSERT_NE (channel1.get_remote_endpoint (), node1.network.endpoint ()); } // Ensure the network filters messages with the incorrect magic number diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 54d1ef29f..c7654c895 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -2704,7 +2704,7 @@ TEST (node, peer_history_restart) ASSERT_TIMELY (10s, !node2->network.empty ()); // Confirm that the peers match with the endpoints we are expecting auto list (node2->network.list (2)); - ASSERT_EQ (node1->network.endpoint (), list[0]->get_endpoint ()); + ASSERT_EQ (node1->network.endpoint (), list[0]->get_remote_endpoint ()); ASSERT_EQ (1, node2->network.size ()); system.stop_node (*node2); } @@ -2727,7 +2727,7 @@ TEST (node, peer_history_restart) ASSERT_TIMELY (10s, !node3->network.empty ()); // Confirm that the peers match with the endpoints we are expecting auto list (node3->network.list (2)); - ASSERT_EQ (node1->network.endpoint (), list[0]->get_endpoint ()); + ASSERT_EQ (node1->network.endpoint (), list[0]->get_remote_endpoint ()); ASSERT_EQ (1, node3->network.size ()); system.stop_node (*node3); } @@ -2789,11 +2789,11 @@ TEST (node, bidirectional_tcp) ASSERT_EQ (1, node2->network.size ()); auto list1 (node1->network.list (1)); ASSERT_EQ (nano::transport::transport_type::tcp, list1[0]->get_type ()); - ASSERT_NE (node2->network.endpoint (), list1[0]->get_endpoint ()); // Ephemeral port + ASSERT_NE (node2->network.endpoint (), list1[0]->get_remote_endpoint ()); // Ephemeral port ASSERT_EQ (node2->node_id.pub, list1[0]->get_node_id ()); auto list2 (node2->network.list (1)); ASSERT_EQ (nano::transport::transport_type::tcp, list2[0]->get_type ()); - ASSERT_EQ (node1->network.endpoint (), list2[0]->get_endpoint ()); + ASSERT_EQ (node1->network.endpoint (), list2[0]->get_remote_endpoint ()); ASSERT_EQ (node1->node_id.pub, list2[0]->get_node_id ()); // Test block propagation from node 1 nano::keypair key; diff --git a/nano/core_test/request_aggregator.cpp b/nano/core_test/request_aggregator.cpp index b0da7dd3b..2f85074e4 100644 --- a/nano/core_test/request_aggregator.cpp +++ b/nano/core_test/request_aggregator.cpp @@ -230,7 +230,7 @@ TEST (request_aggregator, two_endpoints) auto dummy_channel1 = std::make_shared (node1, node1); auto dummy_channel2 = std::make_shared (node2, node2); - ASSERT_NE (nano::transport::map_endpoint_to_v6 (dummy_channel1->get_endpoint ()), nano::transport::map_endpoint_to_v6 (dummy_channel2->get_endpoint ())); + ASSERT_NE (nano::transport::map_endpoint_to_v6 (dummy_channel1->get_remote_endpoint ()), nano::transport::map_endpoint_to_v6 (dummy_channel2->get_remote_endpoint ())); std::vector> request{ { send1->hash (), send1->root () } }; diff --git a/nano/core_test/telemetry.cpp b/nano/core_test/telemetry.cpp index 4ebe65c5c..d5b898b5b 100644 --- a/nano/core_test/telemetry.cpp +++ b/nano/core_test/telemetry.cpp @@ -68,18 +68,18 @@ TEST (telemetry, basic) ASSERT_NE (nullptr, channel); std::optional telemetry_data; - ASSERT_TIMELY (5s, telemetry_data = node_client->telemetry.get_telemetry (channel->get_endpoint ())); + ASSERT_TIMELY (5s, telemetry_data = node_client->telemetry.get_telemetry (channel->get_remote_endpoint ())); ASSERT_EQ (node_server->get_node_id (), telemetry_data->node_id); // Check the metrics are correct ASSERT_TRUE (nano::test::compare_telemetry (*telemetry_data, *node_server)); // Call again straight away - auto telemetry_data_2 = node_client->telemetry.get_telemetry (channel->get_endpoint ()); + auto telemetry_data_2 = node_client->telemetry.get_telemetry (channel->get_remote_endpoint ()); ASSERT_TRUE (telemetry_data_2); // Call again straight away - auto telemetry_data_3 = node_client->telemetry.get_telemetry (channel->get_endpoint ()); + auto telemetry_data_3 = node_client->telemetry.get_telemetry (channel->get_remote_endpoint ()); ASSERT_TRUE (telemetry_data_3); // we expect at least one consecutive repeat of telemetry @@ -89,7 +89,7 @@ TEST (telemetry, basic) WAIT (3s); std::optional telemetry_data_4; - ASSERT_TIMELY (5s, telemetry_data_4 = node_client->telemetry.get_telemetry (channel->get_endpoint ())); + ASSERT_TIMELY (5s, telemetry_data_4 = node_client->telemetry.get_telemetry (channel->get_remote_endpoint ())); ASSERT_NE (*telemetry_data, *telemetry_data_4); } @@ -120,13 +120,13 @@ TEST (telemetry, disconnected) ASSERT_NE (nullptr, channel); // Ensure telemetry is available before disconnecting - ASSERT_TIMELY (5s, node_client->telemetry.get_telemetry (channel->get_endpoint ())); + ASSERT_TIMELY (5s, node_client->telemetry.get_telemetry (channel->get_remote_endpoint ())); system.stop_node (*node_server); ASSERT_TRUE (channel); // Ensure telemetry from disconnected peer is removed - ASSERT_TIMELY (5s, !node_client->telemetry.get_telemetry (channel->get_endpoint ())); + ASSERT_TIMELY (5s, !node_client->telemetry.get_telemetry (channel->get_remote_endpoint ())); } TEST (telemetry, dos_tcp) @@ -185,14 +185,14 @@ TEST (telemetry, disable_metrics) node_client->telemetry.trigger (); - ASSERT_NEVER (1s, node_client->telemetry.get_telemetry (channel->get_endpoint ())); + ASSERT_NEVER (1s, node_client->telemetry.get_telemetry (channel->get_remote_endpoint ())); // It should still be able to receive metrics though auto channel1 = node_server->network.find_node_id (node_client->get_node_id ()); ASSERT_NE (nullptr, channel1); std::optional telemetry_data; - ASSERT_TIMELY (5s, telemetry_data = node_server->telemetry.get_telemetry (channel1->get_endpoint ())); + ASSERT_TIMELY (5s, telemetry_data = node_server->telemetry.get_telemetry (channel1->get_remote_endpoint ())); ASSERT_TRUE (nano::test::compare_telemetry (*telemetry_data, *node_client)); } @@ -237,7 +237,7 @@ TEST (telemetry, maker_pruning) ASSERT_NE (nullptr, channel); std::optional telemetry_data; - ASSERT_TIMELY (5s, telemetry_data = node_client->telemetry.get_telemetry (channel->get_endpoint ())); + ASSERT_TIMELY (5s, telemetry_data = node_client->telemetry.get_telemetry (channel->get_remote_endpoint ())); ASSERT_EQ (node_server->get_node_id (), telemetry_data->node_id); // Ensure telemetry response indicates pruned node diff --git a/nano/core_test/websocket.cpp b/nano/core_test/websocket.cpp index dacfd7b10..50d30d953 100644 --- a/nano/core_test/websocket.cpp +++ b/nano/core_test/websocket.cpp @@ -1005,7 +1005,7 @@ TEST (websocket, telemetry) auto channel = node1->network.find_node_id (node2->get_node_id ()); ASSERT_NE (channel, nullptr); - ASSERT_TIMELY (5s, node1->telemetry.get_telemetry (channel->get_endpoint ())); + ASSERT_TIMELY (5s, node1->telemetry.get_telemetry (channel->get_remote_endpoint ())); ASSERT_TIMELY_EQ (10s, future.wait_for (0s), std::future_status::ready); diff --git a/nano/node/bootstrap/bootstrap_connections.cpp b/nano/node/bootstrap/bootstrap_connections.cpp index dfbdff12f..358538a65 100644 --- a/nano/node/bootstrap/bootstrap_connections.cpp +++ b/nano/node/bootstrap/bootstrap_connections.cpp @@ -102,7 +102,7 @@ void nano::bootstrap_connections::pool_connection (std::shared_ptr lock{ mutex }; auto const & socket_l = client_a->socket; - if (!stopped && !client_a->pending_stop && !node.network.excluded_peers.check (client_a->channel->get_tcp_endpoint ())) + if (!stopped && !client_a->pending_stop && !node.network.excluded_peers.check (client_a->channel->get_remote_endpoint ())) { socket_l->set_timeout (node.network_params.network.idle_timeout); // Push into idle deque @@ -138,7 +138,7 @@ std::shared_ptr nano::bootstrap_connections::find_connec std::shared_ptr result; for (auto i (idle.begin ()), end (idle.end ()); i != end && !stopped; ++i) { - if ((*i)->channel->get_tcp_endpoint () == endpoint_a) + if ((*i)->channel->get_remote_endpoint () == endpoint_a) { result = *i; idle.erase (i); diff --git a/nano/node/bootstrap/bootstrap_legacy.cpp b/nano/node/bootstrap/bootstrap_legacy.cpp index 6ceb30394..47368eccf 100644 --- a/nano/node/bootstrap/bootstrap_legacy.cpp +++ b/nano/node/bootstrap/bootstrap_legacy.cpp @@ -138,7 +138,7 @@ bool nano::bootstrap_attempt_legacy::request_frontier (nano::unique_lockchannel->get_tcp_endpoint (); + endpoint_frontier_request = connection_l->channel->get_remote_endpoint (); std::future future; { auto this_l = std::dynamic_pointer_cast (shared_from_this ()); diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index 198bdeac1..d8a253a7a 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -2991,7 +2991,7 @@ void nano::json_handler::peers () bool const peer_details = request.get ("peer_details", false); auto peers_list (node.network.list (std::numeric_limits::max ())); std::sort (peers_list.begin (), peers_list.end (), [] (auto const & lhs, auto const & rhs) { - return lhs->get_endpoint () < rhs->get_endpoint (); + return lhs->get_remote_endpoint () < rhs->get_remote_endpoint (); }); for (auto i (peers_list.begin ()), n (peers_list.end ()); i != n; ++i) { diff --git a/nano/node/message_processor.cpp b/nano/node/message_processor.cpp index bf3dce51a..469c55bd1 100644 --- a/nano/node/message_processor.cpp +++ b/nano/node/message_processor.cpp @@ -175,7 +175,7 @@ public: if (peer0.address () == boost::asio::ip::address_v6{} && peer0.port () != 0) { // TODO: Remove this as we do not need to establish a second connection to the same peer - nano::endpoint new_endpoint (channel->get_tcp_endpoint ().address (), peer0.port ()); + nano::endpoint new_endpoint (channel->get_remote_endpoint ().address (), peer0.port ()); node.network.merge_peer (new_endpoint); // Remember this for future forwarding to other peers diff --git a/nano/node/network.cpp b/nano/node/network.cpp index d780f634e..7b0435bd2 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -504,14 +504,14 @@ void nano::network::erase (nano::transport::channel const & channel_a) auto const channel_type = channel_a.get_type (); if (channel_type == nano::transport::transport_type::tcp) { - tcp_channels.erase (channel_a.get_tcp_endpoint ()); + tcp_channels.erase (channel_a.get_remote_endpoint ()); } } void nano::network::exclude (std::shared_ptr const & channel) { // Add to peer exclusion list - excluded_peers.add (channel->get_tcp_endpoint ()); + excluded_peers.add (channel->get_remote_endpoint ()); // Disconnect erase (*channel); diff --git a/nano/node/repcrawler.cpp b/nano/node/repcrawler.cpp index 16d72b17a..b3dc58c40 100644 --- a/nano/node/repcrawler.cpp +++ b/nano/node/repcrawler.cpp @@ -102,7 +102,7 @@ void nano::rep_crawler::validate_and_process (nano::unique_lock & l rep.last_response = std::chrono::steady_clock::now (); // Update if representative channel was changed - if (rep.channel->get_endpoint () != channel->get_endpoint ()) + if (rep.channel->get_remote_endpoint () != channel->get_remote_endpoint ()) { debug_assert (rep.account == vote->account); updated = true; diff --git a/nano/node/telemetry.cpp b/nano/node/telemetry.cpp index 1ae2a59be..593454241 100644 --- a/nano/node/telemetry.cpp +++ b/nano/node/telemetry.cpp @@ -96,7 +96,7 @@ void nano::telemetry::process (const nano::telemetry_ack & telemetry, const std: nano::unique_lock lock{ mutex }; - const auto endpoint = channel->get_endpoint (); + const auto endpoint = channel->get_remote_endpoint (); if (auto it = telemetries.get ().find (endpoint); it != telemetries.get ().end ()) { diff --git a/nano/node/transport/channel.cpp b/nano/node/transport/channel.cpp index 183704449..60c758ba5 100644 --- a/nano/node/transport/channel.cpp +++ b/nano/node/transport/channel.cpp @@ -51,21 +51,20 @@ void nano::transport::channel::set_peering_endpoint (nano::endpoint endpoint) nano::endpoint nano::transport::channel::get_peering_endpoint () const { - nano::unique_lock lock{ channel_mutex }; - if (peering_endpoint) { - return *peering_endpoint; - } - else - { - lock.unlock (); - return get_endpoint (); + nano::lock_guard lock{ channel_mutex }; + if (peering_endpoint) + { + return *peering_endpoint; + } } + return get_remote_endpoint (); } void nano::transport::channel::operator() (nano::object_stream & obs) const { - obs.write ("endpoint", get_endpoint ()); + obs.write ("remote_endpoint", get_remote_endpoint ()); + obs.write ("local_endpoint", get_local_endpoint ()); obs.write ("peering_endpoint", get_peering_endpoint ()); obs.write ("node_id", get_node_id ().to_node_id ()); } diff --git a/nano/node/transport/channel.hpp b/nano/node/transport/channel.hpp index e01cc8c57..cb0458666 100644 --- a/nano/node/transport/channel.hpp +++ b/nano/node/transport/channel.hpp @@ -40,10 +40,10 @@ public: virtual void close () = 0; - virtual std::string to_string () const = 0; - virtual nano::endpoint get_endpoint () const = 0; - virtual nano::tcp_endpoint get_tcp_endpoint () const = 0; + virtual nano::endpoint get_remote_endpoint () const = 0; virtual nano::endpoint get_local_endpoint () const = 0; + + virtual std::string to_string () const = 0; virtual nano::transport::transport_type get_type () const = 0; virtual bool max (nano::transport::traffic_type = nano::transport::traffic_type::generic) diff --git a/nano/node/transport/fake.hpp b/nano/node/transport/fake.hpp index a1c95b55f..d9ce585cb 100644 --- a/nano/node/transport/fake.hpp +++ b/nano/node/transport/fake.hpp @@ -30,16 +30,11 @@ namespace transport endpoint = endpoint_a; } - nano::endpoint get_endpoint () const override + nano::endpoint get_remote_endpoint () const override { return endpoint; } - nano::tcp_endpoint get_tcp_endpoint () const override - { - return nano::transport::map_endpoint_to_tcp (endpoint); - } - nano::endpoint get_local_endpoint () const override { return endpoint; diff --git a/nano/node/transport/inproc.hpp b/nano/node/transport/inproc.hpp index 9ae567029..d93fbed2d 100644 --- a/nano/node/transport/inproc.hpp +++ b/nano/node/transport/inproc.hpp @@ -22,16 +22,11 @@ namespace transport std::string to_string () const override; - nano::endpoint get_endpoint () const override + nano::endpoint get_remote_endpoint () const override { return endpoint; } - nano::tcp_endpoint get_tcp_endpoint () const override - { - return nano::transport::map_endpoint_to_tcp (endpoint); - } - nano::endpoint get_local_endpoint () const override { return endpoint; diff --git a/nano/node/transport/tcp_channel.cpp b/nano/node/transport/tcp_channel.cpp index 57f8811ba..3d4d06383 100644 --- a/nano/node/transport/tcp_channel.cpp +++ b/nano/node/transport/tcp_channel.cpp @@ -28,12 +28,12 @@ void nano::transport::tcp_channel::update_endpoints () { nano::lock_guard lk (channel_mutex); - debug_assert (endpoint == nano::endpoint{}); // Not initialized endpoint value + debug_assert (remote_endpoint == nano::endpoint{}); // Not initialized endpoint value debug_assert (local_endpoint == nano::endpoint{}); // Not initialized endpoint value if (auto socket_l = socket.lock ()) { - endpoint = socket_l->remote_endpoint (); + remote_endpoint = socket_l->remote_endpoint (); local_endpoint = socket_l->local_endpoint (); } } @@ -90,7 +90,7 @@ void nano::transport::tcp_channel::send_buffer (nano::shared_const_buffer const std::string nano::transport::tcp_channel::to_string () const { - return nano::util::to_str (get_tcp_endpoint ()); + return nano::util::to_str (get_remote_endpoint ()); } void nano::transport::tcp_channel::operator() (nano::object_stream & obs) const diff --git a/nano/node/transport/tcp_channel.hpp b/nano/node/transport/tcp_channel.hpp index b72db5654..ea77f4811 100644 --- a/nano/node/transport/tcp_channel.hpp +++ b/nano/node/transport/tcp_channel.hpp @@ -24,15 +24,10 @@ public: std::string to_string () const override; - nano::endpoint get_endpoint () const override - { - return nano::transport::map_tcp_to_endpoint (get_tcp_endpoint ()); - } - - nano::tcp_endpoint get_tcp_endpoint () const override + nano::endpoint get_remote_endpoint () const override { nano::lock_guard lk (channel_mutex); - return endpoint; + return remote_endpoint; } nano::endpoint get_local_endpoint () const override @@ -77,7 +72,7 @@ public: std::weak_ptr socket; private: - nano::endpoint endpoint; + nano::endpoint remote_endpoint; nano::endpoint local_endpoint; public: // Logging diff --git a/nano/node/transport/tcp_channels.cpp b/nano/node/transport/tcp_channels.cpp index 2d1f147f0..4b983cb7b 100644 --- a/nano/node/transport/tcp_channels.cpp +++ b/nano/node/transport/tcp_channels.cpp @@ -196,9 +196,9 @@ void nano::transport::tcp_channels::random_fill (std::array & auto j (target_a.begin ()); for (auto i (peers.begin ()), n (peers.end ()); i != n; ++i, ++j) { - debug_assert ((*i)->get_endpoint ().address ().is_v6 ()); + debug_assert ((*i)->get_remote_endpoint ().address ().is_v6 ()); debug_assert (j < target_a.end ()); - *j = (*i)->get_endpoint (); + *j = (*i)->get_remote_endpoint (); } } diff --git a/nano/node/transport/tcp_channels.hpp b/nano/node/transport/tcp_channels.hpp index 0e18d75e8..1b6f1e363 100644 --- a/nano/node/transport/tcp_channels.hpp +++ b/nano/node/transport/tcp_channels.hpp @@ -80,7 +80,7 @@ private: } nano::tcp_endpoint endpoint () const { - return channel->get_tcp_endpoint (); + return channel->get_remote_endpoint (); } std::chrono::steady_clock::time_point last_bootstrap_attempt () const { diff --git a/nano/node/websocket.cpp b/nano/node/websocket.cpp index 76d19aa80..d2b8eab72 100644 --- a/nano/node/websocket.cpp +++ b/nano/node/websocket.cpp @@ -1050,7 +1050,7 @@ nano::websocket_server::websocket_server (nano::websocket::config & config_a, na if (server->any_subscriber (nano::websocket::topic::telemetry)) { nano::websocket::message_builder builder; - server->broadcast (builder.telemetry_received (telemetry_data, channel->get_endpoint ())); + server->broadcast (builder.telemetry_received (telemetry_data, channel->get_remote_endpoint ())); } }); diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index b7e1e13be..763a6e5cf 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -1944,7 +1944,7 @@ void nano_qt::advanced_actions::refresh_peers () peers_model->removeRows (0, peers_model->rowCount ()); auto list (wallet.node.network.list (std::numeric_limits::max ())); std::sort (list.begin (), list.end (), [] (auto const & lhs, auto const & rhs) { - return lhs->get_endpoint () < rhs->get_endpoint (); + return lhs->get_remote_endpoint () < rhs->get_remote_endpoint (); }); for (auto i (list.begin ()), n (list.end ()); i != n; ++i) { diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 5539efc96..1efdeacaf 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -6786,7 +6786,7 @@ TEST (rpc, telemetry_all) auto channel = node1->network.find_node_id (node->get_node_id ()); ASSERT_TRUE (channel); - ASSERT_TIMELY (10s, node1->telemetry.get_telemetry (channel->get_endpoint ())); + ASSERT_TIMELY (10s, node1->telemetry.get_telemetry (channel->get_remote_endpoint ())); boost::property_tree::ptree request; request.put ("action", "telemetry"); diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 4e4781d41..945b661cf 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -1383,7 +1383,7 @@ namespace transport // Pick first peer to be consistent auto peer = data.node->network.tcp_channels.channels[0].channel; - auto maybe_telemetry = data.node->telemetry.get_telemetry (peer->get_endpoint ()); + auto maybe_telemetry = data.node->telemetry.get_telemetry (peer->get_remote_endpoint ()); if (maybe_telemetry) { callback_process (shared_data, data, node_data, maybe_telemetry->timestamp); @@ -1513,7 +1513,7 @@ TEST (telemetry, cache_read_and_timeout) ASSERT_NE (channel, nullptr); node_client->telemetry.trigger (); - ASSERT_TIMELY (5s, telemetry_data = node_client->telemetry.get_telemetry (channel->get_endpoint ())); + ASSERT_TIMELY (5s, telemetry_data = node_client->telemetry.get_telemetry (channel->get_remote_endpoint ())); auto responses = node_client->telemetry.get_all_telemetries (); ASSERT_TRUE (!responses.empty ()); @@ -1536,7 +1536,7 @@ TEST (telemetry, cache_read_and_timeout) // Request telemetry metrics again node_client->telemetry.trigger (); - ASSERT_TIMELY (5s, telemetry_data = node_client->telemetry.get_telemetry (channel->get_endpoint ())); + ASSERT_TIMELY (5s, telemetry_data = node_client->telemetry.get_telemetry (channel->get_remote_endpoint ())); responses = node_client->telemetry.get_all_telemetries (); ASSERT_TRUE (!responses.empty ()); @@ -1611,7 +1611,7 @@ TEST (telemetry, many_nodes) for (auto const & peer : peers) { std::optional telemetry_data; - ASSERT_TIMELY (5s, telemetry_data = node_client->telemetry.get_telemetry (peer->get_endpoint ())); + ASSERT_TIMELY (5s, telemetry_data = node_client->telemetry.get_telemetry (peer->get_remote_endpoint ())); telemetry_datas.push_back (*telemetry_data); } From 0990dc73064ea358c45df2df976cdf211279c5e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Fri, 3 May 2024 11:51:31 +0200 Subject: [PATCH 05/48] Encapsulate channel mutex --- nano/node/transport/channel.cpp | 4 ++-- nano/node/transport/channel.hpp | 25 ++++++++++++------------- nano/node/transport/tcp_channel.cpp | 4 +--- nano/node/transport/tcp_channel.hpp | 4 ++-- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/nano/node/transport/channel.cpp b/nano/node/transport/channel.cpp index 60c758ba5..7a3328100 100644 --- a/nano/node/transport/channel.cpp +++ b/nano/node/transport/channel.cpp @@ -45,14 +45,14 @@ void nano::transport::channel::send (nano::message & message_a, std::function lock{ channel_mutex }; + nano::lock_guard lock{ mutex }; peering_endpoint = endpoint; } nano::endpoint nano::transport::channel::get_peering_endpoint () const { { - nano::lock_guard lock{ channel_mutex }; + nano::lock_guard lock{ mutex }; if (peering_endpoint) { return *peering_endpoint; diff --git a/nano/node/transport/channel.hpp b/nano/node/transport/channel.hpp index cb0458666..157b240cf 100644 --- a/nano/node/transport/channel.hpp +++ b/nano/node/transport/channel.hpp @@ -58,49 +58,49 @@ public: std::chrono::steady_clock::time_point get_last_bootstrap_attempt () const { - nano::lock_guard lk (channel_mutex); + nano::lock_guard lock{ mutex }; return last_bootstrap_attempt; } void set_last_bootstrap_attempt (std::chrono::steady_clock::time_point const time_a) { - nano::lock_guard lk (channel_mutex); + nano::lock_guard lock{ mutex }; last_bootstrap_attempt = time_a; } std::chrono::steady_clock::time_point get_last_packet_received () const { - nano::lock_guard lk (channel_mutex); + nano::lock_guard lock{ mutex }; return last_packet_received; } void set_last_packet_received (std::chrono::steady_clock::time_point const time_a) { - nano::lock_guard lk (channel_mutex); + nano::lock_guard lock{ mutex }; last_packet_received = time_a; } std::chrono::steady_clock::time_point get_last_packet_sent () const { - nano::lock_guard lk (channel_mutex); + nano::lock_guard lock{ mutex }; return last_packet_sent; } void set_last_packet_sent (std::chrono::steady_clock::time_point const time_a) { - nano::lock_guard lk (channel_mutex); + nano::lock_guard lock{ mutex }; last_packet_sent = time_a; } boost::optional get_node_id_optional () const { - nano::lock_guard lk (channel_mutex); + nano::lock_guard lock{ mutex }; return node_id; } nano::account get_node_id () const { - nano::lock_guard lk (channel_mutex); + nano::lock_guard lock{ mutex }; if (node_id.is_initialized ()) { return node_id.get (); @@ -113,7 +113,7 @@ public: void set_node_id (nano::account node_id_a) { - nano::lock_guard lk (channel_mutex); + nano::lock_guard lock{ mutex }; node_id = node_id_a; } @@ -130,7 +130,9 @@ public: nano::endpoint get_peering_endpoint () const; void set_peering_endpoint (nano::endpoint endpoint); - mutable nano::mutex channel_mutex; +protected: + nano::node & node; + mutable nano::mutex mutex; private: std::chrono::steady_clock::time_point last_bootstrap_attempt{ std::chrono::steady_clock::time_point () }; @@ -140,9 +142,6 @@ private: std::atomic network_version{ 0 }; std::optional peering_endpoint{}; -protected: - nano::node & node; - public: // Logging virtual void operator() (nano::object_stream &) const; }; diff --git a/nano/node/transport/tcp_channel.cpp b/nano/node/transport/tcp_channel.cpp index 3d4d06383..cd0f3645b 100644 --- a/nano/node/transport/tcp_channel.cpp +++ b/nano/node/transport/tcp_channel.cpp @@ -16,8 +16,6 @@ nano::transport::tcp_channel::tcp_channel (nano::node & node_a, std::weak_ptr lk{ channel_mutex }; - // Close socket. Exception: socket is used by tcp_server if (auto socket_l = socket.lock ()) { socket_l->close (); @@ -26,7 +24,7 @@ nano::transport::tcp_channel::~tcp_channel () void nano::transport::tcp_channel::update_endpoints () { - nano::lock_guard lk (channel_mutex); + nano::lock_guard lock{ mutex }; debug_assert (remote_endpoint == nano::endpoint{}); // Not initialized endpoint value debug_assert (local_endpoint == nano::endpoint{}); // Not initialized endpoint value diff --git a/nano/node/transport/tcp_channel.hpp b/nano/node/transport/tcp_channel.hpp index ea77f4811..3936e3e9a 100644 --- a/nano/node/transport/tcp_channel.hpp +++ b/nano/node/transport/tcp_channel.hpp @@ -26,13 +26,13 @@ public: nano::endpoint get_remote_endpoint () const override { - nano::lock_guard lk (channel_mutex); + nano::lock_guard lock{ mutex }; return remote_endpoint; } nano::endpoint get_local_endpoint () const override { - nano::lock_guard lk (channel_mutex); + nano::lock_guard lock{ mutex }; return local_endpoint; } From 934cd6eba57e2a66457d96fdfd1dab5e412fca3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Mon, 7 Oct 2024 22:55:16 +0200 Subject: [PATCH 06/48] Use std:::optional --- nano/node/json_handler.cpp | 4 ++-- nano/node/transport/channel.hpp | 13 +++---------- nano/qt/qt.cpp | 4 ++-- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index d8a253a7a..a0232c342 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -3003,9 +3003,9 @@ void nano::json_handler::peers () boost::property_tree::ptree pending_tree; pending_tree.put ("protocol_version", std::to_string (channel->get_network_version ())); auto node_id_l (channel->get_node_id_optional ()); - if (node_id_l.is_initialized ()) + if (node_id_l.has_value ()) { - pending_tree.put ("node_id", node_id_l.get ().to_node_id ()); + pending_tree.put ("node_id", node_id_l.value ().to_node_id ()); } else { diff --git a/nano/node/transport/channel.hpp b/nano/node/transport/channel.hpp index 157b240cf..2dbe3c848 100644 --- a/nano/node/transport/channel.hpp +++ b/nano/node/transport/channel.hpp @@ -92,7 +92,7 @@ public: last_packet_sent = time_a; } - boost::optional get_node_id_optional () const + std::optional get_node_id_optional () const { nano::lock_guard lock{ mutex }; return node_id; @@ -101,14 +101,7 @@ public: nano::account get_node_id () const { nano::lock_guard lock{ mutex }; - if (node_id.is_initialized ()) - { - return node_id.get (); - } - else - { - return 0; - } + return node_id.value_or (0); } void set_node_id (nano::account node_id_a) @@ -138,7 +131,7 @@ private: std::chrono::steady_clock::time_point last_bootstrap_attempt{ std::chrono::steady_clock::time_point () }; std::chrono::steady_clock::time_point last_packet_received{ std::chrono::steady_clock::now () }; std::chrono::steady_clock::time_point last_packet_sent{ std::chrono::steady_clock::now () }; - boost::optional node_id{ boost::none }; + std::optional node_id{}; std::atomic network_version{ 0 }; std::optional peering_endpoint{}; diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index 763a6e5cf..aefd693bd 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -1959,9 +1959,9 @@ void nano_qt::advanced_actions::refresh_peers () items.push_back (version); QString node_id (""); auto node_id_l (channel->get_node_id_optional ()); - if (node_id_l.is_initialized ()) + if (node_id_l.has_value ()) { - node_id = node_id_l.get ().to_account ().c_str (); + node_id = node_id_l.value ().to_account ().c_str (); } items.push_back (new QStandardItem (node_id)); peers_model->appendRow (items); From cd5b6bd91f9e4245c7802787601829081832c76a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Thu, 17 Oct 2024 15:13:03 +0200 Subject: [PATCH 07/48] Pass explicit dependencies to election schedulers --- nano/node/node.cpp | 2 +- nano/node/scheduler/component.cpp | 8 ++++---- nano/node/scheduler/component.hpp | 4 +--- nano/node/scheduler/priority.cpp | 31 +++++++++++++++++-------------- nano/node/scheduler/priority.hpp | 5 ++++- 5 files changed, 27 insertions(+), 23 deletions(-) diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 3cb0e0353..991b5c9cd 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -137,7 +137,7 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy generator{ *generator_impl }, final_generator_impl{ std::make_unique (config, *this, ledger, wallets, vote_processor, history, network, stats, logger, /* final */ true) }, final_generator{ *final_generator_impl }, - scheduler_impl{ std::make_unique (*this) }, + scheduler_impl{ std::make_unique (config, *this, ledger, active, online_reps, vote_cache, stats, logger) }, scheduler{ *scheduler_impl }, aggregator_impl{ std::make_unique (config.request_aggregator, *this, stats, generator, final_generator, history, ledger, wallets, vote_router) }, aggregator{ *aggregator_impl }, diff --git a/nano/node/scheduler/component.cpp b/nano/node/scheduler/component.cpp index de3f7469c..97c5926df 100644 --- a/nano/node/scheduler/component.cpp +++ b/nano/node/scheduler/component.cpp @@ -5,11 +5,11 @@ #include #include -nano::scheduler::component::component (nano::node & node) : - hinted_impl{ std::make_unique (node.config.hinted_scheduler, node, node.vote_cache, node.active, node.online_reps, node.stats) }, +nano::scheduler::component::component (nano::node_config & node_config, nano::node & node, nano::ledger & ledger, nano::active_elections & active, nano::online_reps & online_reps, nano::vote_cache & vote_cache, nano::stats & stats, nano::logger & logger) : + hinted_impl{ std::make_unique (node_config.hinted_scheduler, node, vote_cache, active, online_reps, stats) }, manual_impl{ std::make_unique (node) }, - optimistic_impl{ std::make_unique (node.config.optimistic_scheduler, node, node.ledger, node.active, node.network_params.network, node.stats) }, - priority_impl{ std::make_unique (node, node.stats) }, + optimistic_impl{ std::make_unique (node_config.optimistic_scheduler, node, ledger, active, node_config.network_params.network, stats) }, + priority_impl{ std::make_unique (node_config, node, ledger, active, stats, logger) }, hinted{ *hinted_impl }, manual{ *manual_impl }, optimistic{ *optimistic_impl }, diff --git a/nano/node/scheduler/component.hpp b/nano/node/scheduler/component.hpp index 090b4f698..35b4a1b6d 100644 --- a/nano/node/scheduler/component.hpp +++ b/nano/node/scheduler/component.hpp @@ -10,12 +10,10 @@ namespace nano::scheduler class component final { public: - explicit component (nano::node & node); + component (nano::node_config &, nano::node &, nano::ledger &, nano::active_elections &, nano::online_reps &, nano::vote_cache &, nano::stats &, nano::logger &); ~component (); - // Starts all schedulers void start (); - // Stops all schedulers void stop (); nano::container_info container_info () const; diff --git a/nano/node/scheduler/priority.cpp b/nano/node/scheduler/priority.cpp index b209a2c59..571753e9f 100644 --- a/nano/node/scheduler/priority.cpp +++ b/nano/node/scheduler/priority.cpp @@ -7,10 +7,13 @@ #include #include -nano::scheduler::priority::priority (nano::node & node_a, nano::stats & stats_a) : - config{ node_a.config.priority_scheduler }, +nano::scheduler::priority::priority (nano::node_config & node_config, nano::node & node_a, nano::ledger & ledger_a, nano::active_elections & active_a, nano::stats & stats_a, nano::logger & logger_a) : + config{ node_config.priority_scheduler }, node{ node_a }, - stats{ stats_a } + ledger{ ledger_a }, + active{ active_a }, + stats{ stats_a }, + logger{ logger_a } { std::vector minimums; @@ -34,11 +37,11 @@ nano::scheduler::priority::priority (nano::node & node_a, nano::stats & stats_a) build_region (uint128_t{ 1 } << 116, uint128_t{ 1 } << 120, 2); minimums.push_back (uint128_t{ 1 } << 120); - node.logger.debug (nano::log::type::election_scheduler, "Number of buckets: {}", minimums.size ()); + logger.debug (nano::log::type::election_scheduler, "Number of buckets: {}", minimums.size ()); for (size_t i = 0u, n = minimums.size (); i < n; ++i) { - auto bucket = std::make_unique (minimums[i], node.config.priority_bucket, node.active, stats); + auto bucket = std::make_unique (minimums[i], node_config.priority_bucket, active, stats); buckets.emplace_back (std::move (bucket)); } } @@ -85,11 +88,11 @@ void nano::scheduler::priority::stop () bool nano::scheduler::priority::activate (secure::transaction const & transaction, nano::account const & account) { debug_assert (!account.is_zero ()); - auto info = node.ledger.any.account_get (transaction, account); + auto info = ledger.any.account_get (transaction, account); if (info) { nano::confirmation_height_info conf_info; - node.store.confirmation_height.get (transaction, account, conf_info); + ledger.store.confirmation_height.get (transaction, account, conf_info); if (conf_info.height < info->block_count) { return activate (transaction, account, *info, conf_info); @@ -103,14 +106,14 @@ bool nano::scheduler::priority::activate (secure::transaction const & transactio { debug_assert (conf_info.frontier != account_info.head); - auto hash = conf_info.height == 0 ? account_info.open_block : node.ledger.any.block_successor (transaction, conf_info.frontier).value (); - auto block = node.ledger.any.block_get (transaction, hash); + auto hash = conf_info.height == 0 ? account_info.open_block : ledger.any.block_successor (transaction, conf_info.frontier).value (); + auto block = ledger.any.block_get (transaction, hash); release_assert (block != nullptr); - if (node.ledger.dependents_confirmed (transaction, *block)) + if (ledger.dependents_confirmed (transaction, *block)) { auto const balance = block->balance (); - auto const previous_balance = node.ledger.any.block_balance (transaction, conf_info.frontier).value_or (0); + auto const previous_balance = ledger.any.block_balance (transaction, conf_info.frontier).value_or (0); auto const balance_priority = std::max (balance, previous_balance); bool added = false; @@ -120,8 +123,8 @@ bool nano::scheduler::priority::activate (secure::transaction const & transactio } if (added) { - node.stats.inc (nano::stat::type::election_scheduler, nano::stat::detail::activated); - node.logger.trace (nano::log::type::election_scheduler, nano::log::detail::block_activated, + stats.inc (nano::stat::type::election_scheduler, nano::stat::detail::activated); + logger.trace (nano::log::type::election_scheduler, nano::log::detail::block_activated, nano::log::arg{ "account", account.to_account () }, // TODO: Convert to lazy eval nano::log::arg{ "block", block }, nano::log::arg{ "time", account_info.modified }, @@ -131,7 +134,7 @@ bool nano::scheduler::priority::activate (secure::transaction const & transactio } else { - node.stats.inc (nano::stat::type::election_scheduler, nano::stat::detail::activate_full); + stats.inc (nano::stat::type::election_scheduler, nano::stat::detail::activate_full); } return true; // Activated diff --git a/nano/node/scheduler/priority.hpp b/nano/node/scheduler/priority.hpp index 727598184..0cf0252f5 100644 --- a/nano/node/scheduler/priority.hpp +++ b/nano/node/scheduler/priority.hpp @@ -26,7 +26,7 @@ public: class priority final { public: - priority (nano::node &, nano::stats &); + priority (nano::node_config &, nano::node &, nano::ledger &, nano::active_elections &, nano::stats &, nano::logger &); ~priority (); void start (); @@ -48,7 +48,10 @@ public: private: // Dependencies priority_config const & config; nano::node & node; + nano::ledger & ledger; + nano::active_elections & active; nano::stats & stats; + nano::logger & logger; private: void run (); From d834d933714201a9eb0b46638de35dbe7e73520b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:03:48 +0200 Subject: [PATCH 08/48] Use `vacancy_updated` event --- nano/core_test/active_elections.cpp | 4 +++- nano/node/active_elections.cpp | 7 +++---- nano/node/active_elections.hpp | 5 ++++- nano/node/node.cpp | 7 ------- nano/node/scheduler/component.cpp | 6 ++++++ 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/nano/core_test/active_elections.cpp b/nano/core_test/active_elections.cpp index 9bd1d6c20..32bc538da 100644 --- a/nano/core_test/active_elections.cpp +++ b/nano/core_test/active_elections.cpp @@ -1308,7 +1308,9 @@ TEST (active_elections, vacancy) .sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub) .work (*system.work.generate (nano::dev::genesis->hash ())) .build (); - node.active.vacancy_update = [&updated] () { updated = true; }; + node.active.vacancy_updated.add ([&updated] () { + updated = true; + }); ASSERT_EQ (nano::block_status::progress, node.process (send)); ASSERT_EQ (1, node.active.vacancy (nano::election_behavior::priority)); ASSERT_EQ (0, node.active.size ()); diff --git a/nano/node/active_elections.cpp b/nano/node/active_elections.cpp index 0cc4953f0..861e7e7ef 100644 --- a/nano/node/active_elections.cpp +++ b/nano/node/active_elections.cpp @@ -312,7 +312,7 @@ void nano::active_elections::cleanup_election (nano::unique_lock & entry.erased_callback (election); } - vacancy_update (); + vacancy_updated.notify (); for (auto const & [hash, block] : blocks_l) { @@ -435,7 +435,7 @@ nano::election_insertion_result nano::active_elections::insert (std::shared_ptr< node.vote_cache_processor.trigger (hash); node.observers.active_started.notify (hash); - vacancy_update (); + vacancy_updated.notify (); } // Votes are generated for inserted or ongoing elections @@ -541,8 +541,7 @@ void nano::active_elections::clear () nano::lock_guard guard{ mutex }; roots.clear (); } - - vacancy_update (); + vacancy_updated.notify (); } nano::container_info nano::active_elections::container_info () const diff --git a/nano/node/active_elections.hpp b/nano/node/active_elections.hpp index 1a76cf044..e3a1a8b4c 100644 --- a/nano/node/active_elections.hpp +++ b/nano/node/active_elections.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -121,10 +122,12 @@ public: * How many election slots are available for specified election type */ int64_t vacancy (nano::election_behavior behavior) const; - std::function vacancy_update{ [] () {} }; nano::container_info container_info () const; +public: // Events + nano::observer_set<> vacancy_updated; + private: void request_loop (); void request_confirm (nano::unique_lock &); diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 991b5c9cd..f2f22608e 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -187,13 +187,6 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy if (!init_error ()) { - // Notify election schedulers when AEC frees election slot - active.vacancy_update = [this] () { - scheduler.priority.notify (); - scheduler.hinted.notify (); - scheduler.optimistic.notify (); - }; - wallets.observer = [this] (bool active) { observers.wallet.notify (active); }; diff --git a/nano/node/scheduler/component.cpp b/nano/node/scheduler/component.cpp index 97c5926df..560594b01 100644 --- a/nano/node/scheduler/component.cpp +++ b/nano/node/scheduler/component.cpp @@ -15,6 +15,12 @@ nano::scheduler::component::component (nano::node_config & node_config, nano::no optimistic{ *optimistic_impl }, priority{ *priority_impl } { + // Notify election schedulers when AEC frees election slot + active.vacancy_updated.add ([this] () { + priority.notify (); + hinted.notify (); + optimistic.notify (); + }); } nano::scheduler::component::~component () From d22b69c934e25ceb24680ba7480132feba172350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:13:58 +0200 Subject: [PATCH 09/48] Activate accounts with freshly processed blocks --- nano/node/node.cpp | 2 +- nano/node/process_live_dispatcher.cpp | 6 ------ nano/node/scheduler/component.cpp | 4 ++-- nano/node/scheduler/component.hpp | 2 +- nano/node/scheduler/priority.cpp | 19 ++++++++++++++++--- nano/node/scheduler/priority.hpp | 3 ++- 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/nano/node/node.cpp b/nano/node/node.cpp index f2f22608e..86a4fa167 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -137,7 +137,7 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy generator{ *generator_impl }, final_generator_impl{ std::make_unique (config, *this, ledger, wallets, vote_processor, history, network, stats, logger, /* final */ true) }, final_generator{ *final_generator_impl }, - scheduler_impl{ std::make_unique (config, *this, ledger, active, online_reps, vote_cache, stats, logger) }, + scheduler_impl{ std::make_unique (config, *this, ledger, block_processor, active, online_reps, vote_cache, stats, logger) }, scheduler{ *scheduler_impl }, aggregator_impl{ std::make_unique (config.request_aggregator, *this, stats, generator, final_generator, history, ledger, wallets, vote_router) }, aggregator{ *aggregator_impl }, diff --git a/nano/node/process_live_dispatcher.cpp b/nano/node/process_live_dispatcher.cpp index 60a80e215..1f00b2324 100644 --- a/nano/node/process_live_dispatcher.cpp +++ b/nano/node/process_live_dispatcher.cpp @@ -43,12 +43,6 @@ void nano::process_live_dispatcher::inspect (nano::block_status const & result, void nano::process_live_dispatcher::process_live (nano::block const & block, secure::transaction const & transaction) { - // Start collecting quorum on block - if (ledger.dependents_confirmed (transaction, block)) - { - scheduler.activate (transaction, block.account ()); - } - if (websocket.server && websocket.server->any_subscriber (nano::websocket::topic::new_unconfirmed_block)) { websocket.server->broadcast (nano::websocket::message_builder ().new_block_arrived (block)); diff --git a/nano/node/scheduler/component.cpp b/nano/node/scheduler/component.cpp index 560594b01..f0352a390 100644 --- a/nano/node/scheduler/component.cpp +++ b/nano/node/scheduler/component.cpp @@ -5,11 +5,11 @@ #include #include -nano::scheduler::component::component (nano::node_config & node_config, nano::node & node, nano::ledger & ledger, nano::active_elections & active, nano::online_reps & online_reps, nano::vote_cache & vote_cache, nano::stats & stats, nano::logger & logger) : +nano::scheduler::component::component (nano::node_config & node_config, nano::node & node, nano::ledger & ledger, nano::block_processor & block_processor, nano::active_elections & active, nano::online_reps & online_reps, nano::vote_cache & vote_cache, nano::stats & stats, nano::logger & logger) : hinted_impl{ std::make_unique (node_config.hinted_scheduler, node, vote_cache, active, online_reps, stats) }, manual_impl{ std::make_unique (node) }, optimistic_impl{ std::make_unique (node_config.optimistic_scheduler, node, ledger, active, node_config.network_params.network, stats) }, - priority_impl{ std::make_unique (node_config, node, ledger, active, stats, logger) }, + priority_impl{ std::make_unique (node_config, node, ledger, block_processor, active, stats, logger) }, hinted{ *hinted_impl }, manual{ *manual_impl }, optimistic{ *optimistic_impl }, diff --git a/nano/node/scheduler/component.hpp b/nano/node/scheduler/component.hpp index 35b4a1b6d..40a53d0f1 100644 --- a/nano/node/scheduler/component.hpp +++ b/nano/node/scheduler/component.hpp @@ -10,7 +10,7 @@ namespace nano::scheduler class component final { public: - component (nano::node_config &, nano::node &, nano::ledger &, nano::active_elections &, nano::online_reps &, nano::vote_cache &, nano::stats &, nano::logger &); + component (nano::node_config &, nano::node &, nano::ledger &, nano::block_processor &, nano::active_elections &, nano::online_reps &, nano::vote_cache &, nano::stats &, nano::logger &); ~component (); void start (); diff --git a/nano/node/scheduler/priority.cpp b/nano/node/scheduler/priority.cpp index 571753e9f..beb360d62 100644 --- a/nano/node/scheduler/priority.cpp +++ b/nano/node/scheduler/priority.cpp @@ -7,10 +7,11 @@ #include #include -nano::scheduler::priority::priority (nano::node_config & node_config, nano::node & node_a, nano::ledger & ledger_a, nano::active_elections & active_a, nano::stats & stats_a, nano::logger & logger_a) : +nano::scheduler::priority::priority (nano::node_config & node_config, nano::node & node_a, nano::ledger & ledger_a, nano::block_processor & block_processor_a, nano::active_elections & active_a, nano::stats & stats_a, nano::logger & logger_a) : config{ node_config.priority_scheduler }, node{ node_a }, ledger{ ledger_a }, + block_processor{ block_processor_a }, active{ active_a }, stats{ stats_a }, logger{ logger_a } @@ -44,6 +45,19 @@ nano::scheduler::priority::priority (nano::node_config & node_config, nano::node auto bucket = std::make_unique (minimums[i], node_config.priority_bucket, active, stats); buckets.emplace_back (std::move (bucket)); } + + // Activate accounts with fresh blocks + block_processor.batch_processed.add ([this] (auto const & batch) { + auto transaction = ledger.tx_begin_read (); + for (auto const & [result, context] : batch) + { + if (result == nano::block_status::progress) + { + release_assert (context.block != nullptr); + activate (transaction, context.block->account ()); + } + } + }); } nano::scheduler::priority::~priority () @@ -88,8 +102,7 @@ void nano::scheduler::priority::stop () bool nano::scheduler::priority::activate (secure::transaction const & transaction, nano::account const & account) { debug_assert (!account.is_zero ()); - auto info = ledger.any.account_get (transaction, account); - if (info) + if (auto info = ledger.any.account_get (transaction, account)) { nano::confirmation_height_info conf_info; ledger.store.confirmation_height.get (transaction, account, conf_info); diff --git a/nano/node/scheduler/priority.hpp b/nano/node/scheduler/priority.hpp index 0cf0252f5..8cdeac02c 100644 --- a/nano/node/scheduler/priority.hpp +++ b/nano/node/scheduler/priority.hpp @@ -26,7 +26,7 @@ public: class priority final { public: - priority (nano::node_config &, nano::node &, nano::ledger &, nano::active_elections &, nano::stats &, nano::logger &); + priority (nano::node_config &, nano::node &, nano::ledger &, nano::block_processor &, nano::active_elections &, nano::stats &, nano::logger &); ~priority (); void start (); @@ -49,6 +49,7 @@ private: // Dependencies priority_config const & config; nano::node & node; nano::ledger & ledger; + nano::block_processor & block_processor; nano::active_elections & active; nano::stats & stats; nano::logger & logger; From f2198c9c0c220a35182b62fc8e62fd7f6a3b5ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:34:53 +0200 Subject: [PATCH 10/48] Activate successors of cemented blocks --- nano/core_test/active_elections.cpp | 4 ++-- nano/node/active_elections.cpp | 20 -------------------- nano/node/active_elections.hpp | 1 - nano/node/node.cpp | 2 +- nano/node/scheduler/component.cpp | 4 ++-- nano/node/scheduler/component.hpp | 2 +- nano/node/scheduler/priority.cpp | 29 ++++++++++++++++++++++++++++- nano/node/scheduler/priority.hpp | 8 +++++--- 8 files changed, 39 insertions(+), 31 deletions(-) diff --git a/nano/core_test/active_elections.cpp b/nano/core_test/active_elections.cpp index 32bc538da..f592ea133 100644 --- a/nano/core_test/active_elections.cpp +++ b/nano/core_test/active_elections.cpp @@ -1232,8 +1232,8 @@ TEST (active_elections, activate_inactive) ASSERT_TIMELY_EQ (5s, 1, node.stats.count (nano::stat::type::confirmation_observer, nano::stat::detail::active_quorum, nano::stat::dir::out)); ASSERT_ALWAYS_EQ (50ms, 0, node.stats.count (nano::stat::type::confirmation_observer, nano::stat::detail::active_conf_height, nano::stat::dir::out)); - // The first block was not active so no activation takes place - ASSERT_FALSE (node.active.active (open->qualified_root ()) || node.block_confirmed_or_being_confirmed (open->hash ())); + // Cementing of send should activate open + ASSERT_TIMELY (5s, node.active.active (open->qualified_root ())); } TEST (active_elections, list_active) diff --git a/nano/node/active_elections.cpp b/nano/node/active_elections.cpp index 861e7e7ef..c161038e4 100644 --- a/nano/node/active_elections.cpp +++ b/nano/node/active_elections.cpp @@ -123,15 +123,6 @@ void nano::active_elections::block_cemented (nano::secure::transaction const & t nano::log::arg{ "source_election", source_election }); notify_observers (transaction, status, votes); - - bool cemented_bootstrap_count_reached = node.ledger.cemented_count () >= node.ledger.bootstrap_weight_max_blocks; - bool was_active = status.type == nano::election_status_type::active_confirmed_quorum || status.type == nano::election_status_type::active_confirmation_height; - - // Next-block activations are only done for blocks with previously active elections - if (cemented_bootstrap_count_reached && was_active && !node.flags.disable_activate_successors) - { - activate_successors (transaction, block); - } } void nano::active_elections::notify_observers (nano::secure::transaction const & transaction, nano::election_status const & status, std::vector const & votes) const @@ -169,17 +160,6 @@ void nano::active_elections::notify_observers (nano::secure::transaction const & } } -void nano::active_elections::activate_successors (nano::secure::transaction const & transaction, std::shared_ptr const & block) -{ - node.scheduler.priority.activate (transaction, block->account ()); - - // Start or vote for the next unconfirmed block in the destination account - if (block->is_send () && !block->destination ().is_zero () && block->destination () != block->account ()) - { - node.scheduler.priority.activate (transaction, block->destination ()); - } -} - int64_t nano::active_elections::limit (nano::election_behavior behavior) const { switch (behavior) diff --git a/nano/node/active_elections.hpp b/nano/node/active_elections.hpp index e3a1a8b4c..049f41428 100644 --- a/nano/node/active_elections.hpp +++ b/nano/node/active_elections.hpp @@ -136,7 +136,6 @@ private: nano::stat::type completion_type (nano::election const & election) const; // Returns a list of elections sorted by difficulty, mutex must be locked std::vector> list_active_impl (std::size_t) const; - void activate_successors (nano::secure::transaction const &, std::shared_ptr const & block); void notify_observers (nano::secure::transaction const &, nano::election_status const & status, std::vector const & votes) const; void block_cemented (nano::secure::transaction const &, std::shared_ptr const & block, nano::block_hash const & confirmation_root, std::shared_ptr const & source_election); diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 86a4fa167..313a18768 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -137,7 +137,7 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy generator{ *generator_impl }, final_generator_impl{ std::make_unique (config, *this, ledger, wallets, vote_processor, history, network, stats, logger, /* final */ true) }, final_generator{ *final_generator_impl }, - scheduler_impl{ std::make_unique (config, *this, ledger, block_processor, active, online_reps, vote_cache, stats, logger) }, + scheduler_impl{ std::make_unique (config, *this, ledger, block_processor, active, online_reps, vote_cache, confirming_set, stats, logger) }, scheduler{ *scheduler_impl }, aggregator_impl{ std::make_unique (config.request_aggregator, *this, stats, generator, final_generator, history, ledger, wallets, vote_router) }, aggregator{ *aggregator_impl }, diff --git a/nano/node/scheduler/component.cpp b/nano/node/scheduler/component.cpp index f0352a390..2d8cf5633 100644 --- a/nano/node/scheduler/component.cpp +++ b/nano/node/scheduler/component.cpp @@ -5,11 +5,11 @@ #include #include -nano::scheduler::component::component (nano::node_config & node_config, nano::node & node, nano::ledger & ledger, nano::block_processor & block_processor, nano::active_elections & active, nano::online_reps & online_reps, nano::vote_cache & vote_cache, nano::stats & stats, nano::logger & logger) : +nano::scheduler::component::component (nano::node_config & node_config, nano::node & node, nano::ledger & ledger, nano::block_processor & block_processor, nano::active_elections & active, nano::online_reps & online_reps, nano::vote_cache & vote_cache, nano::confirming_set & confirming_set, nano::stats & stats, nano::logger & logger) : hinted_impl{ std::make_unique (node_config.hinted_scheduler, node, vote_cache, active, online_reps, stats) }, manual_impl{ std::make_unique (node) }, optimistic_impl{ std::make_unique (node_config.optimistic_scheduler, node, ledger, active, node_config.network_params.network, stats) }, - priority_impl{ std::make_unique (node_config, node, ledger, block_processor, active, stats, logger) }, + priority_impl{ std::make_unique (node_config, node, ledger, block_processor, active, confirming_set, stats, logger) }, hinted{ *hinted_impl }, manual{ *manual_impl }, optimistic{ *optimistic_impl }, diff --git a/nano/node/scheduler/component.hpp b/nano/node/scheduler/component.hpp index 40a53d0f1..96de3d94a 100644 --- a/nano/node/scheduler/component.hpp +++ b/nano/node/scheduler/component.hpp @@ -10,7 +10,7 @@ namespace nano::scheduler class component final { public: - component (nano::node_config &, nano::node &, nano::ledger &, nano::block_processor &, nano::active_elections &, nano::online_reps &, nano::vote_cache &, nano::stats &, nano::logger &); + component (nano::node_config &, nano::node &, nano::ledger &, nano::block_processor &, nano::active_elections &, nano::online_reps &, nano::vote_cache &, nano::confirming_set &, nano::stats &, nano::logger &); ~component (); void start (); diff --git a/nano/node/scheduler/priority.cpp b/nano/node/scheduler/priority.cpp index beb360d62..4063ce60d 100644 --- a/nano/node/scheduler/priority.cpp +++ b/nano/node/scheduler/priority.cpp @@ -7,12 +7,13 @@ #include #include -nano::scheduler::priority::priority (nano::node_config & node_config, nano::node & node_a, nano::ledger & ledger_a, nano::block_processor & block_processor_a, nano::active_elections & active_a, nano::stats & stats_a, nano::logger & logger_a) : +nano::scheduler::priority::priority (nano::node_config & node_config, nano::node & node_a, nano::ledger & ledger_a, nano::block_processor & block_processor_a, nano::active_elections & active_a, nano::confirming_set & confirming_set_a, nano::stats & stats_a, nano::logger & logger_a) : config{ node_config.priority_scheduler }, node{ node_a }, ledger{ ledger_a }, block_processor{ block_processor_a }, active{ active_a }, + confirming_set{ confirming_set_a }, stats{ stats_a }, logger{ logger_a } { @@ -58,6 +59,21 @@ nano::scheduler::priority::priority (nano::node_config & node_config, nano::node } } }); + + // Activate successors of cemented blocks + confirming_set.batch_cemented.add ([this] (auto const & batch) { + if (node.flags.disable_activate_successors) + { + return; + } + + auto transaction = ledger.tx_begin_read (); + for (auto const & context : batch) + { + release_assert (context.block != nullptr); + activate_successors (transaction, *context.block); + } + }); } nano::scheduler::priority::~priority () @@ -157,6 +173,17 @@ bool nano::scheduler::priority::activate (secure::transaction const & transactio return false; // Not activated } +bool nano::scheduler::priority::activate_successors (secure::transaction const & transaction, nano::block const & block) +{ + bool result = activate (transaction, block.account ()); + // Start or vote for the next unconfirmed block in the destination account + if (block.is_send () && !block.destination ().is_zero () && block.destination () != block.account ()) + { + result |= activate (transaction, block.destination ()); + } + return result; +} + void nano::scheduler::priority::notify () { condition.notify_all (); diff --git a/nano/node/scheduler/priority.hpp b/nano/node/scheduler/priority.hpp index 8cdeac02c..0e901de99 100644 --- a/nano/node/scheduler/priority.hpp +++ b/nano/node/scheduler/priority.hpp @@ -26,7 +26,7 @@ public: class priority final { public: - priority (nano::node_config &, nano::node &, nano::ledger &, nano::block_processor &, nano::active_elections &, nano::stats &, nano::logger &); + priority (nano::node_config &, nano::node &, nano::ledger &, nano::block_processor &, nano::active_elections &, nano::confirming_set &, nano::stats &, nano::logger &); ~priority (); void start (); @@ -36,8 +36,9 @@ public: * Activates the first unconfirmed block of \p account_a * @return true if account was activated */ - bool activate (secure::transaction const &, nano::account const &); - bool activate (secure::transaction const &, nano::account const &, nano::account_info const &, nano::confirmation_height_info const &); + bool activate (nano::secure::transaction const &, nano::account const &); + bool activate (nano::secure::transaction const &, nano::account const &, nano::account_info const &, nano::confirmation_height_info const &); + bool activate_successors (nano::secure::transaction const &, nano::block const &); void notify (); std::size_t size () const; @@ -51,6 +52,7 @@ private: // Dependencies nano::ledger & ledger; nano::block_processor & block_processor; nano::active_elections & active; + nano::confirming_set & confirming_set; nano::stats & stats; nano::logger & logger; From b6efeb699ad4329c1b4824d96f2dadab60fa0b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:57:58 +0200 Subject: [PATCH 11/48] Cleanup --- nano/node/active_elections.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/nano/node/active_elections.cpp b/nano/node/active_elections.cpp index c161038e4..6536b2c47 100644 --- a/nano/node/active_elections.cpp +++ b/nano/node/active_elections.cpp @@ -29,6 +29,7 @@ nano::active_elections::active_elections (nano::node & node_a, nano::confirming_ { count_by_behavior.fill (0); // Zero initialize array + // Cementing blocks might implicitly confirm dependent elections confirming_set.batch_cemented.add ([this] (auto const & cemented) { auto transaction = node.ledger.tx_begin_read (); for (auto const & [block, confirmation_root, source_election] : cemented) @@ -39,10 +40,13 @@ nano::active_elections::active_elections (nano::node & node_a, nano::confirming_ }); // Notify elections about alternative (forked) blocks - block_processor.block_processed.add ([this] (auto const & result, auto const & context) { - if (result == nano::block_status::fork) + block_processor.batch_processed.add ([this] (auto const & batch) { + for (auto const & [result, context] : batch) { - publish (context.block); + if (result == nano::block_status::fork) + { + publish (context.block); + } } }); } From 82d9d2d323abf2821032b7d88d21b3369957b814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:17:04 +0200 Subject: [PATCH 12/48] Process cemented elections with exclusive lock to avoid races --- nano/node/active_elections.cpp | 42 +++++++++++++++++++++++++--------- nano/node/active_elections.hpp | 12 ++++++---- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/nano/node/active_elections.cpp b/nano/node/active_elections.cpp index 6536b2c47..4d8c953f5 100644 --- a/nano/node/active_elections.cpp +++ b/nano/node/active_elections.cpp @@ -31,11 +31,24 @@ nano::active_elections::active_elections (nano::node & node_a, nano::confirming_ // Cementing blocks might implicitly confirm dependent elections confirming_set.batch_cemented.add ([this] (auto const & cemented) { - auto transaction = node.ledger.tx_begin_read (); - for (auto const & [block, confirmation_root, source_election] : cemented) + std::deque results; { - transaction.refresh_if_needed (); - block_cemented (transaction, block, confirmation_root, source_election); + // Process all cemented blocks while holding the lock to avoid races where an election for a block that is already cemented is inserted + nano::lock_guard guard{ mutex }; + for (auto const & [block, confirmation_root, source_election] : cemented) + { + auto result = block_cemented (block, confirmation_root, source_election); + results.push_back (result); + } + } + { + // TODO: This could be offloaded to a separate notification worker, profiling is needed + auto transaction = node.ledger.tx_begin_read (); + for (auto const & [status, votes] : results) + { + transaction.refresh_if_needed (); + notify_observers (transaction, status, votes); + } } }); @@ -83,16 +96,17 @@ void nano::active_elections::stop () clear (); } -void nano::active_elections::block_cemented (nano::secure::transaction const & transaction, std::shared_ptr const & block, nano::block_hash const & confirmation_root, std::shared_ptr const & source_election) +auto nano::active_elections::block_cemented (std::shared_ptr const & block, nano::block_hash const & confirmation_root, std::shared_ptr const & source_election) -> block_cemented_result { + debug_assert (!mutex.try_lock ()); debug_assert (node.block_confirmed (block->hash ())); // Dependent elections are implicitly confirmed when their block is cemented - auto dependend_election = election (block->qualified_root ()); + auto dependend_election = election_impl (block->qualified_root ()); if (dependend_election) { node.stats.inc (nano::stat::type::active_elections, nano::stat::detail::confirm_dependent); - dependend_election->try_confirm (block->hash ()); + dependend_election->try_confirm (block->hash ()); // TODO: This should either confirm or cancel the election } nano::election_status status; @@ -126,7 +140,7 @@ void nano::active_elections::block_cemented (nano::secure::transaction const & t nano::log::arg{ "confirmation_root", confirmation_root }, nano::log::arg{ "source_election", source_election }); - notify_observers (transaction, status, votes); + return { status, votes }; } void nano::active_elections::notify_observers (nano::secure::transaction const & transaction, nano::election_status const & status, std::vector const & votes) const @@ -443,11 +457,17 @@ bool nano::active_elections::active (nano::block const & block_a) const return roots.get ().find (block_a.qualified_root ()) != roots.get ().end (); } -std::shared_ptr nano::active_elections::election (nano::qualified_root const & root_a) const +std::shared_ptr nano::active_elections::election (nano::qualified_root const & root) const { - std::shared_ptr result; nano::lock_guard lock{ mutex }; - auto existing = roots.get ().find (root_a); + return election_impl (root); +} + +std::shared_ptr nano::active_elections::election_impl (nano::qualified_root const & root) const +{ + debug_assert (!mutex.try_lock ()); + std::shared_ptr result; + auto existing = roots.get ().find (root); if (existing != roots.get ().end ()) { result = existing->election; diff --git a/nano/node/active_elections.hpp b/nano/node/active_elections.hpp index 049f41428..8b831112b 100644 --- a/nano/node/active_elections.hpp +++ b/nano/node/active_elections.hpp @@ -105,7 +105,7 @@ public: bool active (nano::qualified_root const &) const; std::shared_ptr election (nano::qualified_root const &) const; // Returns a list of elections sorted by difficulty - std::vector> list_active (std::size_t = std::numeric_limits::max ()); + std::vector> list_active (std::size_t max_count = std::numeric_limits::max ()); bool erase (nano::block const &); bool erase (nano::qualified_root const &); bool empty () const; @@ -133,11 +133,13 @@ private: void request_confirm (nano::unique_lock &); // Erase all blocks from active and, if not confirmed, clear digests from network filters void cleanup_election (nano::unique_lock & lock_a, std::shared_ptr); - nano::stat::type completion_type (nano::election const & election) const; - // Returns a list of elections sorted by difficulty, mutex must be locked - std::vector> list_active_impl (std::size_t) const; + + using block_cemented_result = std::pair>; + block_cemented_result block_cemented (std::shared_ptr const & block, nano::block_hash const & confirmation_root, std::shared_ptr const & source_election); void notify_observers (nano::secure::transaction const &, nano::election_status const & status, std::vector const & votes) const; - void block_cemented (nano::secure::transaction const &, std::shared_ptr const & block, nano::block_hash const & confirmation_root, std::shared_ptr const & source_election); + + std::shared_ptr election_impl (nano::qualified_root const &) const; + std::vector> list_active_impl (std::size_t max_count) const; private: // Dependencies active_elections_config const & config; From d78f53927d221ddbb4e9ab0ff16b98a6d00c5317 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Thu, 10 Oct 2024 13:19:54 +0200 Subject: [PATCH 13/48] Remove unnecessary FQNs --- nano/store/iterator_impl.hpp | 10 +++--- nano/store/lmdb/iterator.hpp | 54 ++++++++++++++++----------------- nano/store/rocksdb/iterator.hpp | 20 ++++++------ 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/nano/store/iterator_impl.hpp b/nano/store/iterator_impl.hpp index 48130d14e..8daf89ead 100644 --- a/nano/store/iterator_impl.hpp +++ b/nano/store/iterator_impl.hpp @@ -11,14 +11,14 @@ template class iterator_impl { public: - explicit iterator_impl (nano::store::transaction const & transaction_a) : - transaction{ transaction_a }, + explicit iterator_impl (transaction const & transaction_a) : + txn{ transaction_a }, transaction_epoch{ transaction_a.epoch () } { } virtual ~iterator_impl () { - debug_assert (transaction_epoch == transaction.epoch (), "invalid iterator-transaction lifetime detected"); + debug_assert (transaction_epoch == txn.epoch (), "invalid iterator-transaction lifetime detected"); } virtual iterator_impl & operator++ () = 0; @@ -37,7 +37,7 @@ public: } protected: - nano::store::transaction const & transaction; - nano::store::transaction::epoch_t const transaction_epoch; + transaction const & txn; + transaction::epoch_t const transaction_epoch; }; } diff --git a/nano/store/lmdb/iterator.hpp b/nano/store/lmdb/iterator.hpp index 3c2fe197c..621d69808 100644 --- a/nano/store/lmdb/iterator.hpp +++ b/nano/store/lmdb/iterator.hpp @@ -14,8 +14,8 @@ template class iterator : public iterator_impl { public: - iterator (store::transaction const & transaction_a, env const & env_a, MDB_dbi db_a, MDB_val const & val_a = MDB_val{}, bool const direction_asc = true) : - nano::store::iterator_impl (transaction_a) + iterator (transaction const & transaction_a, env const & env_a, MDB_dbi db_a, MDB_val const & val_a = MDB_val{}, bool const direction_asc = true) : + iterator_impl (transaction_a) { auto status (mdb_cursor_open (env_a.tx (transaction_a), db_a, &cursor)); release_assert (status == 0); @@ -47,14 +47,14 @@ public: iterator () = default; - iterator (nano::store::lmdb::iterator && other_a) + iterator (iterator && other_a) { cursor = other_a.cursor; other_a.cursor = nullptr; current = other_a.current; } - iterator (nano::store::lmdb::iterator const &) = delete; + iterator (iterator const &) = delete; ~iterator () { @@ -64,7 +64,7 @@ public: } } - store::iterator_impl & operator++ () override + iterator_impl & operator++ () override { debug_assert (cursor != nullptr); auto status (mdb_cursor_get (cursor, ¤t.first.value, ¤t.second.value, MDB_NEXT)); @@ -80,7 +80,7 @@ public: return *this; } - store::iterator_impl & operator-- () override + iterator_impl & operator-- () override { debug_assert (cursor != nullptr); auto status (mdb_cursor_get (cursor, ¤t.first.value, ¤t.second.value, MDB_PREV)); @@ -101,9 +101,9 @@ public: return ¤t; } - bool operator== (nano::store::lmdb::iterator const & base_a) const + bool operator== (iterator const & base_a) const { - auto const other_a (boost::polymorphic_downcast const *> (&base_a)); + auto const other_a (boost::polymorphic_downcast const *> (&base_a)); auto result (current.first.data () == other_a->current.first.data ()); debug_assert (!result || (current.first.size () == other_a->current.first.size ())); debug_assert (!result || (current.second.data () == other_a->current.second.data ())); @@ -111,9 +111,9 @@ public: return result; } - bool operator== (store::iterator_impl const & base_a) const override + bool operator== (iterator_impl const & base_a) const override { - auto const other_a (boost::polymorphic_downcast const *> (&base_a)); + auto const other_a (boost::polymorphic_downcast const *> (&base_a)); auto result (current.first.data () == other_a->current.first.data ()); debug_assert (!result || (current.first.size () == other_a->current.first.size ())); debug_assert (!result || (current.second.data () == other_a->current.second.data ())); @@ -151,7 +151,7 @@ public: debug_assert (is_end_sentinal ()); } - nano::store::lmdb::iterator & operator= (nano::store::lmdb::iterator && other_a) + iterator & operator= (iterator && other_a) { if (cursor != nullptr) { @@ -164,7 +164,7 @@ public: return *this; } - store::iterator_impl & operator= (store::iterator_impl const &) = delete; + iterator_impl & operator= (iterator_impl const &) = delete; MDB_cursor * cursor{ nullptr }; std::pair, store::db_val> current; }; @@ -176,21 +176,21 @@ template class merge_iterator : public iterator_impl { public: - merge_iterator (store::transaction const & transaction_a, MDB_dbi db1_a, MDB_dbi db2_a) : - impl1 (std::make_unique> (transaction_a, db1_a)), - impl2 (std::make_unique> (transaction_a, db2_a)) + merge_iterator (transaction const & transaction_a, MDB_dbi db1_a, MDB_dbi db2_a) : + impl1 (std::make_unique> (transaction_a, db1_a)), + impl2 (std::make_unique> (transaction_a, db2_a)) { } merge_iterator () : - impl1 (std::make_unique> ()), - impl2 (std::make_unique> ()) + impl1 (std::make_unique> ()), + impl2 (std::make_unique> ()) { } - merge_iterator (store::transaction const & transaction_a, MDB_dbi db1_a, MDB_dbi db2_a, MDB_val const & val_a) : - impl1 (std::make_unique> (transaction_a, db1_a, val_a)), - impl2 (std::make_unique> (transaction_a, db2_a, val_a)) + merge_iterator (transaction const & transaction_a, MDB_dbi db1_a, MDB_dbi db2_a, MDB_val const & val_a) : + impl1 (std::make_unique> (transaction_a, db1_a, val_a)), + impl2 (std::make_unique> (transaction_a, db2_a, val_a)) { } @@ -202,13 +202,13 @@ public: merge_iterator (merge_iterator const &) = delete; - store::iterator_impl & operator++ () override + iterator_impl & operator++ () override { ++least_iterator (); return *this; } - store::iterator_impl & operator-- () override + iterator_impl & operator-- () override { --least_iterator (); return *this; @@ -229,7 +229,7 @@ public: return !(*this == base_a); } - bool operator== (store::iterator_impl const & base_a) const override + bool operator== (iterator_impl const & base_a) const override { debug_assert ((dynamic_cast const *> (&base_a) != nullptr) && "Incompatible iterator comparison"); auto & other (static_cast const &> (base_a)); @@ -267,9 +267,9 @@ public: mutable bool from_first_database{ false }; private: - nano::store::lmdb::iterator & least_iterator () const + iterator & least_iterator () const { - nano::store::lmdb::iterator * result; + iterator * result; if (impl1->is_end_sentinal ()) { result = impl2.get (); @@ -304,7 +304,7 @@ private: return *result; } - std::unique_ptr> impl1; - std::unique_ptr> impl2; + std::unique_ptr> impl1; + std::unique_ptr> impl2; }; } diff --git a/nano/store/rocksdb/iterator.hpp b/nano/store/rocksdb/iterator.hpp index b661c8af6..99fc9a9c5 100644 --- a/nano/store/rocksdb/iterator.hpp +++ b/nano/store/rocksdb/iterator.hpp @@ -33,8 +33,8 @@ class iterator : public iterator_impl public: iterator () = default; - iterator (::rocksdb::DB * db, store::transaction const & transaction_a, ::rocksdb::ColumnFamilyHandle * handle_a, db_val const * val_a, bool const direction_asc) : - nano::store::iterator_impl (transaction_a) + iterator (::rocksdb::DB * db, transaction const & transaction_a, ::rocksdb::ColumnFamilyHandle * handle_a, db_val const * val_a, bool const direction_asc) : + iterator_impl (transaction_a) { // Don't fill the block cache for any blocks read as a result of an iterator if (is_read (transaction_a)) @@ -79,16 +79,16 @@ public: { } - iterator (nano::store::rocksdb::iterator && other_a) + iterator (iterator && other_a) { cursor = other_a.cursor; other_a.cursor = nullptr; current = other_a.current; } - iterator (nano::store::rocksdb::iterator const &) = delete; + iterator (iterator const &) = delete; - store::iterator_impl & operator++ () override + iterator_impl & operator++ () override { cursor->Next (); if (cursor->Valid ()) @@ -109,7 +109,7 @@ public: return *this; } - store::iterator_impl & operator-- () override + iterator_impl & operator-- () override { cursor->Prev (); if (cursor->Valid ()) @@ -135,9 +135,9 @@ public: return ¤t; } - bool operator== (store::iterator_impl const & base_a) const override + bool operator== (iterator_impl const & base_a) const override { - auto const other_a (boost::polymorphic_downcast const *> (&base_a)); + auto const other_a (boost::polymorphic_downcast const *> (&base_a)); if (!current.first.data () && !other_a->current.first.data ()) { @@ -187,13 +187,13 @@ public: current.second = nano::store::rocksdb::db_val{}; debug_assert (is_end_sentinal ()); } - nano::store::rocksdb::iterator & operator= (nano::store::rocksdb::iterator && other_a) + iterator & operator= (iterator && other_a) { cursor = std::move (other_a.cursor); current = other_a.current; return *this; } - store::iterator_impl & operator= (store::iterator_impl const &) = delete; + iterator_impl & operator= (iterator_impl const &) = delete; std::unique_ptr<::rocksdb::Iterator> cursor; std::pair current; From 635740a512bd066c5d6db9dc51b208051e6af031 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Thu, 10 Oct 2024 14:28:29 +0200 Subject: [PATCH 14/48] Adding type aliases to store classes. --- nano/node/wallet.cpp | 17 +++++++++-------- nano/node/wallet.hpp | 11 +++++++---- nano/store/CMakeLists.txt | 1 + nano/store/account.hpp | 13 ++++++++----- nano/store/block.hpp | 11 +++++++---- nano/store/confirmation_height.hpp | 11 +++++++---- nano/store/final.hpp | 11 +++++++---- nano/store/lmdb/account.cpp | 12 ++++++------ nano/store/lmdb/account.hpp | 10 +++++----- nano/store/lmdb/block.cpp | 11 ++++++----- nano/store/lmdb/block.hpp | 8 ++++---- nano/store/lmdb/confirmation_height.cpp | 10 +++++----- nano/store/lmdb/confirmation_height.hpp | 8 ++++---- nano/store/lmdb/final_vote.cpp | 10 +++++----- nano/store/lmdb/final_vote.hpp | 8 ++++---- nano/store/lmdb/online_weight.cpp | 8 ++++---- nano/store/lmdb/online_weight.hpp | 6 +++--- nano/store/lmdb/peer.cpp | 6 +++--- nano/store/lmdb/peer.hpp | 4 ++-- nano/store/lmdb/pending.cpp | 10 +++++----- nano/store/lmdb/pending.hpp | 8 ++++---- nano/store/lmdb/pruned.cpp | 10 +++++----- nano/store/lmdb/pruned.hpp | 8 ++++---- nano/store/lmdb/rep_weight.cpp | 10 +++++----- nano/store/lmdb/rep_weight.hpp | 8 ++++---- nano/store/online_weight.hpp | 9 ++++++--- nano/store/peer.hpp | 7 +++++-- nano/store/pending.hpp | 8 ++++---- nano/store/pruned.hpp | 11 +++++++---- nano/store/rep_weight.hpp | 11 +++++++---- nano/store/rocksdb/account.cpp | 12 ++++++------ nano/store/rocksdb/account.hpp | 10 +++++----- nano/store/rocksdb/block.cpp | 17 ++++++++++++----- nano/store/rocksdb/block.hpp | 8 ++++---- nano/store/rocksdb/confirmation_height.cpp | 10 +++++----- nano/store/rocksdb/confirmation_height.hpp | 8 ++++---- nano/store/rocksdb/final_vote.cpp | 10 +++++----- nano/store/rocksdb/final_vote.hpp | 8 ++++---- nano/store/rocksdb/online_weight.cpp | 8 ++++---- nano/store/rocksdb/online_weight.hpp | 6 +++--- nano/store/rocksdb/peer.cpp | 6 +++--- nano/store/rocksdb/peer.hpp | 4 ++-- nano/store/rocksdb/pending.cpp | 10 +++++----- nano/store/rocksdb/pending.hpp | 8 ++++---- nano/store/rocksdb/pruned.cpp | 10 +++++----- nano/store/rocksdb/pruned.hpp | 8 ++++---- nano/store/rocksdb/rep_weight.cpp | 12 ++++++------ nano/store/rocksdb/rep_weight.hpp | 8 ++++---- 48 files changed, 238 insertions(+), 201 deletions(-) diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index 716f78ee2..a1f46c78f 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1753,22 +1753,22 @@ std::unordered_map> nano::wallets nano::uint128_t const nano::wallets::generate_priority = std::numeric_limits::max (); nano::uint128_t const nano::wallets::high_priority = std::numeric_limits::max () - 1; -nano::store::iterator nano::wallet_store::begin (store::transaction const & transaction_a) +auto nano::wallet_store::begin (store::transaction const & transaction_a) -> iterator { - store::iterator result (std::make_unique> (transaction_a, env, handle, nano::store::lmdb::db_val (nano::account (special_count)))); + iterator result (std::make_unique> (transaction_a, env, handle, nano::store::lmdb::db_val (nano::account (special_count)))); return result; } -nano::store::iterator nano::wallet_store::begin (store::transaction const & transaction_a, nano::account const & key) +auto nano::wallet_store::begin (store::transaction const & transaction_a, nano::account const & key) -> iterator { - store::iterator result (std::make_unique> (transaction_a, env, handle, nano::store::lmdb::db_val (key))); + iterator result (std::make_unique> (transaction_a, env, handle, nano::store::lmdb::db_val (key))); return result; } -nano::store::iterator nano::wallet_store::find (store::transaction const & transaction_a, nano::account const & key) +auto nano::wallet_store::find (store::transaction const & transaction_a, nano::account const & key) -> iterator { auto result (begin (transaction_a, key)); - store::iterator end (nullptr); + iterator end{ nullptr }; if (result != end) { if (result->first == key) @@ -1787,10 +1787,11 @@ nano::store::iterator nano::wallet_store::fin return result; } -nano::store::iterator nano::wallet_store::end () +auto nano::wallet_store::end () -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } + nano::mdb_wallets_store::mdb_wallets_store (std::filesystem::path const & path_a, nano::lmdb_config const & lmdb_config_a) : environment (error, path_a, nano::store::lmdb::env::options::make ().set_config (lmdb_config_a).override_config_sync (nano::lmdb_config::sync_strategy::always).override_config_map_size (1ULL * 1024 * 1024 * 1024)) { diff --git a/nano/node/wallet.hpp b/nano/node/wallet.hpp index 7ef86efba..ef26f4b0b 100644 --- a/nano/node/wallet.hpp +++ b/nano/node/wallet.hpp @@ -57,6 +57,9 @@ enum class key_type class wallet_store final { +public: + using iterator = store::iterator; + public: wallet_store (bool &, nano::kdf &, store::transaction &, store::lmdb::env &, nano::account, unsigned, std::string const &); wallet_store (bool &, nano::kdf &, store::transaction &, store::lmdb::env &, nano::account, unsigned, std::string const &, std::string const &); @@ -89,10 +92,10 @@ public: bool fetch (store::transaction const &, nano::account const &, nano::raw_key &); bool exists (store::transaction const &, nano::account const &); void destroy (store::transaction const &); - store::iterator find (store::transaction const &, nano::account const &); - store::iterator begin (store::transaction const &, nano::account const &); - store::iterator begin (store::transaction const &); - store::iterator end (); + iterator find (store::transaction const &, nano::account const &); + iterator begin (store::transaction const &, nano::account const &); + iterator begin (store::transaction const &); + iterator end (); void derive_key (nano::raw_key &, store::transaction const &, std::string const &); void serialize_json (store::transaction const &, std::string &); void write_backup (store::transaction const &, std::filesystem::path const &); diff --git a/nano/store/CMakeLists.txt b/nano/store/CMakeLists.txt index 19ae4cf2e..c44d7fc0d 100644 --- a/nano/store/CMakeLists.txt +++ b/nano/store/CMakeLists.txt @@ -32,6 +32,7 @@ add_library( peer.hpp pending.hpp pruned.hpp + rep_weight.hpp rocksdb/account.hpp rocksdb/block.hpp rocksdb/confirmation_height.hpp diff --git a/nano/store/account.hpp b/nano/store/account.hpp index 749cd9c84..ffa05de08 100644 --- a/nano/store/account.hpp +++ b/nano/store/account.hpp @@ -19,6 +19,9 @@ namespace nano::store */ class account { +public: + using iterator = store::iterator; + public: virtual void put (store::write_transaction const &, nano::account const &, nano::account_info const &) = 0; virtual bool get (store::transaction const &, nano::account const &, nano::account_info &) = 0; @@ -26,10 +29,10 @@ public: virtual void del (store::write_transaction const &, nano::account const &) = 0; virtual bool exists (store::transaction const &, nano::account const &) = 0; virtual size_t count (store::transaction const &) = 0; - virtual iterator begin (store::transaction const &, nano::account const &) const = 0; - virtual iterator begin (store::transaction const &) const = 0; - virtual iterator rbegin (store::transaction const &) const = 0; - virtual iterator end () const = 0; - virtual void for_each_par (std::function, iterator)> const &) const = 0; + virtual iterator begin (store::transaction const &, nano::account const &) const = 0; + virtual iterator begin (store::transaction const &) const = 0; + virtual iterator rbegin (store::transaction const &) const = 0; + virtual iterator end () const = 0; + virtual void for_each_par (std::function const &) const = 0; }; } // namespace nano::store diff --git a/nano/store/block.hpp b/nano/store/block.hpp index 17f92669d..acd2ba72f 100644 --- a/nano/store/block.hpp +++ b/nano/store/block.hpp @@ -21,6 +21,9 @@ namespace nano::store */ class block { +public: + using iterator = store::iterator; + public: virtual void put (store::write_transaction const &, nano::block_hash const &, nano::block const &) = 0; virtual void raw_put (store::write_transaction const &, std::vector const &, nano::block_hash const &) = 0; @@ -31,9 +34,9 @@ public: virtual void del (store::write_transaction const &, nano::block_hash const &) = 0; virtual bool exists (store::transaction const &, nano::block_hash const &) = 0; virtual uint64_t count (store::transaction const &) = 0; - virtual iterator begin (store::transaction const &, nano::block_hash const &) const = 0; - virtual iterator begin (store::transaction const &) const = 0; - virtual iterator end () const = 0; - virtual void for_each_par (std::function, iterator)> const & action_a) const = 0; + virtual iterator begin (store::transaction const &, nano::block_hash const &) const = 0; + virtual iterator begin (store::transaction const &) const = 0; + virtual iterator end () const = 0; + virtual void for_each_par (std::function const & action_a) const = 0; }; } // namespace nano::store diff --git a/nano/store/confirmation_height.hpp b/nano/store/confirmation_height.hpp index f0cb5ee73..5569bec7c 100644 --- a/nano/store/confirmation_height.hpp +++ b/nano/store/confirmation_height.hpp @@ -17,6 +17,9 @@ namespace nano::store */ class confirmation_height { +public: + using iterator = store::iterator; + public: virtual void put (store::write_transaction const & transaction_a, nano::account const & account_a, nano::confirmation_height_info const & confirmation_height_info_a) = 0; @@ -32,9 +35,9 @@ public: virtual uint64_t count (store::transaction const & transaction_a) = 0; virtual void clear (store::write_transaction const &, nano::account const &) = 0; virtual void clear (store::write_transaction const &) = 0; - virtual iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const = 0; - virtual iterator begin (store::transaction const & transaction_a) const = 0; - virtual iterator end () const = 0; - virtual void for_each_par (std::function, iterator)> const &) const = 0; + virtual iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const = 0; + virtual iterator begin (store::transaction const & transaction_a) const = 0; + virtual iterator end () const = 0; + virtual void for_each_par (std::function const &) const = 0; }; } // namespace nano::store diff --git a/nano/store/final.hpp b/nano/store/final.hpp index 1b9f15995..677159dda 100644 --- a/nano/store/final.hpp +++ b/nano/store/final.hpp @@ -17,6 +17,9 @@ namespace nano::store */ class final_vote { +public: + using iterator = store::iterator; + public: virtual bool put (store::write_transaction const & transaction_a, nano::qualified_root const & root_a, nano::block_hash const & hash_a) = 0; virtual std::vector get (store::transaction const & transaction_a, nano::root const & root_a) = 0; @@ -24,9 +27,9 @@ public: virtual size_t count (store::transaction const & transaction_a) const = 0; virtual void clear (store::write_transaction const &, nano::root const &) = 0; virtual void clear (store::write_transaction const &) = 0; - virtual store::iterator begin (store::transaction const & transaction_a, nano::qualified_root const & root_a) const = 0; - virtual store::iterator begin (store::transaction const & transaction_a) const = 0; - virtual store::iterator end () const = 0; - virtual void for_each_par (std::function, store::iterator)> const & action_a) const = 0; + virtual iterator begin (store::transaction const & transaction_a, nano::qualified_root const & root_a) const = 0; + virtual iterator begin (store::transaction const & transaction_a) const = 0; + virtual iterator end () const = 0; + virtual void for_each_par (std::function const & action_a) const = 0; }; } // namespace nano::store diff --git a/nano/store/lmdb/account.cpp b/nano/store/lmdb/account.cpp index 19a35c8e4..e01ce6236 100644 --- a/nano/store/lmdb/account.cpp +++ b/nano/store/lmdb/account.cpp @@ -43,27 +43,27 @@ size_t nano::store::lmdb::account::count (store::transaction const & transaction return store.count (transaction_a, tables::accounts); } -nano::store::iterator nano::store::lmdb::account::begin (store::transaction const & transaction, nano::account const & account) const +auto nano::store::lmdb::account::begin (store::transaction const & transaction, nano::account const & account) const -> iterator { return store.make_iterator (transaction, tables::accounts, account); } -nano::store::iterator nano::store::lmdb::account::begin (store::transaction const & transaction) const +auto nano::store::lmdb::account::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::accounts); } -nano::store::iterator nano::store::lmdb::account::rbegin (store::transaction const & transaction_a) const +auto nano::store::lmdb::account::rbegin (store::transaction const & transaction_a) const -> iterator { return store.make_iterator (transaction_a, tables::accounts, false); } -nano::store::iterator nano::store::lmdb::account::end () const +auto nano::store::lmdb::account::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::lmdb::account::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::lmdb::account::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { diff --git a/nano/store/lmdb/account.hpp b/nano/store/lmdb/account.hpp index 6faaf3cfe..6650f19fc 100644 --- a/nano/store/lmdb/account.hpp +++ b/nano/store/lmdb/account.hpp @@ -22,11 +22,11 @@ public: void del (store::write_transaction const & transaction_a, nano::account const & account_a) override; bool exists (store::transaction const & transaction_a, nano::account const & account_a) override; size_t count (store::transaction const & transaction_a) override; - store::iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator rbegin (store::transaction const & transaction_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator rbegin (store::transaction const & transaction_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; /** * Maps account v1 to account information, head, rep, open, balance, timestamp and block count. (Removed) diff --git a/nano/store/lmdb/block.cpp b/nano/store/lmdb/block.cpp index 9d3e308ab..461e0b99f 100644 --- a/nano/store/lmdb/block.cpp +++ b/nano/store/lmdb/block.cpp @@ -134,22 +134,23 @@ uint64_t nano::store::lmdb::block::count (store::transaction const & transaction { return store.count (transaction_a, tables::blocks); } -nano::store::iterator nano::store::lmdb::block::begin (store::transaction const & transaction) const + +auto nano::store::lmdb::block::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::blocks); } -nano::store::iterator nano::store::lmdb::block::begin (store::transaction const & transaction, nano::block_hash const & hash) const +auto nano::store::lmdb::block::begin (store::transaction const & transaction, nano::block_hash const & hash) const -> iterator { return store.make_iterator (transaction, tables::blocks, hash); } -nano::store::iterator nano::store::lmdb::block::end () const +auto nano::store::lmdb::block::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::lmdb::block::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::lmdb::block::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { diff --git a/nano/store/lmdb/block.hpp b/nano/store/lmdb/block.hpp index 575803d83..259494511 100644 --- a/nano/store/lmdb/block.hpp +++ b/nano/store/lmdb/block.hpp @@ -31,10 +31,10 @@ public: void del (store::write_transaction const & transaction_a, nano::block_hash const & hash_a) override; bool exists (store::transaction const & transaction_a, nano::block_hash const & hash_a) override; uint64_t count (store::transaction const & transaction_a) override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; /** * Contains block_sideband and block for all block types (legacy send/change/open/receive & state blocks) diff --git a/nano/store/lmdb/confirmation_height.cpp b/nano/store/lmdb/confirmation_height.cpp index 1ce01edab..234c56844 100644 --- a/nano/store/lmdb/confirmation_height.cpp +++ b/nano/store/lmdb/confirmation_height.cpp @@ -59,22 +59,22 @@ void nano::store::lmdb::confirmation_height::clear (store::write_transaction con store.drop (transaction_a, nano::tables::confirmation_height); } -nano::store::iterator nano::store::lmdb::confirmation_height::begin (store::transaction const & transaction, nano::account const & account) const +auto nano::store::lmdb::confirmation_height::begin (store::transaction const & transaction, nano::account const & account) const -> iterator { return store.make_iterator (transaction, tables::confirmation_height, account); } -nano::store::iterator nano::store::lmdb::confirmation_height::begin (store::transaction const & transaction) const +auto nano::store::lmdb::confirmation_height::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::confirmation_height); } -nano::store::iterator nano::store::lmdb::confirmation_height::end () const +auto nano::store::lmdb::confirmation_height::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::lmdb::confirmation_height::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::lmdb::confirmation_height::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { diff --git a/nano/store/lmdb/confirmation_height.hpp b/nano/store/lmdb/confirmation_height.hpp index 4674f8113..de3532459 100644 --- a/nano/store/lmdb/confirmation_height.hpp +++ b/nano/store/lmdb/confirmation_height.hpp @@ -23,10 +23,10 @@ public: uint64_t count (store::transaction const & transaction_a) override; void clear (store::write_transaction const & transaction_a, nano::account const & account_a) override; void clear (store::write_transaction const & transaction_a) override; - store::iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; /* * Confirmation height of an account, and the hash for the block at that height diff --git a/nano/store/lmdb/final_vote.cpp b/nano/store/lmdb/final_vote.cpp index 2ae93bd5a..a26153d1f 100644 --- a/nano/store/lmdb/final_vote.cpp +++ b/nano/store/lmdb/final_vote.cpp @@ -64,22 +64,22 @@ void nano::store::lmdb::final_vote::clear (store::write_transaction const & tran store.drop (transaction_a, nano::tables::final_votes); } -nano::store::iterator nano::store::lmdb::final_vote::begin (store::transaction const & transaction, nano::qualified_root const & root) const +auto nano::store::lmdb::final_vote::begin (store::transaction const & transaction, nano::qualified_root const & root) const -> iterator { return store.make_iterator (transaction, tables::final_votes, root); } -nano::store::iterator nano::store::lmdb::final_vote::begin (store::transaction const & transaction) const +auto nano::store::lmdb::final_vote::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::final_votes); } -nano::store::iterator nano::store::lmdb::final_vote::end () const +auto nano::store::lmdb::final_vote::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::lmdb::final_vote::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::lmdb::final_vote::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { diff --git a/nano/store/lmdb/final_vote.hpp b/nano/store/lmdb/final_vote.hpp index 92fc5253f..896ab5d6a 100644 --- a/nano/store/lmdb/final_vote.hpp +++ b/nano/store/lmdb/final_vote.hpp @@ -23,10 +23,10 @@ public: size_t count (store::transaction const & transaction_a) const override; void clear (store::write_transaction const & transaction_a, nano::root const & root_a) override; void clear (store::write_transaction const & transaction_a) override; - store::iterator begin (store::transaction const & transaction_a, nano::qualified_root const & root_a) const override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a, nano::qualified_root const & root_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; /** * Maps root to block hash for generated final votes. diff --git a/nano/store/lmdb/online_weight.cpp b/nano/store/lmdb/online_weight.cpp index 647aaf34d..c9e553a09 100644 --- a/nano/store/lmdb/online_weight.cpp +++ b/nano/store/lmdb/online_weight.cpp @@ -18,19 +18,19 @@ void nano::store::lmdb::online_weight::del (store::write_transaction const & tra store.release_assert_success (status); } -nano::store::iterator nano::store::lmdb::online_weight::begin (store::transaction const & transaction) const +auto nano::store::lmdb::online_weight::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::online_weight); } -nano::store::iterator nano::store::lmdb::online_weight::rbegin (store::transaction const & transaction) const +auto nano::store::lmdb::online_weight::rbegin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::online_weight, false); } -nano::store::iterator nano::store::lmdb::online_weight::end () const +auto nano::store::lmdb::online_weight::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } size_t nano::store::lmdb::online_weight::count (store::transaction const & transaction) const diff --git a/nano/store/lmdb/online_weight.hpp b/nano/store/lmdb/online_weight.hpp index 0567c63d9..fe2810351 100644 --- a/nano/store/lmdb/online_weight.hpp +++ b/nano/store/lmdb/online_weight.hpp @@ -15,9 +15,9 @@ public: explicit online_weight (nano::store::lmdb::component & store_a); void put (store::write_transaction const & transaction_a, uint64_t time_a, nano::amount const & amount_a) override; void del (store::write_transaction const & transaction_a, uint64_t time_a) override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator rbegin (store::transaction const & transaction_a) const override; - store::iterator end () const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator rbegin (store::transaction const & transaction_a) const override; + iterator end () const override; size_t count (store::transaction const & transaction_a) const override; void clear (store::write_transaction const & transaction_a) override; diff --git a/nano/store/lmdb/peer.cpp b/nano/store/lmdb/peer.cpp index c43412d9d..a91cd3002 100644 --- a/nano/store/lmdb/peer.cpp +++ b/nano/store/lmdb/peer.cpp @@ -45,12 +45,12 @@ void nano::store::lmdb::peer::clear (store::write_transaction const & transactio store.release_assert_success (status); } -nano::store::iterator nano::store::lmdb::peer::begin (store::transaction const & transaction) const +auto nano::store::lmdb::peer::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::peers); } -nano::store::iterator nano::store::lmdb::peer::end () const +auto nano::store::lmdb::peer::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } diff --git a/nano/store/lmdb/peer.hpp b/nano/store/lmdb/peer.hpp index 8197c00be..db39eb512 100644 --- a/nano/store/lmdb/peer.hpp +++ b/nano/store/lmdb/peer.hpp @@ -19,8 +19,8 @@ public: bool exists (store::transaction const &, nano::endpoint_key const & endpoint) const override; size_t count (store::transaction const &) const override; void clear (store::write_transaction const &) override; - store::iterator begin (store::transaction const &) const override; - store::iterator end () const override; + iterator begin (store::transaction const &) const override; + iterator end () const override; /* * Endpoints for peers diff --git a/nano/store/lmdb/pending.cpp b/nano/store/lmdb/pending.cpp index cabb70896..925203d54 100644 --- a/nano/store/lmdb/pending.cpp +++ b/nano/store/lmdb/pending.cpp @@ -45,22 +45,22 @@ bool nano::store::lmdb::pending::any (store::transaction const & transaction_a, return iterator != end () && nano::pending_key (iterator->first).account == account_a; } -nano::store::iterator nano::store::lmdb::pending::begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const +auto nano::store::lmdb::pending::begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const -> iterator { return store.make_iterator (transaction_a, tables::pending, key_a); } -nano::store::iterator nano::store::lmdb::pending::begin (store::transaction const & transaction_a) const +auto nano::store::lmdb::pending::begin (store::transaction const & transaction_a) const -> iterator { return store.make_iterator (transaction_a, tables::pending); } -nano::store::iterator nano::store::lmdb::pending::end () const +auto nano::store::lmdb::pending::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::lmdb::pending::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::lmdb::pending::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { diff --git a/nano/store/lmdb/pending.hpp b/nano/store/lmdb/pending.hpp index 13cd9172d..46b5f7947 100644 --- a/nano/store/lmdb/pending.hpp +++ b/nano/store/lmdb/pending.hpp @@ -22,10 +22,10 @@ public: std::optional get (store::transaction const & transaction_a, nano::pending_key const & key_a) override; bool exists (store::transaction const & transaction_a, nano::pending_key const & key_a) override; bool any (store::transaction const & transaction_a, nano::account const & account_a) override; - store::iterator begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; /** * Maps min_version 0 (destination account, pending block) to (source account, amount). (Removed) diff --git a/nano/store/lmdb/pruned.cpp b/nano/store/lmdb/pruned.cpp index 2be19c24f..30bf1e0b9 100644 --- a/nano/store/lmdb/pruned.cpp +++ b/nano/store/lmdb/pruned.cpp @@ -45,22 +45,22 @@ void nano::store::lmdb::pruned::clear (store::write_transaction const & transact store.release_assert_success (status); } -nano::store::iterator nano::store::lmdb::pruned::begin (store::transaction const & transaction, nano::block_hash const & hash) const +auto nano::store::lmdb::pruned::begin (store::transaction const & transaction, nano::block_hash const & hash) const -> iterator { return store.make_iterator (transaction, tables::pruned, hash); } -nano::store::iterator nano::store::lmdb::pruned::begin (store::transaction const & transaction) const +auto nano::store::lmdb::pruned::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::pruned); } -nano::store::iterator nano::store::lmdb::pruned::end () const +auto nano::store::lmdb::pruned::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::lmdb::pruned::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::lmdb::pruned::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { diff --git a/nano/store/lmdb/pruned.hpp b/nano/store/lmdb/pruned.hpp index 0aa2d7fc2..de1be14a1 100644 --- a/nano/store/lmdb/pruned.hpp +++ b/nano/store/lmdb/pruned.hpp @@ -19,10 +19,10 @@ public: nano::block_hash random (store::transaction const & transaction_a) override; size_t count (store::transaction const & transaction_a) const override; void clear (store::write_transaction const & transaction_a) override; - store::iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; /** * Pruned blocks hashes diff --git a/nano/store/lmdb/rep_weight.cpp b/nano/store/lmdb/rep_weight.cpp index 529efae68..d01d204d5 100644 --- a/nano/store/lmdb/rep_weight.cpp +++ b/nano/store/lmdb/rep_weight.cpp @@ -43,22 +43,22 @@ void nano::store::lmdb::rep_weight::del (store::write_transaction const & txn_a, store.release_assert_success (status); } -nano::store::iterator nano::store::lmdb::rep_weight::begin (store::transaction const & transaction_a, nano::account const & representative_a) const +auto nano::store::lmdb::rep_weight::begin (store::transaction const & transaction_a, nano::account const & representative_a) const -> iterator { return store.make_iterator (transaction_a, tables::rep_weights, representative_a); } -nano::store::iterator nano::store::lmdb::rep_weight::begin (store::transaction const & transaction_a) const +auto nano::store::lmdb::rep_weight::begin (store::transaction const & transaction_a) const -> iterator { return store.make_iterator (transaction_a, tables::rep_weights); } -nano::store::iterator nano::store::lmdb::rep_weight::end () const +auto nano::store::lmdb::rep_weight::end () const -> iterator { - return nano::store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::lmdb::rep_weight::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::lmdb::rep_weight::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { diff --git a/nano/store/lmdb/rep_weight.hpp b/nano/store/lmdb/rep_weight.hpp index 2a6ef53c5..809b23ae2 100644 --- a/nano/store/lmdb/rep_weight.hpp +++ b/nano/store/lmdb/rep_weight.hpp @@ -20,10 +20,10 @@ public: nano::uint128_t get (store::transaction const & txn_a, nano::account const & representative_a) override; void put (store::write_transaction const & txn_a, nano::account const & representative_a, nano::uint128_t const & weight_a) override; void del (store::write_transaction const &, nano::account const & representative_a) override; - store::iterator begin (store::transaction const & transaction_a, nano::account const & representative_a) const override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a, nano::account const & representative_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; /** * Representative weights diff --git a/nano/store/online_weight.hpp b/nano/store/online_weight.hpp index aa17938e8..595a51510 100644 --- a/nano/store/online_weight.hpp +++ b/nano/store/online_weight.hpp @@ -17,12 +17,15 @@ namespace nano::store */ class online_weight { +public: + using iterator = store::iterator; + public: virtual void put (store::write_transaction const &, uint64_t, nano::amount const &) = 0; virtual void del (store::write_transaction const &, uint64_t) = 0; - virtual store::iterator begin (store::transaction const &) const = 0; - virtual store::iterator rbegin (store::transaction const &) const = 0; - virtual store::iterator end () const = 0; + virtual iterator begin (store::transaction const &) const = 0; + virtual iterator rbegin (store::transaction const &) const = 0; + virtual iterator end () const = 0; virtual size_t count (store::transaction const &) const = 0; virtual void clear (store::write_transaction const &) = 0; }; diff --git a/nano/store/peer.hpp b/nano/store/peer.hpp index 82f9a5381..58e3c1d1e 100644 --- a/nano/store/peer.hpp +++ b/nano/store/peer.hpp @@ -17,6 +17,9 @@ namespace nano::store */ class peer { +public: + using iterator = store::iterator; + public: /// Returns true if the peer was inserted, false if it was already in the container virtual void put (store::write_transaction const &, nano::endpoint_key const & endpoint, nano::millis_t timestamp) = 0; @@ -25,7 +28,7 @@ public: virtual bool exists (store::transaction const &, nano::endpoint_key const & endpoint) const = 0; virtual size_t count (store::transaction const &) const = 0; virtual void clear (store::write_transaction const &) = 0; - virtual store::iterator begin (store::transaction const &) const = 0; - virtual store::iterator end () const = 0; + virtual iterator begin (store::transaction const &) const = 0; + virtual iterator end () const = 0; }; } // namespace nano::store diff --git a/nano/store/pending.hpp b/nano/store/pending.hpp index 23272cba7..771bfba5c 100644 --- a/nano/store/pending.hpp +++ b/nano/store/pending.hpp @@ -29,9 +29,9 @@ public: virtual std::optional get (store::transaction const &, nano::pending_key const &) = 0; virtual bool exists (store::transaction const &, nano::pending_key const &) = 0; virtual bool any (store::transaction const &, nano::account const &) = 0; - virtual store::iterator begin (store::transaction const &, nano::pending_key const &) const = 0; - virtual store::iterator begin (store::transaction const &) const = 0; - virtual store::iterator end () const = 0; - virtual void for_each_par (std::function, store::iterator)> const & action_a) const = 0; + virtual iterator begin (store::transaction const &, nano::pending_key const &) const = 0; + virtual iterator begin (store::transaction const &) const = 0; + virtual iterator end () const = 0; + virtual void for_each_par (std::function const & action_a) const = 0; }; } // namespace nano::store diff --git a/nano/store/pruned.hpp b/nano/store/pruned.hpp index cc40c812b..5899c3d0c 100644 --- a/nano/store/pruned.hpp +++ b/nano/store/pruned.hpp @@ -17,6 +17,9 @@ namespace nano::store */ class pruned { +public: + using iterator = store::iterator; + public: virtual void put (store::write_transaction const & transaction_a, nano::block_hash const & hash_a) = 0; virtual void del (store::write_transaction const & transaction_a, nano::block_hash const & hash_a) = 0; @@ -24,9 +27,9 @@ public: virtual nano::block_hash random (store::transaction const & transaction_a) = 0; virtual size_t count (store::transaction const & transaction_a) const = 0; virtual void clear (store::write_transaction const &) = 0; - virtual store::iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const = 0; - virtual store::iterator begin (store::transaction const & transaction_a) const = 0; - virtual store::iterator end () const = 0; - virtual void for_each_par (std::function, store::iterator)> const & action_a) const = 0; + virtual iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const = 0; + virtual iterator begin (store::transaction const & transaction_a) const = 0; + virtual iterator end () const = 0; + virtual void for_each_par (std::function const & action_a) const = 0; }; } // namespace nano::store diff --git a/nano/store/rep_weight.hpp b/nano/store/rep_weight.hpp index 72ac9f84a..5d8fdb80a 100644 --- a/nano/store/rep_weight.hpp +++ b/nano/store/rep_weight.hpp @@ -18,15 +18,18 @@ namespace nano::store */ class rep_weight { +public: + using iterator = store::iterator; + public: virtual ~rep_weight (){}; virtual uint64_t count (store::transaction const & txn_a) = 0; virtual nano::uint128_t get (store::transaction const & txn_a, nano::account const & representative_a) = 0; virtual void put (store::write_transaction const & txn_a, nano::account const & representative_a, nano::uint128_t const & weight_a) = 0; virtual void del (store::write_transaction const &, nano::account const & representative_a) = 0; - virtual store::iterator begin (store::transaction const & transaction_a, nano::account const & representative_a) const = 0; - virtual store::iterator begin (store::transaction const & transaction_a) const = 0; - virtual store::iterator end () const = 0; - virtual void for_each_par (std::function, store::iterator)> const & action_a) const = 0; + virtual iterator begin (store::transaction const & transaction_a, nano::account const & representative_a) const = 0; + virtual iterator begin (store::transaction const & transaction_a) const = 0; + virtual iterator end () const = 0; + virtual void for_each_par (std::function const & action_a) const = 0; }; } diff --git a/nano/store/rocksdb/account.cpp b/nano/store/rocksdb/account.cpp index 8ee01b98f..9040f22e3 100644 --- a/nano/store/rocksdb/account.cpp +++ b/nano/store/rocksdb/account.cpp @@ -42,27 +42,27 @@ size_t nano::store::rocksdb::account::count (store::transaction const & transact return store.count (transaction_a, tables::accounts); } -nano::store::iterator nano::store::rocksdb::account::begin (store::transaction const & transaction, nano::account const & account) const +auto nano::store::rocksdb::account::begin (store::transaction const & transaction, nano::account const & account) const -> iterator { return store.make_iterator (transaction, tables::accounts, account); } -nano::store::iterator nano::store::rocksdb::account::begin (store::transaction const & transaction) const +auto nano::store::rocksdb::account::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::accounts); } -nano::store::iterator nano::store::rocksdb::account::rbegin (store::transaction const & transaction_a) const +auto nano::store::rocksdb::account::rbegin (store::transaction const & transaction_a) const -> iterator { return store.make_iterator (transaction_a, tables::accounts, false); } -nano::store::iterator nano::store::rocksdb::account::end () const +auto nano::store::rocksdb::account::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::rocksdb::account::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::rocksdb::account::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { diff --git a/nano/store/rocksdb/account.hpp b/nano/store/rocksdb/account.hpp index df5752b4f..1b2c068d0 100644 --- a/nano/store/rocksdb/account.hpp +++ b/nano/store/rocksdb/account.hpp @@ -20,10 +20,10 @@ public: void del (store::write_transaction const & transaction_a, nano::account const & account_a) override; bool exists (store::transaction const & transaction_a, nano::account const & account_a) override; size_t count (store::transaction const & transaction_a) override; - store::iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator rbegin (store::transaction const & transaction_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator rbegin (store::transaction const & transaction_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; }; } // namespace nano::store::rocksdb diff --git a/nano/store/rocksdb/block.cpp b/nano/store/rocksdb/block.cpp index 10ca4067e..7532193ae 100644 --- a/nano/store/rocksdb/block.cpp +++ b/nano/store/rocksdb/block.cpp @@ -133,22 +133,23 @@ uint64_t nano::store::rocksdb::block::count (store::transaction const & transact { return store.count (transaction_a, tables::blocks); } -nano::store::iterator nano::store::rocksdb::block::begin (store::transaction const & transaction) const + +auto nano::store::rocksdb::block::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::blocks); } -nano::store::iterator nano::store::rocksdb::block::begin (store::transaction const & transaction, nano::block_hash const & hash) const +auto nano::store::rocksdb::block::begin (store::transaction const & transaction, nano::block_hash const & hash) const -> iterator { return store.make_iterator (transaction, tables::blocks, hash); } -nano::store::iterator nano::store::rocksdb::block::end () const +auto nano::store::rocksdb::block::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::rocksdb::block::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::rocksdb::block::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { @@ -179,6 +180,7 @@ nano::block_predecessor_rocksdb_set::block_predecessor_rocksdb_set (store::write block_store{ block_store_a } { } + void nano::block_predecessor_rocksdb_set::fill_value (nano::block const & block_a) { auto hash = block_a.hash (); @@ -190,22 +192,27 @@ void nano::block_predecessor_rocksdb_set::fill_value (nano::block const & block_ std::copy (hash.bytes.begin (), hash.bytes.end (), data.begin () + block_store.block_successor_offset (transaction, value.size (), type)); block_store.raw_put (transaction, data, block_a.previous ()); } + void nano::block_predecessor_rocksdb_set::send_block (nano::send_block const & block_a) { fill_value (block_a); } + void nano::block_predecessor_rocksdb_set::receive_block (nano::receive_block const & block_a) { fill_value (block_a); } + void nano::block_predecessor_rocksdb_set::open_block (nano::open_block const & block_a) { // Open blocks don't have a predecessor } + void nano::block_predecessor_rocksdb_set::change_block (nano::change_block const & block_a) { fill_value (block_a); } + void nano::block_predecessor_rocksdb_set::state_block (nano::state_block const & block_a) { if (!block_a.previous ().is_zero ()) diff --git a/nano/store/rocksdb/block.hpp b/nano/store/rocksdb/block.hpp index 7df264a2f..0a093f1c3 100644 --- a/nano/store/rocksdb/block.hpp +++ b/nano/store/rocksdb/block.hpp @@ -29,10 +29,10 @@ public: void del (store::write_transaction const & transaction_a, nano::block_hash const & hash_a) override; bool exists (store::transaction const & transaction_a, nano::block_hash const & hash_a) override; uint64_t count (store::transaction const & transaction_a) override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; protected: void block_raw_get (store::transaction const & transaction_a, nano::block_hash const & hash_a, nano::store::rocksdb::db_val & value) const; diff --git a/nano/store/rocksdb/confirmation_height.cpp b/nano/store/rocksdb/confirmation_height.cpp index 380cd80e3..eea420237 100644 --- a/nano/store/rocksdb/confirmation_height.cpp +++ b/nano/store/rocksdb/confirmation_height.cpp @@ -59,22 +59,22 @@ void nano::store::rocksdb::confirmation_height::clear (store::write_transaction store.drop (transaction, nano::tables::confirmation_height); } -nano::store::iterator nano::store::rocksdb::confirmation_height::begin (store::transaction const & transaction, nano::account const & account) const +auto nano::store::rocksdb::confirmation_height::begin (store::transaction const & transaction, nano::account const & account) const -> iterator { return store.make_iterator (transaction, tables::confirmation_height, account); } -nano::store::iterator nano::store::rocksdb::confirmation_height::begin (store::transaction const & transaction) const +auto nano::store::rocksdb::confirmation_height::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::confirmation_height); } -nano::store::iterator nano::store::rocksdb::confirmation_height::end () const +auto nano::store::rocksdb::confirmation_height::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::rocksdb::confirmation_height::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::rocksdb::confirmation_height::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { diff --git a/nano/store/rocksdb/confirmation_height.hpp b/nano/store/rocksdb/confirmation_height.hpp index 95d730046..050ceef9b 100644 --- a/nano/store/rocksdb/confirmation_height.hpp +++ b/nano/store/rocksdb/confirmation_height.hpp @@ -21,9 +21,9 @@ public: uint64_t count (store::transaction const & transaction_a) override; void clear (store::write_transaction const & transaction_a, nano::account const & account_a) override; void clear (store::write_transaction const & transaction_a) override; - store::iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; }; } // namespace nano::store::rocksdb diff --git a/nano/store/rocksdb/final_vote.cpp b/nano/store/rocksdb/final_vote.cpp index 121da3336..3979b16ca 100644 --- a/nano/store/rocksdb/final_vote.cpp +++ b/nano/store/rocksdb/final_vote.cpp @@ -64,22 +64,22 @@ void nano::store::rocksdb::final_vote::clear (store::write_transaction const & t store.drop (transaction_a, nano::tables::final_votes); } -nano::store::iterator nano::store::rocksdb::final_vote::begin (store::transaction const & transaction, nano::qualified_root const & root) const +auto nano::store::rocksdb::final_vote::begin (store::transaction const & transaction, nano::qualified_root const & root) const -> iterator { return store.make_iterator (transaction, tables::final_votes, root); } -nano::store::iterator nano::store::rocksdb::final_vote::begin (store::transaction const & transaction) const +auto nano::store::rocksdb::final_vote::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::final_votes); } -nano::store::iterator nano::store::rocksdb::final_vote::end () const +auto nano::store::rocksdb::final_vote::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::rocksdb::final_vote::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::rocksdb::final_vote::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { diff --git a/nano/store/rocksdb/final_vote.hpp b/nano/store/rocksdb/final_vote.hpp index d730ec08b..0ffa549fa 100644 --- a/nano/store/rocksdb/final_vote.hpp +++ b/nano/store/rocksdb/final_vote.hpp @@ -21,9 +21,9 @@ public: size_t count (store::transaction const & transaction_a) const override; void clear (store::write_transaction const & transaction_a, nano::root const & root_a) override; void clear (store::write_transaction const & transaction_a) override; - store::iterator begin (store::transaction const & transaction_a, nano::qualified_root const & root_a) const override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a, nano::qualified_root const & root_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; }; } // namespace nano::store::rocksdb diff --git a/nano/store/rocksdb/online_weight.cpp b/nano/store/rocksdb/online_weight.cpp index c6f7e1dac..42250c689 100644 --- a/nano/store/rocksdb/online_weight.cpp +++ b/nano/store/rocksdb/online_weight.cpp @@ -18,19 +18,19 @@ void nano::store::rocksdb::online_weight::del (store::write_transaction const & store.release_assert_success (status); } -nano::store::iterator nano::store::rocksdb::online_weight::begin (store::transaction const & transaction) const +auto nano::store::rocksdb::online_weight::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::online_weight); } -nano::store::iterator nano::store::rocksdb::online_weight::rbegin (store::transaction const & transaction) const +auto nano::store::rocksdb::online_weight::rbegin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::online_weight, false); } -nano::store::iterator nano::store::rocksdb::online_weight::end () const +auto nano::store::rocksdb::online_weight::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } size_t nano::store::rocksdb::online_weight::count (store::transaction const & transaction) const diff --git a/nano/store/rocksdb/online_weight.hpp b/nano/store/rocksdb/online_weight.hpp index 68718f3e0..4d940ffda 100644 --- a/nano/store/rocksdb/online_weight.hpp +++ b/nano/store/rocksdb/online_weight.hpp @@ -17,9 +17,9 @@ public: explicit online_weight (nano::store::rocksdb::component & store_a); void put (store::write_transaction const & transaction_a, uint64_t time_a, nano::amount const & amount_a) override; void del (store::write_transaction const & transaction_a, uint64_t time_a) override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator rbegin (store::transaction const & transaction_a) const override; - store::iterator end () const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator rbegin (store::transaction const & transaction_a) const override; + iterator end () const override; size_t count (store::transaction const & transaction_a) const override; void clear (store::write_transaction const & transaction_a) override; }; diff --git a/nano/store/rocksdb/peer.cpp b/nano/store/rocksdb/peer.cpp index af226e8a8..71fa3ccc5 100644 --- a/nano/store/rocksdb/peer.cpp +++ b/nano/store/rocksdb/peer.cpp @@ -45,12 +45,12 @@ void nano::store::rocksdb::peer::clear (store::write_transaction const & transac store.release_assert_success (status); } -nano::store::iterator nano::store::rocksdb::peer::begin (store::transaction const & transaction) const +auto nano::store::rocksdb::peer::begin (store::transaction const & transaction) const -> iterator { return store.make_iterator (transaction, tables::peers); } -nano::store::iterator nano::store::rocksdb::peer::end () const +auto nano::store::rocksdb::peer::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } diff --git a/nano/store/rocksdb/peer.hpp b/nano/store/rocksdb/peer.hpp index a4ce7286c..30e57644f 100644 --- a/nano/store/rocksdb/peer.hpp +++ b/nano/store/rocksdb/peer.hpp @@ -21,7 +21,7 @@ public: bool exists (store::transaction const &, nano::endpoint_key const & endpoint) const override; size_t count (store::transaction const &) const override; void clear (store::write_transaction const &) override; - store::iterator begin (store::transaction const &) const override; - store::iterator end () const override; + iterator begin (store::transaction const &) const override; + iterator end () const override; }; } // namespace nano::store::rocksdb diff --git a/nano/store/rocksdb/pending.cpp b/nano/store/rocksdb/pending.cpp index 27efe5e63..3286cd8f9 100644 --- a/nano/store/rocksdb/pending.cpp +++ b/nano/store/rocksdb/pending.cpp @@ -45,22 +45,22 @@ bool nano::store::rocksdb::pending::any (store::transaction const & transaction_ return iterator != end () && nano::pending_key (iterator->first).account == account_a; } -nano::store::iterator nano::store::rocksdb::pending::begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const +auto nano::store::rocksdb::pending::begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const -> iterator { return store.template make_iterator (transaction_a, tables::pending, key_a); } -nano::store::iterator nano::store::rocksdb::pending::begin (store::transaction const & transaction_a) const +auto nano::store::rocksdb::pending::begin (store::transaction const & transaction_a) const -> iterator { return store.template make_iterator (transaction_a, tables::pending); } -nano::store::iterator nano::store::rocksdb::pending::end () const +auto nano::store::rocksdb::pending::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::rocksdb::pending::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::rocksdb::pending::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { diff --git a/nano/store/rocksdb/pending.hpp b/nano/store/rocksdb/pending.hpp index 0ee4ced54..4b98b0f07 100644 --- a/nano/store/rocksdb/pending.hpp +++ b/nano/store/rocksdb/pending.hpp @@ -16,9 +16,9 @@ public: std::optional get (store::transaction const & transaction_a, nano::pending_key const & key_a) override; bool exists (store::transaction const & transaction_a, nano::pending_key const & key_a) override; bool any (store::transaction const & transaction_a, nano::account const & account_a) override; - store::iterator begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; }; } // namespace nano::store::rocksdb diff --git a/nano/store/rocksdb/pruned.cpp b/nano/store/rocksdb/pruned.cpp index 41d7fbb58..572f17e34 100644 --- a/nano/store/rocksdb/pruned.cpp +++ b/nano/store/rocksdb/pruned.cpp @@ -45,22 +45,22 @@ void nano::store::rocksdb::pruned::clear (store::write_transaction const & trans store.release_assert_success (status); } -nano::store::iterator nano::store::rocksdb::pruned::begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const +auto nano::store::rocksdb::pruned::begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const -> iterator { return store.make_iterator (transaction_a, tables::pruned, hash_a); } -nano::store::iterator nano::store::rocksdb::pruned::begin (store::transaction const & transaction_a) const +auto nano::store::rocksdb::pruned::begin (store::transaction const & transaction_a) const -> iterator { return store.make_iterator (transaction_a, tables::pruned); } -nano::store::iterator nano::store::rocksdb::pruned::end () const +auto nano::store::rocksdb::pruned::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::rocksdb::pruned::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::rocksdb::pruned::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { diff --git a/nano/store/rocksdb/pruned.hpp b/nano/store/rocksdb/pruned.hpp index aa5db1fba..0dc84b84e 100644 --- a/nano/store/rocksdb/pruned.hpp +++ b/nano/store/rocksdb/pruned.hpp @@ -21,9 +21,9 @@ public: nano::block_hash random (store::transaction const & transaction_a) override; size_t count (store::transaction const & transaction_a) const override; void clear (store::write_transaction const & transaction_a) override; - store::iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const override; - store::iterator begin (store::transaction const & transaction_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const override; + iterator begin (store::transaction const & transaction_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; }; } // namespace nano::store::rocksdb diff --git a/nano/store/rocksdb/rep_weight.cpp b/nano/store/rocksdb/rep_weight.cpp index 7f29e61e4..68d4684ce 100644 --- a/nano/store/rocksdb/rep_weight.cpp +++ b/nano/store/rocksdb/rep_weight.cpp @@ -42,26 +42,26 @@ void nano::store::rocksdb::rep_weight::del (store::write_transaction const & txn store.release_assert_success (status); } -nano::store::iterator nano::store::rocksdb::rep_weight::begin (store::transaction const & txn_a, nano::account const & representative_a) const +auto nano::store::rocksdb::rep_weight::begin (store::transaction const & txn_a, nano::account const & representative_a) const -> iterator { return store.make_iterator (txn_a, tables::rep_weights, representative_a); } -nano::store::iterator nano::store::rocksdb::rep_weight::begin (store::transaction const & txn_a) const +auto nano::store::rocksdb::rep_weight::begin (store::transaction const & txn_a) const -> iterator { return store.make_iterator (txn_a, tables::rep_weights); } -nano::store::iterator nano::store::rocksdb::rep_weight::end () const +auto nano::store::rocksdb::rep_weight::end () const -> iterator { - return store::iterator (nullptr); + return iterator{ nullptr }; } -void nano::store::rocksdb::rep_weight::for_each_par (std::function, store::iterator)> const & action_a) const +void nano::store::rocksdb::rep_weight::for_each_par (std::function const & action_a) const { parallel_traversal ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); }); -} \ No newline at end of file +} diff --git a/nano/store/rocksdb/rep_weight.hpp b/nano/store/rocksdb/rep_weight.hpp index c86f27150..76e542264 100644 --- a/nano/store/rocksdb/rep_weight.hpp +++ b/nano/store/rocksdb/rep_weight.hpp @@ -19,9 +19,9 @@ public: nano::uint128_t get (store::transaction const & txn_a, nano::account const & representative_a) override; void put (store::write_transaction const & txn_a, nano::account const & representative_a, nano::uint128_t const & weight_a) override; void del (store::write_transaction const &, nano::account const & representative_a) override; - store::iterator begin (store::transaction const & txn_a, nano::account const & representative_a) const override; - store::iterator begin (store::transaction const & txn_a) const override; - store::iterator end () const override; - void for_each_par (std::function, store::iterator)> const & action_a) const override; + iterator begin (store::transaction const & txn_a, nano::account const & representative_a) const override; + iterator begin (store::transaction const & txn_a) const override; + iterator end () const override; + void for_each_par (std::function const & action_a) const override; }; } From d54258102cca2f8876b636b5a49c3dbf3e9565d8 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Thu, 10 Oct 2024 14:37:08 +0200 Subject: [PATCH 15/48] Renaming file "final" to "final_vote". --- nano/secure/ledger.cpp | 4 ++-- nano/store/CMakeLists.txt | 4 ++-- nano/store/final.cpp | 1 - nano/store/final_vote.cpp | 1 + nano/store/{final.hpp => final_vote.hpp} | 0 nano/store/lmdb/final_vote.hpp | 2 +- nano/store/rocksdb/final_vote.hpp | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 nano/store/final.cpp create mode 100644 nano/store/final_vote.cpp rename nano/store/{final.hpp => final_vote.hpp} (100%) diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index cba173a6c..bc9514a8b 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -1523,4 +1523,4 @@ nano::container_info nano::ledger::container_info () const info.put ("bootstrap_weights", bootstrap_weights); info.add ("rep_weights", cache.rep_weights.container_info ()); return info; -} \ No newline at end of file +} diff --git a/nano/store/CMakeLists.txt b/nano/store/CMakeLists.txt index c44d7fc0d..e5e6a8c47 100644 --- a/nano/store/CMakeLists.txt +++ b/nano/store/CMakeLists.txt @@ -9,7 +9,7 @@ add_library( db_val_impl.hpp iterator.hpp iterator_impl.hpp - final.hpp + final_vote.hpp lmdb/account.hpp lmdb/block.hpp lmdb/confirmation_height.hpp @@ -59,7 +59,7 @@ add_library( db_val.cpp iterator.cpp iterator_impl.cpp - final.cpp + final_vote.cpp lmdb/account.cpp lmdb/block.cpp lmdb/confirmation_height.cpp diff --git a/nano/store/final.cpp b/nano/store/final.cpp deleted file mode 100644 index 69d469dc7..000000000 --- a/nano/store/final.cpp +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/nano/store/final_vote.cpp b/nano/store/final_vote.cpp new file mode 100644 index 000000000..0b4565c1a --- /dev/null +++ b/nano/store/final_vote.cpp @@ -0,0 +1 @@ +#include diff --git a/nano/store/final.hpp b/nano/store/final_vote.hpp similarity index 100% rename from nano/store/final.hpp rename to nano/store/final_vote.hpp diff --git a/nano/store/lmdb/final_vote.hpp b/nano/store/lmdb/final_vote.hpp index 896ab5d6a..9b72b085a 100644 --- a/nano/store/lmdb/final_vote.hpp +++ b/nano/store/lmdb/final_vote.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include diff --git a/nano/store/rocksdb/final_vote.hpp b/nano/store/rocksdb/final_vote.hpp index 0ffa549fa..a24093a57 100644 --- a/nano/store/rocksdb/final_vote.hpp +++ b/nano/store/rocksdb/final_vote.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace nano::store::rocksdb { From c659c8b1658b19ce858fabfb8e86568b0be76c84 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Thu, 10 Oct 2024 20:14:25 +0100 Subject: [PATCH 16/48] Using type inference in a few places for iterators. --- nano/nano_node/entry.cpp | 4 ++-- nano/secure/ledger.cpp | 6 +++--- nano/test_common/system.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/nano/nano_node/entry.cpp b/nano/nano_node/entry.cpp index ae49f157a..66b9a86fa 100644 --- a/nano/nano_node/entry.cpp +++ b/nano/nano_node/entry.cpp @@ -1942,7 +1942,7 @@ int main (int argc, char * const * argv) nano::locked>> opened_account_versions_shared (epoch_count); using opened_account_versions_t = decltype (opened_account_versions_shared)::value_type; node->store.account.for_each_par ( - [&opened_account_versions_shared, epoch_count] (nano::store::read_transaction const & /*unused*/, nano::store::iterator i, nano::store::iterator n) { + [&opened_account_versions_shared, epoch_count] (nano::store::read_transaction const & /*unused*/, auto i, auto n) { // First cache locally opened_account_versions_t opened_account_versions_l (epoch_count); for (; i != n; ++i) @@ -1979,7 +1979,7 @@ int main (int argc, char * const * argv) nano::locked>> unopened_highest_pending_shared; using unopened_highest_pending_t = decltype (unopened_highest_pending_shared)::value_type; node->store.pending.for_each_par ( - [&unopened_highest_pending_shared, &opened_accounts] (nano::store::read_transaction const & /*unused*/, nano::store::iterator i, nano::store::iterator n) { + [&unopened_highest_pending_shared, &opened_accounts] (nano::store::read_transaction const & /*unused*/, auto i, auto n) { // First cache locally unopened_highest_pending_t unopened_highest_pending_l; for (; i != n; ++i) diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index bc9514a8b..93eb61cea 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -749,7 +749,7 @@ void nano::ledger::initialize (nano::generate_cache_flags const & generate_cache if (generate_cache_flags_a.reps || generate_cache_flags_a.account_count || generate_cache_flags_a.block_count) { store.account.for_each_par ( - [this] (store::read_transaction const & /*unused*/, store::iterator i, store::iterator n) { + [this] (store::read_transaction const & /*unused*/, auto i, auto n) { uint64_t block_count_l{ 0 }; uint64_t account_count_l{ 0 }; for (; i != n; ++i) @@ -763,7 +763,7 @@ void nano::ledger::initialize (nano::generate_cache_flags const & generate_cache }); store.rep_weight.for_each_par ( - [this] (store::read_transaction const & /*unused*/, store::iterator i, store::iterator n) { + [this] (store::read_transaction const & /*unused*/, auto i, auto n) { nano::rep_weights rep_weights_l{ this->store.rep_weight }; for (; i != n; ++i) { @@ -776,7 +776,7 @@ void nano::ledger::initialize (nano::generate_cache_flags const & generate_cache if (generate_cache_flags_a.cemented_count) { store.confirmation_height.for_each_par ( - [this] (store::read_transaction const & /*unused*/, store::iterator i, store::iterator n) { + [this] (store::read_transaction const & /*unused*/, auto i, auto n) { uint64_t cemented_count_l (0); for (; i != n; ++i) { diff --git a/nano/test_common/system.cpp b/nano/test_common/system.cpp index c0a9831cf..40f8be220 100644 --- a/nano/test_common/system.cpp +++ b/nano/test_common/system.cpp @@ -532,7 +532,7 @@ void nano::test::system::generate_send_existing (nano::node & node_a, std::vecto nano::account account; random_pool::generate_block (account.bytes.data (), sizeof (account.bytes)); auto transaction = node_a.ledger.tx_begin_read (); - store::iterator entry (node_a.store.account.begin (transaction, account)); + auto entry = node_a.store.account.begin (transaction, account); if (entry == node_a.store.account.end ()) { entry = node_a.store.account.begin (transaction); From dd08220e2ccdc3092b4594bcc37aecda2007d1c1 Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:47:32 +0200 Subject: [PATCH 17/48] Only broadcast every 100ms or 255 votes --- nano/node/vote_generator.cpp | 18 ++++++++++++++++-- nano/node/vote_generator.hpp | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/nano/node/vote_generator.cpp b/nano/node/vote_generator.cpp index 00dccfd57..a54ec1369 100644 --- a/nano/node/vote_generator.cpp +++ b/nano/node/vote_generator.cpp @@ -289,11 +289,12 @@ void nano::vote_generator::run () nano::unique_lock lock{ mutex }; while (!stopped) { - condition.wait_for (lock, config.vote_generator_delay, [this] () { return this->candidates.size () >= nano::network::confirm_ack_hashes_max || !requests.empty (); }); + condition.wait_for (lock, config.vote_generator_delay, [this] () { return broadcast_predicate () || !requests.empty (); }); - if (!candidates.empty ()) + if (broadcast_predicate ()) { broadcast (lock); + next_broadcast = std::chrono::steady_clock::now () + std::chrono::milliseconds (config.vote_generator_delay); } if (!requests.empty ()) @@ -305,6 +306,19 @@ void nano::vote_generator::run () } } +bool nano::vote_generator::broadcast_predicate () const +{ + if (candidates.size () >= nano::network::confirm_ack_hashes_max) + { + return true; + } + if (candidates.size () > 0 && std::chrono::steady_clock::now () > next_broadcast) + { + return true; + } + return false; +} + nano::container_info nano::vote_generator::container_info () const { nano::lock_guard guard{ mutex }; diff --git a/nano/node/vote_generator.hpp b/nano/node/vote_generator.hpp index c93317bcc..76fc0c583 100644 --- a/nano/node/vote_generator.hpp +++ b/nano/node/vote_generator.hpp @@ -30,6 +30,7 @@ private: using candidate_t = std::pair; using request_t = std::pair, std::shared_ptr>; using queue_entry_t = std::pair; + std::chrono::steady_clock::time_point next_broadcast = { std::chrono::steady_clock::now () }; public: vote_generator (nano::node_config const &, nano::node &, nano::ledger &, nano::wallets &, nano::vote_processor &, nano::local_vote_history &, nano::network &, nano::stats &, nano::logger &, bool is_final); @@ -56,6 +57,7 @@ private: void broadcast_action (std::shared_ptr const &) const; void process_batch (std::deque & batch); bool should_vote (transaction_variant_t const &, nano::root const &, nano::block_hash const &) const; + bool broadcast_predicate () const; private: std::function const &, std::shared_ptr &)> reply_action; // must be set only during initialization by using set_reply_action From 471e9ed93016bcf7aa0cefa3088803d995b76c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Mon, 21 Oct 2024 19:30:44 +0200 Subject: [PATCH 18/48] Move thread pool tests --- nano/core_test/CMakeLists.txt | 1 + nano/core_test/thread_pool.cpp | 91 ++++++++++++++++++++++++++++++++++ nano/core_test/utility.cpp | 87 +------------------------------- 3 files changed, 93 insertions(+), 86 deletions(-) create mode 100644 nano/core_test/thread_pool.cpp diff --git a/nano/core_test/CMakeLists.txt b/nano/core_test/CMakeLists.txt index e5b47c9e4..d8752feab 100644 --- a/nano/core_test/CMakeLists.txt +++ b/nano/core_test/CMakeLists.txt @@ -51,6 +51,7 @@ add_executable( socket.cpp system.cpp telemetry.cpp + thread_pool.cpp throttle.cpp toml.cpp timer.cpp diff --git a/nano/core_test/thread_pool.cpp b/nano/core_test/thread_pool.cpp new file mode 100644 index 000000000..d257fce28 --- /dev/null +++ b/nano/core_test/thread_pool.cpp @@ -0,0 +1,91 @@ +#include +#include + +#include + +#include + +TEST (thread_pool, thread_pool) +{ + std::atomic passed_sleep{ false }; + + auto func = [&passed_sleep] () { + std::this_thread::sleep_for (std::chrono::seconds (1)); + passed_sleep = true; + }; + + nano::thread_pool workers (1u, nano::thread_role::name::unknown); + workers.push_task (func); + ASSERT_FALSE (passed_sleep); + + nano::timer timer_l; + timer_l.start (); + while (!passed_sleep) + { + if (timer_l.since_start () > std::chrono::seconds (10)) + { + break; + } + } + ASSERT_TRUE (passed_sleep); +} + +TEST (thread_pool, one) +{ + std::atomic done (false); + nano::mutex mutex; + nano::condition_variable condition; + nano::thread_pool workers (1u, nano::thread_role::name::unknown); + workers.add_timed_task (std::chrono::steady_clock::now (), [&] () { + { + nano::lock_guard lock{ mutex }; + done = true; + } + condition.notify_one (); + }); + nano::unique_lock unique{ mutex }; + condition.wait (unique, [&] () { return !!done; }); +} + +TEST (thread_pool, many) +{ + std::atomic count (0); + nano::mutex mutex; + nano::condition_variable condition; + nano::thread_pool workers (50u, nano::thread_role::name::unknown); + for (auto i (0); i < 50; ++i) + { + workers.add_timed_task (std::chrono::steady_clock::now (), [&] () { + { + nano::lock_guard lock{ mutex }; + count += 1; + } + condition.notify_one (); + }); + } + nano::unique_lock unique{ mutex }; + condition.wait (unique, [&] () { return count == 50; }); +} + +TEST (thread_pool, top_execution) +{ + int value1 (0); + int value2 (0); + nano::mutex mutex; + std::promise promise; + nano::thread_pool workers (1u, nano::thread_role::name::unknown); + workers.add_timed_task (std::chrono::steady_clock::now (), [&] () { + nano::lock_guard lock{ mutex }; + value1 = 1; + value2 = 1; + }); + workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::milliseconds (1), [&] () { + nano::lock_guard lock{ mutex }; + value2 = 2; + promise.set_value (false); + }); + promise.get_future ().get (); + nano::lock_guard lock{ mutex }; + ASSERT_EQ (1, value1); + ASSERT_EQ (2, value2); +} \ No newline at end of file diff --git a/nano/core_test/utility.cpp b/nano/core_test/utility.cpp index 730714dc8..30ee29544 100644 --- a/nano/core_test/utility.cpp +++ b/nano/core_test/utility.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -146,91 +146,6 @@ TEST (optional_ptr, basic) ASSERT_EQ (opt->z, 3); } -TEST (thread, thread_pool) -{ - std::atomic passed_sleep{ false }; - - auto func = [&passed_sleep] () { - std::this_thread::sleep_for (std::chrono::seconds (1)); - passed_sleep = true; - }; - - nano::thread_pool workers (1u, nano::thread_role::name::unknown); - workers.push_task (func); - ASSERT_FALSE (passed_sleep); - - nano::timer timer_l; - timer_l.start (); - while (!passed_sleep) - { - if (timer_l.since_start () > std::chrono::seconds (10)) - { - break; - } - } - ASSERT_TRUE (passed_sleep); -} - -TEST (thread_pool_alarm, one) -{ - std::atomic done (false); - nano::mutex mutex; - nano::condition_variable condition; - nano::thread_pool workers (1u, nano::thread_role::name::unknown); - workers.add_timed_task (std::chrono::steady_clock::now (), [&] () { - { - nano::lock_guard lock{ mutex }; - done = true; - } - condition.notify_one (); - }); - nano::unique_lock unique{ mutex }; - condition.wait (unique, [&] () { return !!done; }); -} - -TEST (thread_pool_alarm, many) -{ - std::atomic count (0); - nano::mutex mutex; - nano::condition_variable condition; - nano::thread_pool workers (50u, nano::thread_role::name::unknown); - for (auto i (0); i < 50; ++i) - { - workers.add_timed_task (std::chrono::steady_clock::now (), [&] () { - { - nano::lock_guard lock{ mutex }; - count += 1; - } - condition.notify_one (); - }); - } - nano::unique_lock unique{ mutex }; - condition.wait (unique, [&] () { return count == 50; }); -} - -TEST (thread_pool_alarm, top_execution) -{ - int value1 (0); - int value2 (0); - nano::mutex mutex; - std::promise promise; - nano::thread_pool workers (1u, nano::thread_role::name::unknown); - workers.add_timed_task (std::chrono::steady_clock::now (), [&] () { - nano::lock_guard lock{ mutex }; - value1 = 1; - value2 = 1; - }); - workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::milliseconds (1), [&] () { - nano::lock_guard lock{ mutex }; - value2 = 2; - promise.set_value (false); - }); - promise.get_future ().get (); - nano::lock_guard lock{ mutex }; - ASSERT_EQ (1, value1); - ASSERT_EQ (2, value2); -} - TEST (filesystem, remove_all_files) { auto path = nano::unique_path (); From 483c6906e8fe556a2347f225c1af16fc04f702aa Mon Sep 17 00:00:00 2001 From: clemahieu Date: Mon, 21 Oct 2024 23:19:36 +0100 Subject: [PATCH 19/48] Pass transaction in to end iterator for future use. (#4761) --- nano/core_test/block_store.cpp | 26 ++++++------ nano/core_test/ledger.cpp | 2 +- nano/core_test/system.cpp | 8 ++-- nano/core_test/wallet.cpp | 16 +++---- nano/nano_node/entry.cpp | 12 +++--- nano/nano_wallet/entry.cpp | 2 +- nano/node/backlog_population.cpp | 2 +- nano/node/bootstrap/bootstrap_frontier.cpp | 6 +-- nano/node/bootstrap/bootstrap_server.cpp | 2 +- .../bootstrap_ascending/database_scan.cpp | 6 +-- nano/node/cli.cpp | 6 +-- nano/node/epoch_upgrader.cpp | 2 +- nano/node/json_handler.cpp | 42 +++++++++---------- nano/node/node.cpp | 10 ++--- nano/node/online_reps.cpp | 4 +- nano/node/peer_history.cpp | 4 +- nano/node/wallet.cpp | 22 +++++----- nano/node/wallet.hpp | 2 +- nano/qt/qt.cpp | 6 +-- nano/rpc_test/rpc.cpp | 14 +++---- nano/secure/ledger.cpp | 4 +- nano/secure/ledger_set_any.cpp | 4 +- nano/secure/ledger_set_confirmed.cpp | 4 +- nano/slow_test/node.cpp | 20 ++++----- nano/store/account.hpp | 2 +- nano/store/block.hpp | 2 +- nano/store/component.cpp | 2 +- nano/store/confirmation_height.hpp | 2 +- nano/store/final_vote.hpp | 2 +- nano/store/lmdb/account.cpp | 6 +-- nano/store/lmdb/account.hpp | 2 +- nano/store/lmdb/block.cpp | 8 ++-- nano/store/lmdb/block.hpp | 2 +- nano/store/lmdb/confirmation_height.cpp | 4 +- nano/store/lmdb/confirmation_height.hpp | 2 +- nano/store/lmdb/final_vote.cpp | 8 ++-- nano/store/lmdb/final_vote.hpp | 2 +- nano/store/lmdb/lmdb.cpp | 2 +- nano/store/lmdb/online_weight.cpp | 2 +- nano/store/lmdb/online_weight.hpp | 2 +- nano/store/lmdb/peer.cpp | 2 +- nano/store/lmdb/peer.hpp | 2 +- nano/store/lmdb/pending.cpp | 8 ++-- nano/store/lmdb/pending.hpp | 2 +- nano/store/lmdb/pruned.cpp | 8 ++-- nano/store/lmdb/pruned.hpp | 2 +- nano/store/lmdb/rep_weight.cpp | 4 +- nano/store/lmdb/rep_weight.hpp | 2 +- nano/store/online_weight.hpp | 2 +- nano/store/peer.hpp | 2 +- nano/store/pending.hpp | 2 +- nano/store/pruned.hpp | 2 +- nano/store/rep_weight.hpp | 2 +- nano/store/rocksdb/account.cpp | 6 +-- nano/store/rocksdb/account.hpp | 2 +- nano/store/rocksdb/block.cpp | 8 ++-- nano/store/rocksdb/block.hpp | 2 +- nano/store/rocksdb/confirmation_height.cpp | 4 +- nano/store/rocksdb/confirmation_height.hpp | 2 +- nano/store/rocksdb/final_vote.cpp | 8 ++-- nano/store/rocksdb/final_vote.hpp | 2 +- nano/store/rocksdb/online_weight.cpp | 2 +- nano/store/rocksdb/online_weight.hpp | 2 +- nano/store/rocksdb/peer.cpp | 2 +- nano/store/rocksdb/peer.hpp | 2 +- nano/store/rocksdb/pending.cpp | 8 ++-- nano/store/rocksdb/pending.hpp | 2 +- nano/store/rocksdb/pruned.cpp | 8 ++-- nano/store/rocksdb/pruned.hpp | 2 +- nano/store/rocksdb/rep_weight.cpp | 4 +- nano/store/rocksdb/rep_weight.hpp | 2 +- nano/store/rocksdb/rocksdb.cpp | 19 +++++---- nano/test_common/system.cpp | 8 ++-- nano/test_common/testutil.cpp | 8 ++-- 74 files changed, 211 insertions(+), 208 deletions(-) diff --git a/nano/core_test/block_store.cpp b/nano/core_test/block_store.cpp index fcf7a5714..84e98380c 100644 --- a/nano/core_test/block_store.cpp +++ b/nano/core_test/block_store.cpp @@ -314,10 +314,10 @@ TEST (block_store, pending_iterator) auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); auto transaction (store->tx_begin_write ()); - ASSERT_EQ (store->pending.end (), store->pending.begin (transaction)); + ASSERT_EQ (store->pending.end (transaction), store->pending.begin (transaction)); store->pending.put (transaction, nano::pending_key (1, 2), { 2, 3, nano::epoch::epoch_1 }); auto current (store->pending.begin (transaction)); - ASSERT_NE (store->pending.end (), current); + ASSERT_NE (store->pending.end (transaction), current); nano::pending_key key1 (current->first); ASSERT_EQ (nano::account (1), key1.account); ASSERT_EQ (nano::block_hash (2), key1.hash); @@ -411,7 +411,7 @@ TEST (block_store, empty_accounts) ASSERT_TRUE (!store->init_error ()); auto transaction (store->tx_begin_read ()); auto begin (store->account.begin (transaction)); - auto end (store->account.end ()); + auto end (store->account.end (transaction)); ASSERT_EQ (end, begin); } @@ -498,7 +498,7 @@ TEST (block_store, one_account) store->confirmation_height.put (transaction, account, { 20, nano::block_hash (15) }); store->account.put (transaction, account, { hash, account, hash, 42, 100, 200, nano::epoch::epoch_0 }); auto begin (store->account.begin (transaction)); - auto end (store->account.end ()); + auto end (store->account.end (transaction)); ASSERT_NE (end, begin); ASSERT_EQ (account, nano::account (begin->first)); nano::account_info info (begin->second); @@ -567,7 +567,7 @@ TEST (block_store, two_account) store->confirmation_height.put (transaction, account2, { 30, nano::block_hash (20) }); store->account.put (transaction, account2, { hash2, account2, hash2, 84, 200, 400, nano::epoch::epoch_0 }); auto begin (store->account.begin (transaction)); - auto end (store->account.end ()); + auto end (store->account.end (transaction)); ASSERT_NE (end, begin); ASSERT_EQ (account1, nano::account (begin->first)); nano::account_info info1 (begin->second); @@ -787,7 +787,7 @@ TEST (block_store, large_iteration) std::unordered_set accounts2; nano::account previous{}; auto transaction (store->tx_begin_read ()); - for (auto i (store->account.begin (transaction, 0)), n (store->account.end ()); i != n; ++i) + for (auto i (store->account.begin (transaction, 0)), n (store->account.end (transaction)); i != n; ++i) { nano::account current (i->first); ASSERT_GT (current.number (), previous.number ()); @@ -798,7 +798,7 @@ TEST (block_store, large_iteration) // Reverse iteration std::unordered_set accounts3; previous = std::numeric_limits::max (); - for (auto i (store->account.rbegin (transaction)), n (store->account.end ()); i != n; --i) + for (auto i (store->account.rbegin (transaction)), n (store->account.end (transaction)); i != n; --i) { nano::account current (i->first); ASSERT_LT (current.number (), previous.number ()); @@ -1253,8 +1253,8 @@ TEST (block_store, online_weight) { auto transaction (store->tx_begin_write ()); ASSERT_EQ (0, store->online_weight.count (transaction)); - ASSERT_EQ (store->online_weight.end (), store->online_weight.begin (transaction)); - ASSERT_EQ (store->online_weight.end (), store->online_weight.rbegin (transaction)); + ASSERT_EQ (store->online_weight.end (transaction), store->online_weight.begin (transaction)); + ASSERT_EQ (store->online_weight.end (transaction), store->online_weight.rbegin (transaction)); store->online_weight.put (transaction, 1, 2); store->online_weight.put (transaction, 3, 4); } @@ -1262,11 +1262,11 @@ TEST (block_store, online_weight) auto transaction (store->tx_begin_write ()); ASSERT_EQ (2, store->online_weight.count (transaction)); auto item (store->online_weight.begin (transaction)); - ASSERT_NE (store->online_weight.end (), item); + ASSERT_NE (store->online_weight.end (transaction), item); ASSERT_EQ (1, item->first); ASSERT_EQ (2, item->second.number ()); auto item_last (store->online_weight.rbegin (transaction)); - ASSERT_NE (store->online_weight.end (), item_last); + ASSERT_NE (store->online_weight.end (transaction), item_last); ASSERT_EQ (3, item_last->first); ASSERT_EQ (4, item_last->second.number ()); store->online_weight.del (transaction, 1); @@ -1276,8 +1276,8 @@ TEST (block_store, online_weight) } auto transaction (store->tx_begin_read ()); ASSERT_EQ (0, store->online_weight.count (transaction)); - ASSERT_EQ (store->online_weight.end (), store->online_weight.begin (transaction)); - ASSERT_EQ (store->online_weight.end (), store->online_weight.rbegin (transaction)); + ASSERT_EQ (store->online_weight.end (transaction), store->online_weight.begin (transaction)); + ASSERT_EQ (store->online_weight.end (transaction), store->online_weight.rbegin (transaction)); } TEST (block_store, pruned_blocks) diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index f30b895cf..23d3d751b 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -5464,7 +5464,7 @@ TEST (ledger, migrate_lmdb_to_rocksdb) ASSERT_TRUE (rocksdb_store.pending.get (rocksdb_transaction, nano::pending_key (nano::dev::genesis_key.pub, send->hash ()))); - for (auto i = rocksdb_store.online_weight.begin (rocksdb_transaction); i != rocksdb_store.online_weight.end (); ++i) + for (auto i = rocksdb_store.online_weight.begin (rocksdb_transaction); i != rocksdb_store.online_weight.end (rocksdb_transaction); ++i) { ASSERT_EQ (i->first, 100); ASSERT_EQ (i->second, 2); diff --git a/nano/core_test/system.cpp b/nano/core_test/system.cpp index 2072fe8cf..7f9f1088a 100644 --- a/nano/core_test/system.cpp +++ b/nano/core_test/system.cpp @@ -95,9 +95,9 @@ TEST (system, DISABLED_generate_send_new) { auto transaction (node1.store.tx_begin_read ()); auto iterator1 (node1.store.account.begin (transaction)); - ASSERT_NE (node1.store.account.end (), iterator1); + ASSERT_NE (node1.store.account.end (transaction), iterator1); ++iterator1; - ASSERT_EQ (node1.store.account.end (), iterator1); + ASSERT_EQ (node1.store.account.end (transaction), iterator1); } nano::keypair stake_preserver; auto send_block (system.wallet (0)->send_action (nano::dev::genesis_key.pub, stake_preserver.pub, nano::dev::constants.genesis_amount / 3 * 2, true)); @@ -130,13 +130,13 @@ TEST (system, DISABLED_generate_send_new) new_account = iterator2->first; } ++iterator2; - ASSERT_NE (system.wallet (0)->store.end (), iterator2); + ASSERT_NE (system.wallet (0)->store.end (transaction), iterator2); if (iterator2->first != nano::dev::genesis_key.pub) { new_account = iterator2->first; } ++iterator2; - ASSERT_EQ (system.wallet (0)->store.end (), iterator2); + ASSERT_EQ (system.wallet (0)->store.end (transaction), iterator2); ASSERT_FALSE (new_account.is_zero ()); } ASSERT_TIMELY (10s, node1.balance (new_account) != 0); diff --git a/nano/core_test/wallet.cpp b/nano/core_test/wallet.cpp index bd3b41325..e9e170f6d 100644 --- a/nano/core_test/wallet.cpp +++ b/nano/core_test/wallet.cpp @@ -104,7 +104,7 @@ TEST (wallet, empty_iteration) nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); ASSERT_FALSE (init); auto i (wallet.begin (transaction)); - auto j (wallet.end ()); + auto j (wallet.end (transaction)); ASSERT_EQ (i, j); } @@ -119,7 +119,7 @@ TEST (wallet, one_item_iteration) ASSERT_FALSE (init); nano::keypair key1; wallet.insert_adhoc (transaction, key1.prv); - for (auto i (wallet.begin (transaction)), j (wallet.end ()); i != j; ++i) + for (auto i (wallet.begin (transaction)), j (wallet.end (transaction)); i != j; ++i) { ASSERT_EQ (key1.pub, nano::uint256_union (i->first)); nano::raw_key password; @@ -147,7 +147,7 @@ TEST (wallet, two_item_iteration) ASSERT_FALSE (init); wallet.insert_adhoc (transaction, key1.prv); wallet.insert_adhoc (transaction, key2.prv); - for (auto i (wallet.begin (transaction)), j (wallet.end ()); i != j; ++i) + for (auto i (wallet.begin (transaction)), j (wallet.end (transaction)); i != j; ++i) { pubs.insert (i->first); nano::raw_key password; @@ -266,7 +266,7 @@ TEST (wallet, find_none) nano::wallet_store wallet (init, kdf, transaction, env, nano::dev::genesis_key.pub, 1, "0"); ASSERT_FALSE (init); nano::account account (1000); - ASSERT_EQ (wallet.end (), wallet.find (transaction, account)); + ASSERT_EQ (wallet.end (transaction), wallet.find (transaction, account)); } TEST (wallet, find_existing) @@ -283,9 +283,9 @@ TEST (wallet, find_existing) wallet.insert_adhoc (transaction, key1.prv); ASSERT_TRUE (wallet.exists (transaction, key1.pub)); auto existing (wallet.find (transaction, key1.pub)); - ASSERT_NE (wallet.end (), existing); + ASSERT_NE (wallet.end (transaction), existing); ++existing; - ASSERT_EQ (wallet.end (), existing); + ASSERT_EQ (wallet.end (transaction), existing); } TEST (wallet, rekey) @@ -487,8 +487,8 @@ TEST (wallet, serialize_json_empty) ASSERT_EQ (wallet1.salt (transaction), wallet2.salt (transaction)); ASSERT_EQ (wallet1.check (transaction), wallet2.check (transaction)); ASSERT_EQ (wallet1.representative (transaction), wallet2.representative (transaction)); - ASSERT_EQ (wallet1.end (), wallet1.begin (transaction)); - ASSERT_EQ (wallet2.end (), wallet2.begin (transaction)); + ASSERT_EQ (wallet1.end (transaction), wallet1.begin (transaction)); + ASSERT_EQ (wallet2.end (transaction), wallet2.begin (transaction)); } TEST (wallet, serialize_json_one) diff --git a/nano/nano_node/entry.cpp b/nano/nano_node/entry.cpp index 66b9a86fa..37c2786bf 100644 --- a/nano/nano_node/entry.cpp +++ b/nano/nano_node/entry.cpp @@ -353,7 +353,7 @@ int main (int argc, char * const * argv) auto inactive_node = nano::default_inactive_node (data_path, vm); auto transaction = inactive_node->node->store.tx_begin_read (); auto i = inactive_node->node->store.block.begin (transaction); - auto end = inactive_node->node->store.block.end (); + auto end = inactive_node->node->store.block.end (transaction); for (; i != end; ++i) { nano::block_hash hash = i->first; @@ -435,7 +435,7 @@ int main (int argc, char * const * argv) auto current (node->online_reps.trended ()); std::cout << boost::str (boost::format ("Trended Weight %1%\n") % current); auto transaction (node->store.tx_begin_read ()); - for (auto i (node->store.online_weight.begin (transaction)), n (node->store.online_weight.end ()); i != n; ++i) + for (auto i (node->store.online_weight.begin (transaction)), n (node->store.online_weight.end (transaction)); i != n; ++i) { using time_point = std::chrono::system_clock::time_point; time_point ts (std::chrono::duration_cast (std::chrono::nanoseconds (i->first))); @@ -471,7 +471,7 @@ int main (int argc, char * const * argv) // Cache the account heads to make searching quicker against unchecked keys. auto transaction (node->store.tx_begin_read ()); std::unordered_set frontier_hashes; - for (auto i (node->store.account.begin (transaction)), n (node->store.account.end ()); i != n; ++i) + for (auto i (node->store.account.begin (transaction)), n (node->store.account.end (transaction)); i != n; ++i) { frontier_hashes.insert (i->second.head); } @@ -1669,7 +1669,7 @@ int main (int argc, char * const * argv) } size_t const accounts_deque_overflow (32 * 1024); auto transaction = node->ledger.tx_begin_read (); - for (auto i (node->store.account.begin (transaction)), n (node->store.account.end ()); i != n; ++i) + for (auto i (node->store.account.begin (transaction)), n (node->store.account.end (transaction)); i != n; ++i) { { nano::unique_lock lock{ mutex }; @@ -1780,7 +1780,7 @@ int main (int argc, char * const * argv) start_threads (check_pending, pending); size_t const pending_deque_overflow (64 * 1024); - for (auto i (node->store.pending.begin (transaction)), n (node->store.pending.end ()); i != n; ++i) + for (auto i (node->store.pending.begin (transaction)), n (node->store.pending.end (transaction)); i != n; ++i) { { nano::unique_lock lock{ mutex }; @@ -1837,7 +1837,7 @@ int main (int argc, char * const * argv) auto transaction = source_node->ledger.tx_begin_read (); block_count = source_node->ledger.block_count (); std::cout << boost::str (boost::format ("Performing bootstrap emulation, %1% blocks in ledger...") % block_count) << std::endl; - for (auto i (source_node->store.account.begin (transaction)), n (source_node->store.account.end ()); i != n; ++i) + for (auto i (source_node->store.account.begin (transaction)), n (source_node->store.account.end (transaction)); i != n; ++i) { nano::account const & account (i->first); nano::account_info const & info (i->second); diff --git a/nano/nano_wallet/entry.cpp b/nano/nano_wallet/entry.cpp index 5d595c9c0..6a3eac399 100644 --- a/nano/nano_wallet/entry.cpp +++ b/nano/nano_wallet/entry.cpp @@ -147,7 +147,7 @@ public: { auto transaction (wallet->wallets.tx_begin_write ()); auto existing (wallet->store.begin (transaction)); - if (existing != wallet->store.end ()) + if (existing != wallet->store.end (transaction)) { wallet_config.account = existing->first; } diff --git a/nano/node/backlog_population.cpp b/nano/node/backlog_population.cpp index cb121dcb6..284b7c599 100644 --- a/nano/node/backlog_population.cpp +++ b/nano/node/backlog_population.cpp @@ -96,7 +96,7 @@ void nano::backlog_population::populate_backlog (nano::unique_lock auto transaction = ledger.tx_begin_read (); auto it = ledger.store.account.begin (transaction, next); - auto const end = ledger.store.account.end (); + auto const end = ledger.store.account.end (transaction); auto should_refresh = [&transaction] () { auto cutoff = std::chrono::steady_clock::now () - 100ms; // TODO: Make this configurable diff --git a/nano/node/bootstrap/bootstrap_frontier.cpp b/nano/node/bootstrap/bootstrap_frontier.cpp index b0b951b55..db696dbd6 100644 --- a/nano/node/bootstrap/bootstrap_frontier.cpp +++ b/nano/node/bootstrap/bootstrap_frontier.cpp @@ -239,7 +239,7 @@ void nano::frontier_req_client::next () { std::size_t max_size (128); auto transaction (node->store.tx_begin_read ()); - for (auto i (node->store.account.begin (transaction, current.number () + 1)), n (node->store.account.end ()); i != n && accounts.size () != max_size; ++i) + for (auto i (node->store.account.begin (transaction, current.number () + 1)), n (node->store.account.end (transaction)); i != n && accounts.size () != max_size; ++i) { nano::account_info const & info (i->second); nano::account const & account (i->first); @@ -381,7 +381,7 @@ void nano::frontier_req_server::next () auto transaction (node->store.tx_begin_read ()); if (!send_confirmed ()) { - for (auto i (node->store.account.begin (transaction, current.number () + 1)), n (node->store.account.end ()); i != n && accounts.size () != max_size; ++i) + for (auto i (node->store.account.begin (transaction, current.number () + 1)), n (node->store.account.end (transaction)); i != n && accounts.size () != max_size; ++i) { nano::account_info const & info (i->second); if (disable_age_filter || (now - info.modified) <= request->age) @@ -393,7 +393,7 @@ void nano::frontier_req_server::next () } else { - for (auto i (node->store.confirmation_height.begin (transaction, current.number () + 1)), n (node->store.confirmation_height.end ()); i != n && accounts.size () != max_size; ++i) + for (auto i (node->store.confirmation_height.begin (transaction, current.number () + 1)), n (node->store.confirmation_height.end (transaction)); i != n && accounts.size () != max_size; ++i) { nano::confirmation_height_info const & info (i->second); nano::block_hash const & confirmed_frontier (info.frontier); diff --git a/nano/node/bootstrap/bootstrap_server.cpp b/nano/node/bootstrap/bootstrap_server.cpp index fbe3b09f9..d8320164d 100644 --- a/nano/node/bootstrap/bootstrap_server.cpp +++ b/nano/node/bootstrap/bootstrap_server.cpp @@ -395,7 +395,7 @@ nano::asc_pull_ack nano::bootstrap_server::process (secure::transaction const & response.type = nano::asc_pull_type::frontiers; nano::asc_pull_ack::frontiers_payload response_payload{}; - for (auto it = store.account.begin (transaction, request.start), end = store.account.end (); it != end && response_payload.frontiers.size () < request.count; ++it) + for (auto it = store.account.begin (transaction, request.start), end = store.account.end (transaction); it != end && response_payload.frontiers.size () < request.count; ++it) { response_payload.frontiers.emplace_back (it->first, it->second.head); } diff --git a/nano/node/bootstrap_ascending/database_scan.cpp b/nano/node/bootstrap_ascending/database_scan.cpp index b2f5622c4..acd202431 100644 --- a/nano/node/bootstrap_ascending/database_scan.cpp +++ b/nano/node/bootstrap_ascending/database_scan.cpp @@ -77,7 +77,7 @@ std::deque nano::bootstrap_ascending::account_database_iterator:: std::deque result; auto it = ledger.store.account.begin (transaction, next); - auto const end = ledger.store.account.end (); + auto const end = ledger.store.account.end (transaction); for (size_t count = 0; it != end && count < batch_size; ++it, ++count) { @@ -115,7 +115,7 @@ std::deque nano::bootstrap_ascending::pending_database_iterator:: std::deque result; auto it = ledger.store.pending.begin (transaction, next); - auto const end = ledger.store.pending.end (); + auto const end = ledger.store.pending.end (transaction); // TODO: This pending iteration heuristic should be encapsulated in a pending_iterator class and reused across other components // The heuristic is to advance the iterator sequentially until we reach a new account or perform a fresh lookup if the account has too many pending blocks @@ -164,4 +164,4 @@ std::deque nano::bootstrap_ascending::pending_database_iterator:: bool nano::bootstrap_ascending::pending_database_iterator::warmed_up () const { return completed > 0; -} \ No newline at end of file +} diff --git a/nano/node/cli.cpp b/nano/node/cli.cpp index 75ec16624..5ebe67bbf 100644 --- a/nano/node/cli.cpp +++ b/nano/node/cli.cpp @@ -1012,7 +1012,7 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map nano::raw_key seed; existing->second->store.seed (seed, transaction); std::cout << boost::str (boost::format ("Seed: %1%\n") % seed.to_string ()); - for (auto i (existing->second->store.begin (transaction)), m (existing->second->store.end ()); i != m; ++i) + for (auto i (existing->second->store.begin (transaction)), m (existing->second->store.end (transaction)); i != m; ++i) { nano::account const & account (i->first); nano::raw_key key; @@ -1201,7 +1201,7 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map { std::cout << boost::str (boost::format ("Wallet ID: %1%\n") % i->first.to_string ()); auto transaction (i->second->wallets.tx_begin_read ()); - for (auto j (i->second->store.begin (transaction)), m (i->second->store.end ()); j != m; ++j) + for (auto j (i->second->store.begin (transaction)), m (i->second->store.end (transaction)); j != m; ++j) { std::cout << nano::account (j->first).to_account () << '\n'; } @@ -1224,7 +1224,7 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map { auto transaction (wallet->second->wallets.tx_begin_write ()); auto account (wallet->second->store.find (transaction, account_id)); - if (account != wallet->second->store.end ()) + if (account != wallet->second->store.end (transaction)) { wallet->second->store.erase (transaction, account_id); } diff --git a/nano/node/epoch_upgrader.cpp b/nano/node/epoch_upgrader.cpp index a2fa389c5..6667e7e20 100644 --- a/nano/node/epoch_upgrader.cpp +++ b/nano/node/epoch_upgrader.cpp @@ -116,7 +116,7 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc { auto transaction (store.tx_begin_read ()); // Collect accounts to upgrade - for (auto i (store.account.begin (transaction)), n (store.account.end ()); i != n && accounts_list.size () < count_limit; ++i) + for (auto i (store.account.begin (transaction)), n (store.account.end (transaction)); i != n && accounts_list.size () < count_limit; ++i) { nano::account const & account (i->first); nano::account_info const & info (i->second); diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index 299acd94a..591ce4b99 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -207,7 +207,7 @@ bool nano::json_handler::wallet_account_impl (store::transaction const & transac bool result (false); if (!ec) { - if (wallet_a->store.find (transaction_a, account_a) != wallet_a->store.end ()) + if (wallet_a->store.find (transaction_a, account_a) != wallet_a->store.end (transaction_a)) { result = true; } @@ -718,7 +718,7 @@ void nano::json_handler::account_list () { boost::property_tree::ptree accounts; auto transaction (node.wallets.tx_begin_read ()); - for (auto i (wallet->store.begin (transaction)), j (wallet->store.end ()); i != j; ++i) + for (auto i (wallet->store.begin (transaction)), j (wallet->store.end (transaction)); i != j; ++i) { boost::property_tree::ptree entry; entry.put ("", nano::account (i->first).to_account ()); @@ -1030,7 +1030,7 @@ void nano::json_handler::accounts_receivable () if (!ec) { boost::property_tree::ptree peers_l; - for (auto i (node.store.pending.begin (transaction, nano::pending_key (account, 0))), n (node.store.pending.end ()); i != n && nano::pending_key (i->first).account == account && peers_l.size () < count; ++i) + for (auto i (node.store.pending.begin (transaction, nano::pending_key (account, 0))), n (node.store.pending.end (transaction)); i != n && nano::pending_key (i->first).account == account && peers_l.size () < count; ++i) { nano::pending_key const & key (i->first); if (block_confirmed (node, transaction, key.hash, include_active, include_only_confirmed)) @@ -2240,7 +2240,7 @@ void nano::json_handler::delegators () { auto transaction (node.ledger.tx_begin_read ()); boost::property_tree::ptree delegators; - for (auto i (node.store.account.begin (transaction, start_account.number () + 1)), n (node.store.account.end ()); i != n && delegators.size () < count; ++i) + for (auto i (node.store.account.begin (transaction, start_account.number () + 1)), n (node.store.account.end (transaction)); i != n && delegators.size () < count; ++i) { nano::account_info const & info (i->second); if (info.representative == representative) @@ -2266,7 +2266,7 @@ void nano::json_handler::delegators_count () { uint64_t count (0); auto transaction (node.ledger.tx_begin_read ()); - for (auto i (node.store.account.begin (transaction)), n (node.store.account.end ()); i != n; ++i) + for (auto i (node.store.account.begin (transaction)), n (node.store.account.end (transaction)); i != n; ++i) { nano::account_info const & info (i->second); if (info.representative == account) @@ -2377,7 +2377,7 @@ void nano::json_handler::frontiers () { boost::property_tree::ptree frontiers; auto transaction (node.ledger.tx_begin_read ()); - for (auto i (node.store.account.begin (transaction, start)), n (node.store.account.end ()); i != n && frontiers.size () < count; ++i) + for (auto i (node.store.account.begin (transaction, start)), n (node.store.account.end (transaction)); i != n && frontiers.size () < count; ++i) { frontiers.put (i->first.to_account (), i->second.head.to_string ()); } @@ -2780,7 +2780,7 @@ void nano::json_handler::ledger () auto transaction = node.ledger.tx_begin_read (); if (!ec && !sorting) // Simple { - for (auto i (node.store.account.begin (transaction, start)), n (node.store.account.end ()); i != n && accounts.size () < count; ++i) + for (auto i (node.store.account.begin (transaction, start)), n (node.store.account.end (transaction)); i != n && accounts.size () < count; ++i) { nano::account_info const & info (i->second); if (info.modified >= modified_since && (receivable || info.balance.number () >= threshold.number ())) @@ -2821,7 +2821,7 @@ void nano::json_handler::ledger () else if (!ec) // Sorting { std::vector> ledger_l; - for (auto i (node.store.account.begin (transaction, start)), n (node.store.account.end ()); i != n; ++i) + for (auto i (node.store.account.begin (transaction, start)), n (node.store.account.end (transaction)); i != n; ++i) { nano::account_info const & info (i->second); nano::uint128_union balance (info.balance); @@ -3055,7 +3055,7 @@ void nano::json_handler::receivable () // The ptree container is used if there are any children nodes (e.g source/min_version) otherwise the amount container is used. std::vector> hash_ptree_pairs; std::vector> hash_amount_pairs; - for (auto i (node.store.pending.begin (transaction, nano::pending_key (account, 0))), n (node.store.pending.end ()); i != n && nano::pending_key (i->first).account == account && (should_sort || peers_l.size () < count); ++i) + for (auto i (node.store.pending.begin (transaction, nano::pending_key (account, 0))), n (node.store.pending.end (transaction)); i != n && nano::pending_key (i->first).account == account && (should_sort || peers_l.size () < count); ++i) { nano::pending_key const & key (i->first); if (block_confirmed (node, transaction, key.hash, include_active, include_only_confirmed)) @@ -4240,7 +4240,7 @@ void nano::json_handler::unopened () { auto transaction = node.store.tx_begin_read (); auto iterator = node.store.pending.begin (transaction, nano::pending_key (start, 0)); - auto end = node.store.pending.end (); + auto end = node.store.pending.end (transaction); nano::account current_account = start; nano::uint128_t current_account_sum{ 0 }; boost::property_tree::ptree accounts; @@ -4392,7 +4392,7 @@ void nano::json_handler::wallet_info () uint64_t adhoc_count (0); auto transaction (node.wallets.tx_begin_read ()); auto block_transaction = node.ledger.tx_begin_read (); - for (auto i (wallet->store.begin (transaction)), n (wallet->store.end ()); i != n; ++i) + for (auto i (wallet->store.begin (transaction)), n (wallet->store.end (transaction)); i != n; ++i) { nano::account const & account (i->first); @@ -4448,7 +4448,7 @@ void nano::json_handler::wallet_balances () boost::property_tree::ptree balances; auto transaction (node.wallets.tx_begin_read ()); auto block_transaction = node.ledger.tx_begin_read (); - for (auto i (wallet->store.begin (transaction)), n (wallet->store.end ()); i != n; ++i) + for (auto i (wallet->store.begin (transaction)), n (wallet->store.end (transaction)); i != n; ++i) { nano::account const & account (i->first); nano::uint128_t balance = node.ledger.any.account_balance (block_transaction, account).value_or (0).number (); @@ -4509,7 +4509,7 @@ void nano::json_handler::wallet_contains () if (!ec) { auto transaction (node.wallets.tx_begin_read ()); - auto exists (wallet->store.find (transaction, account) != wallet->store.end ()); + auto exists (wallet->store.find (transaction, account) != wallet->store.end (transaction)); response_l.put ("exists", exists ? "1" : "0"); } response_errors (); @@ -4599,7 +4599,7 @@ void nano::json_handler::wallet_frontiers () boost::property_tree::ptree frontiers; auto transaction (node.wallets.tx_begin_read ()); auto block_transaction = node.ledger.tx_begin_read (); - for (auto i (wallet->store.begin (transaction)), n (wallet->store.end ()); i != n; ++i) + for (auto i (wallet->store.begin (transaction)), n (wallet->store.end (transaction)); i != n; ++i) { nano::account const & account (i->first); auto latest (node.ledger.any.account_head (block_transaction, account)); @@ -4630,7 +4630,7 @@ void nano::json_handler::wallet_history () std::multimap> entries; auto transaction (node.wallets.tx_begin_read ()); auto block_transaction = node.ledger.tx_begin_read (); - for (auto i (wallet->store.begin (transaction)), n (wallet->store.end ()); i != n; ++i) + for (auto i (wallet->store.begin (transaction)), n (wallet->store.end (transaction)); i != n; ++i) { nano::account const & account (i->first); auto info = node.ledger.any.account_get (block_transaction, account); @@ -4704,7 +4704,7 @@ void nano::json_handler::wallet_ledger () boost::property_tree::ptree accounts; auto transaction (node.wallets.tx_begin_read ()); auto block_transaction = node.ledger.tx_begin_read (); - for (auto i (wallet->store.begin (transaction)), n (wallet->store.end ()); i != n; ++i) + for (auto i (wallet->store.begin (transaction)), n (wallet->store.end (transaction)); i != n; ++i) { nano::account const & account (i->first); auto info = node.ledger.any.account_get (block_transaction, account); @@ -4780,11 +4780,11 @@ void nano::json_handler::wallet_receivable () boost::property_tree::ptree pending; auto transaction (node.wallets.tx_begin_read ()); auto block_transaction = node.ledger.tx_begin_read (); - for (auto i (wallet->store.begin (transaction)), n (wallet->store.end ()); i != n; ++i) + for (auto i (wallet->store.begin (transaction)), n (wallet->store.end (transaction)); i != n; ++i) { nano::account const & account (i->first); boost::property_tree::ptree peers_l; - for (auto ii (node.store.pending.begin (block_transaction, nano::pending_key (account, 0))), nn (node.store.pending.end ()); ii != nn && nano::pending_key (ii->first).account == account && peers_l.size () < count; ++ii) + for (auto ii (node.store.pending.begin (block_transaction, nano::pending_key (account, 0))), nn (node.store.pending.end (block_transaction)); ii != nn && nano::pending_key (ii->first).account == account && peers_l.size () < count; ++ii) { nano::pending_key key (ii->first); if (block_confirmed (node, block_transaction, key.hash, include_active, include_only_confirmed)) @@ -4871,7 +4871,7 @@ void nano::json_handler::wallet_representative_set () { auto transaction (rpc_l->node.wallets.tx_begin_read ()); auto block_transaction = rpc_l->node.ledger.tx_begin_read (); - for (auto i (wallet->store.begin (transaction)), n (wallet->store.end ()); i != n; ++i) + for (auto i (wallet->store.begin (transaction)), n (wallet->store.end (transaction)); i != n; ++i) { nano::account const & account (i->first); auto info = rpc_l->node.ledger.any.account_get (block_transaction, account); @@ -4905,7 +4905,7 @@ void nano::json_handler::wallet_republish () std::deque> republish_bundle; auto transaction (node.wallets.tx_begin_read ()); auto block_transaction = node.ledger.tx_begin_read (); - for (auto i (wallet->store.begin (transaction)), n (wallet->store.end ()); i != n; ++i) + for (auto i (wallet->store.begin (transaction)), n (wallet->store.end (transaction)); i != n; ++i) { nano::account const & account (i->first); auto latest (node.ledger.any.account_head (block_transaction, account)); @@ -4967,7 +4967,7 @@ void nano::json_handler::wallet_work_get () { boost::property_tree::ptree works; auto transaction (node.wallets.tx_begin_read ()); - for (auto i (wallet->store.begin (transaction)), n (wallet->store.end ()); i != n; ++i) + for (auto i (wallet->store.begin (transaction)), n (wallet->store.end (transaction)); i != n; ++i) { nano::account const & account (i->first); uint64_t work (0); diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 313a18768..229d17ce1 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -311,7 +311,7 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy auto is_initialized (false); { auto const transaction (store.tx_begin_read ()); - is_initialized = (store.account.begin (transaction) != store.account.end ()); + is_initialized = (store.account.begin (transaction) != store.account.end (transaction)); } if (!is_initialized && !flags.read_only) @@ -754,7 +754,7 @@ void nano::node::long_inactivity_cleanup () if (store.online_weight.count (transaction) > 0) { auto sample (store.online_weight.rbegin (transaction)); - auto n (store.online_weight.end ()); + auto n (store.online_weight.end (transaction)); debug_assert (sample != n); auto const one_week_ago = static_cast ((std::chrono::system_clock::now () - std::chrono::hours (7 * 24)).time_since_epoch ().count ()); perform_cleanup = sample->first < one_week_ago; @@ -803,7 +803,7 @@ void nano::node::ongoing_bootstrap () { auto transaction = store.tx_begin_read (); auto last_record = store.online_weight.rbegin (transaction); - if (last_record != store.online_weight.end ()) + if (last_record != store.online_weight.end (transaction)) { last_sample_time = last_record->first; } @@ -870,7 +870,7 @@ void nano::node::bootstrap_wallet () { auto & wallet (*i->second); nano::lock_guard wallet_lock{ wallet.store.mutex }; - for (auto j (wallet.store.begin (transaction)), m (wallet.store.end ()); j != m && accounts.size () < 128; ++j) + for (auto j (wallet.store.begin (transaction)), m (wallet.store.end (transaction)); j != m && accounts.size () < 128; ++j) { nano::account account (j->first); accounts.push_back (account); @@ -888,7 +888,7 @@ bool nano::node::collect_ledger_pruning_targets (std::deque & uint64_t read_operations (0); bool finish_transaction (false); auto transaction = ledger.tx_begin_read (); - for (auto i (store.confirmation_height.begin (transaction, last_account_a)), n (store.confirmation_height.end ()); i != n && !finish_transaction;) + for (auto i (store.confirmation_height.begin (transaction, last_account_a)), n (store.confirmation_height.end (transaction)); i != n && !finish_transaction;) { ++read_operations; auto const & account (i->first); diff --git a/nano/node/online_reps.cpp b/nano/node/online_reps.cpp index 72842ec2e..b04912820 100644 --- a/nano/node/online_reps.cpp +++ b/nano/node/online_reps.cpp @@ -45,7 +45,7 @@ void nano::online_reps::sample () while (ledger.store.online_weight.count (transaction) >= config.network_params.node.max_weight_samples) { auto oldest (ledger.store.online_weight.begin (transaction)); - debug_assert (oldest != ledger.store.online_weight.end ()); + debug_assert (oldest != ledger.store.online_weight.end (transaction)); ledger.store.online_weight.del (transaction, oldest->first); } ledger.store.online_weight.put (transaction, std::chrono::system_clock::now ().time_since_epoch ().count (), online_l); @@ -70,7 +70,7 @@ nano::uint128_t nano::online_reps::calculate_trend (store::transaction & transac std::vector items; items.reserve (config.network_params.node.max_weight_samples + 1); items.push_back (config.online_weight_minimum.number ()); - for (auto i (ledger.store.online_weight.begin (transaction_a)), n (ledger.store.online_weight.end ()); i != n; ++i) + for (auto i (ledger.store.online_weight.begin (transaction_a)), n (ledger.store.online_weight.end (transaction_a)); i != n; ++i) { items.push_back (i->second.number ()); } diff --git a/nano/node/peer_history.cpp b/nano/node/peer_history.cpp index 1c605d901..99b96ed1a 100644 --- a/nano/node/peer_history.cpp +++ b/nano/node/peer_history.cpp @@ -104,7 +104,7 @@ void nano::peer_history::run_one () auto const now = std::chrono::system_clock::now (); auto const cutoff = now - config.erase_cutoff; - for (auto it = store.peer.begin (transaction); it != store.peer.end (); ++it) + for (auto it = store.peer.begin (transaction); it != store.peer.end (transaction); ++it) { auto const [endpoint, timestamp_millis] = *it; auto timestamp = nano::from_milliseconds_since_epoch (timestamp_millis); @@ -124,7 +124,7 @@ std::vector nano::peer_history::peers () const { auto transaction = store.tx_begin_read (); std::vector peers; - for (auto it = store.peer.begin (transaction); it != store.peer.end (); ++it) + for (auto it = store.peer.begin (transaction); it != store.peer.end (transaction); ++it) { auto const [endpoint, timestamp_millis] = *it; peers.push_back (endpoint.endpoint ()); diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index a1f46c78f..536441690 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -114,7 +114,7 @@ void nano::wallet_store::deterministic_index_set (store::transaction const & tra void nano::wallet_store::deterministic_clear (store::transaction const & transaction_a) { nano::uint256_union key (0); - for (auto i (begin (transaction_a)), n (end ()); i != n;) + for (auto i (begin (transaction_a)), n (end (transaction_a)); i != n;) { switch (key_type (nano::wallet_value (i->second))) { @@ -370,7 +370,7 @@ nano::wallet_store::wallet_store (bool & init_a, nano::kdf & kdf_a, store::trans std::vector nano::wallet_store::accounts (store::transaction const & transaction_a) { std::vector result; - for (auto i (begin (transaction_a)), n (end ()); i != n; ++i) + for (auto i (begin (transaction_a)), n (end (transaction_a)); i != n; ++i) { nano::account const & account (i->first); result.push_back (account); @@ -542,7 +542,7 @@ bool nano::wallet_store::valid_public_key (nano::public_key const & pub) bool nano::wallet_store::exists (store::transaction const & transaction_a, nano::public_key const & pub) { - return valid_public_key (pub) && find (transaction_a, pub) != end (); + return valid_public_key (pub) && find (transaction_a, pub) != end (transaction_a); } void nano::wallet_store::serialize_json (store::transaction const & transaction_a, std::string & string_a) @@ -597,7 +597,7 @@ bool nano::wallet_store::import (store::transaction const & transaction_a, nano: debug_assert (valid_password (transaction_a)); debug_assert (other_a.valid_password (transaction_a)); auto result (false); - for (auto i (other_a.begin (transaction_a)), n (end ()); i != n; ++i) + for (auto i (other_a.begin (transaction_a)), n (end (transaction_a)); i != n; ++i) { nano::raw_key prv; auto error (other_a.fetch (transaction_a, i->first, prv)); @@ -910,7 +910,7 @@ std::shared_ptr nano::wallet::change_action (nano::account const & if (store.valid_password (transaction)) { auto existing (store.find (transaction, source_a)); - if (existing != store.end () && !wallets.node.ledger.any.account_head (block_transaction, source_a).is_zero ()) + if (existing != store.end (transaction) && !wallets.node.ledger.any.account_head (block_transaction, source_a).is_zero ()) { auto info = wallets.node.ledger.any.account_get (block_transaction, source_a); debug_assert (info); @@ -977,7 +977,7 @@ std::shared_ptr nano::wallet::send_action (nano::account const & so if (store.valid_password (transaction)) { auto existing (store.find (transaction, source_a)); - if (existing != store.end ()) + if (existing != store.end (transaction)) { auto balance (wallets.node.ledger.any.account_balance (block_transaction, source_a)); if (balance && balance.value ().number () >= amount_a) @@ -1178,14 +1178,14 @@ bool nano::wallet::search_receivable (store::transaction const & wallet_transact { wallets.node.logger.info (nano::log::type::wallet, "Beginning receivable block search"); - for (auto i (store.begin (wallet_transaction_a)), n (store.end ()); i != n; ++i) + for (auto i (store.begin (wallet_transaction_a)), n (store.end (wallet_transaction_a)); i != n; ++i) { auto block_transaction = wallets.node.ledger.tx_begin_read (); nano::account const & account (i->first); // Don't search pending for watch-only accounts if (!nano::wallet_value (i->second).key.is_zero ()) { - for (auto j (wallets.node.store.pending.begin (block_transaction, nano::pending_key (account, 0))), k (wallets.node.store.pending.end ()); j != k && nano::pending_key (j->first).account == account; ++j) + for (auto j (wallets.node.store.pending.begin (block_transaction, nano::pending_key (account, 0))), k (wallets.node.store.pending.end (block_transaction)); j != k && nano::pending_key (j->first).account == account; ++j) { nano::pending_key key (j->first); auto hash (key.hash); @@ -1227,7 +1227,7 @@ bool nano::wallet::search_receivable (store::transaction const & wallet_transact void nano::wallet::init_free_accounts (store::transaction const & transaction_a) { free_accounts.clear (); - for (auto i (store.begin (transaction_a)), n (store.end ()); i != n; ++i) + for (auto i (store.begin (transaction_a)), n (store.end (transaction_a)); i != n; ++i) { free_accounts.insert (i->first); } @@ -1686,7 +1686,7 @@ void nano::wallets::compute_reps () { auto & wallet (*i->second); decltype (wallet.representatives) representatives_l; - for (auto ii (wallet.store.begin (transaction)), nn (wallet.store.end ()); ii != nn; ++ii) + for (auto ii (wallet.store.begin (transaction)), nn (wallet.store.end (transaction)); ii != nn; ++ii) { auto account (ii->first); if (check_rep (account, half_principal_weight, false)) @@ -1787,7 +1787,7 @@ auto nano::wallet_store::find (store::transaction const & transaction_a, nano::a return result; } -auto nano::wallet_store::end () -> iterator +auto nano::wallet_store::end (store::transaction const & transaction_a) -> iterator { return iterator{ nullptr }; } diff --git a/nano/node/wallet.hpp b/nano/node/wallet.hpp index ef26f4b0b..f3daef817 100644 --- a/nano/node/wallet.hpp +++ b/nano/node/wallet.hpp @@ -95,7 +95,7 @@ public: iterator find (store::transaction const &, nano::account const &); iterator begin (store::transaction const &, nano::account const &); iterator begin (store::transaction const &); - iterator end (); + iterator end (store::transaction const &); void derive_key (nano::raw_key &, store::transaction const &, std::string const &); void serialize_json (store::transaction const &, std::string &); void write_backup (store::transaction const &, std::filesystem::path const &); diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index aefd693bd..48466d012 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -268,7 +268,7 @@ void nano_qt::accounts::refresh_wallet_balance () auto block_transaction = this->wallet.node.ledger.tx_begin_read (); nano::uint128_t balance (0); nano::uint128_t pending (0); - for (auto i (this->wallet.wallet_m->store.begin (transaction)), j (this->wallet.wallet_m->store.end ()); i != j; ++i) + for (auto i (this->wallet.wallet_m->store.begin (transaction)), j (this->wallet.wallet_m->store.end (transaction)); i != j; ++i) { nano::public_key const & key (i->first); balance = balance + this->wallet.node.ledger.any.account_balance (block_transaction, key).value_or (0).number (); @@ -293,7 +293,7 @@ void nano_qt::accounts::refresh () auto transaction (wallet.wallet_m->wallets.tx_begin_read ()); auto block_transaction = this->wallet.node.ledger.tx_begin_read (); QBrush brush; - for (auto i (wallet.wallet_m->store.begin (transaction)), j (wallet.wallet_m->store.end ()); i != j; ++i) + for (auto i (wallet.wallet_m->store.begin (transaction)), j (wallet.wallet_m->store.end (transaction)); i != j; ++i) { nano::public_key key (i->first); auto balance_amount = wallet.node.ledger.any.account_balance (block_transaction, key).value_or (0).number (); @@ -1973,7 +1973,7 @@ void nano_qt::advanced_actions::refresh_ledger () { ledger_model->removeRows (0, ledger_model->rowCount ()); auto transaction (wallet.node.ledger.tx_begin_read ()); - for (auto i (wallet.node.ledger.store.account.begin (transaction)), j (wallet.node.ledger.store.account.end ()); i != j; ++i) + for (auto i (wallet.node.ledger.store.account.begin (transaction)), j (wallet.node.ledger.store.account.end (transaction)); i != j; ++i) { QList items; items.push_back (new QStandardItem (QString (i->first.to_account ().c_str ()))); diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 1efdeacaf..a13926989 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -721,7 +721,7 @@ TEST (rpc, account_move) ASSERT_TRUE (destination->exists (key.pub)); ASSERT_TRUE (destination->exists (nano::dev::genesis_key.pub)); auto transaction (node->wallets.tx_begin_read ()); - ASSERT_EQ (source->store.end (), source->store.begin (transaction)); + ASSERT_EQ (source->store.end (transaction), source->store.begin (transaction)); } TEST (rpc, block) @@ -6212,7 +6212,7 @@ TEST (rpc, epoch_upgrade) { auto transaction (node->ledger.tx_begin_read ()); ASSERT_EQ (2, node->store.account.count (transaction)); - for (auto i (node->store.account.begin (transaction)); i != node->store.account.end (); ++i) + for (auto i (node->store.account.begin (transaction)); i != node->store.account.end (transaction); ++i) { nano::account_info info (i->second); ASSERT_EQ (info.epoch (), nano::epoch::epoch_0); @@ -6230,7 +6230,7 @@ TEST (rpc, epoch_upgrade) { auto transaction (node->ledger.tx_begin_read ()); ASSERT_EQ (4, node->store.account.count (transaction)); - for (auto i (node->store.account.begin (transaction)); i != node->store.account.end (); ++i) + for (auto i (node->store.account.begin (transaction)); i != node->store.account.end (transaction); ++i) { nano::account_info info (i->second); ASSERT_EQ (info.epoch (), nano::epoch::epoch_1); @@ -6293,7 +6293,7 @@ TEST (rpc, epoch_upgrade) { auto transaction (node->ledger.tx_begin_read ()); ASSERT_EQ (5, node->store.account.count (transaction)); - for (auto i (node->store.account.begin (transaction)); i != node->store.account.end (); ++i) + for (auto i (node->store.account.begin (transaction)); i != node->store.account.end (transaction); ++i) { nano::account_info info (i->second); ASSERT_EQ (info.epoch (), nano::epoch::epoch_2); @@ -6375,7 +6375,7 @@ TEST (rpc, epoch_upgrade_multithreaded) { auto transaction (node->ledger.tx_begin_read ()); ASSERT_EQ (2, node->store.account.count (transaction)); - for (auto i (node->store.account.begin (transaction)); i != node->store.account.end (); ++i) + for (auto i (node->store.account.begin (transaction)); i != node->store.account.end (transaction); ++i) { nano::account_info info (i->second); ASSERT_EQ (info.epoch (), nano::epoch::epoch_0); @@ -6394,7 +6394,7 @@ TEST (rpc, epoch_upgrade_multithreaded) { auto transaction (node->ledger.tx_begin_read ()); ASSERT_EQ (4, node->store.account.count (transaction)); - for (auto i (node->store.account.begin (transaction)); i != node->store.account.end (); ++i) + for (auto i (node->store.account.begin (transaction)); i != node->store.account.end (transaction); ++i) { nano::account_info info (i->second); ASSERT_EQ (info.epoch (), nano::epoch::epoch_1); @@ -6457,7 +6457,7 @@ TEST (rpc, epoch_upgrade_multithreaded) { auto transaction (node->ledger.tx_begin_read ()); ASSERT_EQ (5, node->store.account.count (transaction)); - for (auto i (node->store.account.begin (transaction)); i != node->store.account.end (); ++i) + for (auto i (node->store.account.begin (transaction)); i != node->store.account.end (transaction); ++i) { nano::account_info info (i->second); ASSERT_EQ (info.epoch (), nano::epoch::epoch_2); diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index 93eb61cea..ec5aa666d 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -1429,12 +1429,12 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (std::filesystem::path const & data_p auto rocksdb_transaction (rocksdb_store->tx_begin_write ()); rocksdb_store->version.put (rocksdb_transaction, version); - for (auto i (store.online_weight.begin (lmdb_transaction)), n (store.online_weight.end ()); i != n; ++i) + for (auto i (store.online_weight.begin (lmdb_transaction)), n (store.online_weight.end (lmdb_transaction)); i != n; ++i) { rocksdb_store->online_weight.put (rocksdb_transaction, i->first, i->second); } - for (auto i (store.peer.begin (lmdb_transaction)), n (store.peer.end ()); i != n; ++i) + for (auto i (store.peer.begin (lmdb_transaction)), n (store.peer.end (lmdb_transaction)); i != n; ++i) { rocksdb_store->peer.put (rocksdb_transaction, i->first, i->second); } diff --git a/nano/secure/ledger_set_any.cpp b/nano/secure/ledger_set_any.cpp index 13e3b2c1f..67b14fda1 100644 --- a/nano/secure/ledger_set_any.cpp +++ b/nano/secure/ledger_set_any.cpp @@ -60,7 +60,7 @@ uint64_t nano::ledger_set_any::account_height (secure::transaction const & trans auto nano::ledger_set_any::account_lower_bound (secure::transaction const & transaction, nano::account const & account) const -> account_iterator { auto disk = ledger.store.account.begin (transaction, account); - if (disk == ledger.store.account.end ()) + if (disk == ledger.store.account.end (transaction)) { return account_iterator{}; } @@ -153,7 +153,7 @@ uint64_t nano::ledger_set_any::block_height (secure::transaction const & transac std::optional> nano::ledger_set_any::receivable_lower_bound (secure::transaction const & transaction, nano::account const & account, nano::block_hash const & hash) const { auto result = ledger.store.pending.begin (transaction, { account, hash }); - if (result == ledger.store.pending.end ()) + if (result == ledger.store.pending.end (transaction)) { return std::nullopt; } diff --git a/nano/secure/ledger_set_confirmed.cpp b/nano/secure/ledger_set_confirmed.cpp index 9fe36d941..8702d61b4 100644 --- a/nano/secure/ledger_set_confirmed.cpp +++ b/nano/secure/ledger_set_confirmed.cpp @@ -108,11 +108,11 @@ auto nano::ledger_set_confirmed::receivable_upper_bound (secure::transaction con std::optional> nano::ledger_set_confirmed::receivable_lower_bound (secure::transaction const & transaction, nano::account const & account, nano::block_hash const & hash) const { auto result = ledger.store.pending.begin (transaction, { account, hash }); - while (result != ledger.store.pending.end () && !block_exists (transaction, result->first.hash)) + while (result != ledger.store.pending.end (transaction) && !block_exists (transaction, result->first.hash)) { ++result; } - if (result == ledger.store.pending.end ()) + if (result == ledger.store.pending.end (transaction)) { return std::nullopt; } diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 5ffca07c6..c49f4d84d 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -37,7 +37,7 @@ size_t manually_count_pruned_blocks (nano::store::component & store) size_t count = 0; auto transaction = store.tx_begin_read (); auto i = store.pruned.begin (transaction); - for (; i != store.pruned.end (); ++i) + for (; i != store.pruned.end (transaction); ++i) { ++count; } @@ -54,7 +54,7 @@ TEST (system, generate_mass_activity) uint32_t count (20); system.generate_mass_activity (count, *system.nodes[0]); auto transaction (system.nodes[0]->store.tx_begin_read ()); - for (auto i (system.nodes[0]->store.account.begin (transaction)), n (system.nodes[0]->store.account.end ()); i != n; ++i) + for (auto i (system.nodes[0]->store.account.begin (transaction)), n (system.nodes[0]->store.account.end (transaction)); i != n; ++i) { } } @@ -76,7 +76,7 @@ TEST (system, generate_mass_activity_long) } system.generate_mass_activity (count, *system.nodes[0]); auto transaction (system.nodes[0]->store.tx_begin_read ()); - for (auto i (system.nodes[0]->store.account.begin (transaction)), n (system.nodes[0]->store.account.end ()); i != n; ++i) + for (auto i (system.nodes[0]->store.account.begin (transaction)), n (system.nodes[0]->store.account.end (transaction)); i != n; ++i) { } system.stop (); @@ -694,7 +694,7 @@ TEST (confirmation_height, many_accounts_single_confirmation) // All frontiers (except last) should have 2 blocks and both should be confirmed auto transaction = node->store.tx_begin_read (); - for (auto i (node->store.account.begin (transaction)), n (node->store.account.end ()); i != n; ++i) + for (auto i (node->store.account.begin (transaction)), n (node->store.account.end (transaction)); i != n; ++i) { auto & account = i->first; auto & account_info = i->second; @@ -706,7 +706,7 @@ TEST (confirmation_height, many_accounts_single_confirmation) } size_t cemented_count = 0; - for (auto i (node->ledger.store.confirmation_height.begin (transaction)), n (node->ledger.store.confirmation_height.end ()); i != n; ++i) + for (auto i (node->ledger.store.confirmation_height.begin (transaction)), n (node->ledger.store.confirmation_height.end (transaction)); i != n; ++i) { cemented_count += i->second.height; } @@ -782,7 +782,7 @@ TEST (confirmation_height, many_accounts_many_confirmations) auto transaction = node->store.tx_begin_read (); size_t cemented_count = 0; - for (auto i (node->ledger.store.confirmation_height.begin (transaction)), n (node->ledger.store.confirmation_height.end ()); i != n; ++i) + for (auto i (node->ledger.store.confirmation_height.begin (transaction)), n (node->ledger.store.confirmation_height.end (transaction)); i != n; ++i) { cemented_count += i->second.height; } @@ -925,7 +925,7 @@ TEST (confirmation_height, long_chains) ASSERT_EQ (num_blocks + 1, info->block_count); size_t cemented_count = 0; - for (auto i (node->ledger.store.confirmation_height.begin (transaction)), n (node->ledger.store.confirmation_height.end ()); i != n; ++i) + for (auto i (node->ledger.store.confirmation_height.begin (transaction)), n (node->ledger.store.confirmation_height.end (transaction)); i != n; ++i) { cemented_count += i->second.height; } @@ -1098,7 +1098,7 @@ TEST (confirmation_height, many_accounts_send_receive_self) auto transaction = node->store.tx_begin_read (); size_t cemented_count = 0; - for (auto i (node->ledger.store.confirmation_height.begin (transaction)), n (node->ledger.store.confirmation_height.end ()); i != n; ++i) + for (auto i (node->ledger.store.confirmation_height.begin (transaction)), n (node->ledger.store.confirmation_height.end (transaction)); i != n; ++i) { cemented_count += i->second.height; } @@ -1252,7 +1252,7 @@ TEST (confirmation_height, many_accounts_send_receive_self_no_elections) auto transaction = store->tx_begin_read (); size_t cemented_count = 0; - for (auto i (store->confirmation_height.begin (transaction)), n (store->confirmation_height.end ()); i != n; ++i) + for (auto i (store->confirmation_height.begin (transaction)), n (store->confirmation_height.end (transaction)); i != n; ++i) { cemented_count += i->second.height; } @@ -1746,7 +1746,7 @@ TEST (node, mass_epoch_upgrader) { auto transaction (node.store.tx_begin_read ()); size_t block_count_sum = 0; - for (auto i (node.store.account.begin (transaction)); i != node.store.account.end (); ++i) + for (auto i (node.store.account.begin (transaction)); i != node.store.account.end (transaction); ++i) { nano::account_info info (i->second); ASSERT_EQ (info.epoch (), nano::epoch::epoch_1); diff --git a/nano/store/account.hpp b/nano/store/account.hpp index ffa05de08..cc9b93f68 100644 --- a/nano/store/account.hpp +++ b/nano/store/account.hpp @@ -32,7 +32,7 @@ public: virtual iterator begin (store::transaction const &, nano::account const &) const = 0; virtual iterator begin (store::transaction const &) const = 0; virtual iterator rbegin (store::transaction const &) const = 0; - virtual iterator end () const = 0; + virtual iterator end (store::transaction const & transaction_a) const = 0; virtual void for_each_par (std::function const &) const = 0; }; } // namespace nano::store diff --git a/nano/store/block.hpp b/nano/store/block.hpp index acd2ba72f..cf0464a52 100644 --- a/nano/store/block.hpp +++ b/nano/store/block.hpp @@ -36,7 +36,7 @@ public: virtual uint64_t count (store::transaction const &) = 0; virtual iterator begin (store::transaction const &, nano::block_hash const &) const = 0; virtual iterator begin (store::transaction const &) const = 0; - virtual iterator end () const = 0; + virtual iterator end (store::transaction const &) const = 0; virtual void for_each_par (std::function const & action_a) const = 0; }; } // namespace nano::store diff --git a/nano/store/component.cpp b/nano/store/component.cpp index 5d8c8bec2..ffe9c6e71 100644 --- a/nano/store/component.cpp +++ b/nano/store/component.cpp @@ -28,7 +28,7 @@ nano::store::component::component (nano::store::block & block_store_a, nano::sto void nano::store::component::initialize (store::write_transaction const & transaction_a, nano::ledger_cache & ledger_cache_a, nano::ledger_constants & constants) { debug_assert (constants.genesis->has_sideband ()); - debug_assert (account.begin (transaction_a) == account.end ()); + debug_assert (account.begin (transaction_a) == account.end (transaction_a)); auto hash_l (constants.genesis->hash ()); block.put (transaction_a, hash_l, *constants.genesis); ++ledger_cache_a.block_count; diff --git a/nano/store/confirmation_height.hpp b/nano/store/confirmation_height.hpp index 5569bec7c..de3cc89e4 100644 --- a/nano/store/confirmation_height.hpp +++ b/nano/store/confirmation_height.hpp @@ -37,7 +37,7 @@ public: virtual void clear (store::write_transaction const &) = 0; virtual iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const = 0; virtual iterator begin (store::transaction const & transaction_a) const = 0; - virtual iterator end () const = 0; + virtual iterator end (store::transaction const & transaction_a) const = 0; virtual void for_each_par (std::function const &) const = 0; }; } // namespace nano::store diff --git a/nano/store/final_vote.hpp b/nano/store/final_vote.hpp index 677159dda..e9f9e3417 100644 --- a/nano/store/final_vote.hpp +++ b/nano/store/final_vote.hpp @@ -29,7 +29,7 @@ public: virtual void clear (store::write_transaction const &) = 0; virtual iterator begin (store::transaction const & transaction_a, nano::qualified_root const & root_a) const = 0; virtual iterator begin (store::transaction const & transaction_a) const = 0; - virtual iterator end () const = 0; + virtual iterator end (store::transaction const & transaction_a) const = 0; virtual void for_each_par (std::function const & action_a) const = 0; }; } // namespace nano::store diff --git a/nano/store/lmdb/account.cpp b/nano/store/lmdb/account.cpp index e01ce6236..766daaa81 100644 --- a/nano/store/lmdb/account.cpp +++ b/nano/store/lmdb/account.cpp @@ -35,7 +35,7 @@ void nano::store::lmdb::account::del (store::write_transaction const & transacti bool nano::store::lmdb::account::exists (store::transaction const & transaction_a, nano::account const & account_a) { auto iterator (begin (transaction_a, account_a)); - return iterator != end () && nano::account (iterator->first) == account_a; + return iterator != end (transaction_a) && nano::account (iterator->first) == account_a; } size_t nano::store::lmdb::account::count (store::transaction const & transaction_a) @@ -58,7 +58,7 @@ auto nano::store::lmdb::account::rbegin (store::transaction const & transaction_ return store.make_iterator (transaction_a, tables::accounts, false); } -auto nano::store::lmdb::account::end () const -> iterator +auto nano::store::lmdb::account::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -68,6 +68,6 @@ void nano::store::lmdb::account::for_each_par (std::function ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end (transaction)); }); } diff --git a/nano/store/lmdb/account.hpp b/nano/store/lmdb/account.hpp index 6650f19fc..283083d8d 100644 --- a/nano/store/lmdb/account.hpp +++ b/nano/store/lmdb/account.hpp @@ -25,7 +25,7 @@ public: iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; iterator begin (store::transaction const & transaction_a) const override; iterator rbegin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; /** diff --git a/nano/store/lmdb/block.cpp b/nano/store/lmdb/block.cpp index 461e0b99f..72c4b0576 100644 --- a/nano/store/lmdb/block.cpp +++ b/nano/store/lmdb/block.cpp @@ -111,11 +111,11 @@ std::shared_ptr nano::store::lmdb::block::random (store::transactio nano::block_hash hash; nano::random_pool::generate_block (hash.bytes.data (), hash.bytes.size ()); auto existing = begin (transaction, hash); - if (existing == end ()) + if (existing == end (transaction)) { existing = begin (transaction); } - debug_assert (existing != end ()); + debug_assert (existing != end (transaction)); return existing->second.block; } @@ -145,7 +145,7 @@ auto nano::store::lmdb::block::begin (store::transaction const & transaction, na return store.make_iterator (transaction, tables::blocks, hash); } -auto nano::store::lmdb::block::end () const -> iterator +auto nano::store::lmdb::block::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -155,7 +155,7 @@ void nano::store::lmdb::block::for_each_par (std::function ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end (transaction)); }); } diff --git a/nano/store/lmdb/block.hpp b/nano/store/lmdb/block.hpp index 259494511..f1130feaa 100644 --- a/nano/store/lmdb/block.hpp +++ b/nano/store/lmdb/block.hpp @@ -33,7 +33,7 @@ public: uint64_t count (store::transaction const & transaction_a) override; iterator begin (store::transaction const & transaction_a) const override; iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; /** diff --git a/nano/store/lmdb/confirmation_height.cpp b/nano/store/lmdb/confirmation_height.cpp index 234c56844..c85e47547 100644 --- a/nano/store/lmdb/confirmation_height.cpp +++ b/nano/store/lmdb/confirmation_height.cpp @@ -69,7 +69,7 @@ auto nano::store::lmdb::confirmation_height::begin (store::transaction const & t return store.make_iterator (transaction, tables::confirmation_height); } -auto nano::store::lmdb::confirmation_height::end () const -> iterator +auto nano::store::lmdb::confirmation_height::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -79,6 +79,6 @@ void nano::store::lmdb::confirmation_height::for_each_par (std::function ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end (transaction)); }); } diff --git a/nano/store/lmdb/confirmation_height.hpp b/nano/store/lmdb/confirmation_height.hpp index de3532459..36acd9fc9 100644 --- a/nano/store/lmdb/confirmation_height.hpp +++ b/nano/store/lmdb/confirmation_height.hpp @@ -25,7 +25,7 @@ public: void clear (store::write_transaction const & transaction_a) override; iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; iterator begin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; /* diff --git a/nano/store/lmdb/final_vote.cpp b/nano/store/lmdb/final_vote.cpp index a26153d1f..aed69f25b 100644 --- a/nano/store/lmdb/final_vote.cpp +++ b/nano/store/lmdb/final_vote.cpp @@ -27,7 +27,7 @@ std::vector nano::store::lmdb::final_vote::get (store::transac { std::vector result; nano::qualified_root key_start{ root_a.raw, 0 }; - for (auto i = begin (transaction, key_start), n = end (); i != n && nano::qualified_root{ i->first }.root () == root_a; ++i) + for (auto i = begin (transaction, key_start), n = end (transaction); i != n && nano::qualified_root{ i->first }.root () == root_a; ++i) { result.push_back (i->second); } @@ -37,7 +37,7 @@ std::vector nano::store::lmdb::final_vote::get (store::transac void nano::store::lmdb::final_vote::del (store::write_transaction const & transaction, nano::root const & root) { std::vector final_vote_qualified_roots; - for (auto i = begin (transaction, nano::qualified_root{ root.raw, 0 }), n = end (); i != n && nano::qualified_root{ i->first }.root () == root; ++i) + for (auto i = begin (transaction, nano::qualified_root{ root.raw, 0 }), n = end (transaction); i != n && nano::qualified_root{ i->first }.root () == root; ++i) { final_vote_qualified_roots.push_back (i->first); } @@ -74,7 +74,7 @@ auto nano::store::lmdb::final_vote::begin (store::transaction const & transactio return store.make_iterator (transaction, tables::final_votes); } -auto nano::store::lmdb::final_vote::end () const -> iterator +auto nano::store::lmdb::final_vote::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -84,6 +84,6 @@ void nano::store::lmdb::final_vote::for_each_par (std::function ( [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end (transaction)); }); } diff --git a/nano/store/lmdb/final_vote.hpp b/nano/store/lmdb/final_vote.hpp index 9b72b085a..c905edc9d 100644 --- a/nano/store/lmdb/final_vote.hpp +++ b/nano/store/lmdb/final_vote.hpp @@ -25,7 +25,7 @@ public: void clear (store::write_transaction const & transaction_a) override; iterator begin (store::transaction const & transaction_a, nano::qualified_root const & root_a) const override; iterator begin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; /** diff --git a/nano/store/lmdb/lmdb.cpp b/nano/store/lmdb/lmdb.cpp index a9d83eb48..ef467208b 100644 --- a/nano/store/lmdb/lmdb.cpp +++ b/nano/store/lmdb/lmdb.cpp @@ -258,7 +258,7 @@ void nano::store::lmdb::component::upgrade_v22_to_v23 (store::write_transaction drop (transaction, tables::rep_weights); transaction.refresh (); - release_assert (rep_weight.begin (tx_begin_read ()) == rep_weight.end (), "rep weights table must be empty before upgrading to v23"); + release_assert (rep_weight.begin (tx_begin_read ()) == rep_weight.end (transaction), "rep weights table must be empty before upgrading to v23"); auto iterate_accounts = [this] (auto && func) { auto transaction = tx_begin_read (); diff --git a/nano/store/lmdb/online_weight.cpp b/nano/store/lmdb/online_weight.cpp index c9e553a09..a570b3ed8 100644 --- a/nano/store/lmdb/online_weight.cpp +++ b/nano/store/lmdb/online_weight.cpp @@ -28,7 +28,7 @@ auto nano::store::lmdb::online_weight::rbegin (store::transaction const & transa return store.make_iterator (transaction, tables::online_weight, false); } -auto nano::store::lmdb::online_weight::end () const -> iterator +auto nano::store::lmdb::online_weight::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } diff --git a/nano/store/lmdb/online_weight.hpp b/nano/store/lmdb/online_weight.hpp index fe2810351..07668532c 100644 --- a/nano/store/lmdb/online_weight.hpp +++ b/nano/store/lmdb/online_weight.hpp @@ -17,7 +17,7 @@ public: void del (store::write_transaction const & transaction_a, uint64_t time_a) override; iterator begin (store::transaction const & transaction_a) const override; iterator rbegin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; size_t count (store::transaction const & transaction_a) const override; void clear (store::write_transaction const & transaction_a) override; diff --git a/nano/store/lmdb/peer.cpp b/nano/store/lmdb/peer.cpp index a91cd3002..e22b9c27a 100644 --- a/nano/store/lmdb/peer.cpp +++ b/nano/store/lmdb/peer.cpp @@ -50,7 +50,7 @@ auto nano::store::lmdb::peer::begin (store::transaction const & transaction) con return store.make_iterator (transaction, tables::peers); } -auto nano::store::lmdb::peer::end () const -> iterator +auto nano::store::lmdb::peer::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } diff --git a/nano/store/lmdb/peer.hpp b/nano/store/lmdb/peer.hpp index db39eb512..ba4eaf322 100644 --- a/nano/store/lmdb/peer.hpp +++ b/nano/store/lmdb/peer.hpp @@ -20,7 +20,7 @@ public: size_t count (store::transaction const &) const override; void clear (store::write_transaction const &) override; iterator begin (store::transaction const &) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; /* * Endpoints for peers diff --git a/nano/store/lmdb/pending.cpp b/nano/store/lmdb/pending.cpp index 925203d54..fd2e57317 100644 --- a/nano/store/lmdb/pending.cpp +++ b/nano/store/lmdb/pending.cpp @@ -36,13 +36,13 @@ std::optional nano::store::lmdb::pending::get (store::transa bool nano::store::lmdb::pending::exists (store::transaction const & transaction_a, nano::pending_key const & key_a) { auto iterator (begin (transaction_a, key_a)); - return iterator != end () && nano::pending_key (iterator->first) == key_a; + return iterator != end (transaction_a) && nano::pending_key (iterator->first) == key_a; } bool nano::store::lmdb::pending::any (store::transaction const & transaction_a, nano::account const & account_a) { auto iterator (begin (transaction_a, nano::pending_key (account_a, 0))); - return iterator != end () && nano::pending_key (iterator->first).account == account_a; + return iterator != end (transaction_a) && nano::pending_key (iterator->first).account == account_a; } auto nano::store::lmdb::pending::begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const -> iterator @@ -55,7 +55,7 @@ auto nano::store::lmdb::pending::begin (store::transaction const & transaction_a return store.make_iterator (transaction_a, tables::pending); } -auto nano::store::lmdb::pending::end () const -> iterator +auto nano::store::lmdb::pending::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -69,6 +69,6 @@ void nano::store::lmdb::pending::for_each_par (std::functionstore.tx_begin_read ()); - action_a (transaction, this->begin (transaction, key_start), !is_last ? this->begin (transaction, key_end) : this->end ()); + action_a (transaction, this->begin (transaction, key_start), !is_last ? this->begin (transaction, key_end) : this->end (transaction)); }); } diff --git a/nano/store/lmdb/pending.hpp b/nano/store/lmdb/pending.hpp index 46b5f7947..501221094 100644 --- a/nano/store/lmdb/pending.hpp +++ b/nano/store/lmdb/pending.hpp @@ -24,7 +24,7 @@ public: bool any (store::transaction const & transaction_a, nano::account const & account_a) override; iterator begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const override; iterator begin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; /** diff --git a/nano/store/lmdb/pruned.cpp b/nano/store/lmdb/pruned.cpp index 30bf1e0b9..960881acc 100644 --- a/nano/store/lmdb/pruned.cpp +++ b/nano/store/lmdb/pruned.cpp @@ -27,11 +27,11 @@ nano::block_hash nano::store::lmdb::pruned::random (store::transaction const & t nano::block_hash random_hash; nano::random_pool::generate_block (random_hash.bytes.data (), random_hash.bytes.size ()); auto existing = begin (transaction, random_hash); - if (existing == end ()) + if (existing == end (transaction)) { existing = begin (transaction); } - return existing != end () ? existing->first : 0; + return existing != end (transaction) ? existing->first : 0; } size_t nano::store::lmdb::pruned::count (store::transaction const & transaction_a) const @@ -55,7 +55,7 @@ auto nano::store::lmdb::pruned::begin (store::transaction const & transaction) c return store.make_iterator (transaction, tables::pruned); } -auto nano::store::lmdb::pruned::end () const -> iterator +auto nano::store::lmdb::pruned::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -65,6 +65,6 @@ void nano::store::lmdb::pruned::for_each_par (std::function ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end (transaction)); }); } diff --git a/nano/store/lmdb/pruned.hpp b/nano/store/lmdb/pruned.hpp index de1be14a1..a5d10ebf3 100644 --- a/nano/store/lmdb/pruned.hpp +++ b/nano/store/lmdb/pruned.hpp @@ -21,7 +21,7 @@ public: void clear (store::write_transaction const & transaction_a) override; iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const override; iterator begin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; /** diff --git a/nano/store/lmdb/rep_weight.cpp b/nano/store/lmdb/rep_weight.cpp index d01d204d5..02e97a9d8 100644 --- a/nano/store/lmdb/rep_weight.cpp +++ b/nano/store/lmdb/rep_weight.cpp @@ -53,7 +53,7 @@ auto nano::store::lmdb::rep_weight::begin (store::transaction const & transactio return store.make_iterator (transaction_a, tables::rep_weights); } -auto nano::store::lmdb::rep_weight::end () const -> iterator +auto nano::store::lmdb::rep_weight::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -63,6 +63,6 @@ void nano::store::lmdb::rep_weight::for_each_par (std::function ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end (transaction)); }); } diff --git a/nano/store/lmdb/rep_weight.hpp b/nano/store/lmdb/rep_weight.hpp index 809b23ae2..b0fa3aecb 100644 --- a/nano/store/lmdb/rep_weight.hpp +++ b/nano/store/lmdb/rep_weight.hpp @@ -22,7 +22,7 @@ public: void del (store::write_transaction const &, nano::account const & representative_a) override; iterator begin (store::transaction const & transaction_a, nano::account const & representative_a) const override; iterator begin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; /** diff --git a/nano/store/online_weight.hpp b/nano/store/online_weight.hpp index 595a51510..e6c90f861 100644 --- a/nano/store/online_weight.hpp +++ b/nano/store/online_weight.hpp @@ -25,7 +25,7 @@ public: virtual void del (store::write_transaction const &, uint64_t) = 0; virtual iterator begin (store::transaction const &) const = 0; virtual iterator rbegin (store::transaction const &) const = 0; - virtual iterator end () const = 0; + virtual iterator end (store::transaction const & transaction_a) const = 0; virtual size_t count (store::transaction const &) const = 0; virtual void clear (store::write_transaction const &) = 0; }; diff --git a/nano/store/peer.hpp b/nano/store/peer.hpp index 58e3c1d1e..9a03721c9 100644 --- a/nano/store/peer.hpp +++ b/nano/store/peer.hpp @@ -29,6 +29,6 @@ public: virtual size_t count (store::transaction const &) const = 0; virtual void clear (store::write_transaction const &) = 0; virtual iterator begin (store::transaction const &) const = 0; - virtual iterator end () const = 0; + virtual iterator end (store::transaction const & transaction_a) const = 0; }; } // namespace nano::store diff --git a/nano/store/pending.hpp b/nano/store/pending.hpp index 771bfba5c..c9d2fd659 100644 --- a/nano/store/pending.hpp +++ b/nano/store/pending.hpp @@ -31,7 +31,7 @@ public: virtual bool any (store::transaction const &, nano::account const &) = 0; virtual iterator begin (store::transaction const &, nano::pending_key const &) const = 0; virtual iterator begin (store::transaction const &) const = 0; - virtual iterator end () const = 0; + virtual iterator end (store::transaction const & transaction_a) const = 0; virtual void for_each_par (std::function const & action_a) const = 0; }; } // namespace nano::store diff --git a/nano/store/pruned.hpp b/nano/store/pruned.hpp index 5899c3d0c..448020c23 100644 --- a/nano/store/pruned.hpp +++ b/nano/store/pruned.hpp @@ -29,7 +29,7 @@ public: virtual void clear (store::write_transaction const &) = 0; virtual iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const = 0; virtual iterator begin (store::transaction const & transaction_a) const = 0; - virtual iterator end () const = 0; + virtual iterator end (store::transaction const & transaction_a) const = 0; virtual void for_each_par (std::function const & action_a) const = 0; }; } // namespace nano::store diff --git a/nano/store/rep_weight.hpp b/nano/store/rep_weight.hpp index 5d8fdb80a..b9fdc704c 100644 --- a/nano/store/rep_weight.hpp +++ b/nano/store/rep_weight.hpp @@ -29,7 +29,7 @@ public: virtual void del (store::write_transaction const &, nano::account const & representative_a) = 0; virtual iterator begin (store::transaction const & transaction_a, nano::account const & representative_a) const = 0; virtual iterator begin (store::transaction const & transaction_a) const = 0; - virtual iterator end () const = 0; + virtual iterator end (store::transaction const & transaction_a) const = 0; virtual void for_each_par (std::function const & action_a) const = 0; }; } diff --git a/nano/store/rocksdb/account.cpp b/nano/store/rocksdb/account.cpp index 9040f22e3..d0ffa20d9 100644 --- a/nano/store/rocksdb/account.cpp +++ b/nano/store/rocksdb/account.cpp @@ -34,7 +34,7 @@ void nano::store::rocksdb::account::del (store::write_transaction const & transa bool nano::store::rocksdb::account::exists (store::transaction const & transaction_a, nano::account const & account_a) { auto iterator (begin (transaction_a, account_a)); - return iterator != end () && nano::account (iterator->first) == account_a; + return iterator != end (transaction_a) && nano::account (iterator->first) == account_a; } size_t nano::store::rocksdb::account::count (store::transaction const & transaction_a) @@ -57,7 +57,7 @@ auto nano::store::rocksdb::account::rbegin (store::transaction const & transacti return store.make_iterator (transaction_a, tables::accounts, false); } -auto nano::store::rocksdb::account::end () const -> iterator +auto nano::store::rocksdb::account::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -67,6 +67,6 @@ void nano::store::rocksdb::account::for_each_par (std::function ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end (transaction)); }); } diff --git a/nano/store/rocksdb/account.hpp b/nano/store/rocksdb/account.hpp index 1b2c068d0..c0b73bde4 100644 --- a/nano/store/rocksdb/account.hpp +++ b/nano/store/rocksdb/account.hpp @@ -23,7 +23,7 @@ public: iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; iterator begin (store::transaction const & transaction_a) const override; iterator rbegin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; }; } // namespace nano::store::rocksdb diff --git a/nano/store/rocksdb/block.cpp b/nano/store/rocksdb/block.cpp index 7532193ae..fcee0ffd3 100644 --- a/nano/store/rocksdb/block.cpp +++ b/nano/store/rocksdb/block.cpp @@ -110,11 +110,11 @@ std::shared_ptr nano::store::rocksdb::block::random (store::transac nano::block_hash hash; nano::random_pool::generate_block (hash.bytes.data (), hash.bytes.size ()); auto existing = begin (transaction, hash); - if (existing == end ()) + if (existing == end (transaction)) { existing = begin (transaction); } - debug_assert (existing != end ()); + debug_assert (existing != end (transaction)); return existing->second.block; } @@ -144,7 +144,7 @@ auto nano::store::rocksdb::block::begin (store::transaction const & transaction, return store.make_iterator (transaction, tables::blocks, hash); } -auto nano::store::rocksdb::block::end () const -> iterator +auto nano::store::rocksdb::block::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -154,7 +154,7 @@ void nano::store::rocksdb::block::for_each_par (std::function ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end (transaction)); }); } diff --git a/nano/store/rocksdb/block.hpp b/nano/store/rocksdb/block.hpp index 0a093f1c3..741c862f7 100644 --- a/nano/store/rocksdb/block.hpp +++ b/nano/store/rocksdb/block.hpp @@ -31,7 +31,7 @@ public: uint64_t count (store::transaction const & transaction_a) override; iterator begin (store::transaction const & transaction_a) const override; iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; protected: diff --git a/nano/store/rocksdb/confirmation_height.cpp b/nano/store/rocksdb/confirmation_height.cpp index eea420237..838a36520 100644 --- a/nano/store/rocksdb/confirmation_height.cpp +++ b/nano/store/rocksdb/confirmation_height.cpp @@ -69,7 +69,7 @@ auto nano::store::rocksdb::confirmation_height::begin (store::transaction const return store.make_iterator (transaction, tables::confirmation_height); } -auto nano::store::rocksdb::confirmation_height::end () const -> iterator +auto nano::store::rocksdb::confirmation_height::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -79,6 +79,6 @@ void nano::store::rocksdb::confirmation_height::for_each_par (std::function ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end (transaction)); }); } diff --git a/nano/store/rocksdb/confirmation_height.hpp b/nano/store/rocksdb/confirmation_height.hpp index 050ceef9b..6819b69eb 100644 --- a/nano/store/rocksdb/confirmation_height.hpp +++ b/nano/store/rocksdb/confirmation_height.hpp @@ -23,7 +23,7 @@ public: void clear (store::write_transaction const & transaction_a) override; iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; iterator begin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; }; } // namespace nano::store::rocksdb diff --git a/nano/store/rocksdb/final_vote.cpp b/nano/store/rocksdb/final_vote.cpp index 3979b16ca..328027ae3 100644 --- a/nano/store/rocksdb/final_vote.cpp +++ b/nano/store/rocksdb/final_vote.cpp @@ -27,7 +27,7 @@ std::vector nano::store::rocksdb::final_vote::get (store::tran { std::vector result; nano::qualified_root key_start{ root_a.raw, 0 }; - for (auto i = begin (transaction, key_start), n = end (); i != n && nano::qualified_root{ i->first }.root () == root_a; ++i) + for (auto i = begin (transaction, key_start), n = end (transaction); i != n && nano::qualified_root{ i->first }.root () == root_a; ++i) { result.push_back (i->second); } @@ -37,7 +37,7 @@ std::vector nano::store::rocksdb::final_vote::get (store::tran void nano::store::rocksdb::final_vote::del (store::write_transaction const & transaction, nano::root const & root) { std::vector final_vote_qualified_roots; - for (auto i = begin (transaction, nano::qualified_root{ root.raw, 0 }), n = end (); i != n && nano::qualified_root{ i->first }.root () == root; ++i) + for (auto i = begin (transaction, nano::qualified_root{ root.raw, 0 }), n = end (transaction); i != n && nano::qualified_root{ i->first }.root () == root; ++i) { final_vote_qualified_roots.push_back (i->first); } @@ -74,7 +74,7 @@ auto nano::store::rocksdb::final_vote::begin (store::transaction const & transac return store.make_iterator (transaction, tables::final_votes); } -auto nano::store::rocksdb::final_vote::end () const -> iterator +auto nano::store::rocksdb::final_vote::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -84,6 +84,6 @@ void nano::store::rocksdb::final_vote::for_each_par (std::function ( [&action_a, this] (nano::uint512_t const & start, nano::uint512_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end (transaction)); }); } diff --git a/nano/store/rocksdb/final_vote.hpp b/nano/store/rocksdb/final_vote.hpp index a24093a57..67a1e0d52 100644 --- a/nano/store/rocksdb/final_vote.hpp +++ b/nano/store/rocksdb/final_vote.hpp @@ -23,7 +23,7 @@ public: void clear (store::write_transaction const & transaction_a) override; iterator begin (store::transaction const & transaction_a, nano::qualified_root const & root_a) const override; iterator begin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; }; } // namespace nano::store::rocksdb diff --git a/nano/store/rocksdb/online_weight.cpp b/nano/store/rocksdb/online_weight.cpp index 42250c689..dafd0f51f 100644 --- a/nano/store/rocksdb/online_weight.cpp +++ b/nano/store/rocksdb/online_weight.cpp @@ -28,7 +28,7 @@ auto nano::store::rocksdb::online_weight::rbegin (store::transaction const & tra return store.make_iterator (transaction, tables::online_weight, false); } -auto nano::store::rocksdb::online_weight::end () const -> iterator +auto nano::store::rocksdb::online_weight::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } diff --git a/nano/store/rocksdb/online_weight.hpp b/nano/store/rocksdb/online_weight.hpp index 4d940ffda..1b88d329d 100644 --- a/nano/store/rocksdb/online_weight.hpp +++ b/nano/store/rocksdb/online_weight.hpp @@ -19,7 +19,7 @@ public: void del (store::write_transaction const & transaction_a, uint64_t time_a) override; iterator begin (store::transaction const & transaction_a) const override; iterator rbegin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; size_t count (store::transaction const & transaction_a) const override; void clear (store::write_transaction const & transaction_a) override; }; diff --git a/nano/store/rocksdb/peer.cpp b/nano/store/rocksdb/peer.cpp index 71fa3ccc5..0da579102 100644 --- a/nano/store/rocksdb/peer.cpp +++ b/nano/store/rocksdb/peer.cpp @@ -50,7 +50,7 @@ auto nano::store::rocksdb::peer::begin (store::transaction const & transaction) return store.make_iterator (transaction, tables::peers); } -auto nano::store::rocksdb::peer::end () const -> iterator +auto nano::store::rocksdb::peer::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } diff --git a/nano/store/rocksdb/peer.hpp b/nano/store/rocksdb/peer.hpp index 30e57644f..61f3b87c6 100644 --- a/nano/store/rocksdb/peer.hpp +++ b/nano/store/rocksdb/peer.hpp @@ -22,6 +22,6 @@ public: size_t count (store::transaction const &) const override; void clear (store::write_transaction const &) override; iterator begin (store::transaction const &) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; }; } // namespace nano::store::rocksdb diff --git a/nano/store/rocksdb/pending.cpp b/nano/store/rocksdb/pending.cpp index 3286cd8f9..9fc4b1a2e 100644 --- a/nano/store/rocksdb/pending.cpp +++ b/nano/store/rocksdb/pending.cpp @@ -36,13 +36,13 @@ std::optional nano::store::rocksdb::pending::get (store::tra bool nano::store::rocksdb::pending::exists (store::transaction const & transaction_a, nano::pending_key const & key_a) { auto iterator (begin (transaction_a, key_a)); - return iterator != end () && nano::pending_key (iterator->first) == key_a; + return iterator != end (transaction_a) && nano::pending_key (iterator->first) == key_a; } bool nano::store::rocksdb::pending::any (store::transaction const & transaction_a, nano::account const & account_a) { auto iterator (begin (transaction_a, nano::pending_key (account_a, 0))); - return iterator != end () && nano::pending_key (iterator->first).account == account_a; + return iterator != end (transaction_a) && nano::pending_key (iterator->first).account == account_a; } auto nano::store::rocksdb::pending::begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const -> iterator @@ -55,7 +55,7 @@ auto nano::store::rocksdb::pending::begin (store::transaction const & transactio return store.template make_iterator (transaction_a, tables::pending); } -auto nano::store::rocksdb::pending::end () const -> iterator +auto nano::store::rocksdb::pending::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -69,6 +69,6 @@ void nano::store::rocksdb::pending::for_each_par (std::functionstore.tx_begin_read ()); - action_a (transaction, this->begin (transaction, key_start), !is_last ? this->begin (transaction, key_end) : this->end ()); + action_a (transaction, this->begin (transaction, key_start), !is_last ? this->begin (transaction, key_end) : this->end (transaction)); }); } diff --git a/nano/store/rocksdb/pending.hpp b/nano/store/rocksdb/pending.hpp index 4b98b0f07..061d0031e 100644 --- a/nano/store/rocksdb/pending.hpp +++ b/nano/store/rocksdb/pending.hpp @@ -18,7 +18,7 @@ public: bool any (store::transaction const & transaction_a, nano::account const & account_a) override; iterator begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const override; iterator begin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; }; } // namespace nano::store::rocksdb diff --git a/nano/store/rocksdb/pruned.cpp b/nano/store/rocksdb/pruned.cpp index 572f17e34..3cca20144 100644 --- a/nano/store/rocksdb/pruned.cpp +++ b/nano/store/rocksdb/pruned.cpp @@ -27,11 +27,11 @@ nano::block_hash nano::store::rocksdb::pruned::random (store::transaction const nano::block_hash random_hash; nano::random_pool::generate_block (random_hash.bytes.data (), random_hash.bytes.size ()); auto existing = begin (transaction, random_hash); - if (existing == end ()) + if (existing == end (transaction)) { existing = begin (transaction); } - return existing != end () ? existing->first : 0; + return existing != end (transaction) ? existing->first : 0; } size_t nano::store::rocksdb::pruned::count (store::transaction const & transaction_a) const @@ -55,7 +55,7 @@ auto nano::store::rocksdb::pruned::begin (store::transaction const & transaction return store.make_iterator (transaction_a, tables::pruned); } -auto nano::store::rocksdb::pruned::end () const -> iterator +auto nano::store::rocksdb::pruned::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -65,6 +65,6 @@ void nano::store::rocksdb::pruned::for_each_par (std::function ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end (transaction)); }); } diff --git a/nano/store/rocksdb/pruned.hpp b/nano/store/rocksdb/pruned.hpp index 0dc84b84e..af10be5e8 100644 --- a/nano/store/rocksdb/pruned.hpp +++ b/nano/store/rocksdb/pruned.hpp @@ -23,7 +23,7 @@ public: void clear (store::write_transaction const & transaction_a) override; iterator begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const override; iterator begin (store::transaction const & transaction_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; }; } // namespace nano::store::rocksdb diff --git a/nano/store/rocksdb/rep_weight.cpp b/nano/store/rocksdb/rep_weight.cpp index 68d4684ce..e719ef990 100644 --- a/nano/store/rocksdb/rep_weight.cpp +++ b/nano/store/rocksdb/rep_weight.cpp @@ -52,7 +52,7 @@ auto nano::store::rocksdb::rep_weight::begin (store::transaction const & txn_a) return store.make_iterator (txn_a, tables::rep_weights); } -auto nano::store::rocksdb::rep_weight::end () const -> iterator +auto nano::store::rocksdb::rep_weight::end (store::transaction const & transaction_a) const -> iterator { return iterator{ nullptr }; } @@ -62,6 +62,6 @@ void nano::store::rocksdb::rep_weight::for_each_par (std::function ( [&action_a, this] (nano::uint256_t const & start, nano::uint256_t const & end, bool const is_last) { auto transaction (this->store.tx_begin_read ()); - action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end ()); + action_a (transaction, this->begin (transaction, start), !is_last ? this->begin (transaction, end) : this->end (transaction)); }); } diff --git a/nano/store/rocksdb/rep_weight.hpp b/nano/store/rocksdb/rep_weight.hpp index 76e542264..d27c23719 100644 --- a/nano/store/rocksdb/rep_weight.hpp +++ b/nano/store/rocksdb/rep_weight.hpp @@ -21,7 +21,7 @@ public: void del (store::write_transaction const &, nano::account const & representative_a) override; iterator begin (store::transaction const & txn_a, nano::account const & representative_a) const override; iterator begin (store::transaction const & txn_a) const override; - iterator end () const override; + iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; }; } diff --git a/nano/store/rocksdb/rocksdb.cpp b/nano/store/rocksdb/rocksdb.cpp index 85207da37..e62d1db09 100644 --- a/nano/store/rocksdb/rocksdb.cpp +++ b/nano/store/rocksdb/rocksdb.cpp @@ -292,7 +292,10 @@ void nano::store::rocksdb::component::upgrade_v22_to_v23 (store::write_transacti transaction.refresh (); } - release_assert (rep_weight.begin (tx_begin_read ()) == rep_weight.end (), "rep weights table must be empty before upgrading to v23"); + { + auto tx = tx_begin_read (); + release_assert (rep_weight.begin (tx) == rep_weight.end (tx), "rep weights table must be empty before upgrading to v23"); + } auto iterate_accounts = [this] (auto && func) { auto transaction = tx_begin_read (); @@ -598,14 +601,14 @@ uint64_t nano::store::rocksdb::component::count (store::transaction const & tran // Peers/online weight are small enough that they can just be iterated to get accurate counts. if (table_a == tables::peers) { - for (auto i (peer.begin (transaction_a)), n (peer.end ()); i != n; ++i) + for (auto i (peer.begin (transaction_a)), n (peer.end (transaction_a)); i != n; ++i) { ++sum; } } else if (table_a == tables::online_weight) { - for (auto i (online_weight.begin (transaction_a)), n (online_weight.end ()); i != n; ++i) + for (auto i (online_weight.begin (transaction_a)), n (online_weight.end (transaction_a)); i != n; ++i) { ++sum; } @@ -624,7 +627,7 @@ uint64_t nano::store::rocksdb::component::count (store::transaction const & tran // otherwise there can be performance issues. else if (table_a == tables::accounts) { - for (auto i (account.begin (transaction_a)), n (account.end ()); i != n; ++i) + for (auto i (account.begin (transaction_a)), n (account.end (transaction_a)); i != n; ++i) { ++sum; } @@ -632,14 +635,14 @@ uint64_t nano::store::rocksdb::component::count (store::transaction const & tran else if (table_a == tables::blocks) { // This is also used in some CLI commands - for (auto i (block.begin (transaction_a)), n (block.end ()); i != n; ++i) + for (auto i (block.begin (transaction_a)), n (block.end (transaction_a)); i != n; ++i) { ++sum; } } else if (table_a == tables::confirmation_height) { - for (auto i (confirmation_height.begin (transaction_a)), n (confirmation_height.end ()); i != n; ++i) + for (auto i (confirmation_height.begin (transaction_a)), n (confirmation_height.end (transaction_a)); i != n; ++i) { ++sum; } @@ -647,7 +650,7 @@ uint64_t nano::store::rocksdb::component::count (store::transaction const & tran // rep_weights should only be used in tests otherwise there can be performance issues. else if (table_a == tables::rep_weights) { - for (auto i (rep_weight.begin (transaction_a)), n (rep_weight.end ()); i != n; ++i) + for (auto i (rep_weight.begin (transaction_a)), n (rep_weight.end (transaction_a)); i != n; ++i) { ++sum; } @@ -673,7 +676,7 @@ int nano::store::rocksdb::component::drop (store::write_transaction const & tran if (table_a == tables::peers) { int status = 0; - for (auto i = peer.begin (transaction_a), n = peer.end (); i != n; ++i) + for (auto i = peer.begin (transaction_a), n = peer.end (transaction_a); i != n; ++i) { status = del (transaction_a, tables::peers, nano::store::rocksdb::db_val (i->first)); release_assert (success (status)); diff --git a/nano/test_common/system.cpp b/nano/test_common/system.cpp index 40f8be220..66af123ae 100644 --- a/nano/test_common/system.cpp +++ b/nano/test_common/system.cpp @@ -257,9 +257,9 @@ nano::account nano::test::system::account (store::transaction const & transactio { auto wallet_l (wallet (index_a)); auto keys (wallet_l->store.begin (transaction_a)); - debug_assert (keys != wallet_l->store.end ()); + debug_assert (keys != wallet_l->store.end (transaction_a)); auto result (keys->first); - debug_assert (++keys == wallet_l->store.end ()); + debug_assert (++keys == wallet_l->store.end (transaction_a)); return nano::account (result); } @@ -533,11 +533,11 @@ void nano::test::system::generate_send_existing (nano::node & node_a, std::vecto random_pool::generate_block (account.bytes.data (), sizeof (account.bytes)); auto transaction = node_a.ledger.tx_begin_read (); auto entry = node_a.store.account.begin (transaction, account); - if (entry == node_a.store.account.end ()) + if (entry == node_a.store.account.end (transaction)) { entry = node_a.store.account.begin (transaction); } - debug_assert (entry != node_a.store.account.end ()); + debug_assert (entry != node_a.store.account.end (transaction)); destination = nano::account (entry->first); source = get_random_account (accounts_a); amount = get_random_amount (transaction, node_a, source); diff --git a/nano/test_common/testutil.cpp b/nano/test_common/testutil.cpp index 06e5ed505..f2c3c7712 100644 --- a/nano/test_common/testutil.cpp +++ b/nano/test_common/testutil.cpp @@ -315,7 +315,7 @@ void nano::test::print_all_receivable_entries (const nano::store::component & st { std::cout << "Printing all receivable entries:\n"; auto const tx = store.tx_begin_read (); - auto const end = store.pending.end (); + auto const end = store.pending.end (tx); for (auto i = store.pending.begin (tx); i != end; ++i) { std::cout << "Key: " << i->first << std::endl; @@ -327,7 +327,7 @@ void nano::test::print_all_account_info (const nano::ledger & ledger) { std::cout << "Printing all account info:\n"; auto const tx = ledger.tx_begin_read (); - auto const end = ledger.store.account.end (); + auto const end = ledger.store.account.end (tx); for (auto i = ledger.store.account.begin (tx); i != end; ++i) { nano::account acc = i->first; @@ -349,7 +349,7 @@ void nano::test::print_all_blocks (const nano::store::component & store) { auto tx = store.tx_begin_read (); auto i = store.block.begin (tx); - auto end = store.block.end (); + auto end = store.block.end (tx); std::cout << "Listing all blocks" << std::endl; for (; i != end; ++i) { @@ -368,7 +368,7 @@ std::vector> nano::test::all_blocks (nano::node & n { auto transaction = node.store.tx_begin_read (); std::vector> result; - for (auto it = node.store.block.begin (transaction), end = node.store.block.end (); it != end; ++it) + for (auto it = node.store.block.begin (transaction), end = node.store.block.end (transaction); it != end; ++it) { result.push_back (it->second.block); } From 63f3e28386accbb2e63f021174beee9f4e2c88ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 22 Oct 2024 13:33:32 +0200 Subject: [PATCH 20/48] Use unique ptrs for node thread pools --- nano/node/fwd.hpp | 1 + nano/node/node.cpp | 15 ++++++++++----- nano/node/node.hpp | 15 +++++++++------ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/nano/node/fwd.hpp b/nano/node/fwd.hpp index 57b216965..7bdcb5766 100644 --- a/nano/node/fwd.hpp +++ b/nano/node/fwd.hpp @@ -9,6 +9,7 @@ namespace nano { class block; class container_info; +class thread_pool; } namespace nano diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 313a18768..649495727 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -68,6 +69,7 @@ nano::node::node (std::shared_ptr io_ctx_a, uint16_t pe nano::node::node (std::shared_ptr io_ctx_a, std::filesystem::path const & application_path_a, nano::node_config const & config_a, nano::work_pool & work_a, nano::node_flags flags_a, unsigned seq) : node_id{ load_or_create_node_id (application_path_a) }, config{ config_a }, + flags{ flags_a }, io_ctx_shared{ std::make_shared () }, io_ctx{ *io_ctx_shared }, logger{ make_logger_identifier (node_id) }, @@ -76,11 +78,14 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy node_initialized_latch (1), network_params{ config.network_params }, stats{ logger, config.stats_config }, - workers{ config.background_threads, nano::thread_role::name::worker }, - bootstrap_workers{ config.bootstrap_serving_threads, nano::thread_role::name::bootstrap_worker }, - wallet_workers{ 1, nano::thread_role::name::wallet_worker }, - election_workers{ 1, nano::thread_role::name::election_worker }, - flags (flags_a), + workers_impl{ std::make_unique (config.background_threads, nano::thread_role::name::worker) }, + workers{ *workers_impl }, + bootstrap_workers_impl{ std::make_unique (config.bootstrap_serving_threads, nano::thread_role::name::bootstrap_worker) }, + bootstrap_workers{ *bootstrap_workers_impl }, + wallet_workers_impl{ std::make_unique (1, nano::thread_role::name::wallet_worker) }, + wallet_workers{ *wallet_workers_impl }, + election_workers_impl{ std::make_unique (1, nano::thread_role::name::election_worker) }, + election_workers{ *election_workers_impl }, work (work_a), distributed_work (*this), store_impl (nano::make_store (logger, application_path_a, network_params.ledger, flags.read_only, true, config_a.rocksdb_config, config_a.diagnostics_config.txn_tracking, config_a.block_processor_batch_max_time, config_a.lmdb_config, config_a.backup_before_upgrade)), diff --git a/nano/node/node.hpp b/nano/node/node.hpp index 49ca17d65..ac9a4bb25 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -148,6 +147,7 @@ public: public: const nano::keypair node_id; nano::node_config config; + nano::node_flags flags; std::shared_ptr io_ctx_shared; boost::asio::io_context & io_ctx; nano::logger logger; @@ -156,11 +156,14 @@ public: boost::latch node_initialized_latch; nano::network_params & network_params; nano::stats stats; - nano::thread_pool workers; - nano::thread_pool bootstrap_workers; - nano::thread_pool wallet_workers; - nano::thread_pool election_workers; - nano::node_flags flags; + std::unique_ptr workers_impl; + nano::thread_pool & workers; + std::unique_ptr bootstrap_workers_impl; + nano::thread_pool & bootstrap_workers; + std::unique_ptr wallet_workers_impl; + nano::thread_pool & wallet_workers; + std::unique_ptr election_workers_impl; + nano::thread_pool & election_workers; nano::work_pool & work; nano::distributed_work_factory distributed_work; std::unique_ptr store_impl; From 5dfce4539b5132d92228af091eee68b246c048b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Mon, 21 Oct 2024 15:38:55 +0200 Subject: [PATCH 21/48] Templated `thread_pool` to support move only tasks --- nano/lib/CMakeLists.txt | 1 - nano/lib/thread_pool.cpp | 97 ---------------------------- nano/lib/thread_pool.hpp | 134 +++++++++++++++++++++++++++++++-------- 3 files changed, 107 insertions(+), 125 deletions(-) delete mode 100644 nano/lib/thread_pool.cpp diff --git a/nano/lib/CMakeLists.txt b/nano/lib/CMakeLists.txt index 702cb84fa..76d53944f 100644 --- a/nano/lib/CMakeLists.txt +++ b/nano/lib/CMakeLists.txt @@ -94,7 +94,6 @@ add_library( stats_sinks.hpp stream.hpp thread_pool.hpp - thread_pool.cpp thread_roles.hpp thread_roles.cpp thread_runner.hpp diff --git a/nano/lib/thread_pool.cpp b/nano/lib/thread_pool.cpp deleted file mode 100644 index c5f0108ee..000000000 --- a/nano/lib/thread_pool.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include - -#include -#include -#include - -/* - * thread_pool - */ - -nano::thread_pool::thread_pool (unsigned num_threads, nano::thread_role::name thread_name) : - num_threads (num_threads), - thread_pool_m (std::make_unique (num_threads)), - thread_names_latch{ num_threads } -{ - set_thread_names (thread_name); -} - -nano::thread_pool::~thread_pool () -{ - stop (); -} - -void nano::thread_pool::stop () -{ - nano::unique_lock lk (mutex); - if (!stopped) - { - stopped = true; -#if defined(BOOST_ASIO_HAS_IOCP) - // A hack needed for Windows to prevent deadlock during destruction, described here: https://github.com/chriskohlhoff/asio/issues/431 - boost::asio::use_service (*thread_pool_m).stop (); -#endif - lk.unlock (); - thread_pool_m->stop (); - thread_pool_m->join (); - lk.lock (); - thread_pool_m = nullptr; - } -} - -void nano::thread_pool::push_task (std::function task) -{ - ++num_tasks; - nano::lock_guard guard (mutex); - if (!stopped) - { - boost::asio::post (*thread_pool_m, [this, task] () { - task (); - --num_tasks; - }); - } -} - -void nano::thread_pool::add_timed_task (std::chrono::steady_clock::time_point const & expiry_time, std::function task) -{ - nano::lock_guard guard (mutex); - if (!stopped && thread_pool_m) - { - auto timer = std::make_shared (thread_pool_m->get_executor (), expiry_time); - timer->async_wait ([this, task, timer] (boost::system::error_code const & ec) { - if (!ec) - { - push_task (task); - } - }); - } -} - -unsigned nano::thread_pool::get_num_threads () const -{ - return num_threads; -} - -uint64_t nano::thread_pool::num_queued_tasks () const -{ - return num_tasks; -} - -void nano::thread_pool::set_thread_names (nano::thread_role::name thread_name) -{ - for (auto i = 0u; i < num_threads; ++i) - { - boost::asio::post (*thread_pool_m, [this, thread_name] () { - nano::thread_role::set (thread_name); - thread_names_latch.arrive_and_wait (); - }); - } - thread_names_latch.wait (); -} - -nano::container_info nano::thread_pool::container_info () const -{ - nano::container_info info; - info.put ("count", num_queued_tasks ()); - return info; -} diff --git a/nano/lib/thread_pool.hpp b/nano/lib/thread_pool.hpp index 2b32e60f5..e0582c3c8 100644 --- a/nano/lib/thread_pool.hpp +++ b/nano/lib/thread_pool.hpp @@ -4,50 +4,130 @@ #include #include +#include +#include +#include + #include #include -#include #include - -namespace boost::asio -{ -class thread_pool; -} +#include +#include namespace nano { class thread_pool final { public: - explicit thread_pool (unsigned num_threads, nano::thread_role::name); - ~thread_pool (); + explicit thread_pool (unsigned num_threads, nano::thread_role::name thread_name) : + num_threads{ num_threads }, + thread_pool_impl{ std::make_unique (num_threads) }, + thread_names_latch{ num_threads } + { + set_thread_names (thread_name); + } - /** This will run when there is an available thread for execution */ - void push_task (std::function); + ~thread_pool () + { + if (alive ()) + { + stop (); + } + } - /** Run a task at a certain point in time */ - void add_timed_task (std::chrono::steady_clock::time_point const & expiry_time, std::function task); + template + void push_task (F && task) + { + nano::lock_guard guard{ mutex }; + if (!stopped) + { + ++num_tasks; + release_assert (thread_pool_impl); + boost::asio::post (*thread_pool_impl, [this, t = std::forward (task)] () mutable { + t (); + --num_tasks; + }); + } + } - /** Stops any further pushed tasks from executing */ - void stop (); + template + void add_timed_task (std::chrono::steady_clock::time_point const & expiry_time, F && task) + { + nano::lock_guard guard{ mutex }; + if (!stopped) + { + release_assert (thread_pool_impl); + auto timer = std::make_shared (thread_pool_impl->get_executor ()); + timer->expires_at (expiry_time); + timer->async_wait ([this, t = std::forward (task), /* preserve lifetime */ timer] (boost::system::error_code const & ec) mutable { + if (!ec) + { + push_task (std::move (t)); + } + }); + } + } - /** Number of threads in the thread pool */ - unsigned get_num_threads () const; + void stop () + { + nano::unique_lock lock{ mutex }; + if (!stopped) + { + stopped = true; +#if defined(BOOST_ASIO_HAS_IOCP) + // A hack needed for Windows to prevent deadlock during destruction, described here: https://github.com/chriskohlhoff/asio/issues/431 + boost::asio::use_service (*thread_pool_m).stop (); +#endif + lock.unlock (); + thread_pool_impl->stop (); + thread_pool_impl->join (); + lock.lock (); + thread_pool_impl = nullptr; + } + } - /** Returns the number of tasks which are awaiting execution by the thread pool **/ - uint64_t num_queued_tasks () const; + bool alive () const + { + nano::lock_guard guard{ mutex }; + return thread_pool_impl != nullptr; + } - nano::container_info container_info () const; + unsigned get_num_threads () const + { + return num_threads; + } + + uint64_t num_queued_tasks () const + { + return num_tasks; + } + + nano::container_info container_info () const + { + nano::container_info info; + info.put ("tasks", num_queued_tasks ()); + return info; + } private: - nano::mutex mutex; - std::atomic stopped{ false }; - unsigned num_threads; - std::unique_ptr thread_pool_m; - nano::relaxed_atomic_integral num_tasks{ 0 }; + void set_thread_names (nano::thread_role::name thread_name) + { + for (auto i = 0u; i < num_threads; ++i) + { + boost::asio::post (*thread_pool_impl, [this, thread_name] () { + nano::thread_role::set (thread_name); + thread_names_latch.arrive_and_wait (); + }); + } + thread_names_latch.wait (); + } - /** Set the names of all the threads in the thread pool for easier identification */ +private: + unsigned const num_threads; + mutable nano::mutex mutex; + std::atomic stopped{ false }; + std::unique_ptr thread_pool_impl; + std::atomic num_tasks{ 0 }; std::latch thread_names_latch; - void set_thread_names (nano::thread_role::name thread_name); }; -} // namespace nano +} \ No newline at end of file From 6637d378b150e01617c2689ecc8932b14c2d16c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Mon, 21 Oct 2024 19:33:35 +0200 Subject: [PATCH 22/48] Use start/stop pattern in `thread_pool` --- nano/core_test/thread_pool.cpp | 5 +++ nano/lib/thread_pool.hpp | 69 +++++++++++++++++++++------------- nano/node/confirming_set.cpp | 2 + nano/node/node.cpp | 18 +++++---- 4 files changed, 60 insertions(+), 34 deletions(-) diff --git a/nano/core_test/thread_pool.cpp b/nano/core_test/thread_pool.cpp index d257fce28..14ec42c85 100644 --- a/nano/core_test/thread_pool.cpp +++ b/nano/core_test/thread_pool.cpp @@ -1,5 +1,6 @@ #include #include +#include #include @@ -15,6 +16,7 @@ TEST (thread_pool, thread_pool) }; nano::thread_pool workers (1u, nano::thread_role::name::unknown); + nano::test::start_stop_guard stop_guard{ workers }; workers.push_task (func); ASSERT_FALSE (passed_sleep); @@ -36,6 +38,7 @@ TEST (thread_pool, one) nano::mutex mutex; nano::condition_variable condition; nano::thread_pool workers (1u, nano::thread_role::name::unknown); + nano::test::start_stop_guard stop_guard{ workers }; workers.add_timed_task (std::chrono::steady_clock::now (), [&] () { { nano::lock_guard lock{ mutex }; @@ -53,6 +56,7 @@ TEST (thread_pool, many) nano::mutex mutex; nano::condition_variable condition; nano::thread_pool workers (50u, nano::thread_role::name::unknown); + nano::test::start_stop_guard stop_guard{ workers }; for (auto i (0); i < 50; ++i) { workers.add_timed_task (std::chrono::steady_clock::now (), [&] () { @@ -74,6 +78,7 @@ TEST (thread_pool, top_execution) nano::mutex mutex; std::promise promise; nano::thread_pool workers (1u, nano::thread_role::name::unknown); + nano::test::start_stop_guard stop_guard{ workers }; workers.add_timed_task (std::chrono::steady_clock::now (), [&] () { nano::lock_guard lock{ mutex }; value1 = 1; diff --git a/nano/lib/thread_pool.hpp b/nano/lib/thread_pool.hpp index e0582c3c8..989a7c387 100644 --- a/nano/lib/thread_pool.hpp +++ b/nano/lib/thread_pool.hpp @@ -19,19 +19,52 @@ namespace nano class thread_pool final { public: - explicit thread_pool (unsigned num_threads, nano::thread_role::name thread_name) : + // TODO: Auto start should be removed once the node is refactored to start the thread pool explicitly + thread_pool (unsigned num_threads, nano::thread_role::name thread_name, bool auto_start = false) : num_threads{ num_threads }, - thread_pool_impl{ std::make_unique (num_threads) }, + thread_name{ thread_name }, thread_names_latch{ num_threads } { - set_thread_names (thread_name); + if (auto_start) + { + start (); + } } ~thread_pool () { - if (alive ()) + // Must be stopped before destruction to avoid running takss when node components are being destroyed + debug_assert (!thread_pool_impl); + } + + void start () + { + debug_assert (!stopped); + debug_assert (!thread_pool_impl); + thread_pool_impl = std::make_unique (num_threads); + set_thread_names (); + } + + void stop () + { + nano::unique_lock lock{ mutex }; + if (!stopped && thread_pool_impl) { - stop (); + stopped = true; + + // TODO: Is this still needed? +#if defined(BOOST_ASIO_HAS_IOCP) + // A hack needed for Windows to prevent deadlock during destruction, described here: https://github.com/chriskohlhoff/asio/issues/431 + boost::asio::use_service (*thread_pool_m).stop (); +#endif + + lock.unlock (); + + thread_pool_impl->stop (); + thread_pool_impl->join (); + + lock.lock (); + thread_pool_impl = nullptr; } } @@ -68,24 +101,6 @@ public: } } - void stop () - { - nano::unique_lock lock{ mutex }; - if (!stopped) - { - stopped = true; -#if defined(BOOST_ASIO_HAS_IOCP) - // A hack needed for Windows to prevent deadlock during destruction, described here: https://github.com/chriskohlhoff/asio/issues/431 - boost::asio::use_service (*thread_pool_m).stop (); -#endif - lock.unlock (); - thread_pool_impl->stop (); - thread_pool_impl->join (); - lock.lock (); - thread_pool_impl = nullptr; - } - } - bool alive () const { nano::lock_guard guard{ mutex }; @@ -110,11 +125,11 @@ public: } private: - void set_thread_names (nano::thread_role::name thread_name) + void set_thread_names () { for (auto i = 0u; i < num_threads; ++i) { - boost::asio::post (*thread_pool_impl, [this, thread_name] () { + boost::asio::post (*thread_pool_impl, [this] () { nano::thread_role::set (thread_name); thread_names_latch.arrive_and_wait (); }); @@ -124,10 +139,12 @@ private: private: unsigned const num_threads; + nano::thread_role::name const thread_name; + + std::latch thread_names_latch; mutable nano::mutex mutex; std::atomic stopped{ false }; std::unique_ptr thread_pool_impl; std::atomic num_tasks{ 0 }; - std::latch thread_names_latch; }; } \ No newline at end of file diff --git a/nano/node/confirming_set.cpp b/nano/node/confirming_set.cpp index 4d8d14508..3d4031d28 100644 --- a/nano/node/confirming_set.cpp +++ b/nano/node/confirming_set.cpp @@ -55,6 +55,8 @@ void nano::confirming_set::start () return; } + notification_workers.start (); + thread = std::thread{ [this] () { nano::thread_role::set (nano::thread_role::name::confirmation_height); run (); diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 649495727..9f81ad2be 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -78,13 +78,13 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy node_initialized_latch (1), network_params{ config.network_params }, stats{ logger, config.stats_config }, - workers_impl{ std::make_unique (config.background_threads, nano::thread_role::name::worker) }, + workers_impl{ std::make_unique (config.background_threads, nano::thread_role::name::worker, /* start immediately */ true) }, workers{ *workers_impl }, - bootstrap_workers_impl{ std::make_unique (config.bootstrap_serving_threads, nano::thread_role::name::bootstrap_worker) }, + bootstrap_workers_impl{ std::make_unique (config.bootstrap_serving_threads, nano::thread_role::name::bootstrap_worker, /* start immediately */ true) }, bootstrap_workers{ *bootstrap_workers_impl }, - wallet_workers_impl{ std::make_unique (1, nano::thread_role::name::wallet_worker) }, + wallet_workers_impl{ std::make_unique (1, nano::thread_role::name::wallet_worker, /* start immediately */ true) }, wallet_workers{ *wallet_workers_impl }, - election_workers_impl{ std::make_unique (1, nano::thread_role::name::election_worker) }, + election_workers_impl{ std::make_unique (1, nano::thread_role::name::election_worker, /* start immediately */ true) }, election_workers{ *election_workers_impl }, work (work_a), distributed_work (*this), @@ -658,9 +658,7 @@ void nano::node::stop () logger.info (nano::log::type::node, "Node stopping..."); tcp_listener.stop (); - bootstrap_workers.stop (); - wallet_workers.stop (); - election_workers.stop (); + vote_router.stop (); peer_history.stop (); // Cancels ongoing work generation tasks, which may be blocking other threads @@ -688,12 +686,16 @@ void nano::node::stop () wallets.stop (); stats.stop (); epoch_upgrader.stop (); - workers.stop (); local_block_broadcaster.stop (); message_processor.stop (); network.stop (); // Stop network last to avoid killing in-use sockets monitor.stop (); + bootstrap_workers.stop (); + wallet_workers.stop (); + election_workers.stop (); + workers.stop (); + // work pool is not stopped on purpose due to testing setup // Stop the IO runner last From ba2e815cf9624f1c44bca11732392d9a7f0afb04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 22 Oct 2024 15:50:04 +0200 Subject: [PATCH 23/48] Rename `num_queued_tasks` to `queued_tasks` --- nano/lib/thread_pool.hpp | 9 ++------- nano/node/confirming_set.cpp | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/nano/lib/thread_pool.hpp b/nano/lib/thread_pool.hpp index 989a7c387..6985c869a 100644 --- a/nano/lib/thread_pool.hpp +++ b/nano/lib/thread_pool.hpp @@ -107,12 +107,7 @@ public: return thread_pool_impl != nullptr; } - unsigned get_num_threads () const - { - return num_threads; - } - - uint64_t num_queued_tasks () const + uint64_t queued_tasks () const { return num_tasks; } @@ -120,7 +115,7 @@ public: nano::container_info container_info () const { nano::container_info info; - info.put ("tasks", num_queued_tasks ()); + info.put ("tasks", queued_tasks ()); return info; } diff --git a/nano/node/confirming_set.cpp b/nano/node/confirming_set.cpp index 3d4031d28..980ddbabc 100644 --- a/nano/node/confirming_set.cpp +++ b/nano/node/confirming_set.cpp @@ -150,7 +150,7 @@ void nano::confirming_set::run_batch (std::unique_lock & lock) std::unique_lock lock{ mutex }; // It's possible that ledger cementing happens faster than the notifications can be processed by other components, cooldown here - while (notification_workers.num_queued_tasks () >= config.max_queued_notifications) + while (notification_workers.queued_tasks () >= config.max_queued_notifications) { stats.inc (nano::stat::type::confirming_set, nano::stat::detail::cooldown); condition.wait_for (lock, 100ms, [this] { return stopped.load (); }); From 4b0e2e8e156ffed09d71e99d8c83b359a58fa1e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 22 Oct 2024 15:53:15 +0200 Subject: [PATCH 24/48] Rename `push_task` to `post` to match asio naming --- nano/core_test/thread_pool.cpp | 2 +- nano/lib/thread_pool.hpp | 4 +-- nano/node/bootstrap/bootstrap_bulk_pull.cpp | 4 +-- nano/node/bootstrap/bootstrap_frontier.cpp | 4 +-- nano/node/confirming_set.cpp | 2 +- nano/node/election.cpp | 2 +- nano/node/epoch_upgrader.cpp | 4 +-- nano/node/json_handler.cpp | 32 ++++++++++----------- nano/node/node.cpp | 6 ++-- nano/node/transport/tcp_server.cpp | 8 +++--- nano/rpc_test/rpc.cpp | 2 +- 11 files changed, 35 insertions(+), 35 deletions(-) diff --git a/nano/core_test/thread_pool.cpp b/nano/core_test/thread_pool.cpp index 14ec42c85..7702190df 100644 --- a/nano/core_test/thread_pool.cpp +++ b/nano/core_test/thread_pool.cpp @@ -17,7 +17,7 @@ TEST (thread_pool, thread_pool) nano::thread_pool workers (1u, nano::thread_role::name::unknown); nano::test::start_stop_guard stop_guard{ workers }; - workers.push_task (func); + workers.post (func); ASSERT_FALSE (passed_sleep); nano::timer timer_l; diff --git a/nano/lib/thread_pool.hpp b/nano/lib/thread_pool.hpp index 6985c869a..c029f27b0 100644 --- a/nano/lib/thread_pool.hpp +++ b/nano/lib/thread_pool.hpp @@ -69,7 +69,7 @@ public: } template - void push_task (F && task) + void post (F && task) { nano::lock_guard guard{ mutex }; if (!stopped) @@ -95,7 +95,7 @@ public: timer->async_wait ([this, t = std::forward (task), /* preserve lifetime */ timer] (boost::system::error_code const & ec) mutable { if (!ec) { - push_task (std::move (t)); + post (std::move (t)); } }); } diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.cpp b/nano/node/bootstrap/bootstrap_bulk_pull.cpp index a4967bf35..539911a40 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.cpp @@ -530,7 +530,7 @@ void nano::bulk_pull_server::sent_action (boost::system::error_code const & ec, } if (!ec) { - node->bootstrap_workers.push_task ([this_l = shared_from_this ()] () { + node->bootstrap_workers.post ([this_l = shared_from_this ()] () { this_l->send_next (); }); } @@ -816,7 +816,7 @@ void nano::bulk_pull_account_server::sent_action (boost::system::error_code cons } if (!ec) { - node->bootstrap_workers.push_task ([this_l = shared_from_this ()] () { + node->bootstrap_workers.post ([this_l = shared_from_this ()] () { this_l->send_next_block (); }); } diff --git a/nano/node/bootstrap/bootstrap_frontier.cpp b/nano/node/bootstrap/bootstrap_frontier.cpp index b0b951b55..4e942e5db 100644 --- a/nano/node/bootstrap/bootstrap_frontier.cpp +++ b/nano/node/bootstrap/bootstrap_frontier.cpp @@ -70,7 +70,7 @@ void nano::frontier_req_client::receive_frontier () // we simply get a size of 0. if (size_a == nano::frontier_req_client::size_frontier) { - node->bootstrap_workers.push_task ([this_l, ec, size_a] () { + node->bootstrap_workers.post ([this_l, ec, size_a] () { this_l->received_frontier (ec, size_a); }); } @@ -355,7 +355,7 @@ void nano::frontier_req_server::sent_action (boost::system::error_code const & e { count++; - node->bootstrap_workers.push_task ([this_l = shared_from_this ()] () { + node->bootstrap_workers.post ([this_l = shared_from_this ()] () { this_l->send_next (); }); } diff --git a/nano/node/confirming_set.cpp b/nano/node/confirming_set.cpp index 980ddbabc..e504b0aca 100644 --- a/nano/node/confirming_set.cpp +++ b/nano/node/confirming_set.cpp @@ -160,7 +160,7 @@ void nano::confirming_set::run_batch (std::unique_lock & lock) } } - notification_workers.push_task ([this, batch = std::move (batch)] () { + notification_workers.post ([this, batch = std::move (batch)] () { stats.inc (nano::stat::type::confirming_set, nano::stat::detail::notify); batch_cemented.notify (batch); }); diff --git a/nano/node/election.cpp b/nano/node/election.cpp index 93b9e8f7d..06ea41350 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -62,7 +62,7 @@ void nano::election::confirm_once (nano::unique_lock & lock) lock.unlock (); - node.election_workers.push_task ([this_l = shared_from_this (), status_l, confirmation_action_l = confirmation_action] () { + node.election_workers.post ([this_l = shared_from_this (), status_l, confirmation_action_l = confirmation_action] () { // This is necessary if the winner of the election is one of the forks. // In that case the winning block is not yet in the ledger and cementing needs to wait for rollbacks to complete. this_l->node.process_confirmed (status_l.winner->hash (), this_l); diff --git a/nano/node/epoch_upgrader.cpp b/nano/node/epoch_upgrader.cpp index a2fa389c5..96dcfc663 100644 --- a/nano/node/epoch_upgrader.cpp +++ b/nano/node/epoch_upgrader.cpp @@ -161,7 +161,7 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc upgrader_condition.wait (lock); } } - node.workers.push_task ([&upgrader_process, &upgrader_mutex, &upgrader_condition, &upgraded_accounts, &workers, epoch, difficulty, signer, root, account] () { + node.workers.post ([&upgrader_process, &upgrader_mutex, &upgrader_condition, &upgraded_accounts, &workers, epoch, difficulty, signer, root, account] () { upgrader_process (upgraded_accounts, epoch, difficulty, signer, root, account); { nano::lock_guard lock{ upgrader_mutex }; @@ -241,7 +241,7 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc upgrader_condition.wait (lock); } } - node.workers.push_task ([&upgrader_process, &upgrader_mutex, &upgrader_condition, &upgraded_pending, &workers, epoch, difficulty, signer, root, account] () { + node.workers.post ([&upgrader_process, &upgrader_mutex, &upgrader_condition, &upgraded_pending, &workers, epoch, difficulty, signer, root, account] () { upgrader_process (upgraded_pending, epoch, difficulty, signer, root, account); { nano::lock_guard lock{ upgrader_mutex }; diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index 299acd94a..56758728d 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -541,7 +541,7 @@ void nano::json_handler::account_block_count () void nano::json_handler::account_create () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { auto wallet (rpc_l->wallet_impl ()); if (!rpc_l->ec) { @@ -731,7 +731,7 @@ void nano::json_handler::account_list () void nano::json_handler::account_move () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { auto wallet (rpc_l->wallet_impl ()); if (!rpc_l->ec) { @@ -770,7 +770,7 @@ void nano::json_handler::account_move () void nano::json_handler::account_remove () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { auto wallet (rpc_l->wallet_impl ()); auto account (rpc_l->account_impl ()); if (!rpc_l->ec) @@ -805,7 +805,7 @@ void nano::json_handler::account_representative () void nano::json_handler::account_representative_set () { - node.workers.push_task (create_worker_task ([work_generation_enabled = node.work_generation_enabled ()] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([work_generation_enabled = node.work_generation_enabled ()] (std::shared_ptr const & rpc_l) { auto wallet (rpc_l->wallet_impl ()); auto account (rpc_l->account_impl ()); std::string representative_text (rpc_l->request.get ("representative")); @@ -948,7 +948,7 @@ void nano::json_handler::accounts_representatives () void nano::json_handler::accounts_create () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { auto wallet (rpc_l->wallet_impl ()); auto count (rpc_l->count_impl ()); if (!rpc_l->ec) @@ -2930,7 +2930,7 @@ void nano::json_handler::node_id_delete () void nano::json_handler::password_change () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { auto wallet (rpc_l->wallet_impl ()); if (!rpc_l->ec) { @@ -2953,7 +2953,7 @@ void nano::json_handler::password_change () void nano::json_handler::password_enter () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { auto wallet (rpc_l->wallet_impl ()); if (!rpc_l->ec) { @@ -3178,7 +3178,7 @@ void nano::json_handler::receivable_exists () void nano::json_handler::process () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { bool const is_async = rpc_l->request.get ("async", false); auto block (rpc_l->block_impl (true)); @@ -4143,7 +4143,7 @@ void nano::json_handler::unchecked () void nano::json_handler::unchecked_clear () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { rpc_l->node.unchecked.clear (); rpc_l->response_l.put ("success", ""); rpc_l->response_errors (); @@ -4316,7 +4316,7 @@ void nano::json_handler::validate_account_number () void nano::json_handler::wallet_add () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { auto wallet (rpc_l->wallet_impl ()); if (!rpc_l->ec) { @@ -4346,7 +4346,7 @@ void nano::json_handler::wallet_add () void nano::json_handler::wallet_add_watch () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { auto wallet (rpc_l->wallet_impl ()); if (!rpc_l->ec) { @@ -4469,7 +4469,7 @@ void nano::json_handler::wallet_balances () void nano::json_handler::wallet_change_seed () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { auto wallet (rpc_l->wallet_impl ()); if (!rpc_l->ec) { @@ -4517,7 +4517,7 @@ void nano::json_handler::wallet_contains () void nano::json_handler::wallet_create () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { nano::raw_key seed; auto seed_text (rpc_l->request.get_optional ("seed")); if (seed_text.is_initialized () && seed.decode_hex (seed_text.get ())) @@ -4553,7 +4553,7 @@ void nano::json_handler::wallet_create () void nano::json_handler::wallet_destroy () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { std::string wallet_text (rpc_l->request.get ("wallet")); nano::wallet_id wallet; if (!wallet.decode_hex (wallet_text)) @@ -4845,7 +4845,7 @@ void nano::json_handler::wallet_representative () void nano::json_handler::wallet_representative_set () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { auto wallet (rpc_l->wallet_impl ()); std::string representative_text (rpc_l->request.get ("representative")); auto representative (rpc_l->account_impl (representative_text, nano::error_rpc::bad_representative_number)); @@ -5132,7 +5132,7 @@ void nano::json_handler::work_get () void nano::json_handler::work_set () { - node.workers.push_task (create_worker_task ([] (std::shared_ptr const & rpc_l) { + node.workers.post (create_worker_task ([] (std::shared_ptr const & rpc_l) { auto wallet (rpc_l->wallet_impl ()); auto account (rpc_l->account_impl ()); auto work (rpc_l->work_optional_impl ()); diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 9f81ad2be..a63d698cf 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -406,7 +406,7 @@ nano::node::node (std::shared_ptr io_ctx_a, std::filesy // TODO: Is it neccessary to call this for all blocks? if (block->is_send ()) { - wallet_workers.push_task ([this, hash = block->hash (), destination = block->destination ()] () { + wallet_workers.post ([this, hash = block->hash (), destination = block->destination ()] () { wallets.receive_confirmed (hash, destination); }); } @@ -568,7 +568,7 @@ void nano::node::start () if (flags.enable_pruning) { auto this_l (shared ()); - workers.push_task ([this_l] () { + workers.post ([this_l] () { this_l->ongoing_ledger_pruning (); }); } @@ -988,7 +988,7 @@ void nano::node::ongoing_ledger_pruning () auto const ledger_pruning_interval (bootstrap_weight_reached ? config.max_pruning_age : std::min (config.max_pruning_age, std::chrono::seconds (15 * 60))); auto this_l (shared ()); workers.add_timed_task (std::chrono::steady_clock::now () + ledger_pruning_interval, [this_l] () { - this_l->workers.push_task ([this_l] () { + this_l->workers.post ([this_l] () { this_l->ongoing_ledger_pruning (); }); }); diff --git a/nano/node/transport/tcp_server.cpp b/nano/node/transport/tcp_server.cpp index a4e59e674..881da00c5 100644 --- a/nano/node/transport/tcp_server.cpp +++ b/nano/node/transport/tcp_server.cpp @@ -526,7 +526,7 @@ void nano::transport::tcp_server::bootstrap_message_visitor::bulk_pull (const na return; } - node->bootstrap_workers.push_task ([server = server, message = message] () { + node->bootstrap_workers.post ([server = server, message = message] () { // TODO: Add completion callback to bulk pull server // TODO: There should be no need to re-copy message as unique pointer, refactor those bulk/frontier pull/push servers auto bulk_pull_server = std::make_shared (server, std::make_unique (message)); @@ -548,7 +548,7 @@ void nano::transport::tcp_server::bootstrap_message_visitor::bulk_pull_account ( return; } - node->bootstrap_workers.push_task ([server = server, message = message] () { + node->bootstrap_workers.post ([server = server, message = message] () { // TODO: Add completion callback to bulk pull server // TODO: There should be no need to re-copy message as unique pointer, refactor those bulk/frontier pull/push servers auto bulk_pull_account_server = std::make_shared (server, std::make_unique (message)); @@ -565,7 +565,7 @@ void nano::transport::tcp_server::bootstrap_message_visitor::bulk_push (const na { return; } - node->bootstrap_workers.push_task ([server = server] () { + node->bootstrap_workers.post ([server = server] () { // TODO: Add completion callback to bulk pull server auto bulk_push_server = std::make_shared (server); bulk_push_server->throttled_receive (); @@ -582,7 +582,7 @@ void nano::transport::tcp_server::bootstrap_message_visitor::frontier_req (const return; } - node->bootstrap_workers.push_task ([server = server, message = message] () { + node->bootstrap_workers.post ([server = server, message = message] () { // TODO: There should be no need to re-copy message as unique pointer, refactor those bulk/frontier pull/push servers auto response = std::make_shared (server, std::make_unique (message)); response->send_next (); diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 1efdeacaf..b077c0aa3 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -67,7 +67,7 @@ TEST (rpc, wrapped_task) // Exception should get caught throw std::runtime_error (""); })); - system.nodes[0]->workers.push_task (task); + system.nodes[0]->workers.post (task); ASSERT_TIMELY_EQ (5s, response, true); } From 5bc6a64eed482834d81bdb5f9a86abf0a36acaf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 22 Oct 2024 15:54:35 +0200 Subject: [PATCH 25/48] Rename `workers.add_timed_task` to `post_timed` --- nano/core_test/thread_pool.cpp | 8 ++-- nano/lib/thread_pool.hpp | 2 +- nano/node/bootstrap/bootstrap_bulk_pull.cpp | 2 +- nano/node/bootstrap/bootstrap_bulk_push.cpp | 2 +- nano/node/bootstrap/bootstrap_connections.cpp | 2 +- nano/node/distributed_work.cpp | 2 +- nano/node/network.cpp | 2 +- nano/node/node.cpp | 14 +++--- nano/node/transport/tcp_socket.cpp | 2 +- nano/node/wallet.cpp | 4 +- nano/qt/qt.cpp | 46 +++++++++---------- nano/slow_test/node.cpp | 2 +- nano/test_common/system.cpp | 2 +- 13 files changed, 45 insertions(+), 45 deletions(-) diff --git a/nano/core_test/thread_pool.cpp b/nano/core_test/thread_pool.cpp index 7702190df..a01b35752 100644 --- a/nano/core_test/thread_pool.cpp +++ b/nano/core_test/thread_pool.cpp @@ -39,7 +39,7 @@ TEST (thread_pool, one) nano::condition_variable condition; nano::thread_pool workers (1u, nano::thread_role::name::unknown); nano::test::start_stop_guard stop_guard{ workers }; - workers.add_timed_task (std::chrono::steady_clock::now (), [&] () { + workers.post_timed (std::chrono::steady_clock::now (), [&] () { { nano::lock_guard lock{ mutex }; done = true; @@ -59,7 +59,7 @@ TEST (thread_pool, many) nano::test::start_stop_guard stop_guard{ workers }; for (auto i (0); i < 50; ++i) { - workers.add_timed_task (std::chrono::steady_clock::now (), [&] () { + workers.post_timed (std::chrono::steady_clock::now (), [&] () { { nano::lock_guard lock{ mutex }; count += 1; @@ -79,12 +79,12 @@ TEST (thread_pool, top_execution) std::promise promise; nano::thread_pool workers (1u, nano::thread_role::name::unknown); nano::test::start_stop_guard stop_guard{ workers }; - workers.add_timed_task (std::chrono::steady_clock::now (), [&] () { + workers.post_timed (std::chrono::steady_clock::now (), [&] () { nano::lock_guard lock{ mutex }; value1 = 1; value2 = 1; }); - workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::milliseconds (1), [&] () { + workers.post_timed (std::chrono::steady_clock::now () + std::chrono::milliseconds (1), [&] () { nano::lock_guard lock{ mutex }; value2 = 2; promise.set_value (false); diff --git a/nano/lib/thread_pool.hpp b/nano/lib/thread_pool.hpp index c029f27b0..bcbc589f0 100644 --- a/nano/lib/thread_pool.hpp +++ b/nano/lib/thread_pool.hpp @@ -84,7 +84,7 @@ public: } template - void add_timed_task (std::chrono::steady_clock::time_point const & expiry_time, F && task) + void post_timed (std::chrono::steady_clock::time_point const & expiry_time, F && task) { nano::lock_guard guard{ mutex }; if (!stopped) diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.cpp b/nano/node/bootstrap/bootstrap_bulk_pull.cpp index 539911a40..cb27272fe 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.cpp @@ -127,7 +127,7 @@ void nano::bulk_pull_client::throttled_receive_block () else { auto this_l (shared_from_this ()); - node->workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (1), [this_l] () { + node->workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (1), [this_l] () { if (!this_l->connection->pending_stop && !this_l->attempt->stopped) { this_l->throttled_receive_block (); diff --git a/nano/node/bootstrap/bootstrap_bulk_push.cpp b/nano/node/bootstrap/bootstrap_bulk_push.cpp index 47508878a..839c00f2e 100644 --- a/nano/node/bootstrap/bootstrap_bulk_push.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_push.cpp @@ -144,7 +144,7 @@ void nano::bulk_push_server::throttled_receive () else { auto this_l (shared_from_this ()); - node->workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (1), [this_l] () { + node->workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (1), [this_l] () { if (!this_l->connection->stopped) { this_l->throttled_receive (); diff --git a/nano/node/bootstrap/bootstrap_connections.cpp b/nano/node/bootstrap/bootstrap_connections.cpp index 358538a65..012c20b07 100644 --- a/nano/node/bootstrap/bootstrap_connections.cpp +++ b/nano/node/bootstrap/bootstrap_connections.cpp @@ -306,7 +306,7 @@ void nano::bootstrap_connections::populate_connections (bool repeat) if (!stopped && repeat) { std::weak_ptr this_w (shared_from_this ()); - node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (1), [this_w] () { + node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (1), [this_w] () { if (auto this_l = this_w.lock ()) { this_l->populate_connections (); diff --git a/nano/node/distributed_work.cpp b/nano/node/distributed_work.cpp index 56312d7cc..f2518ad28 100644 --- a/nano/node/distributed_work.cpp +++ b/nano/node/distributed_work.cpp @@ -403,7 +403,7 @@ void nano::distributed_work::handle_failure () auto now (std::chrono::steady_clock::now ()); std::weak_ptr node_weak (node.shared ()); auto next_backoff (std::min (backoff * 2, std::chrono::seconds (5 * 60))); - node.workers.add_timed_task (now + std::chrono::seconds (backoff), [node_weak, request_l = request, next_backoff] { + node.workers.post_timed (now + std::chrono::seconds (backoff), [node_weak, request_l = request, next_backoff] { bool error_l{ true }; if (auto node_l = node_weak.lock ()) { diff --git a/nano/node/network.cpp b/nano/node/network.cpp index 6a74df915..859be2225 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -300,7 +300,7 @@ void nano::network::flood_block_many (std::deque> b if (!blocks_a.empty ()) { std::weak_ptr node_w (node.shared ()); - node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::milliseconds (delay_a + std::rand () % delay_a), [node_w, blocks (std::move (blocks_a)), callback_a, delay_a] () { + node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::milliseconds (delay_a + std::rand () % delay_a), [node_w, blocks (std::move (blocks_a)), callback_a, delay_a] () { if (auto node_l = node_w.lock ()) { node_l->network.flood_block_many (std::move (blocks), callback_a, delay_a); diff --git a/nano/node/node.cpp b/nano/node/node.cpp index a63d698cf..9b73f13e5 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -609,7 +609,7 @@ void nano::node::start () { // Delay to start wallet lazy bootstrap auto this_l (shared ()); - workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::minutes (1), [this_l] () { + workers.post_timed (std::chrono::steady_clock::now () + std::chrono::minutes (1), [this_l] () { this_l->bootstrap_wallet (); }); } @@ -829,7 +829,7 @@ void nano::node::ongoing_bootstrap () // Bootstrap and schedule for next attempt bootstrap_initiator.bootstrap (false, boost::str (boost::format ("auto_bootstrap_%1%") % previous_bootstrap_count), frontiers_age); std::weak_ptr node_w (shared_from_this ()); - workers.add_timed_task (std::chrono::steady_clock::now () + next_wakeup, [node_w] () { + workers.post_timed (std::chrono::steady_clock::now () + next_wakeup, [node_w] () { if (auto node_l = node_w.lock ()) { node_l->ongoing_bootstrap (); @@ -850,7 +850,7 @@ void nano::node::backup_wallet () i->second->store.write_backup (transaction, backup_path / (i->first.to_string () + ".json")); } auto this_l (shared ()); - workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.backup_interval, [this_l] () { + workers.post_timed (std::chrono::steady_clock::now () + network_params.node.backup_interval, [this_l] () { this_l->backup_wallet (); }); } @@ -862,7 +862,7 @@ void nano::node::search_receivable_all () // Search pending wallets.search_receivable_all (); auto this_l (shared ()); - workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.search_pending_interval, [this_l] () { + workers.post_timed (std::chrono::steady_clock::now () + network_params.node.search_pending_interval, [this_l] () { this_l->search_receivable_all (); }); } @@ -987,7 +987,7 @@ void nano::node::ongoing_ledger_pruning () ledger_pruning (flags.block_processor_batch_size != 0 ? flags.block_processor_batch_size : 2 * 1024, bootstrap_weight_reached); auto const ledger_pruning_interval (bootstrap_weight_reached ? config.max_pruning_age : std::min (config.max_pruning_age, std::chrono::seconds (15 * 60))); auto this_l (shared ()); - workers.add_timed_task (std::chrono::steady_clock::now () + ledger_pruning_interval, [this_l] () { + workers.post_timed (std::chrono::steady_clock::now () + ledger_pruning_interval, [this_l] () { this_l->workers.post ([this_l] () { this_l->ongoing_ledger_pruning (); }); @@ -1132,7 +1132,7 @@ bool nano::node::block_confirmed_or_being_confirmed (nano::block_hash const & ha void nano::node::ongoing_online_weight_calculation_queue () { std::weak_ptr node_w (shared_from_this ()); - workers.add_timed_task (std::chrono::steady_clock::now () + (std::chrono::seconds (network_params.node.weight_period)), [node_w] () { + workers.post_timed (std::chrono::steady_clock::now () + (std::chrono::seconds (network_params.node.weight_period)), [node_w] () { if (auto node_l = node_w.lock ()) { node_l->ongoing_online_weight_calculation (); @@ -1171,7 +1171,7 @@ void nano::node::process_confirmed (nano::block_hash hash, std::shared_ptrworkers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (node_l->network_params.network.is_dev_network () ? 1 : 5), [this_w = weak_from_this ()] () { + node_l->workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (node_l->network_params.network.is_dev_network () ? 1 : 5), [this_w = weak_from_this ()] () { auto this_l = this_w.lock (); if (!this_l) { diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index a1f46c78f..6b0bba582 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1158,7 +1158,7 @@ void nano::wallet::work_ensure (nano::account const & account_a, nano::root cons wallets.delayed_work->operator[] (account_a) = root_a; - wallets.node.workers.add_timed_task (std::chrono::steady_clock::now () + precache_delay, [this_l = shared_from_this (), account_a, root_a] { + wallets.node.workers.post_timed (std::chrono::steady_clock::now () + precache_delay, [this_l = shared_from_this (), account_a, root_a] { auto delayed_work = this_l->wallets.delayed_work.lock (); auto existing (delayed_work->find (account_a)); if (existing != delayed_work->end () && existing->second == root_a) @@ -1705,7 +1705,7 @@ void nano::wallets::ongoing_compute_reps () auto & node_l (node); // Representation drifts quickly on the test network but very slowly on the live network auto compute_delay = network_params.network.is_dev_network () ? std::chrono::milliseconds (10) : (network_params.network.is_test_network () ? std::chrono::milliseconds (nano::test_scan_wallet_reps_delay ()) : std::chrono::minutes (15)); - node.workers.add_timed_task (std::chrono::steady_clock::now () + compute_delay, [&node_l] () { + node.workers.post_timed (std::chrono::steady_clock::now () + compute_delay, [&node_l] () { node_l.wallets.ongoing_compute_reps (); }); } diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index aefd693bd..aeeef01e5 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -107,7 +107,7 @@ nano_qt::self_pane::self_pane (nano_qt::wallet & wallet_a, nano::account const & QObject::connect (copy_button, &QPushButton::clicked, [this] () { this->wallet.application.clipboard ()->setText (QString (this->wallet.account.to_account ().c_str ())); copy_button->setText ("Copied!"); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (2), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (2), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { copy_button->setText ("Copy"); })); @@ -201,7 +201,7 @@ nano_qt::accounts::accounts (nano_qt::wallet & wallet_a) : this->wallet.wallet_m->deterministic_insert (transaction); show_button_success (*create_account); create_account->setText ("New account was created"); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*create_account); create_account->setText ("Create account"); @@ -212,7 +212,7 @@ nano_qt::accounts::accounts (nano_qt::wallet & wallet_a) : { show_button_error (*create_account); create_account->setText ("Wallet is locked, unlock it to create account"); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*create_account); create_account->setText ("Create account"); @@ -234,7 +234,7 @@ nano_qt::accounts::accounts (nano_qt::wallet & wallet_a) : this->wallet.application.clipboard ()->setText (QString (seed.to_string ().c_str ())); show_button_success (*backup_seed); backup_seed->setText ("Seed was copied to clipboard"); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*backup_seed); backup_seed->setText ("Copy wallet seed to clipboard"); @@ -246,7 +246,7 @@ nano_qt::accounts::accounts (nano_qt::wallet & wallet_a) : this->wallet.application.clipboard ()->setText (""); show_button_error (*backup_seed); backup_seed->setText ("Wallet is locked, unlock it to enable the backup"); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*backup_seed); backup_seed->setText ("Copy wallet seed to clipboard"); @@ -280,7 +280,7 @@ void nano_qt::accounts::refresh_wallet_balance () final_text += "\nReady to receive: " + wallet.format_balance (pending); } wallet_balance_label->setText (QString (final_text.c_str ())); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (60), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (60), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { refresh_wallet_balance (); })); @@ -410,7 +410,7 @@ nano_qt::import::import (nano_qt::wallet & wallet_a) : show_line_error (*seed); show_button_error (*import_seed); import_seed->setText ("Wallet is locked, unlock it to enable the import"); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (10), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (10), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_line_ok (*seed); show_button_ok (*import_seed); @@ -427,7 +427,7 @@ nano_qt::import::import (nano_qt::wallet & wallet_a) : show_button_success (*import_seed); import_seed->setText ("Successful import of seed"); this->wallet.refresh (); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*import_seed); import_seed->setText ("Import seed"); @@ -447,7 +447,7 @@ nano_qt::import::import (nano_qt::wallet & wallet_a) : { import_seed->setText ("Incorrect seed. Only HEX characters allowed"); } - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*import_seed); import_seed->setText ("Import seed"); @@ -460,7 +460,7 @@ nano_qt::import::import (nano_qt::wallet & wallet_a) : show_line_error (*clear_line); show_button_error (*import_seed); import_seed->setText ("Type words 'clear keys'"); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*import_seed); import_seed->setText ("Import seed"); @@ -745,7 +745,7 @@ void nano_qt::block_viewer::rebroadcast_action (nano::block_hash const & hash_a) if (successor) { done = false; - wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (1), [this, successor] () { + wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (1), [this, successor] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this, successor] () { rebroadcast_action (successor.value ()); })); @@ -1147,7 +1147,7 @@ void nano_qt::wallet::ongoing_refresh () } })); - node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [wallet_w] () { + node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [wallet_w] () { if (auto wallet_l = wallet_w.lock ()) { wallet_l->ongoing_refresh (); @@ -1231,7 +1231,7 @@ void nano_qt::wallet::start () { show_button_error (*this_l->send_blocks_send); this_l->send_blocks_send->setText ("Wallet is locked, unlock it to send"); - this_l->node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this_w] () { + this_l->node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this_w] () { if (auto this_l = this_w.lock ()) { this_l->application.postEvent (&this_l->processor, new eventloop_event ([this_w] () { @@ -1250,7 +1250,7 @@ void nano_qt::wallet::start () show_line_error (*this_l->send_count); show_button_error (*this_l->send_blocks_send); this_l->send_blocks_send->setText ("Not enough balance"); - this_l->node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this_w] () { + this_l->node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this_w] () { if (auto this_l = this_w.lock ()) { this_l->application.postEvent (&this_l->processor, new eventloop_event ([this_w] () { @@ -1269,7 +1269,7 @@ void nano_qt::wallet::start () show_line_error (*this_l->send_account); show_button_error (*this_l->send_blocks_send); this_l->send_blocks_send->setText ("Bad destination account"); - this_l->node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this_w] () { + this_l->node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this_w] () { if (auto this_l = this_w.lock ()) { this_l->application.postEvent (&this_l->processor, new eventloop_event ([this_w] () { @@ -1288,7 +1288,7 @@ void nano_qt::wallet::start () show_line_error (*this_l->send_count); show_button_error (*this_l->send_blocks_send); this_l->send_blocks_send->setText ("Bad amount number"); - this_l->node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this_w] () { + this_l->node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this_w] () { if (auto this_l = this_w.lock ()) { this_l->application.postEvent (&this_l->processor, new eventloop_event ([this_w] () { @@ -1464,7 +1464,7 @@ void nano_qt::wallet::update_connected () void nano_qt::wallet::empty_password () { - this->node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (3), [this] () { + this->node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (3), [this] () { auto transaction (wallet_m->wallets.tx_begin_write ()); wallet_m->enter_password (transaction, std::string ("")); }); @@ -1568,7 +1568,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : change->setText ("Password was changed"); this->wallet.node.logger.warn (nano::log::type::qt, "Wallet password changed"); update_locked (false, false); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*change); change->setText ("Set/Change password"); @@ -1586,7 +1586,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : { show_button_error (*change); change->setText ("Wallet is locked, unlock it"); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*change); change->setText ("Set/Change password"); @@ -1612,7 +1612,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : change_rep->setText ("Representative was changed"); current_representative->setText (QString (representative_l.to_account ().c_str ())); new_representative->clear (); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*change_rep); change_rep->setText ("Change representative"); @@ -1623,7 +1623,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : { show_button_error (*change_rep); change_rep->setText ("Wallet is locked, unlock it"); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*change_rep); change_rep->setText ("Change representative"); @@ -1636,7 +1636,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : show_line_error (*new_representative); show_button_error (*change_rep); change_rep->setText ("Invalid account"); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_line_ok (*new_representative); show_button_ok (*change_rep); @@ -1676,7 +1676,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : show_line_error (*password); show_button_error (*lock_toggle); lock_toggle->setText ("Invalid password"); - this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_line_ok (*password); show_button_ok (*lock_toggle); diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 5ffca07c6..ec1bb8d38 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -104,7 +104,7 @@ TEST (system, receive_while_synchronizing) node1->start (); system.nodes.push_back (node1); ASSERT_NE (nullptr, nano::test::establish_tcp (system, *node1, node->network.endpoint ())); - node1->workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::milliseconds (200), ([&system, &key] () { + node1->workers.post_timed (std::chrono::steady_clock::now () + std::chrono::milliseconds (200), ([&system, &key] () { auto hash (system.wallet (0)->send_sync (nano::dev::genesis_key.pub, key.pub, system.nodes[0]->config.receive_minimum.number ())); auto transaction = system.nodes[0]->ledger.tx_begin_read (); auto block = system.nodes[0]->ledger.any.block_get (transaction, hash); diff --git a/nano/test_common/system.cpp b/nano/test_common/system.cpp index 40f8be220..ac3aecd78 100644 --- a/nano/test_common/system.cpp +++ b/nano/test_common/system.cpp @@ -405,7 +405,7 @@ public: if (count_l > 0) { auto this_l (shared_from_this ()); - node->workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::milliseconds (wait), [this_l] () { this_l->run (); }); + node->workers.post_timed (std::chrono::steady_clock::now () + std::chrono::milliseconds (wait), [this_l] () { this_l->run (); }); } } std::vector accounts; From f53f1f8d98b044d7fe670f2c08e5b53f84a903cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 22 Oct 2024 16:13:19 +0200 Subject: [PATCH 26/48] Replace `post_timed` with `post_delayed` --- nano/core_test/thread_pool.cpp | 8 ++-- nano/lib/thread_pool.hpp | 15 ++++-- nano/node/bootstrap/bootstrap_bulk_pull.cpp | 2 +- nano/node/bootstrap/bootstrap_bulk_push.cpp | 2 +- nano/node/bootstrap/bootstrap_connections.cpp | 2 +- nano/node/distributed_work.cpp | 3 +- nano/node/network.cpp | 2 +- nano/node/node.cpp | 14 +++--- nano/node/transport/tcp_socket.cpp | 2 +- nano/node/wallet.cpp | 4 +- nano/qt/qt.cpp | 46 +++++++++---------- nano/slow_test/node.cpp | 2 +- nano/test_common/system.cpp | 2 +- 13 files changed, 56 insertions(+), 48 deletions(-) diff --git a/nano/core_test/thread_pool.cpp b/nano/core_test/thread_pool.cpp index a01b35752..810bbd0ac 100644 --- a/nano/core_test/thread_pool.cpp +++ b/nano/core_test/thread_pool.cpp @@ -39,7 +39,7 @@ TEST (thread_pool, one) nano::condition_variable condition; nano::thread_pool workers (1u, nano::thread_role::name::unknown); nano::test::start_stop_guard stop_guard{ workers }; - workers.post_timed (std::chrono::steady_clock::now (), [&] () { + workers.post ([&] () { { nano::lock_guard lock{ mutex }; done = true; @@ -59,7 +59,7 @@ TEST (thread_pool, many) nano::test::start_stop_guard stop_guard{ workers }; for (auto i (0); i < 50; ++i) { - workers.post_timed (std::chrono::steady_clock::now (), [&] () { + workers.post ([&] () { { nano::lock_guard lock{ mutex }; count += 1; @@ -79,12 +79,12 @@ TEST (thread_pool, top_execution) std::promise promise; nano::thread_pool workers (1u, nano::thread_role::name::unknown); nano::test::start_stop_guard stop_guard{ workers }; - workers.post_timed (std::chrono::steady_clock::now (), [&] () { + workers.post ([&] () { nano::lock_guard lock{ mutex }; value1 = 1; value2 = 1; }); - workers.post_timed (std::chrono::steady_clock::now () + std::chrono::milliseconds (1), [&] () { + workers.post_delayed (std::chrono::milliseconds (1), [&] () { nano::lock_guard lock{ mutex }; value2 = 2; promise.set_value (false); diff --git a/nano/lib/thread_pool.hpp b/nano/lib/thread_pool.hpp index bcbc589f0..0e42c6e10 100644 --- a/nano/lib/thread_pool.hpp +++ b/nano/lib/thread_pool.hpp @@ -84,17 +84,19 @@ public: } template - void post_timed (std::chrono::steady_clock::time_point const & expiry_time, F && task) + void post_delayed (std::chrono::steady_clock::duration const & delay, F && task) { nano::lock_guard guard{ mutex }; if (!stopped) { + ++num_delayed; release_assert (thread_pool_impl); auto timer = std::make_shared (thread_pool_impl->get_executor ()); - timer->expires_at (expiry_time); + timer->expires_after (delay); timer->async_wait ([this, t = std::forward (task), /* preserve lifetime */ timer] (boost::system::error_code const & ec) mutable { if (!ec) { + --num_delayed; post (std::move (t)); } }); @@ -112,10 +114,16 @@ public: return num_tasks; } + uint64_t delayed_tasks () const + { + return num_delayed; + } + nano::container_info container_info () const { nano::container_info info; - info.put ("tasks", queued_tasks ()); + info.put ("tasks", num_tasks); + info.put ("delayed", num_delayed); return info; } @@ -141,5 +149,6 @@ private: std::atomic stopped{ false }; std::unique_ptr thread_pool_impl; std::atomic num_tasks{ 0 }; + std::atomic num_delayed{ 0 }; }; } \ No newline at end of file diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.cpp b/nano/node/bootstrap/bootstrap_bulk_pull.cpp index cb27272fe..cfebdfbd0 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.cpp @@ -127,7 +127,7 @@ void nano::bulk_pull_client::throttled_receive_block () else { auto this_l (shared_from_this ()); - node->workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (1), [this_l] () { + node->workers.post_delayed (std::chrono::seconds (1), [this_l] () { if (!this_l->connection->pending_stop && !this_l->attempt->stopped) { this_l->throttled_receive_block (); diff --git a/nano/node/bootstrap/bootstrap_bulk_push.cpp b/nano/node/bootstrap/bootstrap_bulk_push.cpp index 839c00f2e..c023ec1fe 100644 --- a/nano/node/bootstrap/bootstrap_bulk_push.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_push.cpp @@ -144,7 +144,7 @@ void nano::bulk_push_server::throttled_receive () else { auto this_l (shared_from_this ()); - node->workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (1), [this_l] () { + node->workers.post_delayed (std::chrono::seconds (1), [this_l] () { if (!this_l->connection->stopped) { this_l->throttled_receive (); diff --git a/nano/node/bootstrap/bootstrap_connections.cpp b/nano/node/bootstrap/bootstrap_connections.cpp index 012c20b07..b3f1334b8 100644 --- a/nano/node/bootstrap/bootstrap_connections.cpp +++ b/nano/node/bootstrap/bootstrap_connections.cpp @@ -306,7 +306,7 @@ void nano::bootstrap_connections::populate_connections (bool repeat) if (!stopped && repeat) { std::weak_ptr this_w (shared_from_this ()); - node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (1), [this_w] () { + node.workers.post_delayed (std::chrono::seconds (1), [this_w] () { if (auto this_l = this_w.lock ()) { this_l->populate_connections (); diff --git a/nano/node/distributed_work.cpp b/nano/node/distributed_work.cpp index f2518ad28..41e876010 100644 --- a/nano/node/distributed_work.cpp +++ b/nano/node/distributed_work.cpp @@ -400,10 +400,9 @@ void nano::distributed_work::handle_failure () status = work_generation_status::failure_peers; - auto now (std::chrono::steady_clock::now ()); std::weak_ptr node_weak (node.shared ()); auto next_backoff (std::min (backoff * 2, std::chrono::seconds (5 * 60))); - node.workers.post_timed (now + std::chrono::seconds (backoff), [node_weak, request_l = request, next_backoff] { + node.workers.post_delayed (std::chrono::seconds (backoff), [node_weak, request_l = request, next_backoff] { bool error_l{ true }; if (auto node_l = node_weak.lock ()) { diff --git a/nano/node/network.cpp b/nano/node/network.cpp index 859be2225..6f2c33759 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -300,7 +300,7 @@ void nano::network::flood_block_many (std::deque> b if (!blocks_a.empty ()) { std::weak_ptr node_w (node.shared ()); - node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::milliseconds (delay_a + std::rand () % delay_a), [node_w, blocks (std::move (blocks_a)), callback_a, delay_a] () { + node.workers.post_delayed (std::chrono::milliseconds (delay_a + std::rand () % delay_a), [node_w, blocks (std::move (blocks_a)), callback_a, delay_a] () { if (auto node_l = node_w.lock ()) { node_l->network.flood_block_many (std::move (blocks), callback_a, delay_a); diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 9b73f13e5..e1649dc9d 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -609,7 +609,7 @@ void nano::node::start () { // Delay to start wallet lazy bootstrap auto this_l (shared ()); - workers.post_timed (std::chrono::steady_clock::now () + std::chrono::minutes (1), [this_l] () { + workers.post_delayed (std::chrono::minutes (1), [this_l] () { this_l->bootstrap_wallet (); }); } @@ -829,7 +829,7 @@ void nano::node::ongoing_bootstrap () // Bootstrap and schedule for next attempt bootstrap_initiator.bootstrap (false, boost::str (boost::format ("auto_bootstrap_%1%") % previous_bootstrap_count), frontiers_age); std::weak_ptr node_w (shared_from_this ()); - workers.post_timed (std::chrono::steady_clock::now () + next_wakeup, [node_w] () { + workers.post_delayed (next_wakeup, [node_w] () { if (auto node_l = node_w.lock ()) { node_l->ongoing_bootstrap (); @@ -850,7 +850,7 @@ void nano::node::backup_wallet () i->second->store.write_backup (transaction, backup_path / (i->first.to_string () + ".json")); } auto this_l (shared ()); - workers.post_timed (std::chrono::steady_clock::now () + network_params.node.backup_interval, [this_l] () { + workers.post_delayed (network_params.node.backup_interval, [this_l] () { this_l->backup_wallet (); }); } @@ -862,7 +862,7 @@ void nano::node::search_receivable_all () // Search pending wallets.search_receivable_all (); auto this_l (shared ()); - workers.post_timed (std::chrono::steady_clock::now () + network_params.node.search_pending_interval, [this_l] () { + workers.post_delayed (network_params.node.search_pending_interval, [this_l] () { this_l->search_receivable_all (); }); } @@ -987,7 +987,7 @@ void nano::node::ongoing_ledger_pruning () ledger_pruning (flags.block_processor_batch_size != 0 ? flags.block_processor_batch_size : 2 * 1024, bootstrap_weight_reached); auto const ledger_pruning_interval (bootstrap_weight_reached ? config.max_pruning_age : std::min (config.max_pruning_age, std::chrono::seconds (15 * 60))); auto this_l (shared ()); - workers.post_timed (std::chrono::steady_clock::now () + ledger_pruning_interval, [this_l] () { + workers.post_delayed (ledger_pruning_interval, [this_l] () { this_l->workers.post ([this_l] () { this_l->ongoing_ledger_pruning (); }); @@ -1132,7 +1132,7 @@ bool nano::node::block_confirmed_or_being_confirmed (nano::block_hash const & ha void nano::node::ongoing_online_weight_calculation_queue () { std::weak_ptr node_w (shared_from_this ()); - workers.post_timed (std::chrono::steady_clock::now () + (std::chrono::seconds (network_params.node.weight_period)), [node_w] () { + workers.post_delayed ((std::chrono::seconds (network_params.node.weight_period)), [node_w] () { if (auto node_l = node_w.lock ()) { node_l->ongoing_online_weight_calculation (); @@ -1171,7 +1171,7 @@ void nano::node::process_confirmed (nano::block_hash hash, std::shared_ptrworkers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (node_l->network_params.network.is_dev_network () ? 1 : 5), [this_w = weak_from_this ()] () { + node_l->workers.post_delayed (std::chrono::seconds (node_l->network_params.network.is_dev_network () ? 1 : 5), [this_w = weak_from_this ()] () { auto this_l = this_w.lock (); if (!this_l) { diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index 6b0bba582..f12dbe5ff 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1158,7 +1158,7 @@ void nano::wallet::work_ensure (nano::account const & account_a, nano::root cons wallets.delayed_work->operator[] (account_a) = root_a; - wallets.node.workers.post_timed (std::chrono::steady_clock::now () + precache_delay, [this_l = shared_from_this (), account_a, root_a] { + wallets.node.workers.post_delayed (precache_delay, [this_l = shared_from_this (), account_a, root_a] { auto delayed_work = this_l->wallets.delayed_work.lock (); auto existing (delayed_work->find (account_a)); if (existing != delayed_work->end () && existing->second == root_a) @@ -1705,7 +1705,7 @@ void nano::wallets::ongoing_compute_reps () auto & node_l (node); // Representation drifts quickly on the test network but very slowly on the live network auto compute_delay = network_params.network.is_dev_network () ? std::chrono::milliseconds (10) : (network_params.network.is_test_network () ? std::chrono::milliseconds (nano::test_scan_wallet_reps_delay ()) : std::chrono::minutes (15)); - node.workers.post_timed (std::chrono::steady_clock::now () + compute_delay, [&node_l] () { + node.workers.post_delayed (compute_delay, [&node_l] () { node_l.wallets.ongoing_compute_reps (); }); } diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index aeeef01e5..18f831935 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -107,7 +107,7 @@ nano_qt::self_pane::self_pane (nano_qt::wallet & wallet_a, nano::account const & QObject::connect (copy_button, &QPushButton::clicked, [this] () { this->wallet.application.clipboard ()->setText (QString (this->wallet.account.to_account ().c_str ())); copy_button->setText ("Copied!"); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (2), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (2), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { copy_button->setText ("Copy"); })); @@ -201,7 +201,7 @@ nano_qt::accounts::accounts (nano_qt::wallet & wallet_a) : this->wallet.wallet_m->deterministic_insert (transaction); show_button_success (*create_account); create_account->setText ("New account was created"); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*create_account); create_account->setText ("Create account"); @@ -212,7 +212,7 @@ nano_qt::accounts::accounts (nano_qt::wallet & wallet_a) : { show_button_error (*create_account); create_account->setText ("Wallet is locked, unlock it to create account"); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*create_account); create_account->setText ("Create account"); @@ -234,7 +234,7 @@ nano_qt::accounts::accounts (nano_qt::wallet & wallet_a) : this->wallet.application.clipboard ()->setText (QString (seed.to_string ().c_str ())); show_button_success (*backup_seed); backup_seed->setText ("Seed was copied to clipboard"); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*backup_seed); backup_seed->setText ("Copy wallet seed to clipboard"); @@ -246,7 +246,7 @@ nano_qt::accounts::accounts (nano_qt::wallet & wallet_a) : this->wallet.application.clipboard ()->setText (""); show_button_error (*backup_seed); backup_seed->setText ("Wallet is locked, unlock it to enable the backup"); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*backup_seed); backup_seed->setText ("Copy wallet seed to clipboard"); @@ -280,7 +280,7 @@ void nano_qt::accounts::refresh_wallet_balance () final_text += "\nReady to receive: " + wallet.format_balance (pending); } wallet_balance_label->setText (QString (final_text.c_str ())); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (60), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (60), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { refresh_wallet_balance (); })); @@ -410,7 +410,7 @@ nano_qt::import::import (nano_qt::wallet & wallet_a) : show_line_error (*seed); show_button_error (*import_seed); import_seed->setText ("Wallet is locked, unlock it to enable the import"); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (10), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (10), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_line_ok (*seed); show_button_ok (*import_seed); @@ -427,7 +427,7 @@ nano_qt::import::import (nano_qt::wallet & wallet_a) : show_button_success (*import_seed); import_seed->setText ("Successful import of seed"); this->wallet.refresh (); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*import_seed); import_seed->setText ("Import seed"); @@ -447,7 +447,7 @@ nano_qt::import::import (nano_qt::wallet & wallet_a) : { import_seed->setText ("Incorrect seed. Only HEX characters allowed"); } - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*import_seed); import_seed->setText ("Import seed"); @@ -460,7 +460,7 @@ nano_qt::import::import (nano_qt::wallet & wallet_a) : show_line_error (*clear_line); show_button_error (*import_seed); import_seed->setText ("Type words 'clear keys'"); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*import_seed); import_seed->setText ("Import seed"); @@ -745,7 +745,7 @@ void nano_qt::block_viewer::rebroadcast_action (nano::block_hash const & hash_a) if (successor) { done = false; - wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (1), [this, successor] () { + wallet.node.workers.post_delayed (std::chrono::seconds (1), [this, successor] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this, successor] () { rebroadcast_action (successor.value ()); })); @@ -1147,7 +1147,7 @@ void nano_qt::wallet::ongoing_refresh () } })); - node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [wallet_w] () { + node.workers.post_delayed (std::chrono::seconds (5), [wallet_w] () { if (auto wallet_l = wallet_w.lock ()) { wallet_l->ongoing_refresh (); @@ -1231,7 +1231,7 @@ void nano_qt::wallet::start () { show_button_error (*this_l->send_blocks_send); this_l->send_blocks_send->setText ("Wallet is locked, unlock it to send"); - this_l->node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this_w] () { + this_l->node.workers.post_delayed (std::chrono::seconds (5), [this_w] () { if (auto this_l = this_w.lock ()) { this_l->application.postEvent (&this_l->processor, new eventloop_event ([this_w] () { @@ -1250,7 +1250,7 @@ void nano_qt::wallet::start () show_line_error (*this_l->send_count); show_button_error (*this_l->send_blocks_send); this_l->send_blocks_send->setText ("Not enough balance"); - this_l->node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this_w] () { + this_l->node.workers.post_delayed (std::chrono::seconds (5), [this_w] () { if (auto this_l = this_w.lock ()) { this_l->application.postEvent (&this_l->processor, new eventloop_event ([this_w] () { @@ -1269,7 +1269,7 @@ void nano_qt::wallet::start () show_line_error (*this_l->send_account); show_button_error (*this_l->send_blocks_send); this_l->send_blocks_send->setText ("Bad destination account"); - this_l->node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this_w] () { + this_l->node.workers.post_delayed (std::chrono::seconds (5), [this_w] () { if (auto this_l = this_w.lock ()) { this_l->application.postEvent (&this_l->processor, new eventloop_event ([this_w] () { @@ -1288,7 +1288,7 @@ void nano_qt::wallet::start () show_line_error (*this_l->send_count); show_button_error (*this_l->send_blocks_send); this_l->send_blocks_send->setText ("Bad amount number"); - this_l->node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this_w] () { + this_l->node.workers.post_delayed (std::chrono::seconds (5), [this_w] () { if (auto this_l = this_w.lock ()) { this_l->application.postEvent (&this_l->processor, new eventloop_event ([this_w] () { @@ -1464,7 +1464,7 @@ void nano_qt::wallet::update_connected () void nano_qt::wallet::empty_password () { - this->node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (3), [this] () { + this->node.workers.post_delayed (std::chrono::seconds (3), [this] () { auto transaction (wallet_m->wallets.tx_begin_write ()); wallet_m->enter_password (transaction, std::string ("")); }); @@ -1568,7 +1568,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : change->setText ("Password was changed"); this->wallet.node.logger.warn (nano::log::type::qt, "Wallet password changed"); update_locked (false, false); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*change); change->setText ("Set/Change password"); @@ -1586,7 +1586,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : { show_button_error (*change); change->setText ("Wallet is locked, unlock it"); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*change); change->setText ("Set/Change password"); @@ -1612,7 +1612,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : change_rep->setText ("Representative was changed"); current_representative->setText (QString (representative_l.to_account ().c_str ())); new_representative->clear (); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*change_rep); change_rep->setText ("Change representative"); @@ -1623,7 +1623,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : { show_button_error (*change_rep); change_rep->setText ("Wallet is locked, unlock it"); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_button_ok (*change_rep); change_rep->setText ("Change representative"); @@ -1636,7 +1636,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : show_line_error (*new_representative); show_button_error (*change_rep); change_rep->setText ("Invalid account"); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_line_ok (*new_representative); show_button_ok (*change_rep); @@ -1676,7 +1676,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : show_line_error (*password); show_button_error (*lock_toggle); lock_toggle->setText ("Invalid password"); - this->wallet.node.workers.post_timed (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { + this->wallet.node.workers.post_delayed (std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { show_line_ok (*password); show_button_ok (*lock_toggle); diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index ec1bb8d38..de292dd06 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -104,7 +104,7 @@ TEST (system, receive_while_synchronizing) node1->start (); system.nodes.push_back (node1); ASSERT_NE (nullptr, nano::test::establish_tcp (system, *node1, node->network.endpoint ())); - node1->workers.post_timed (std::chrono::steady_clock::now () + std::chrono::milliseconds (200), ([&system, &key] () { + node1->workers.post_delayed (std::chrono::milliseconds (200), ([&system, &key] () { auto hash (system.wallet (0)->send_sync (nano::dev::genesis_key.pub, key.pub, system.nodes[0]->config.receive_minimum.number ())); auto transaction = system.nodes[0]->ledger.tx_begin_read (); auto block = system.nodes[0]->ledger.any.block_get (transaction, hash); diff --git a/nano/test_common/system.cpp b/nano/test_common/system.cpp index ac3aecd78..93e87245b 100644 --- a/nano/test_common/system.cpp +++ b/nano/test_common/system.cpp @@ -405,7 +405,7 @@ public: if (count_l > 0) { auto this_l (shared_from_this ()); - node->workers.post_timed (std::chrono::steady_clock::now () + std::chrono::milliseconds (wait), [this_l] () { this_l->run (); }); + node->workers.post_delayed (std::chrono::milliseconds (wait), [this_l] () { this_l->run (); }); } } std::vector accounts; From 7e7f91ba06939cdd512c779fc1bff06bd063381b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20W=C3=B3jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Tue, 22 Oct 2024 21:12:53 +0200 Subject: [PATCH 27/48] Update boost to 1.86 (#4743) --- CMakeLists.txt | 2 ++ nano/core_test/websocket.cpp | 1 + nano/lib/config.cpp | 1 + nano/nano_wallet/entry.cpp | 1 + nano/node/distributed_work.cpp | 1 + nano/node/ipc/ipc_server.cpp | 1 + nano/node/node.cpp | 1 + nano/rpc_test/rpc.cpp | 1 + nano/test_common/system.cpp | 1 + submodules/boost | 2 +- 10 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0614d03be..5b93fac65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -466,6 +466,8 @@ set(BOOST_MODULE_LIBS ratio rational regex + scope + scope_exit serialization smart_ptr spirit diff --git a/nano/core_test/websocket.cpp b/nano/core_test/websocket.cpp index 6cf553d3e..90991493d 100644 --- a/nano/core_test/websocket.cpp +++ b/nano/core_test/websocket.cpp @@ -12,6 +12,7 @@ #include +#include #include #include diff --git a/nano/lib/config.cpp b/nano/lib/config.cpp index df922fcc0..4dda3dcf1 100644 --- a/nano/lib/config.cpp +++ b/nano/lib/config.cpp @@ -6,6 +6,7 @@ #include #include +#include #include diff --git a/nano/nano_wallet/entry.cpp b/nano/nano_wallet/entry.cpp index 6a3eac399..4f149aa51 100644 --- a/nano/nano_wallet/entry.cpp +++ b/nano/nano_wallet/entry.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include diff --git a/nano/node/distributed_work.cpp b/nano/node/distributed_work.cpp index 56312d7cc..1404c0652 100644 --- a/nano/node/distributed_work.cpp +++ b/nano/node/distributed_work.cpp @@ -4,6 +4,7 @@ #include #include +#include std::shared_ptr nano::distributed_work::peer_request::get_prepared_json_request (std::string const & request_string_a) const { diff --git a/nano/node/ipc/ipc_server.cpp b/nano/node/ipc/ipc_server.cpp index bdd1eac70..ce711cb39 100644 --- a/nano/node/ipc/ipc_server.cpp +++ b/nano/node/ipc/ipc_server.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 229d17ce1..b3d595551 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index a13926989..309290dc1 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -30,6 +30,7 @@ #include +#include #include #include diff --git a/nano/test_common/system.cpp b/nano/test_common/system.cpp index 66af123ae..15aed9614 100644 --- a/nano/test_common/system.cpp +++ b/nano/test_common/system.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include diff --git a/submodules/boost b/submodules/boost index b6928ae5c..65c1319bb 160000 --- a/submodules/boost +++ b/submodules/boost @@ -1 +1 @@ -Subproject commit b6928ae5c92e21a04bbe17a558e6e066dbe632f6 +Subproject commit 65c1319bb92fe7a9a4abd588eff5818d9c2bccf9 From 1d4e8363c2e46d2bfa4c1f490189764639f77519 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Tue, 22 Oct 2024 23:39:31 +0100 Subject: [PATCH 28/48] Disable backtrace in CI build until backtrace log linking is resolved. (#4764) --- ci/build-ci.sh | 2 +- ci/build.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/build-ci.sh b/ci/build-ci.sh index f03b00c9d..b2be2f791 100755 --- a/ci/build-ci.sh +++ b/ci/build-ci.sh @@ -48,7 +48,7 @@ cmake \ -DNANO_WARN_TO_ERR=ON \ -DCMAKE_BUILD_TYPE=${BUILD_TYPE:-Debug} \ -DQt5_DIR=${qt_dir} \ -${BACKTRACE:-} \ +#${BACKTRACE:-} \ ${SANITIZERS:-} \ .. diff --git a/ci/build.sh b/ci/build.sh index 41d13cf26..f8610efa5 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -66,7 +66,7 @@ cmake \ -DCI_VERSION_PRE_RELEASE=${CI_VERSION_PRE_RELEASE:-OFF} \ ${CMAKE_SANITIZER:-} \ ${CMAKE_QT_DIR:-} \ -${CMAKE_BACKTRACE:-} \ +#${CMAKE_BACKTRACE:-} \ ${SRC} number_of_processors() { From 9efd84972ee89030f337964f4528041b9e716212 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Wed, 23 Oct 2024 06:42:09 +0100 Subject: [PATCH 29/48] Removing lines in build scripts because bash. (#4765) --- ci/build-ci.sh | 1 - ci/build.sh | 1 - 2 files changed, 2 deletions(-) diff --git a/ci/build-ci.sh b/ci/build-ci.sh index b2be2f791..31a65eed7 100755 --- a/ci/build-ci.sh +++ b/ci/build-ci.sh @@ -48,7 +48,6 @@ cmake \ -DNANO_WARN_TO_ERR=ON \ -DCMAKE_BUILD_TYPE=${BUILD_TYPE:-Debug} \ -DQt5_DIR=${qt_dir} \ -#${BACKTRACE:-} \ ${SANITIZERS:-} \ .. diff --git a/ci/build.sh b/ci/build.sh index f8610efa5..090aecbe8 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -66,7 +66,6 @@ cmake \ -DCI_VERSION_PRE_RELEASE=${CI_VERSION_PRE_RELEASE:-OFF} \ ${CMAKE_SANITIZER:-} \ ${CMAKE_QT_DIR:-} \ -#${CMAKE_BACKTRACE:-} \ ${SRC} number_of_processors() { From e9b07516ff1dba1df2acdf661c38c1bc1cccb386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Wed, 23 Oct 2024 12:29:22 +0200 Subject: [PATCH 30/48] Fix windows compilation --- nano/lib/thread_pool.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nano/lib/thread_pool.hpp b/nano/lib/thread_pool.hpp index 0e42c6e10..157272b7f 100644 --- a/nano/lib/thread_pool.hpp +++ b/nano/lib/thread_pool.hpp @@ -55,7 +55,7 @@ public: // TODO: Is this still needed? #if defined(BOOST_ASIO_HAS_IOCP) // A hack needed for Windows to prevent deadlock during destruction, described here: https://github.com/chriskohlhoff/asio/issues/431 - boost::asio::use_service (*thread_pool_m).stop (); + boost::asio::use_service (*thread_pool_impl).stop (); #endif lock.unlock (); From e1a4fcbec52448c92452d4fc5bb12fc6f8b36be3 Mon Sep 17 00:00:00 2001 From: gr0vity-dev <85646666+gr0vity-dev@users.noreply.github.com> Date: Fri, 25 Oct 2024 14:23:34 +0200 Subject: [PATCH 31/48] Optimize vote distribution between PRs and non-PRs (#4766) * Publish votes to all PRs and a subset of non PRs This avoids potential duplicate votes to PRs and better confirmation times for non PRs * small optimisation for list_non_pr --------- Co-authored-by: gr0vity-dev --- nano/node/network.cpp | 19 +++++++++++++++---- nano/node/network.hpp | 1 + nano/node/vote_generator.cpp | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/nano/node/network.cpp b/nano/node/network.cpp index 6a74df915..269edcd87 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -281,6 +281,15 @@ void nano::network::flood_vote (std::shared_ptr const & vote, float } } +void nano::network::flood_vote_non_pr (std::shared_ptr const & vote, float scale, bool rebroadcasted) +{ + nano::confirm_ack message{ node.network_params.network, vote, rebroadcasted }; + for (auto & i : list_non_pr (fanout (scale))) + { + i->send (message, nullptr); + } +} + void nano::network::flood_vote_pr (std::shared_ptr const & vote, bool rebroadcasted) { nano::confirm_ack message{ node.network_params.network, vote, rebroadcasted }; @@ -377,11 +386,13 @@ std::deque> nano::network::list_non_pr { std::deque> result; tcp_channels.list (result); + + auto partition_point = std::partition (result.begin (), result.end (), + [this] (std::shared_ptr const & channel) { + return !node.rep_crawler.is_pr (channel); + }); + result.resize (std::distance (result.begin (), partition_point)); nano::random_pool_shuffle (result.begin (), result.end ()); - result.erase (std::remove_if (result.begin (), result.end (), [this] (std::shared_ptr const & channel) { - return node.rep_crawler.is_pr (channel); - }), - result.end ()); if (result.size () > count_a) { result.resize (count_a, nullptr); diff --git a/nano/node/network.hpp b/nano/node/network.hpp index 5aa6ec877..0ab498ed2 100644 --- a/nano/node/network.hpp +++ b/nano/node/network.hpp @@ -95,6 +95,7 @@ public: void flood_keepalive_self (float const scale_a = 0.5f); void flood_vote (std::shared_ptr const &, float scale, bool rebroadcasted = false); void flood_vote_pr (std::shared_ptr const &, bool rebroadcasted = false); + void flood_vote_non_pr (std::shared_ptr const &, float scale, bool rebroadcasted = false); // Flood block to all PRs and a random selection of non-PRs void flood_block_initial (std::shared_ptr const &); // Flood block to a random selection of peers diff --git a/nano/node/vote_generator.cpp b/nano/node/vote_generator.cpp index 68792d690..e29c88cc9 100644 --- a/nano/node/vote_generator.cpp +++ b/nano/node/vote_generator.cpp @@ -277,7 +277,7 @@ void nano::vote_generator::vote (std::vector const & hashes_a, void nano::vote_generator::broadcast_action (std::shared_ptr const & vote_a) const { network.flood_vote_pr (vote_a); - network.flood_vote (vote_a, 2.0f); + network.flood_vote_non_pr (vote_a, 2.0f); vote_processor.vote (vote_a, inproc_channel); } From 6a26366e8b72818e85b9ea8507e885db16576bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Thu, 24 Oct 2024 19:16:21 +0200 Subject: [PATCH 32/48] Move random_pool test to a separate file --- nano/core_test/CMakeLists.txt | 1 + nano/core_test/random_pool.cpp | 48 ++++++++++++++++++++++++++++++++ nano/core_test/uint256_union.cpp | 43 ---------------------------- 3 files changed, 49 insertions(+), 43 deletions(-) create mode 100644 nano/core_test/random_pool.cpp diff --git a/nano/core_test/CMakeLists.txt b/nano/core_test/CMakeLists.txt index e5b47c9e4..6470ad273 100644 --- a/nano/core_test/CMakeLists.txt +++ b/nano/core_test/CMakeLists.txt @@ -39,6 +39,7 @@ add_executable( optimistic_scheduler.cpp processing_queue.cpp processor_service.cpp + random_pool.cpp rep_crawler.cpp receivable.cpp peer_history.cpp diff --git a/nano/core_test/random_pool.cpp b/nano/core_test/random_pool.cpp new file mode 100644 index 000000000..227ea87fc --- /dev/null +++ b/nano/core_test/random_pool.cpp @@ -0,0 +1,48 @@ +#include +#include + +#include + +#include + +TEST (random_pool, multithreading) +{ + std::vector threads; + for (auto i = 0; i < 100; ++i) + { + threads.emplace_back ([] () { + nano::uint256_union number; + nano::random_pool::generate_block (number.bytes.data (), number.bytes.size ()); + }); + } + for (auto & i : threads) + { + i.join (); + } +} + +// Test that random 64bit numbers are within the given range +TEST (random_pool, generate_word64) +{ + int occurrences[10] = { 0 }; + for (auto i = 0; i < 1000; ++i) + { + auto random = nano::random_pool::generate_word64 (1, 9); + ASSERT_TRUE (random >= 1 && random <= 9); + occurrences[random] += 1; + } + + for (auto i = 1; i < 10; ++i) + { + ASSERT_GT (occurrences[i], 0); + } +} + +// Test random numbers > uint32 max +TEST (random_pool, generate_word64_big_number) +{ + uint64_t min = static_cast (std::numeric_limits::max ()) + 1; + uint64_t max = std::numeric_limits::max (); + auto big_random = nano::random_pool::generate_word64 (min, max); + ASSERT_GE (big_random, min); +} diff --git a/nano/core_test/uint256_union.cpp b/nano/core_test/uint256_union.cpp index 743d0fe1c..7d939ad32 100644 --- a/nano/core_test/uint256_union.cpp +++ b/nano/core_test/uint256_union.cpp @@ -1,4 +1,3 @@ -#include #include #include @@ -573,45 +572,3 @@ void check_operator_greater_than (Num lhs, Num rhs) ASSERT_FALSE (rhs > rhs); } } - -TEST (random_pool, multithreading) -{ - std::vector threads; - for (auto i = 0; i < 100; ++i) - { - threads.emplace_back ([] () { - nano::uint256_union number; - nano::random_pool::generate_block (number.bytes.data (), number.bytes.size ()); - }); - } - for (auto & i : threads) - { - i.join (); - } -} - -// Test that random 64bit numbers are within the given range -TEST (random_pool, generate_word64) -{ - int occurrences[10] = { 0 }; - for (auto i = 0; i < 1000; ++i) - { - auto random = nano::random_pool::generate_word64 (1, 9); - ASSERT_TRUE (random >= 1 && random <= 9); - occurrences[random] += 1; - } - - for (auto i = 1; i < 10; ++i) - { - ASSERT_GT (occurrences[i], 0); - } -} - -// Test random numbers > uint32 max -TEST (random_pool, generate_word64_big_number) -{ - uint64_t min = static_cast (std::numeric_limits::max ()) + 1; - uint64_t max = std::numeric_limits::max (); - auto big_random = nano::random_pool::generate_word64 (min, max); - ASSERT_GE (big_random, min); -} From 674d5af863e85e729e8edf4f617f818108cd2df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Thu, 24 Oct 2024 19:23:08 +0200 Subject: [PATCH 33/48] Rename uint256 tests to numbers --- nano/core_test/CMakeLists.txt | 2 +- nano/core_test/{uint256_union.cpp => numbers.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename nano/core_test/{uint256_union.cpp => numbers.cpp} (100%) diff --git a/nano/core_test/CMakeLists.txt b/nano/core_test/CMakeLists.txt index 6470ad273..1d01f6e79 100644 --- a/nano/core_test/CMakeLists.txt +++ b/nano/core_test/CMakeLists.txt @@ -35,6 +35,7 @@ add_executable( network_filter.cpp network_functions.cpp node.cpp + numbers.cpp object_stream.cpp optimistic_scheduler.cpp processing_queue.cpp @@ -55,7 +56,6 @@ add_executable( throttle.cpp toml.cpp timer.cpp - uint256_union.cpp unchecked_map.cpp utility.cpp vote_cache.cpp diff --git a/nano/core_test/uint256_union.cpp b/nano/core_test/numbers.cpp similarity index 100% rename from nano/core_test/uint256_union.cpp rename to nano/core_test/numbers.cpp From 7f5c394ca54f82a57d10ae29263e561b9f9288f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Thu, 24 Oct 2024 19:31:05 +0200 Subject: [PATCH 34/48] Complete missing testcase --- nano/core_test/numbers.cpp | 7 ++++++- nano/lib/numbers.hpp | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/nano/core_test/numbers.cpp b/nano/core_test/numbers.cpp index 7d939ad32..1ffe78808 100644 --- a/nano/core_test/numbers.cpp +++ b/nano/core_test/numbers.cpp @@ -1,5 +1,5 @@ +#include #include -#include #include @@ -453,6 +453,11 @@ TEST (uint256_union, operator_less_than) test_union_operator_less_than (); } +TEST (uint256_union, operator_greater_than) +{ + test_union_operator_greater_than (); +} + TEST (uint64_t, parse) { uint64_t value0 (1); diff --git a/nano/lib/numbers.hpp b/nano/lib/numbers.hpp index c637e1594..71856e3b0 100644 --- a/nano/lib/numbers.hpp +++ b/nano/lib/numbers.hpp @@ -13,6 +13,7 @@ namespace nano using uint128_t = boost::multiprecision::uint128_t; using uint256_t = boost::multiprecision::uint256_t; using uint512_t = boost::multiprecision::uint512_t; + // SI dividers nano::uint128_t const Knano_ratio = nano::uint128_t ("1000000000000000000000000000000000"); // 10^33 = 1000 nano nano::uint128_t const nano_ratio = nano::uint128_t ("1000000000000000000000000000000"); // 10^30 = 1 nano @@ -113,6 +114,10 @@ inline bool operator< (nano::uint256_union const & lhs, nano::uint256_union cons { return std::memcmp (lhs.bytes.data (), rhs.bytes.data (), 32) < 0; } +inline bool operator> (nano::uint256_union const & lhs, nano::uint256_union const & rhs) +{ + return std::memcmp (lhs.bytes.data (), rhs.bytes.data (), 32) > 0; +} static_assert (std::is_nothrow_move_constructible::value, "uint256_union should be noexcept MoveConstructible"); class link; From aefd7c18fbebf836e337d2831e52a2fc27451891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Thu, 24 Oct 2024 20:02:30 +0200 Subject: [PATCH 35/48] Use spaceship comparisons --- nano/core_test/ledger.cpp | 2 +- nano/lib/numbers.cpp | 65 ------- nano/lib/numbers.hpp | 200 +++++++++++++++----- nano/node/bootstrap/bootstrap_bulk_pull.cpp | 4 +- nano/node/bootstrap/bootstrap_frontier.cpp | 2 +- nano/node/bootstrap/bootstrap_lazy.cpp | 2 +- nano/node/bootstrap_ascending/service.cpp | 2 +- nano/node/json_handler.cpp | 2 +- nano/qt/qt.cpp | 2 +- nano/rpc_test/rpc.cpp | 2 +- nano/secure/ledger.cpp | 2 +- 11 files changed, 160 insertions(+), 125 deletions(-) diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index 23d3d751b..0dd6e786d 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -2406,7 +2406,7 @@ TEST (ledger, state_account) .work (*pool.generate (nano::dev::genesis->hash ())) .build (); ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1)); - ASSERT_EQ (nano::dev::genesis_key.pub, ledger.any.block_account (transaction, send1->hash ())); + ASSERT_EQ (nano::dev::genesis_key.pub, ledger.any.block_account (transaction, send1->hash ()).value ()); } TEST (ledger, state_send_receive) diff --git a/nano/lib/numbers.cpp b/nano/lib/numbers.cpp index f33d6f3cb..b4bb819b7 100644 --- a/nano/lib/numbers.cpp +++ b/nano/lib/numbers.cpp @@ -286,11 +286,6 @@ nano::uint256_union::uint256_union (uint64_t value0) *this = nano::uint256_t (value0); } -bool nano::uint512_union::operator== (nano::uint512_union const & other_a) const -{ - return bytes == other_a.bytes; -} - nano::uint512_union::uint512_union (nano::uint256_union const & upper, nano::uint256_union const & lower) { uint256s[0] = upper; @@ -355,11 +350,6 @@ bool nano::uint512_union::decode_hex (std::string const & text) return error; } -bool nano::uint512_union::operator!= (nano::uint512_union const & other_a) const -{ - return !(*this == other_a); -} - nano::uint512_union & nano::uint512_union::operator^= (nano::uint512_union const & other_a) { uint256s[0] ^= other_a.uint256s[0]; @@ -446,26 +436,6 @@ nano::uint128_union::uint128_union (nano::uint128_t const & number_a) boost::multiprecision::export_bits (number_a, bytes.rbegin (), 8, false); } -bool nano::uint128_union::operator== (nano::uint128_union const & other_a) const -{ - return qwords[0] == other_a.qwords[0] && qwords[1] == other_a.qwords[1]; -} - -bool nano::uint128_union::operator!= (nano::uint128_union const & other_a) const -{ - return !(*this == other_a); -} - -bool nano::uint128_union::operator< (nano::uint128_union const & other_a) const -{ - return std::memcmp (bytes.data (), other_a.bytes.data (), 16) < 0; -} - -bool nano::uint128_union::operator> (nano::uint128_union const & other_a) const -{ - return std::memcmp (bytes.data (), other_a.bytes.data (), 16) > 0; -} - nano::uint128_t nano::uint128_union::number () const { nano::uint128_t result; @@ -811,36 +781,11 @@ std::string nano::hash_or_account::to_account () const return account.to_account (); } -nano::block_hash const & nano::hash_or_account::as_block_hash () const -{ - return hash; -} - -nano::account const & nano::hash_or_account::as_account () const -{ - return account; -} - -nano::hash_or_account::operator nano::uint256_union const & () const -{ - return raw; -} - nano::block_hash const & nano::root::previous () const { return hash; } -bool nano::hash_or_account::operator== (nano::hash_or_account const & hash_or_account_a) const -{ - return bytes == hash_or_account_a.bytes; -} - -bool nano::hash_or_account::operator!= (nano::hash_or_account const & hash_or_account_a) const -{ - return !(*this == hash_or_account_a); -} - std::string nano::to_string_hex (uint64_t const value_a) { std::stringstream stream; @@ -963,16 +908,6 @@ nano::public_key::operator nano::hash_or_account const & () const return reinterpret_cast (*this); } -bool nano::public_key::operator== (std::nullptr_t) const -{ - return bytes == null ().bytes; -} - -bool nano::public_key::operator!= (std::nullptr_t) const -{ - return !(*this == nullptr); -} - nano::block_hash::operator nano::link const & () const { return reinterpret_cast (*this); diff --git a/nano/lib/numbers.hpp b/nano/lib/numbers.hpp index 71856e3b0..aca9a338c 100644 --- a/nano/lib/numbers.hpp +++ b/nano/lib/numbers.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -23,29 +24,32 @@ class uint128_union { public: uint128_union () = default; + uint128_union (uint64_t); + uint128_union (nano::uint128_t const &); + /** * Decode from hex string * @warning Aborts at runtime if the input is invalid */ - uint128_union (std::string const &); - uint128_union (uint64_t); - uint128_union (nano::uint128_t const &); - bool operator== (nano::uint128_union const &) const; - bool operator!= (nano::uint128_union const &) const; - bool operator< (nano::uint128_union const &) const; - bool operator> (nano::uint128_union const &) const; + explicit uint128_union (std::string const &); + void encode_hex (std::string &) const; bool decode_hex (std::string const &); void encode_dec (std::string &) const; bool decode_dec (std::string const &, bool = false); bool decode_dec (std::string const &, nano::uint128_t); + std::string format_balance (nano::uint128_t scale, int precision, bool group_digits) const; std::string format_balance (nano::uint128_t scale, int precision, bool group_digits, std::locale const & locale) const; + nano::uint128_t number () const; void clear (); bool is_zero () const; + std::string to_string () const; std::string to_string_dec () const; + +public: union { std::array bytes; @@ -53,6 +57,24 @@ public: std::array dwords; std::array qwords; }; + +public: // Keep operators inlined + std::strong_ordering operator<=> (nano::uint128_union const & other) const + { + return std::memcmp (bytes.data (), other.bytes.data (), 16) <=> 0; + }; + bool operator== (nano::uint128_union const & other) const + { + return *this <=> other == 0; + } + operator nano::uint128_t () const + { + return number (); + } + uint128_union const & as_union () const + { + return *this; + } }; static_assert (std::is_nothrow_move_constructible::value, "uint128_union should be noexcept MoveConstructible"); @@ -62,37 +84,48 @@ class amount : public uint128_union public: using uint128_union::uint128_union; + auto operator<=> (nano::amount const & other) const + { + return uint128_union::operator<=> (other); + } operator nano::uint128_t () const { return number (); } }; + class raw_key; class uint256_union { public: uint256_union () = default; + uint256_union (uint64_t); + uint256_union (uint256_t const &); + /** * Decode from hex string * @warning Aborts at runtime if the input is invalid */ explicit uint256_union (std::string const &); - uint256_union (uint64_t); - uint256_union (nano::uint256_t const &); + void encrypt (nano::raw_key const &, nano::raw_key const &, uint128_union const &); - uint256_union & operator^= (nano::uint256_union const &); - uint256_union operator^ (nano::uint256_union const &) const; + + uint256_union & operator^= (uint256_union const &); + uint256_union operator^ (uint256_union const &) const; + void encode_hex (std::string &) const; bool decode_hex (std::string const &); void encode_dec (std::string &) const; bool decode_dec (std::string const &); + nano::uint256_t number () const; void clear (); bool is_zero () const; - std::string to_string () const; - nano::uint256_t number () const; + std::string to_string () const; + +public: union { std::array bytes; @@ -101,23 +134,25 @@ public: std::array qwords; std::array owords; }; + +public: // Keep operators inlined + std::strong_ordering operator<=> (nano::uint256_union const & other) const + { + return std::memcmp (bytes.data (), other.bytes.data (), 32) <=> 0; + }; + bool operator== (nano::uint256_union const & other) const + { + return *this <=> other == 0; + } + operator nano::uint256_t () const + { + return number (); + } + uint256_union const & as_union () const + { + return *this; + } }; -inline bool operator== (nano::uint256_union const & lhs, nano::uint256_union const & rhs) -{ - return lhs.bytes == rhs.bytes; -} -inline bool operator!= (nano::uint256_union const & lhs, nano::uint256_union const & rhs) -{ - return !(lhs == rhs); -} -inline bool operator< (nano::uint256_union const & lhs, nano::uint256_union const & rhs) -{ - return std::memcmp (lhs.bytes.data (), rhs.bytes.data (), 32) < 0; -} -inline bool operator> (nano::uint256_union const & lhs, nano::uint256_union const & rhs) -{ - return std::memcmp (lhs.bytes.data (), rhs.bytes.data (), 32) > 0; -} static_assert (std::is_nothrow_move_constructible::value, "uint256_union should be noexcept MoveConstructible"); class link; @@ -129,9 +164,24 @@ class block_hash final : public uint256_union { public: using uint256_union::uint256_union; + operator nano::link const & () const; operator nano::root const & () const; operator nano::hash_or_account const & () const; + +public: // Keep operators inlined + auto operator<=> (nano::block_hash const & other) const + { + return uint256_union::operator<=> (other); + } + bool operator== (nano::block_hash const & other) const + { + return *this <=> other == 0; + } + operator nano::uint256_t () const + { + return number (); + } }; class public_key final : public uint256_union @@ -152,8 +202,24 @@ public: operator nano::link const & () const; operator nano::root const & () const; operator nano::hash_or_account const & () const; - bool operator== (std::nullptr_t) const; - bool operator!= (std::nullptr_t) const; + +public: // Keep operators inlined + auto operator<=> (nano::public_key const & other) const + { + return uint256_union::operator<=> (other); + } + bool operator== (nano::public_key const & other) const + { + return *this <=> other == 0; + } + bool operator== (std::nullptr_t) const + { + return *this == null (); + } + operator nano::uint256_t () const + { + return number (); + } }; class wallet_id : public uint256_union @@ -172,19 +238,13 @@ public: bool is_zero () const; void clear (); + std::string to_string () const; bool decode_hex (std::string const &); bool decode_account (std::string const &); std::string to_account () const; - nano::account const & as_account () const; - nano::block_hash const & as_block_hash () const; - - operator nano::uint256_union const & () const; - - bool operator== (nano::hash_or_account const &) const; - bool operator!= (nano::hash_or_account const &) const; - +public: union { std::array bytes; @@ -192,6 +252,32 @@ public: nano::account account; nano::block_hash hash; }; + +public: // Keep operators inlined + auto operator<=> (nano::hash_or_account const & other) const + { + return raw <=> other.raw; + }; + bool operator== (nano::hash_or_account const & other) const + { + return *this <=> other == 0; + } + operator nano::uint256_t () const + { + return raw.number (); + } + operator nano::uint256_union () const + { + return raw; + } + nano::account const & as_account () const + { + return account; + } + nano::block_hash const & as_block_hash () const + { + return hash; + } }; // A link can either be a destination account or source hash @@ -218,22 +304,27 @@ public: ~raw_key (); void decrypt (nano::uint256_union const &, nano::raw_key const &, uint128_union const &); }; + class uint512_union { public: uint512_union () = default; uint512_union (nano::uint256_union const &, nano::uint256_union const &); uint512_union (nano::uint512_t const &); - bool operator== (nano::uint512_union const &) const; - bool operator!= (nano::uint512_union const &) const; + nano::uint512_union & operator^= (nano::uint512_union const &); + void encode_hex (std::string &) const; bool decode_hex (std::string const &); + void clear (); bool is_zero () const; + nano::uint512_t number () const; + std::string to_string () const; +public: union { std::array bytes; @@ -241,6 +332,24 @@ public: std::array qwords; std::array uint256s; }; + +public: // Keep operators inlined + std::strong_ordering operator<=> (nano::uint512_union const & other) const + { + return std::memcmp (bytes.data (), other.bytes.data (), 64) <=> 0; + }; + bool operator== (nano::uint512_union const & other) const + { + return *this <=> other == 0; + } + operator nano::uint512_t () const + { + return number (); + } + uint512_union const & as_union () const + { + return *this; + } }; static_assert (std::is_nothrow_move_constructible::value, "uint512_union should be noexcept MoveConstructible"); @@ -381,15 +490,6 @@ struct hash<::nano::qualified_root> return hash<::nano::uint512_union> () (data_a); } }; - -template <> -struct equal_to> -{ - bool operator() (std::reference_wrapper<::nano::block_hash const> const & lhs, std::reference_wrapper<::nano::block_hash const> const & rhs) const - { - return lhs.get () == rhs.get (); - } -}; } namespace boost diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.cpp b/nano/node/bootstrap/bootstrap_bulk_pull.cpp index a4967bf35..892e28691 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.cpp @@ -177,7 +177,7 @@ void nano::bulk_pull_client::received_block (boost::system::error_code ec, std:: // Is block expected? bool block_expected (false); // Unconfirmed head is used only for lazy destinations if legacy bootstrap is not available, see nano::bootstrap_attempt::lazy_destinations_increment (...) - bool unconfirmed_account_head = node->flags.disable_legacy_bootstrap && pull_blocks == 0 && pull.retry_limit <= node->network_params.bootstrap.lazy_retry_limit && (expected == pull.account_or_head.as_block_hash ()) && (block->account_field () == pull.account_or_head.as_account ()); + bool unconfirmed_account_head = node->flags.disable_legacy_bootstrap && pull_blocks == 0 && pull.retry_limit <= node->network_params.bootstrap.lazy_retry_limit && (expected == pull.account_or_head.as_block_hash ()) && (block->account_field ().value_or (0) == pull.account_or_head.as_account ()); if (hash == expected || unconfirmed_account_head) { expected = block->previous (); @@ -394,7 +394,7 @@ void nano::bulk_pull_server::set_current_end () if (!request->end.is_zero ()) { auto account (node->ledger.any.block_account (transaction, request->end)); - if (account != request->start.as_account ()) + if (account.value_or (0) != request->start.as_account ()) { node->logger.debug (nano::log::type::bulk_pull_server, "Request for block that is not on account chain: {} not on {}", request->end.to_string (), request->start.to_account ()); diff --git a/nano/node/bootstrap/bootstrap_frontier.cpp b/nano/node/bootstrap/bootstrap_frontier.cpp index db696dbd6..d0ad8276a 100644 --- a/nano/node/bootstrap/bootstrap_frontier.cpp +++ b/nano/node/bootstrap/bootstrap_frontier.cpp @@ -22,7 +22,7 @@ void nano::frontier_req_client::run (nano::account const & start_account_a, uint return; } nano::frontier_req request{ node->network_params.network }; - request.start = (start_account_a.is_zero () || start_account_a.number () == std::numeric_limits::max ()) ? start_account_a : start_account_a.number () + 1; + request.start = (start_account_a.is_zero () || start_account_a.number () == std::numeric_limits::max ()) ? start_account_a.number () : start_account_a.number () + 1; request.age = frontiers_age_a; request.count = count_a; current = start_account_a; diff --git a/nano/node/bootstrap/bootstrap_lazy.cpp b/nano/node/bootstrap/bootstrap_lazy.cpp index 30661abd7..439aa0ced 100644 --- a/nano/node/bootstrap/bootstrap_lazy.cpp +++ b/nano/node/bootstrap/bootstrap_lazy.cpp @@ -293,7 +293,7 @@ bool nano::bootstrap_attempt_lazy::process_block_lazy (std::shared_ptrsource_field () && !node->block_or_pruned_exists (block_a->source_field ().value ()) && block_a->source_field ().value () != node->network_params.ledger.genesis->account ()) + if (block_a->source_field () && !node->block_or_pruned_exists (block_a->source_field ().value ()) && block_a->source_field ().value () != node->network_params.ledger.genesis->account ().as_union ()) { lazy_add (block_a->source_field ().value (), retry_limit); } diff --git a/nano/node/bootstrap_ascending/service.cpp b/nano/node/bootstrap_ascending/service.cpp index 776f0b3d8..661072b44 100644 --- a/nano/node/bootstrap_ascending/service.cpp +++ b/nano/node/bootstrap_ascending/service.cpp @@ -789,7 +789,7 @@ nano::bootstrap_ascending::service::verify_result nano::bootstrap_ascending::ser case query_type::blocks_by_account: { // Open & state blocks always contain account field - if (first->account_field () != tag.start.as_account ()) + if (first->account_field ().value_or (0) != tag.start.as_account ()) { // TODO: Stat & log return verify_result::invalid; diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index 591ce4b99..1091f3828 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -2462,7 +2462,7 @@ public: // Report opens as a receive tree.put ("type", "receive"); } - if (block_a.hashables.source != handler.node.ledger.constants.genesis->account ()) + if (block_a.hashables.source != handler.node.ledger.constants.genesis->account ().as_union ()) { bool error_or_pruned (false); auto amount = handler.node.ledger.any.block_amount (transaction, hash); diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index 48466d012..7a513e8b4 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -555,7 +555,7 @@ public: void open_block (nano::open_block const & block_a) { type = "Receive"; - if (block_a.hashables.source != ledger.constants.genesis->account ()) + if (block_a.hashables.source != ledger.constants.genesis->account ().as_union ()) { auto account_l = ledger.any.block_account (transaction, block_a.hashables.source); auto amount_l = ledger.any.block_amount (transaction, block_a.hash ()); diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 309290dc1..206a55092 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -2628,7 +2628,7 @@ TEST (rpc, wallet_frontiers) frontiers.push_back (nano::account (i->second.get (""))); } ASSERT_EQ (1, frontiers.size ()); - ASSERT_EQ (node->latest (nano::dev::genesis_key.pub), frontiers[0]); + ASSERT_EQ (node->latest (nano::dev::genesis_key.pub), frontiers[0].as_union ()); } TEST (rpc, work_validate) diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index ec5aa666d..d2857974d 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -1093,7 +1093,7 @@ public: } void open_block (nano::open_block const & block_a) override { - if (block_a.source_field ().value () != ledger.constants.genesis->account ()) + if (block_a.source_field ().value () != ledger.constants.genesis->account ().as_union ()) { result[0] = block_a.source_field ().value (); } From 57d263df1eee6d9a396a5908d2023f36307b74ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Thu, 24 Oct 2024 22:46:33 +0200 Subject: [PATCH 36/48] Avoid reinterpret casts --- nano/lib/numbers.cpp | 42 +++++---------------------------- nano/lib/numbers.hpp | 56 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 52 insertions(+), 46 deletions(-) diff --git a/nano/lib/numbers.cpp b/nano/lib/numbers.cpp index b4bb819b7..d5cb7f0c9 100644 --- a/nano/lib/numbers.cpp +++ b/nano/lib/numbers.cpp @@ -747,7 +747,12 @@ nano::hash_or_account::hash_or_account () : } nano::hash_or_account::hash_or_account (uint64_t value_a) : - raw (value_a) + raw{ value_a } +{ +} + +nano::hash_or_account::hash_or_account (uint256_union const & value_a) : + raw{ value_a } { } @@ -781,11 +786,6 @@ std::string nano::hash_or_account::to_account () const return account.to_account (); } -nano::block_hash const & nano::root::previous () const -{ - return hash; -} - std::string nano::to_string_hex (uint64_t const value_a) { std::stringstream stream; @@ -892,33 +892,3 @@ double nano::difficulty::to_multiplier (uint64_t const difficulty_a, uint64_t co #ifdef _WIN32 #pragma warning(pop) #endif - -nano::public_key::operator nano::link const & () const -{ - return reinterpret_cast (*this); -} - -nano::public_key::operator nano::root const & () const -{ - return reinterpret_cast (*this); -} - -nano::public_key::operator nano::hash_or_account const & () const -{ - return reinterpret_cast (*this); -} - -nano::block_hash::operator nano::link const & () const -{ - return reinterpret_cast (*this); -} - -nano::block_hash::operator nano::root const & () const -{ - return reinterpret_cast (*this); -} - -nano::block_hash::operator nano::hash_or_account const & () const -{ - return reinterpret_cast (*this); -} diff --git a/nano/lib/numbers.hpp b/nano/lib/numbers.hpp index aca9a338c..82b4786e8 100644 --- a/nano/lib/numbers.hpp +++ b/nano/lib/numbers.hpp @@ -165,10 +165,6 @@ class block_hash final : public uint256_union public: using uint256_union::uint256_union; - operator nano::link const & () const; - operator nano::root const & () const; - operator nano::hash_or_account const & () const; - public: // Keep operators inlined auto operator<=> (nano::block_hash const & other) const { @@ -182,6 +178,18 @@ public: // Keep operators inlined { return number (); } + operator nano::link () const + { + return nano::link{ *this }; + } + operator nano::root () const + { + return nano::root{ *this }; + } + operator nano::hash_or_account () const + { + return nano::hash_or_account{ *this }; + } }; class public_key final : public uint256_union @@ -234,7 +242,8 @@ class hash_or_account { public: hash_or_account (); - hash_or_account (uint64_t value_a); + hash_or_account (uint64_t); + explicit hash_or_account (uint256_union const &); bool is_zero () const; void clear (); @@ -278,6 +287,10 @@ public: // Keep operators inlined { return hash; } + nano::uint256_union const & as_union () const + { + return raw; + } }; // A link can either be a destination account or source hash @@ -285,6 +298,16 @@ class link final : public hash_or_account { public: using hash_or_account::hash_or_account; + +public: // Keep operators inlined + auto operator<=> (nano::link const & other) const + { + return hash_or_account::operator<=> (other); + } + bool operator== (nano::link const & other) const + { + return *this <=> other == 0; + } }; // A root can either be an open block hash or a previous hash @@ -293,7 +316,20 @@ class root final : public hash_or_account public: using hash_or_account::hash_or_account; - nano::block_hash const & previous () const; + nano::block_hash const & previous () const + { + return hash; + } + +public: // Keep operators inlined + auto operator<=> (nano::root const & other) const + { + return hash_or_account::operator<=> (other); + } + bool operator== (nano::root const & other) const + { + return *this <=> other == 0; + } }; // The seed or private key @@ -364,13 +400,13 @@ class qualified_root : public uint512_union public: using uint512_union::uint512_union; - nano::root const & root () const + nano::root root () const { - return reinterpret_cast (uint256s[0]); + return nano::root{ uint256s[0] }; } - nano::block_hash const & previous () const + nano::block_hash previous () const { - return reinterpret_cast (uint256s[1]); + return nano::block_hash{ uint256s[1] }; } }; From e246aa4e40da715b27d76564dad431ec3255773d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Thu, 24 Oct 2024 23:18:46 +0200 Subject: [PATCH 37/48] Keep commonly used functions inline --- nano/lib/numbers.cpp | 125 ---------------------------------------- nano/lib/numbers.hpp | 133 +++++++++++++++++++++++++++++++++---------- 2 files changed, 104 insertions(+), 154 deletions(-) diff --git a/nano/lib/numbers.cpp b/nano/lib/numbers.cpp index d5cb7f0c9..3d2e88823 100644 --- a/nano/lib/numbers.cpp +++ b/nano/lib/numbers.cpp @@ -61,11 +61,6 @@ std::string nano::public_key::to_account () const return result; } -nano::public_key::public_key () : - uint256_union{ 0 } -{ -} - nano::public_key const & nano::public_key::null () { return nano::hardened_constants::get ().not_an_account; @@ -143,12 +138,6 @@ bool nano::public_key::decode_account (std::string const & source_a) return error; } -nano::uint256_union::uint256_union (nano::uint256_t const & number_a) -{ - bytes.fill (0); - boost::multiprecision::export_bits (number_a, bytes.rbegin (), 8, false); -} - // Construct a uint256_union = AES_ENC_CTR (cleartext, key, iv) void nano::uint256_union::encrypt (nano::raw_key const & cleartext, nano::raw_key const & key, uint128_union const & iv) { @@ -157,11 +146,6 @@ void nano::uint256_union::encrypt (nano::raw_key const & cleartext, nano::raw_ke enc.ProcessData (bytes.data (), cleartext.bytes.data (), sizeof (cleartext.bytes)); } -bool nano::uint256_union::is_zero () const -{ - return qwords[0] == 0 && qwords[1] == 0 && qwords[2] == 0 && qwords[3] == 0; -} - std::string nano::uint256_union::to_string () const { std::string result; @@ -193,22 +177,9 @@ nano::uint256_union nano::uint256_union::operator^ (nano::uint256_union const & nano::uint256_union::uint256_union (std::string const & hex_a) { auto error (decode_hex (hex_a)); - release_assert (!error); } -void nano::uint256_union::clear () -{ - qwords.fill (0); -} - -nano::uint256_t nano::uint256_union::number () const -{ - nano::uint256_t result; - boost::multiprecision::import_bits (result, bytes.begin (), bytes.end ()); - return result; -} - void nano::uint256_union::encode_hex (std::string & text) const { debug_assert (text.empty ()); @@ -281,41 +252,6 @@ bool nano::uint256_union::decode_dec (std::string const & text) return error; } -nano::uint256_union::uint256_union (uint64_t value0) -{ - *this = nano::uint256_t (value0); -} - -nano::uint512_union::uint512_union (nano::uint256_union const & upper, nano::uint256_union const & lower) -{ - uint256s[0] = upper; - uint256s[1] = lower; -} - -nano::uint512_union::uint512_union (nano::uint512_t const & number_a) -{ - bytes.fill (0); - boost::multiprecision::export_bits (number_a, bytes.rbegin (), 8, false); -} - -bool nano::uint512_union::is_zero () const -{ - return qwords[0] == 0 && qwords[1] == 0 && qwords[2] == 0 && qwords[3] == 0 - && qwords[4] == 0 && qwords[5] == 0 && qwords[6] == 0 && qwords[7] == 0; -} - -void nano::uint512_union::clear () -{ - bytes.fill (0); -} - -nano::uint512_t nano::uint512_union::number () const -{ - nano::uint512_t result; - boost::multiprecision::import_bits (result, bytes.begin (), bytes.end ()); - return result; -} - void nano::uint512_union::encode_hex (std::string & text) const { debug_assert (text.empty ()); @@ -350,13 +286,6 @@ bool nano::uint512_union::decode_hex (std::string const & text) return error; } -nano::uint512_union & nano::uint512_union::operator^= (nano::uint512_union const & other_a) -{ - uint256s[0] ^= other_a.uint256s[0]; - uint256s[1] ^= other_a.uint256s[1]; - return *this; -} - std::string nano::uint512_union::to_string () const { std::string result; @@ -421,28 +350,9 @@ bool nano::validate_message (nano::public_key const & public_key, nano::uint256_ nano::uint128_union::uint128_union (std::string const & string_a) { auto error (decode_hex (string_a)); - release_assert (!error); } -nano::uint128_union::uint128_union (uint64_t value_a) -{ - *this = nano::uint128_t (value_a); -} - -nano::uint128_union::uint128_union (nano::uint128_t const & number_a) -{ - bytes.fill (0); - boost::multiprecision::export_bits (number_a, bytes.rbegin (), 8, false); -} - -nano::uint128_t nano::uint128_union::number () const -{ - nano::uint128_t result; - boost::multiprecision::import_bits (result, bytes.begin (), bytes.end ()); - return result; -} - void nano::uint128_union::encode_hex (std::string & text) const { debug_assert (text.empty ()); @@ -717,16 +627,6 @@ std::string nano::uint128_union::format_balance (nano::uint128_t scale, int prec return ::format_balance (number (), scale, precision, group_digits, thousands_sep, decimal_point, grouping); } -void nano::uint128_union::clear () -{ - qwords.fill (0); -} - -bool nano::uint128_union::is_zero () const -{ - return qwords[0] == 0 && qwords[1] == 0; -} - std::string nano::uint128_union::to_string () const { std::string result; @@ -741,31 +641,6 @@ std::string nano::uint128_union::to_string_dec () const return result; } -nano::hash_or_account::hash_or_account () : - account{} -{ -} - -nano::hash_or_account::hash_or_account (uint64_t value_a) : - raw{ value_a } -{ -} - -nano::hash_or_account::hash_or_account (uint256_union const & value_a) : - raw{ value_a } -{ -} - -bool nano::hash_or_account::is_zero () const -{ - return raw.is_zero (); -} - -void nano::hash_or_account::clear () -{ - raw.clear (); -} - bool nano::hash_or_account::decode_hex (std::string const & text_a) { return raw.decode_hex (text_a); diff --git a/nano/lib/numbers.hpp b/nano/lib/numbers.hpp index 82b4786e8..2db23118b 100644 --- a/nano/lib/numbers.hpp +++ b/nano/lib/numbers.hpp @@ -24,8 +24,13 @@ class uint128_union { public: uint128_union () = default; - uint128_union (uint64_t); - uint128_union (nano::uint128_t const &); + uint128_union (uint64_t value) : + uint128_union (nano::uint128_t{ value }){}; + uint128_union (nano::uint128_t const & value) + { + bytes.fill (0); + boost::multiprecision::export_bits (value, bytes.rbegin (), 8, false); + } /** * Decode from hex string @@ -42,9 +47,21 @@ public: std::string format_balance (nano::uint128_t scale, int precision, bool group_digits) const; std::string format_balance (nano::uint128_t scale, int precision, bool group_digits, std::locale const & locale) const; - nano::uint128_t number () const; - void clear (); - bool is_zero () const; + void clear () + { + qwords.fill (0); + } + bool is_zero () const + { + return qwords[0] == 0 && qwords[1] == 0; + } + + nano::uint128_t number () const + { + nano::uint128_t result; + boost::multiprecision::import_bits (result, bytes.begin (), bytes.end ()); + return result; + } std::string to_string () const; std::string to_string_dec () const; @@ -100,8 +117,13 @@ class uint256_union { public: uint256_union () = default; - uint256_union (uint64_t); - uint256_union (uint256_t const &); + uint256_union (uint64_t value) : + uint256_union (nano::uint256_t{ value }){}; + uint256_union (uint256_t const & value) + { + bytes.fill (0); + boost::multiprecision::export_bits (value, bytes.rbegin (), 8, false); + } /** * Decode from hex string @@ -119,9 +141,21 @@ public: void encode_dec (std::string &) const; bool decode_dec (std::string const &); - nano::uint256_t number () const; - void clear (); - bool is_zero () const; + void clear () + { + qwords.fill (0); + } + bool is_zero () const + { + return owords[0].is_zero () && owords[1].is_zero (); + } + + nano::uint256_t number () const + { + nano::uint256_t result; + boost::multiprecision::import_bits (result, bytes.begin (), bytes.end ()); + return result; + } std::string to_string () const; @@ -197,19 +231,17 @@ class public_key final : public uint256_union public: using uint256_union::uint256_union; - public_key (); + public_key () : + uint256_union{ 0 } {}; static const public_key & null (); - std::string to_node_id () const; - bool decode_node_id (std::string const & source_a); + bool decode_node_id (std::string const &); void encode_account (std::string &) const; - std::string to_account () const; bool decode_account (std::string const &); - operator nano::link const & () const; - operator nano::root const & () const; - operator nano::hash_or_account const & () const; + std::string to_node_id () const; + std::string to_account () const; public: // Keep operators inlined auto operator<=> (nano::public_key const & other) const @@ -228,6 +260,18 @@ public: // Keep operators inlined { return number (); } + operator nano::link () const + { + return nano::link{ *this }; + } + operator nano::root () const + { + return nano::root{ *this }; + } + operator nano::hash_or_account () const + { + return nano::hash_or_account{ *this }; + } }; class wallet_id : public uint256_union @@ -241,16 +285,26 @@ using account = public_key; class hash_or_account { public: - hash_or_account (); - hash_or_account (uint64_t); - explicit hash_or_account (uint256_union const &); + hash_or_account () : + account{} {}; + hash_or_account (uint64_t value) : + raw{ value } {}; + explicit hash_or_account (uint256_union const & value) : + raw{ value } {}; - bool is_zero () const; - void clear (); + void clear () + { + raw.clear (); + } + bool is_zero () const + { + return raw.is_zero (); + } - std::string to_string () const; bool decode_hex (std::string const &); bool decode_account (std::string const &); + + std::string to_string () const; std::string to_account () const; public: @@ -345,18 +399,39 @@ class uint512_union { public: uint512_union () = default; - uint512_union (nano::uint256_union const &, nano::uint256_union const &); - uint512_union (nano::uint512_t const &); + uint512_union (nano::uint256_union const & upper, nano::uint256_union const & lower) : + uint256s{ upper, lower } {}; + uint512_union (nano::uint512_t const & value) + { + bytes.fill (0); + boost::multiprecision::export_bits (value, bytes.rbegin (), 8, false); + } - nano::uint512_union & operator^= (nano::uint512_union const &); + nano::uint512_union & operator^= (nano::uint512_union const & other) + { + uint256s[0] ^= other.uint256s[0]; + uint256s[1] ^= other.uint256s[1]; + return *this; + } void encode_hex (std::string &) const; bool decode_hex (std::string const &); - void clear (); - bool is_zero () const; + void clear () + { + bytes.fill (0); + } + bool is_zero () const + { + return uint256s[0].is_zero () && uint256s[1].is_zero (); + } - nano::uint512_t number () const; + nano::uint512_t number () const + { + nano::uint512_t result; + boost::multiprecision::import_bits (result, bytes.begin (), bytes.end ()); + return result; + } std::string to_string () const; From ffd46598ad15a0968f3579455c40cb9170584068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Fri, 25 Oct 2024 13:01:41 +0200 Subject: [PATCH 38/48] Fix dangling reference returns --- nano/lib/blocks.cpp | 10 +++--- nano/lib/blocks.hpp | 12 +++---- nano/lib/numbers.cpp | 7 +++++ nano/lib/numbers.hpp | 52 ++++++++++--------------------- nano/node/bootstrap/bootstrap.cpp | 6 ++-- 5 files changed, 38 insertions(+), 49 deletions(-) diff --git a/nano/lib/blocks.cpp b/nano/lib/blocks.cpp index a4c21b867..4fc527eb0 100644 --- a/nano/lib/blocks.cpp +++ b/nano/lib/blocks.cpp @@ -609,7 +609,7 @@ std::optional nano::send_block::destination_field () const return hashables.destination; } -nano::root const & nano::send_block::root () const +nano::root nano::send_block::root () const { return hashables.previous; } @@ -899,7 +899,7 @@ std::optional nano::open_block::source_field () const return hashables.source; } -nano::root const & nano::open_block::root () const +nano::root nano::open_block::root () const { return hashables.account; } @@ -1165,7 +1165,7 @@ bool nano::change_block::valid_predecessor (nano::block const & block_a) const return result; } -nano::root const & nano::change_block::root () const +nano::root nano::change_block::root () const { return hashables.previous; } @@ -1482,7 +1482,7 @@ bool nano::state_block::valid_predecessor (nano::block const & block_a) const return true; } -nano::root const & nano::state_block::root () const +nano::root nano::state_block::root () const { if (!hashables.previous.is_zero ()) { @@ -1836,7 +1836,7 @@ std::optional nano::receive_block::source_field () const return hashables.source; } -nano::root const & nano::receive_block::root () const +nano::root nano::receive_block::root () const { return hashables.previous; } diff --git a/nano/lib/blocks.hpp b/nano/lib/blocks.hpp index 1ddb8302d..2312855cb 100644 --- a/nano/lib/blocks.hpp +++ b/nano/lib/blocks.hpp @@ -33,7 +33,7 @@ public: virtual uint64_t block_work () const = 0; virtual void block_work_set (uint64_t) = 0; // Previous block or account number for open blocks - virtual nano::root const & root () const = 0; + virtual nano::root root () const = 0; // Qualified root value based on previous() and root() virtual nano::qualified_root qualified_root () const; virtual void serialize (nano::stream &) const = 0; @@ -123,7 +123,7 @@ public: virtual ~send_block () = default; uint64_t block_work () const override; void block_work_set (uint64_t) override; - nano::root const & root () const override; + nano::root root () const override; void serialize (nano::stream &) const override; bool deserialize (nano::stream &); void serialize_json (std::string &, bool = false) const override; @@ -177,7 +177,7 @@ public: virtual ~receive_block () = default; uint64_t block_work () const override; void block_work_set (uint64_t) override; - nano::root const & root () const override; + nano::root root () const override; void serialize (nano::stream &) const override; bool deserialize (nano::stream &); void serialize_json (std::string &, bool = false) const override; @@ -232,7 +232,7 @@ public: virtual ~open_block () = default; uint64_t block_work () const override; void block_work_set (uint64_t) override; - nano::root const & root () const override; + nano::root root () const override; void serialize (nano::stream &) const override; bool deserialize (nano::stream &); void serialize_json (std::string &, bool = false) const override; @@ -287,7 +287,7 @@ public: virtual ~change_block () = default; uint64_t block_work () const override; void block_work_set (uint64_t) override; - nano::root const & root () const override; + nano::root root () const override; void serialize (nano::stream &) const override; bool deserialize (nano::stream &); void serialize_json (std::string &, bool = false) const override; @@ -353,7 +353,7 @@ public: virtual ~state_block () = default; uint64_t block_work () const override; void block_work_set (uint64_t) override; - nano::root const & root () const override; + nano::root root () const override; void serialize (nano::stream &) const override; bool deserialize (nano::stream &); void serialize_json (std::string &, bool = false) const override; diff --git a/nano/lib/numbers.cpp b/nano/lib/numbers.cpp index 3d2e88823..916329b67 100644 --- a/nano/lib/numbers.cpp +++ b/nano/lib/numbers.cpp @@ -735,6 +735,13 @@ std::ostream & nano::operator<< (std::ostream & os, const uint512_union & val) return os; } +std::ostream & nano::operator<< (std::ostream & os, const hash_or_account & val) +{ + // TODO: Replace with streaming implementation + os << val.to_string (); + return os; +} + #ifdef _WIN32 #pragma warning(push) #pragma warning(disable : 4146) // warning C4146: unary minus operator applied to unsigned type, result still unsigned diff --git a/nano/lib/numbers.hpp b/nano/lib/numbers.hpp index 2db23118b..88e4de560 100644 --- a/nano/lib/numbers.hpp +++ b/nano/lib/numbers.hpp @@ -189,10 +189,6 @@ public: // Keep operators inlined }; static_assert (std::is_nothrow_move_constructible::value, "uint256_union should be noexcept MoveConstructible"); -class link; -class root; -class hash_or_account; - // All keys and hashes are 256 bit. class block_hash final : public uint256_union { @@ -212,18 +208,6 @@ public: // Keep operators inlined { return number (); } - operator nano::link () const - { - return nano::link{ *this }; - } - operator nano::root () const - { - return nano::root{ *this }; - } - operator nano::hash_or_account () const - { - return nano::hash_or_account{ *this }; - } }; class public_key final : public uint256_union @@ -260,18 +244,6 @@ public: // Keep operators inlined { return number (); } - operator nano::link () const - { - return nano::link{ *this }; - } - operator nano::root () const - { - return nano::root{ *this }; - } - operator nano::hash_or_account () const - { - return nano::hash_or_account{ *this }; - } }; class wallet_id : public uint256_union @@ -289,7 +261,7 @@ public: account{} {}; hash_or_account (uint64_t value) : raw{ value } {}; - explicit hash_or_account (uint256_union const & value) : + hash_or_account (uint256_union const & value) : raw{ value } {}; void clear () @@ -325,11 +297,11 @@ public: // Keep operators inlined { return *this <=> other == 0; } - operator nano::uint256_t () const + explicit operator nano::uint256_t () const { return raw.number (); } - operator nano::uint256_union () const + explicit operator nano::uint256_union () const { return raw; } @@ -399,13 +371,13 @@ class uint512_union { public: uint512_union () = default; - uint512_union (nano::uint256_union const & upper, nano::uint256_union const & lower) : - uint256s{ upper, lower } {}; uint512_union (nano::uint512_t const & value) { bytes.fill (0); boost::multiprecision::export_bits (value, bytes.rbegin (), 8, false); } + uint512_union (nano::uint256_union const & upper, nano::uint256_union const & lower) : + uint256s{ upper, lower } {}; nano::uint512_union & operator^= (nano::uint512_union const & other) { @@ -473,7 +445,11 @@ public: class qualified_root : public uint512_union { public: - using uint512_union::uint512_union; + qualified_root () = default; + qualified_root (nano::root const & root, nano::block_hash const & previous) : + uint512_union{ root.as_union (), previous.as_union () } {}; + qualified_root (nano::uint512_t const & value) : + uint512_union{ value } {}; nano::root root () const { @@ -501,6 +477,7 @@ bool from_string_hex (std::string const &, uint64_t &); std::ostream & operator<< (std::ostream &, const uint128_union &); std::ostream & operator<< (std::ostream &, const uint256_union &); std::ostream & operator<< (std::ostream &, const uint512_union &); +std::ostream & operator<< (std::ostream &, const hash_or_account &); /** * Convert a double to string in fixed format @@ -643,6 +620,11 @@ struct fmt::formatter : fmt::ostream_formatter { }; +template <> +struct fmt::formatter : fmt::ostream_formatter +{ +}; + template <> struct fmt::formatter : fmt::formatter { @@ -656,4 +638,4 @@ struct fmt::formatter : fmt::formatter template <> struct fmt::formatter : fmt::formatter { -}; \ No newline at end of file +}; diff --git a/nano/node/bootstrap/bootstrap.cpp b/nano/node/bootstrap/bootstrap.cpp index 3db711dfc..8779400ee 100644 --- a/nano/node/bootstrap/bootstrap.cpp +++ b/nano/node/bootstrap/bootstrap.cpp @@ -313,7 +313,7 @@ void nano::pulls_cache::add (nano::pull_info const & pull_a) cache.erase (cache.begin ()); } debug_assert (cache.size () <= cache_size_max); - nano::uint512_union head_512 (pull_a.account_or_head, pull_a.head_original); + nano::uint512_union head_512 (pull_a.account_or_head.as_union (), pull_a.head_original); auto existing (cache.get ().find (head_512)); if (existing == cache.get ().end ()) { @@ -336,7 +336,7 @@ void nano::pulls_cache::add (nano::pull_info const & pull_a) void nano::pulls_cache::update_pull (nano::pull_info & pull_a) { nano::lock_guard guard{ pulls_cache_mutex }; - nano::uint512_union head_512 (pull_a.account_or_head, pull_a.head_original); + nano::uint512_union head_512 (pull_a.account_or_head.as_union (), pull_a.head_original); auto existing (cache.get ().find (head_512)); if (existing != cache.get ().end ()) { @@ -347,7 +347,7 @@ void nano::pulls_cache::update_pull (nano::pull_info & pull_a) void nano::pulls_cache::remove (nano::pull_info const & pull_a) { nano::lock_guard guard{ pulls_cache_mutex }; - nano::uint512_union head_512 (pull_a.account_or_head, pull_a.head_original); + nano::uint512_union head_512 (pull_a.account_or_head.as_union (), pull_a.head_original); cache.get ().erase (head_512); } From 2b2fd12106b8be409362dc84d28ea9a3db3ab389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Fri, 25 Oct 2024 12:41:45 +0200 Subject: [PATCH 39/48] Hashing cleanup --- nano/core_test/numbers.cpp | 94 ++++++++++++++++++ nano/lib/numbers.hpp | 178 +++++++++++++++++++++++++++-------- nano/secure/common.hpp | 55 ----------- nano/secure/pending_info.hpp | 4 +- 4 files changed, 233 insertions(+), 98 deletions(-) diff --git a/nano/core_test/numbers.cpp b/nano/core_test/numbers.cpp index 1ffe78808..d6b141fa5 100644 --- a/nano/core_test/numbers.cpp +++ b/nano/core_test/numbers.cpp @@ -3,7 +3,10 @@ #include +#include + #include +#include namespace { @@ -577,3 +580,94 @@ void check_operator_greater_than (Num lhs, Num rhs) ASSERT_FALSE (rhs > rhs); } } + +namespace +{ +template class Hash> +void test_hashing () +{ + Hash hash; + using underlying_t = typename Type::underlying_type; + + // Basic equality tests + ASSERT_EQ (hash (Type{}), hash (Type{})); + ASSERT_EQ (hash (Type{ 123 }), hash (Type{ 123 })); + + // Basic inequality tests + ASSERT_NE (hash (Type{ 123 }), hash (Type{ 124 })); + ASSERT_NE (hash (Type{ 0 }), hash (Type{ 1 })); + + // Boundary value tests + constexpr auto min_val = std::numeric_limits::min (); + constexpr auto max_val = std::numeric_limits::max (); + + // Min/Max tests + ASSERT_EQ (hash (Type{ min_val }), hash (Type{ min_val })); + ASSERT_EQ (hash (Type{ max_val }), hash (Type{ max_val })); + ASSERT_NE (hash (Type{ min_val }), hash (Type{ max_val })); + + // Near boundary tests + ASSERT_NE (hash (Type{ min_val }), hash (Type{ min_val + 1 })); + ASSERT_NE (hash (Type{ max_val }), hash (Type{ max_val - 1 })); + ASSERT_NE (hash (Type{ min_val + 1 }), hash (Type{ max_val })); + ASSERT_NE (hash (Type{ max_val - 1 }), hash (Type{ min_val })); + + // Common value tests + std::vector common_values = { + 0, // Zero + 1, // One + 42, // Common test value + 0xFF, // Byte boundary + 0xFFFF, // Word boundary + min_val, // Minimum + max_val, // Maximum + max_val / 2, // Middle value + min_val + (max_val / 2) // Offset middle + }; + + // Test all common values against each other + for (size_t i = 0; i < common_values.size (); ++i) + { + for (size_t j = i + 1; j < common_values.size (); ++j) + { + if (common_values[i] != common_values[j]) + { + ASSERT_NE (hash (Type{ common_values[i] }), hash (Type{ common_values[j] })); + } + else + { + ASSERT_EQ (hash (Type{ common_values[i] }), hash (Type{ common_values[j] })); + } + } + } +} +} + +TEST (numbers, hashing) +{ + // Using std::hash + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + + // Using boost::hash + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); +} diff --git a/nano/lib/numbers.hpp b/nano/lib/numbers.hpp index 88e4de560..bf8137c65 100644 --- a/nano/lib/numbers.hpp +++ b/nano/lib/numbers.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -22,6 +23,10 @@ nano::uint128_t const raw_ratio = nano::uint128_t ("1"); // 10^0 class uint128_union { +public: + // Type that is implicitly convertible to this union + using underlying_type = nano::uint128_t; + public: uint128_union () = default; uint128_union (uint64_t value) : @@ -115,11 +120,15 @@ class raw_key; class uint256_union { +public: + // Type that is implicitly convertible to this union + using underlying_type = nano::uint256_t; + public: uint256_union () = default; uint256_union (uint64_t value) : uint256_union (nano::uint256_t{ value }){}; - uint256_union (uint256_t const & value) + uint256_union (nano::uint256_t const & value) { bytes.fill (0); boost::multiprecision::export_bits (value, bytes.rbegin (), 8, false); @@ -256,6 +265,10 @@ using account = public_key; class hash_or_account { +public: + // Type that is implicitly convertible to this union + using underlying_type = nano::uint256_t; + public: hash_or_account () : account{} {}; @@ -369,6 +382,10 @@ public: class uint512_union { +public: + // Type that is implicitly convertible to this union + using underlying_type = nano::uint512_t; + public: uint512_union () = default; uint512_union (nano::uint512_t const & value) @@ -499,83 +516,91 @@ namespace difficulty namespace std { template <> -struct hash<::nano::uint256_union> +struct hash<::nano::uint128_union> { - size_t operator() (::nano::uint256_union const & data_a) const + size_t operator() (::nano::uint128_union const & value) const noexcept { - return data_a.qwords[0] + data_a.qwords[1] + data_a.qwords[2] + data_a.qwords[3]; + return value.qwords[0] + value.qwords[1]; } }; template <> -struct hash<::nano::account> +struct hash<::nano::uint256_union> { - size_t operator() (::nano::account const & data_a) const + size_t operator() (::nano::uint256_union const & value) const noexcept { - return hash<::nano::uint256_union> () (data_a); + return value.qwords[0] + value.qwords[1] + value.qwords[2] + value.qwords[3]; + } +}; +template <> +struct hash<::nano::public_key> +{ + size_t operator() (::nano::public_key const & value) const noexcept + { + return hash<::nano::uint256_union>{}(value); } }; template <> struct hash<::nano::block_hash> { - size_t operator() (::nano::block_hash const & data_a) const + size_t operator() (::nano::block_hash const & value) const noexcept { - return hash<::nano::uint256_union> () (data_a); + return hash<::nano::uint256_union>{}(value); } }; template <> struct hash<::nano::hash_or_account> { - size_t operator() (::nano::hash_or_account const & data_a) const + size_t operator() (::nano::hash_or_account const & value) const noexcept { - return hash<::nano::block_hash> () (data_a.as_block_hash ()); - } -}; -template <> -struct hash<::nano::raw_key> -{ - size_t operator() (::nano::raw_key const & data_a) const - { - return hash<::nano::uint256_union> () (data_a); + return hash<::nano::block_hash>{}(value.as_block_hash ()); } }; template <> struct hash<::nano::root> { - size_t operator() (::nano::root const & data_a) const + size_t operator() (::nano::root const & value) const noexcept { - return hash<::nano::uint256_union> () (data_a); + return hash<::nano::hash_or_account>{}(value); + } +}; +template <> +struct hash<::nano::link> +{ + size_t operator() (::nano::link const & value) const noexcept + { + return hash<::nano::hash_or_account>{}(value); + } +}; +template <> +struct hash<::nano::raw_key> +{ + size_t operator() (::nano::raw_key const & value) const noexcept + { + return hash<::nano::uint256_union>{}(value); } }; template <> struct hash<::nano::wallet_id> { - size_t operator() (::nano::wallet_id const & data_a) const + size_t operator() (::nano::wallet_id const & value) const noexcept { - return hash<::nano::uint256_union> () (data_a); - } -}; -template <> -struct hash<::nano::uint256_t> -{ - size_t operator() (::nano::uint256_t const & number_a) const - { - return number_a.convert_to (); + return hash<::nano::uint256_union>{}(value); } }; template <> struct hash<::nano::uint512_union> { - size_t operator() (::nano::uint512_union const & data_a) const + size_t operator() (::nano::uint512_union const & value) const noexcept { - return hash<::nano::uint256_union> () (data_a.uint256s[0]) + hash<::nano::uint256_union> () (data_a.uint256s[1]); + return hash<::nano::uint256_union>{}(value.uint256s[0]) + hash<::nano::uint256_union> () (value.uint256s[1]); } }; template <> struct hash<::nano::qualified_root> { - size_t operator() (::nano::qualified_root const & data_a) const + size_t operator() (::nano::qualified_root const & value) const noexcept { - return hash<::nano::uint512_union> () (data_a); + return hash<::nano::uint512_union>{}(value); } }; } @@ -583,20 +608,91 @@ struct hash<::nano::qualified_root> namespace boost { template <> -struct hash> +struct hash<::nano::uint128_union> { - size_t operator() (std::reference_wrapper<::nano::block_hash const> const & hash_a) const + size_t operator() (::nano::uint128_union const & value) const noexcept { - std::hash<::nano::block_hash> hash; - return hash (hash_a); + return std::hash<::nano::uint128_union> () (value); + } +}; +template <> +struct hash<::nano::uint256_union> +{ + size_t operator() (::nano::uint256_union const & value) const noexcept + { + return std::hash<::nano::uint256_union> () (value); + } +}; +template <> +struct hash<::nano::public_key> +{ + size_t operator() (::nano::public_key const & value) const noexcept + { + return std::hash<::nano::public_key> () (value); + } +}; +template <> +struct hash<::nano::block_hash> +{ + size_t operator() (::nano::block_hash const & value) const noexcept + { + return std::hash<::nano::block_hash> () (value); + } +}; +template <> +struct hash<::nano::hash_or_account> +{ + size_t operator() (::nano::hash_or_account const & value) const noexcept + { + return std::hash<::nano::hash_or_account> () (value); } }; template <> struct hash<::nano::root> { - size_t operator() (::nano::root const & value_a) const + size_t operator() (::nano::root const & value) const noexcept { - return std::hash<::nano::root> () (value_a); + return std::hash<::nano::root> () (value); + } +}; +template <> +struct hash<::nano::link> +{ + size_t operator() (::nano::link const & value) const noexcept + { + return std::hash<::nano::link> () (value); + } +}; +template <> +struct hash<::nano::raw_key> +{ + size_t operator() (::nano::raw_key const & value) const noexcept + { + return std::hash<::nano::raw_key> () (value); + } +}; +template <> +struct hash<::nano::wallet_id> +{ + size_t operator() (::nano::wallet_id const & value) const noexcept + { + return std::hash<::nano::wallet_id> () (value); + } +}; +template <> +struct hash<::nano::uint512_union> +{ + size_t operator() (::nano::uint512_union const & value) const noexcept + { + return std::hash<::nano::uint512_union> () (value); + } +}; +template <> +struct hash<::nano::qualified_root> +{ + size_t operator() (::nano::qualified_root const & value) const noexcept + { + return std::hash<::nano::qualified_root> () (value); } }; } diff --git a/nano/secure/common.hpp b/nano/secure/common.hpp index fd28d30b1..e1639bd26 100644 --- a/nano/secure/common.hpp +++ b/nano/secure/common.hpp @@ -21,61 +21,6 @@ #include #include -namespace boost -{ -template <> -struct hash<::nano::uint256_union> -{ - size_t operator() (::nano::uint256_union const & value_a) const - { - return std::hash<::nano::uint256_union> () (value_a); - } -}; - -template <> -struct hash<::nano::block_hash> -{ - size_t operator() (::nano::block_hash const & value_a) const - { - return std::hash<::nano::block_hash> () (value_a); - } -}; - -template <> -struct hash<::nano::hash_or_account> -{ - size_t operator() (::nano::hash_or_account const & data_a) const - { - return std::hash<::nano::hash_or_account> () (data_a); - } -}; - -template <> -struct hash<::nano::public_key> -{ - size_t operator() (::nano::public_key const & value_a) const - { - return std::hash<::nano::public_key> () (value_a); - } -}; -template <> -struct hash<::nano::uint512_union> -{ - size_t operator() (::nano::uint512_union const & value_a) const - { - return std::hash<::nano::uint512_union> () (value_a); - } -}; -template <> -struct hash<::nano::qualified_root> -{ - size_t operator() (::nano::qualified_root const & value_a) const - { - return std::hash<::nano::qualified_root> () (value_a); - } -}; -} - namespace nano { /** diff --git a/nano/secure/pending_info.hpp b/nano/secure/pending_info.hpp index 2d57df9ba..c00e1cdb3 100644 --- a/nano/secure/pending_info.hpp +++ b/nano/secure/pending_info.hpp @@ -67,9 +67,9 @@ namespace std template <> struct hash<::nano::pending_key> { - size_t operator() (::nano::pending_key const & data_a) const + size_t operator() (::nano::pending_key const & value) const { - return hash<::nano::uint512_union>{}({ ::nano::uint256_union{ data_a.account.number () }, data_a.hash }); + return hash<::nano::uint512_union>{}({ ::nano::uint256_union{ value.account.number () }, value.hash }); } }; } From 5d341f44b88425ca782b00f87a7acabe3ed2b29e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Fri, 25 Oct 2024 20:16:54 +0200 Subject: [PATCH 40/48] Test comparison for all types --- nano/core_test/numbers.cpp | 371 +++++++++++++++++-------------------- 1 file changed, 174 insertions(+), 197 deletions(-) diff --git a/nano/core_test/numbers.cpp b/nano/core_test/numbers.cpp index d6b141fa5..a30b2eb10 100644 --- a/nano/core_test/numbers.cpp +++ b/nano/core_test/numbers.cpp @@ -8,22 +8,185 @@ #include #include +TEST (numbers, identity) +{ + ASSERT_EQ (1, nano::uint128_union (1).number ().convert_to ()); + ASSERT_EQ (1, nano::uint256_union (1).number ().convert_to ()); + ASSERT_EQ (1, nano::uint512_union (1).number ().convert_to ()); +} + namespace { -template -void assert_union_types (); +template +void check_operator_less_than (Type lhs, Type rhs) +{ + ASSERT_TRUE (lhs < rhs); + ASSERT_FALSE (rhs < lhs); + ASSERT_FALSE (lhs < lhs); + ASSERT_FALSE (rhs < rhs); +} -template -void test_union_operator_less_than (); +template +void test_operator_less_than () +{ + using underlying_t = typename Type::underlying_type; -template -void check_operator_less_than (Num lhs, Num rhs); + // Small + check_operator_less_than (Type{ 123 }, Type{ 124 }); + check_operator_less_than (Type{ 124 }, Type{ 125 }); -template -void test_union_operator_greater_than (); + // Medium + check_operator_less_than (Type{ std::numeric_limits::max () - 1 }, Type{ std::numeric_limits::max () + 1 }); + check_operator_less_than (Type{ std::numeric_limits::max () - 12345678 }, Type{ std::numeric_limits::max () - 123456 }); -template -void check_operator_greater_than (Num lhs, Num rhs); + // Large + check_operator_less_than (Type{ std::numeric_limits::max () - 555555555555 }, Type{ std::numeric_limits::max () - 1 }); + + // Boundary values + check_operator_less_than (Type{ std::numeric_limits::min () }, Type{ std::numeric_limits::max () }); +} + +template +void check_operator_greater_than (Type lhs, Type rhs) +{ + ASSERT_TRUE (lhs > rhs); + ASSERT_FALSE (rhs > lhs); + ASSERT_FALSE (lhs > lhs); + ASSERT_FALSE (rhs > rhs); +} + +template +void test_operator_greater_than () +{ + using underlying_t = typename Type::underlying_type; + + // Small + check_operator_greater_than (Type{ 124 }, Type{ 123 }); + check_operator_greater_than (Type{ 125 }, Type{ 124 }); + + // Medium + check_operator_greater_than (Type{ std::numeric_limits::max () + 1 }, Type{ std::numeric_limits::max () - 1 }); + check_operator_greater_than (Type{ std::numeric_limits::max () - 123456 }, Type{ std::numeric_limits::max () - 12345678 }); + + // Large + check_operator_greater_than (Type{ std::numeric_limits::max () - 1 }, Type{ std::numeric_limits::max () - 555555555555 }); + + // Boundary values + check_operator_greater_than (Type{ std::numeric_limits::max () }, Type{ std::numeric_limits::min () }); +} + +template +void test_comparison () +{ + test_operator_less_than (); + test_operator_greater_than (); +} +} + +TEST (numbers, comparison) +{ + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); + test_comparison (); +} + +namespace +{ +template class Hash> +void test_hashing () +{ + Hash hash; + using underlying_t = typename Type::underlying_type; + + // Basic equality tests + ASSERT_EQ (hash (Type{}), hash (Type{})); + ASSERT_EQ (hash (Type{ 123 }), hash (Type{ 123 })); + + // Basic inequality tests + ASSERT_NE (hash (Type{ 123 }), hash (Type{ 124 })); + ASSERT_NE (hash (Type{ 0 }), hash (Type{ 1 })); + + // Boundary value tests + constexpr auto min_val = std::numeric_limits::min (); + constexpr auto max_val = std::numeric_limits::max (); + + // Min/Max tests + ASSERT_EQ (hash (Type{ min_val }), hash (Type{ min_val })); + ASSERT_EQ (hash (Type{ max_val }), hash (Type{ max_val })); + ASSERT_NE (hash (Type{ min_val }), hash (Type{ max_val })); + + // Near boundary tests + ASSERT_NE (hash (Type{ min_val }), hash (Type{ min_val + 1 })); + ASSERT_NE (hash (Type{ max_val }), hash (Type{ max_val - 1 })); + ASSERT_NE (hash (Type{ min_val + 1 }), hash (Type{ max_val })); + ASSERT_NE (hash (Type{ max_val - 1 }), hash (Type{ min_val })); + + // Common value tests + std::vector common_values = { + 0, // Zero + 1, // One + 42, // Common test value + 0xFF, // Byte boundary + 0xFFFF, // Word boundary + min_val, // Minimum + max_val, // Maximum + max_val / 2, // Middle value + min_val + (max_val / 2) // Offset middle + }; + + // Test all common values against each other + for (size_t i = 0; i < common_values.size (); ++i) + { + for (size_t j = i + 1; j < common_values.size (); ++j) + { + if (common_values[i] != common_values[j]) + { + ASSERT_NE (hash (Type{ common_values[i] }), hash (Type{ common_values[j] })); + } + else + { + ASSERT_EQ (hash (Type{ common_values[i] }), hash (Type{ common_values[j] })); + } + } + } +} +} + +TEST (numbers, hashing) +{ + // Using std::hash + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + + // Using boost::hash + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); + test_hashing (); } TEST (uint128_union, decode_dec) @@ -66,16 +229,6 @@ TEST (uint128_union, decode_dec_overflow) ASSERT_TRUE (error); } -TEST (uint128_union, operator_less_than) -{ - test_union_operator_less_than (); -} - -TEST (uint128_union, operator_greater_than) -{ - test_union_operator_greater_than (); -} - struct test_punct : std::moneypunct { pattern do_pos_format () const @@ -151,13 +304,6 @@ TEST (uint128_union, decode_decimal) ASSERT_EQ (1230 * nano::Knano_ratio, amount.number ()); } -TEST (unions, identity) -{ - ASSERT_EQ (1, nano::uint128_union (1).number ().convert_to ()); - ASSERT_EQ (1, nano::uint256_union (1).number ().convert_to ()); - ASSERT_EQ (1, nano::uint512_union (1).number ().convert_to ()); -} - TEST (uint256_union, key_encryption) { nano::keypair key1; @@ -451,16 +597,6 @@ TEST (uint256_union, bounds) ASSERT_TRUE (key.decode_account (bad2)); } -TEST (uint256_union, operator_less_than) -{ - test_union_operator_less_than (); -} - -TEST (uint256_union, operator_greater_than) -{ - test_union_operator_greater_than (); -} - TEST (uint64_t, parse) { uint64_t value0 (1); @@ -511,163 +647,4 @@ TEST (uint512_union, hash) ASSERT_NE (h (x1), h (x2)); } } -} - -namespace -{ -template -void assert_union_types () -{ - static_assert ((std::is_same::value && std::is_same::value) || (std::is_same::value && std::is_same::value) || (std::is_same::value && std::is_same::value), - "Union type needs to be consistent with the lower/upper Bound type"); -} - -template -void test_union_operator_less_than () -{ - assert_union_types (); - - // Small - check_operator_less_than (Union (123), Union (124)); - check_operator_less_than (Union (124), Union (125)); - - // Medium - check_operator_less_than (Union (std::numeric_limits::max () - 1), Union (std::numeric_limits::max () + 1)); - check_operator_less_than (Union (std::numeric_limits::max () - 12345678), Union (std::numeric_limits::max () - 123456)); - - // Large - check_operator_less_than (Union (std::numeric_limits::max () - 555555555555), Union (std::numeric_limits::max () - 1)); - - // Boundary values - check_operator_less_than (Union (std::numeric_limits::min ()), Union (std::numeric_limits::max ())); -} - -template -void check_operator_less_than (Num lhs, Num rhs) -{ - ASSERT_TRUE (lhs < rhs); - ASSERT_FALSE (rhs < lhs); - ASSERT_FALSE (lhs < lhs); - ASSERT_FALSE (rhs < rhs); -} - -template -void test_union_operator_greater_than () -{ - assert_union_types (); - - // Small - check_operator_greater_than (Union (124), Union (123)); - check_operator_greater_than (Union (125), Union (124)); - - // Medium - check_operator_greater_than (Union (std::numeric_limits::max () + 1), Union (std::numeric_limits::max () - 1)); - check_operator_greater_than (Union (std::numeric_limits::max () - 123456), Union (std::numeric_limits::max () - 12345678)); - - // Large - check_operator_greater_than (Union (std::numeric_limits::max () - 1), Union (std::numeric_limits::max () - 555555555555)); - - // Boundary values - check_operator_greater_than (Union (std::numeric_limits::max ()), Union (std::numeric_limits::min ())); -} - -template -void check_operator_greater_than (Num lhs, Num rhs) -{ - ASSERT_TRUE (lhs > rhs); - ASSERT_FALSE (rhs > lhs); - ASSERT_FALSE (lhs > lhs); - ASSERT_FALSE (rhs > rhs); -} -} - -namespace -{ -template class Hash> -void test_hashing () -{ - Hash hash; - using underlying_t = typename Type::underlying_type; - - // Basic equality tests - ASSERT_EQ (hash (Type{}), hash (Type{})); - ASSERT_EQ (hash (Type{ 123 }), hash (Type{ 123 })); - - // Basic inequality tests - ASSERT_NE (hash (Type{ 123 }), hash (Type{ 124 })); - ASSERT_NE (hash (Type{ 0 }), hash (Type{ 1 })); - - // Boundary value tests - constexpr auto min_val = std::numeric_limits::min (); - constexpr auto max_val = std::numeric_limits::max (); - - // Min/Max tests - ASSERT_EQ (hash (Type{ min_val }), hash (Type{ min_val })); - ASSERT_EQ (hash (Type{ max_val }), hash (Type{ max_val })); - ASSERT_NE (hash (Type{ min_val }), hash (Type{ max_val })); - - // Near boundary tests - ASSERT_NE (hash (Type{ min_val }), hash (Type{ min_val + 1 })); - ASSERT_NE (hash (Type{ max_val }), hash (Type{ max_val - 1 })); - ASSERT_NE (hash (Type{ min_val + 1 }), hash (Type{ max_val })); - ASSERT_NE (hash (Type{ max_val - 1 }), hash (Type{ min_val })); - - // Common value tests - std::vector common_values = { - 0, // Zero - 1, // One - 42, // Common test value - 0xFF, // Byte boundary - 0xFFFF, // Word boundary - min_val, // Minimum - max_val, // Maximum - max_val / 2, // Middle value - min_val + (max_val / 2) // Offset middle - }; - - // Test all common values against each other - for (size_t i = 0; i < common_values.size (); ++i) - { - for (size_t j = i + 1; j < common_values.size (); ++j) - { - if (common_values[i] != common_values[j]) - { - ASSERT_NE (hash (Type{ common_values[i] }), hash (Type{ common_values[j] })); - } - else - { - ASSERT_EQ (hash (Type{ common_values[i] }), hash (Type{ common_values[j] })); - } - } - } -} -} - -TEST (numbers, hashing) -{ - // Using std::hash - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - - // Using boost::hash - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); - test_hashing (); -} +} \ No newline at end of file From db7405f580af21b6ad98741430054ee04419b453 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Mon, 30 Sep 2024 11:44:50 +0100 Subject: [PATCH 41/48] This adds strong typing via std::variant to extracting internals via transaction->GetHandle() Returning either Transaction * or ReadOptions * seems dubious, the intent of this commit is to retain 1-to-1 compatibility while adding strong typing. --- nano/store/CMakeLists.txt | 2 + nano/store/rocksdb/iterator.hpp | 55 +++++++++++--------------- nano/store/rocksdb/rocksdb.cpp | 70 +++++++++++++++++++-------------- nano/store/rocksdb/rocksdb.hpp | 1 - nano/store/rocksdb/utility.cpp | 11 ++++++ nano/store/rocksdb/utility.hpp | 15 +++++++ 6 files changed, 90 insertions(+), 64 deletions(-) create mode 100644 nano/store/rocksdb/utility.cpp create mode 100644 nano/store/rocksdb/utility.hpp diff --git a/nano/store/CMakeLists.txt b/nano/store/CMakeLists.txt index e5e6a8c47..21306182f 100644 --- a/nano/store/CMakeLists.txt +++ b/nano/store/CMakeLists.txt @@ -47,6 +47,7 @@ add_library( rocksdb/rocksdb.hpp rocksdb/iterator.hpp rocksdb/transaction_impl.hpp + rocksdb/utility.hpp rocksdb/version.hpp tables.hpp transaction.hpp @@ -91,6 +92,7 @@ add_library( rocksdb/rep_weight.cpp rocksdb/rocksdb.cpp rocksdb/transaction.cpp + rocksdb/utility.cpp rocksdb/version.cpp transaction.cpp version.cpp diff --git a/nano/store/rocksdb/iterator.hpp b/nano/store/rocksdb/iterator.hpp index 99fc9a9c5..bec1c3cd4 100644 --- a/nano/store/rocksdb/iterator.hpp +++ b/nano/store/rocksdb/iterator.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -11,20 +12,6 @@ #include #include -namespace -{ -inline bool is_read (nano::store::transaction const & transaction_a) -{ - return (dynamic_cast (&transaction_a) != nullptr); -} - -inline rocksdb::ReadOptions & snapshot_options (nano::store::transaction const & transaction_a) -{ - debug_assert (is_read (transaction_a)); - return *static_cast (transaction_a.get_handle ()); -} -} - namespace nano::store::rocksdb { template @@ -36,19 +23,27 @@ public: iterator (::rocksdb::DB * db, transaction const & transaction_a, ::rocksdb::ColumnFamilyHandle * handle_a, db_val const * val_a, bool const direction_asc) : iterator_impl (transaction_a) { - // Don't fill the block cache for any blocks read as a result of an iterator - if (is_read (transaction_a)) - { - auto read_options = snapshot_options (transaction_a); - read_options.fill_cache = false; - cursor.reset (db->NewIterator (read_options, handle_a)); - } - else - { - ::rocksdb::ReadOptions ropts; - ropts.fill_cache = false; - cursor.reset (tx (transaction_a)->GetIterator (ropts, handle_a)); - } + auto internals = rocksdb::tx (transaction_a); + auto iterator = std::visit ([&] (auto && ptr) { + using V = std::remove_cvref_t; + if constexpr (std::is_same_v) + { + ::rocksdb::ReadOptions ropts; + ropts.fill_cache = false; + return ptr->GetIterator (ropts, handle_a); + } + else if constexpr (std::is_same_v) + { + ptr->fill_cache = false; + return db->NewIterator (*ptr, handle_a); + } + else + { + static_assert (sizeof (V) == 0, "Missing variant handler for type V"); + } + }, + internals); + cursor.reset (iterator); if (val_a) { @@ -197,11 +192,5 @@ public: std::unique_ptr<::rocksdb::Iterator> cursor; std::pair current; - -private: - ::rocksdb::Transaction * tx (store::transaction const & transaction_a) const - { - return static_cast<::rocksdb::Transaction *> (transaction_a.get_handle ()); - } }; } diff --git a/nano/store/rocksdb/rocksdb.cpp b/nano/store/rocksdb/rocksdb.cpp index e62d1db09..a739bc325 100644 --- a/nano/store/rocksdb/rocksdb.cpp +++ b/nano/store/rocksdb/rocksdb.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -499,19 +500,27 @@ rocksdb::ColumnFamilyHandle * nano::store::rocksdb::component::table_to_column_f bool nano::store::rocksdb::component::exists (store::transaction const & transaction_a, tables table_a, nano::store::rocksdb::db_val const & key_a) const { ::rocksdb::PinnableSlice slice; - ::rocksdb::Status status; - if (is_read (transaction_a)) - { - status = db->Get (snapshot_options (transaction_a), table_to_column_family (table_a), key_a, &slice); - } - else - { - ::rocksdb::ReadOptions options; - options.fill_cache = false; - status = tx (transaction_a)->Get (options, table_to_column_family (table_a), key_a, &slice); - } + auto internals = rocksdb::tx (transaction_a); + auto status = std::visit ([&] (auto && ptr) { + using V = std::remove_cvref_t; + if constexpr (std::is_same_v) + { + ::rocksdb::ReadOptions options; + options.fill_cache = false; + return ptr->Get (options, table_to_column_family (table_a), key_a, &slice); + } + else if constexpr (std::is_same_v) + { + return db->Get (*ptr, table_to_column_family (table_a), key_a, &slice); + } + else + { + static_assert (sizeof (V) == 0, "Missing variant handler for type V"); + } + }, + internals); - return (status.ok ()); + return status.ok (); } int nano::store::rocksdb::component::del (store::write_transaction const & transaction_a, tables table_a, nano::store::rocksdb::db_val const & key_a) @@ -520,7 +529,7 @@ int nano::store::rocksdb::component::del (store::write_transaction const & trans // RocksDB does not report not_found status, it is a pre-condition that the key exists debug_assert (exists (transaction_a, table_a, key_a)); flush_tombstones_check (table_a); - return tx (transaction_a)->Delete (table_to_column_family (table_a), key_a).code (); + return std::get<::rocksdb::Transaction *> (rocksdb::tx (transaction_a))->Delete (table_to_column_family (table_a), key_a).code (); } void nano::store::rocksdb::component::flush_tombstones_check (tables table_a) @@ -543,26 +552,28 @@ void nano::store::rocksdb::component::flush_table (nano::tables table_a) db->Flush (::rocksdb::FlushOptions{}, table_to_column_family (table_a)); } -rocksdb::Transaction * nano::store::rocksdb::component::tx (store::transaction const & transaction_a) const -{ - debug_assert (!is_read (transaction_a)); - return static_cast<::rocksdb::Transaction *> (transaction_a.get_handle ()); -} - int nano::store::rocksdb::component::get (store::transaction const & transaction_a, tables table_a, nano::store::rocksdb::db_val const & key_a, nano::store::rocksdb::db_val & value_a) const { ::rocksdb::ReadOptions options; ::rocksdb::PinnableSlice slice; auto handle = table_to_column_family (table_a); - ::rocksdb::Status status; - if (is_read (transaction_a)) - { - status = db->Get (snapshot_options (transaction_a), handle, key_a, &slice); - } - else - { - status = tx (transaction_a)->Get (options, handle, key_a, &slice); - } + auto internals = rocksdb::tx (transaction_a); + auto status = std::visit ([&] (auto && ptr) { + using V = std::remove_cvref_t; + if constexpr (std::is_same_v) + { + return ptr->Get (options, handle, key_a, &slice); + } + else if constexpr (std::is_same_v) + { + return db->Get (*ptr, handle, key_a, &slice); + } + else + { + static_assert (sizeof (V) == 0, "Missing variant handler for type V"); + } + }, + internals); if (status.ok ()) { @@ -576,8 +587,7 @@ int nano::store::rocksdb::component::get (store::transaction const & transaction int nano::store::rocksdb::component::put (store::write_transaction const & transaction_a, tables table_a, nano::store::rocksdb::db_val const & key_a, nano::store::rocksdb::db_val const & value_a) { debug_assert (transaction_a.contains (table_a)); - auto txn = tx (transaction_a); - return txn->Put (table_to_column_family (table_a), key_a, value_a).code (); + return std::get<::rocksdb::Transaction *> (rocksdb::tx (transaction_a))->Put (table_to_column_family (table_a), key_a, value_a).code (); } bool nano::store::rocksdb::component::not_found (int status) const diff --git a/nano/store/rocksdb/rocksdb.hpp b/nano/store/rocksdb/rocksdb.hpp index 1d964b8ee..493a26fff 100644 --- a/nano/store/rocksdb/rocksdb.hpp +++ b/nano/store/rocksdb/rocksdb.hpp @@ -122,7 +122,6 @@ private: std::unordered_map tombstone_map; std::unordered_map cf_name_table_map; - ::rocksdb::Transaction * tx (store::transaction const & transaction_a) const; std::vector all_tables () const; bool not_found (int status) const override; diff --git a/nano/store/rocksdb/utility.cpp b/nano/store/rocksdb/utility.cpp new file mode 100644 index 000000000..092e75a9f --- /dev/null +++ b/nano/store/rocksdb/utility.cpp @@ -0,0 +1,11 @@ +#include +#include + +auto nano::store::rocksdb::tx (store::transaction const & transaction_a) -> std::variant<::rocksdb::Transaction *, ::rocksdb::ReadOptions *> +{ + if (dynamic_cast (&transaction_a) != nullptr) + { + return static_cast<::rocksdb::ReadOptions *> (transaction_a.get_handle ()); + } + return static_cast<::rocksdb::Transaction *> (transaction_a.get_handle ()); +} diff --git a/nano/store/rocksdb/utility.hpp b/nano/store/rocksdb/utility.hpp new file mode 100644 index 000000000..7686b6b4d --- /dev/null +++ b/nano/store/rocksdb/utility.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include + +#include + +namespace nano::store +{ +class transaction; +} + +namespace nano::store::rocksdb +{ +auto tx (store::transaction const & transaction_a) -> std::variant<::rocksdb::Transaction *, ::rocksdb::ReadOptions *>; +} From 37f4f5c2d6fb385d62a72603ad21385b2cb3db50 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Mon, 14 Oct 2024 18:39:43 +0100 Subject: [PATCH 42/48] Rewrite nano::store iterators to use variants instead of polymorphism. --- nano/core_test/block_store.cpp | 10 +- nano/node/node.cpp | 2 +- nano/node/wallet.cpp | 38 ++- nano/node/wallet.hpp | 3 +- nano/store/CMakeLists.txt | 10 +- nano/store/account.cpp | 17 ++ nano/store/account.hpp | 29 +- nano/store/block.cpp | 3 + nano/store/block.hpp | 30 +- nano/store/confirmation_height.cpp | 3 + nano/store/confirmation_height.hpp | 4 +- nano/store/final_vote.cpp | 3 + nano/store/final_vote.hpp | 4 +- nano/store/iterator.cpp | 80 +++++ nano/store/iterator.hpp | 94 +++--- nano/store/iterator_impl.cpp | 1 - nano/store/iterator_impl.hpp | 43 --- nano/store/lmdb/account.cpp | 14 +- nano/store/lmdb/account.hpp | 1 - nano/store/lmdb/block.cpp | 7 +- nano/store/lmdb/confirmation_height.cpp | 7 +- nano/store/lmdb/final_vote.cpp | 7 +- nano/store/lmdb/iterator.cpp | 133 +++++++++ nano/store/lmdb/iterator.hpp | 332 +++------------------ nano/store/lmdb/lmdb.cpp | 15 +- nano/store/lmdb/lmdb.hpp | 12 - nano/store/lmdb/online_weight.cpp | 9 +- nano/store/lmdb/online_weight.hpp | 1 - nano/store/lmdb/peer.cpp | 4 +- nano/store/lmdb/pending.cpp | 7 +- nano/store/lmdb/pruned.cpp | 7 +- nano/store/lmdb/rep_weight.cpp | 7 +- nano/store/online_weight.cpp | 17 ++ nano/store/online_weight.hpp | 9 +- nano/store/peer.cpp | 3 + nano/store/peer.hpp | 4 +- nano/store/pending.cpp | 4 + nano/store/pending.hpp | 4 +- nano/store/pruned.cpp | 3 + nano/store/pruned.hpp | 4 +- nano/store/rep_weight.cpp | 4 + nano/store/rep_weight.hpp | 4 +- nano/store/reverse_iterator.hpp | 48 +++ nano/store/reverse_iterator_templ.hpp | 63 ++++ nano/store/rocksdb/account.cpp | 15 +- nano/store/rocksdb/account.hpp | 1 - nano/store/rocksdb/block.cpp | 8 +- nano/store/rocksdb/confirmation_height.cpp | 8 +- nano/store/rocksdb/final_vote.cpp | 8 +- nano/store/rocksdb/iterator.cpp | 146 +++++++++ nano/store/rocksdb/iterator.hpp | 222 +++----------- nano/store/rocksdb/online_weight.cpp | 10 +- nano/store/rocksdb/online_weight.hpp | 1 - nano/store/rocksdb/peer.cpp | 5 +- nano/store/rocksdb/pending.cpp | 8 +- nano/store/rocksdb/pruned.cpp | 8 +- nano/store/rocksdb/rep_weight.cpp | 8 +- nano/store/rocksdb/rocksdb.cpp | 4 +- nano/store/rocksdb/rocksdb.hpp | 12 - nano/store/typed_iterator.cpp | 1 + nano/store/typed_iterator.hpp | 63 ++++ nano/store/typed_iterator_templ.hpp | 88 ++++++ 62 files changed, 978 insertions(+), 742 deletions(-) delete mode 100644 nano/store/iterator_impl.cpp delete mode 100644 nano/store/iterator_impl.hpp create mode 100644 nano/store/lmdb/iterator.cpp create mode 100644 nano/store/rep_weight.cpp create mode 100644 nano/store/reverse_iterator.hpp create mode 100644 nano/store/reverse_iterator_templ.hpp create mode 100644 nano/store/rocksdb/iterator.cpp create mode 100644 nano/store/typed_iterator.cpp create mode 100644 nano/store/typed_iterator.hpp create mode 100644 nano/store/typed_iterator_templ.hpp diff --git a/nano/core_test/block_store.cpp b/nano/core_test/block_store.cpp index 84e98380c..491741708 100644 --- a/nano/core_test/block_store.cpp +++ b/nano/core_test/block_store.cpp @@ -798,7 +798,7 @@ TEST (block_store, large_iteration) // Reverse iteration std::unordered_set accounts3; previous = std::numeric_limits::max (); - for (auto i (store->account.rbegin (transaction)), n (store->account.end (transaction)); i != n; --i) + for (auto i (store->account.rbegin (transaction)), n (store->account.rend (transaction)); i != n; ++i) { nano::account current (i->first); ASSERT_LT (current.number (), previous.number ()); @@ -1254,7 +1254,7 @@ TEST (block_store, online_weight) auto transaction (store->tx_begin_write ()); ASSERT_EQ (0, store->online_weight.count (transaction)); ASSERT_EQ (store->online_weight.end (transaction), store->online_weight.begin (transaction)); - ASSERT_EQ (store->online_weight.end (transaction), store->online_weight.rbegin (transaction)); + ASSERT_EQ (store->online_weight.rend (transaction), store->online_weight.rbegin (transaction)); store->online_weight.put (transaction, 1, 2); store->online_weight.put (transaction, 3, 4); } @@ -1266,18 +1266,18 @@ TEST (block_store, online_weight) ASSERT_EQ (1, item->first); ASSERT_EQ (2, item->second.number ()); auto item_last (store->online_weight.rbegin (transaction)); - ASSERT_NE (store->online_weight.end (transaction), item_last); + ASSERT_NE (store->online_weight.rend (transaction), item_last); ASSERT_EQ (3, item_last->first); ASSERT_EQ (4, item_last->second.number ()); store->online_weight.del (transaction, 1); ASSERT_EQ (1, store->online_weight.count (transaction)); - ASSERT_EQ (store->online_weight.begin (transaction), store->online_weight.rbegin (transaction)); + ASSERT_EQ (*store->online_weight.begin (transaction), *store->online_weight.rbegin (transaction)); store->online_weight.del (transaction, 3); } auto transaction (store->tx_begin_read ()); ASSERT_EQ (0, store->online_weight.count (transaction)); ASSERT_EQ (store->online_weight.end (transaction), store->online_weight.begin (transaction)); - ASSERT_EQ (store->online_weight.end (transaction), store->online_weight.rbegin (transaction)); + ASSERT_EQ (store->online_weight.rend (transaction), store->online_weight.rbegin (transaction)); } TEST (block_store, pruned_blocks) diff --git a/nano/node/node.cpp b/nano/node/node.cpp index b3d595551..41cdfae18 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -755,7 +755,7 @@ void nano::node::long_inactivity_cleanup () if (store.online_weight.count (transaction) > 0) { auto sample (store.online_weight.rbegin (transaction)); - auto n (store.online_weight.end (transaction)); + auto n (store.online_weight.rend (transaction)); debug_assert (sample != n); auto const one_week_ago = static_cast ((std::chrono::system_clock::now () - std::chrono::hours (7 * 24)).time_since_epoch ().count ()); perform_cleanup = sample->first < one_week_ago; diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index 536441690..387c479e9 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,8 @@ #include +template class nano::store::typed_iterator; + nano::uint256_union nano::wallet_store::check (store::transaction const & transaction_a) { nano::wallet_value value (entry_get_raw (transaction_a, nano::wallet_store::check_special)); @@ -548,7 +551,8 @@ bool nano::wallet_store::exists (store::transaction const & transaction_a, nano: void nano::wallet_store::serialize_json (store::transaction const & transaction_a, std::string & string_a) { boost::property_tree::ptree tree; - for (store::iterator i (std::make_unique> (transaction_a, env, handle)), n (nullptr); i != n; ++i) + using iterator = store::typed_iterator; + for (iterator i{ store::iterator{ store::lmdb::iterator::begin (env.tx (transaction_a), handle) } }, n{ store::iterator{ store::lmdb::iterator::end (env.tx (transaction_a), handle) } }; i != n; ++i) { tree.put (i->first.to_string (), i->second.key.to_string ()); } @@ -1359,13 +1363,15 @@ nano::wallets::wallets (bool error_a, nano::node & node_a) : status |= mdb_dbi_open (env.tx (transaction), "send_action_ids", MDB_CREATE, &send_action_ids); release_assert (status == 0); std::string beginning (nano::uint256_union (0).to_string ()); + nano::store::lmdb::db_val beginning_val{ beginning.size (), const_cast (beginning.c_str ()) }; std::string end ((nano::uint256_union (nano::uint256_t (0) - nano::uint256_t (1))).to_string ()); - store::iterator, nano::no_value> i (std::make_unique, nano::no_value>> (transaction, env, handle, nano::store::lmdb::db_val (beginning.size (), const_cast (beginning.c_str ())))); - store::iterator, nano::no_value> n (std::make_unique, nano::no_value>> (transaction, env, handle, nano::store::lmdb::db_val (end.size (), const_cast (end.c_str ())))); + nano::store::lmdb::db_val end_val{ end.size (), const_cast (end.c_str ()) }; + store::iterator i{ store::lmdb::iterator::lower_bound (env.tx (transaction), handle, beginning_val) }; + store::iterator n{ store::lmdb::iterator::lower_bound (env.tx (transaction), handle, end_val) }; for (; i != n; ++i) { nano::wallet_id id; - std::string text (i->first.data (), i->first.size ()); + std::string text (reinterpret_cast (i->first.data ()), i->first.size ()); auto error (id.decode_hex (text)); release_assert (!error); release_assert (items.find (id) == items.end ()); @@ -1488,13 +1494,15 @@ void nano::wallets::reload () auto transaction (tx_begin_write ()); std::unordered_set stored_items; std::string beginning (nano::uint256_union (0).to_string ()); + nano::store::lmdb::db_val beginning_val{ beginning.size (), const_cast (beginning.c_str ()) }; std::string end ((nano::uint256_union (nano::uint256_t (0) - nano::uint256_t (1))).to_string ()); - store::iterator, nano::no_value> i (std::make_unique, nano::no_value>> (transaction, env, handle, nano::store::lmdb::db_val (beginning.size (), const_cast (beginning.c_str ())))); - store::iterator, nano::no_value> n (std::make_unique, nano::no_value>> (transaction, env, handle, nano::store::lmdb::db_val (end.size (), const_cast (end.c_str ())))); + nano::store::lmdb::db_val end_val{ end.size (), const_cast (end.c_str ()) }; + store::iterator i{ store::lmdb::iterator::lower_bound (env.tx (transaction), handle, beginning_val) }; + store::iterator n{ store::lmdb::iterator::lower_bound (env.tx (transaction), handle, end_val) }; for (; i != n; ++i) { nano::wallet_id id; - std::string text (i->first.data (), i->first.size ()); + std::string text (reinterpret_cast (i->first.data ()), i->first.size ()); auto error (id.decode_hex (text)); debug_assert (!error); // New wallet @@ -1755,20 +1763,22 @@ nano::uint128_t const nano::wallets::high_priority = std::numeric_limits iterator { - iterator result (std::make_unique> (transaction_a, env, handle, nano::store::lmdb::db_val (nano::account (special_count)))); - return result; + nano::account account{ special_count }; + nano::store::lmdb::db_val val{ account }; + return iterator{ store::iterator{ store::lmdb::iterator::lower_bound (env.tx (transaction_a), handle, val) } }; } auto nano::wallet_store::begin (store::transaction const & transaction_a, nano::account const & key) -> iterator { - iterator result (std::make_unique> (transaction_a, env, handle, nano::store::lmdb::db_val (key))); - return result; + nano::account account (key); + nano::store::lmdb::db_val val{ account }; + return iterator{ store::iterator{ store::lmdb::iterator::lower_bound (env.tx (transaction_a), handle, val) } }; } auto nano::wallet_store::find (store::transaction const & transaction_a, nano::account const & key) -> iterator { - auto result (begin (transaction_a, key)); - iterator end{ nullptr }; + auto result = begin (transaction_a, key); + auto end = this->end (transaction_a); if (result != end) { if (result->first == key) @@ -1789,7 +1799,7 @@ auto nano::wallet_store::find (store::transaction const & transaction_a, nano::a auto nano::wallet_store::end (store::transaction const & transaction_a) -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ store::lmdb::iterator::end (env.tx (transaction_a), handle) } }; } nano::mdb_wallets_store::mdb_wallets_store (std::filesystem::path const & path_a, nano::lmdb_config const & lmdb_config_a) : diff --git a/nano/node/wallet.hpp b/nano/node/wallet.hpp index f3daef817..9cb7aa50e 100644 --- a/nano/node/wallet.hpp +++ b/nano/node/wallet.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -58,7 +59,7 @@ enum class key_type class wallet_store final { public: - using iterator = store::iterator; + using iterator = store::typed_iterator; public: wallet_store (bool &, nano::kdf &, store::transaction &, store::lmdb::env &, nano::account, unsigned, std::string const &); diff --git a/nano/store/CMakeLists.txt b/nano/store/CMakeLists.txt index 21306182f..0fb509489 100644 --- a/nano/store/CMakeLists.txt +++ b/nano/store/CMakeLists.txt @@ -8,7 +8,6 @@ add_library( db_val.hpp db_val_impl.hpp iterator.hpp - iterator_impl.hpp final_vote.hpp lmdb/account.hpp lmdb/block.hpp @@ -33,6 +32,8 @@ add_library( pending.hpp pruned.hpp rep_weight.hpp + reverse_iterator.hpp + reverse_iterator_templ.hpp rocksdb/account.hpp rocksdb/block.hpp rocksdb/confirmation_height.hpp @@ -51,6 +52,8 @@ add_library( rocksdb/version.hpp tables.hpp transaction.hpp + typed_iterator.hpp + typed_iterator_templ.hpp version.hpp versioning.hpp account.cpp @@ -59,13 +62,13 @@ add_library( confirmation_height.cpp db_val.cpp iterator.cpp - iterator_impl.cpp final_vote.cpp lmdb/account.cpp lmdb/block.cpp lmdb/confirmation_height.cpp lmdb/db_val.cpp lmdb/final_vote.cpp + lmdb/iterator.cpp lmdb/lmdb.cpp lmdb/lmdb_env.cpp lmdb/transaction.cpp @@ -80,11 +83,13 @@ add_library( peer.cpp pending.cpp pruned.cpp + rep_weight.cpp rocksdb/account.cpp rocksdb/block.cpp rocksdb/confirmation_height.cpp rocksdb/db_val.cpp rocksdb/final_vote.cpp + rocksdb/iterator.cpp rocksdb/online_weight.cpp rocksdb/peer.cpp rocksdb/pending.cpp @@ -95,6 +100,7 @@ add_library( rocksdb/utility.cpp rocksdb/version.cpp transaction.cpp + typed_iterator.cpp version.cpp versioning.cpp write_queue.hpp diff --git a/nano/store/account.cpp b/nano/store/account.cpp index a3bb7a197..61549712a 100644 --- a/nano/store/account.cpp +++ b/nano/store/account.cpp @@ -1,4 +1,9 @@ #include +#include +#include + +template class nano::store::typed_iterator; +template class nano::store::reverse_iterator>; std::optional nano::store::account::get (store::transaction const & transaction, nano::account const & account) { @@ -13,3 +18,15 @@ std::optional nano::store::account::get (store::transaction return std::nullopt; } } + +auto nano::store::account::rbegin (store::transaction const & tx) const -> reverse_iterator +{ + auto iter = end (tx); + --iter; + return reverse_iterator{ std::move (iter) }; +} + +auto nano::store::account::rend (transaction const & tx) const -> reverse_iterator +{ + return reverse_iterator{ end (tx) }; +} diff --git a/nano/store/account.hpp b/nano/store/account.hpp index cc9b93f68..dab7556b1 100644 --- a/nano/store/account.hpp +++ b/nano/store/account.hpp @@ -3,7 +3,8 @@ #include #include #include -#include +#include +#include #include @@ -20,19 +21,21 @@ namespace nano::store class account { public: - using iterator = store::iterator; + using iterator = typed_iterator; + using reverse_iterator = store::reverse_iterator; public: - virtual void put (store::write_transaction const &, nano::account const &, nano::account_info const &) = 0; - virtual bool get (store::transaction const &, nano::account const &, nano::account_info &) = 0; - std::optional get (store::transaction const &, nano::account const &); - virtual void del (store::write_transaction const &, nano::account const &) = 0; - virtual bool exists (store::transaction const &, nano::account const &) = 0; - virtual size_t count (store::transaction const &) = 0; - virtual iterator begin (store::transaction const &, nano::account const &) const = 0; - virtual iterator begin (store::transaction const &) const = 0; - virtual iterator rbegin (store::transaction const &) const = 0; - virtual iterator end (store::transaction const & transaction_a) const = 0; - virtual void for_each_par (std::function const &) const = 0; + virtual void put (write_transaction const & tx, nano::account const &, nano::account_info const &) = 0; + virtual bool get (transaction const & tx, nano::account const &, nano::account_info &) = 0; + std::optional get (transaction const & tx, nano::account const &); + virtual void del (write_transaction const & tx, nano::account const &) = 0; + virtual bool exists (transaction const & tx, nano::account const &) = 0; + virtual size_t count (transaction const & tx) = 0; + virtual iterator begin (transaction const & tx, nano::account const &) const = 0; + virtual iterator begin (transaction const & tx) const = 0; + reverse_iterator rbegin (transaction const & tx) const; + reverse_iterator rend (transaction const & tx) const; + virtual iterator end (transaction const & tx) const = 0; + virtual void for_each_par (std::function const &) const = 0; }; } // namespace nano::store diff --git a/nano/store/block.cpp b/nano/store/block.cpp index 40d128b96..272a25290 100644 --- a/nano/store/block.cpp +++ b/nano/store/block.cpp @@ -1 +1,4 @@ #include +#include + +template class nano::store::typed_iterator; diff --git a/nano/store/block.hpp b/nano/store/block.hpp index cf0464a52..10cda6d29 100644 --- a/nano/store/block.hpp +++ b/nano/store/block.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -22,21 +22,21 @@ namespace nano::store class block { public: - using iterator = store::iterator; + using iterator = typed_iterator; public: - virtual void put (store::write_transaction const &, nano::block_hash const &, nano::block const &) = 0; - virtual void raw_put (store::write_transaction const &, std::vector const &, nano::block_hash const &) = 0; - virtual std::optional successor (store::transaction const &, nano::block_hash const &) const = 0; - virtual void successor_clear (store::write_transaction const &, nano::block_hash const &) = 0; - virtual std::shared_ptr get (store::transaction const &, nano::block_hash const &) const = 0; - virtual std::shared_ptr random (store::transaction const &) = 0; - virtual void del (store::write_transaction const &, nano::block_hash const &) = 0; - virtual bool exists (store::transaction const &, nano::block_hash const &) = 0; - virtual uint64_t count (store::transaction const &) = 0; - virtual iterator begin (store::transaction const &, nano::block_hash const &) const = 0; - virtual iterator begin (store::transaction const &) const = 0; - virtual iterator end (store::transaction const &) const = 0; - virtual void for_each_par (std::function const & action_a) const = 0; + virtual void put (write_transaction const & tx, nano::block_hash const &, nano::block const &) = 0; + virtual void raw_put (write_transaction const & tx, std::vector const &, nano::block_hash const &) = 0; + virtual std::optional successor (transaction const & tx, nano::block_hash const &) const = 0; + virtual void successor_clear (write_transaction const & tx, nano::block_hash const &) = 0; + virtual std::shared_ptr get (transaction const & tx, nano::block_hash const &) const = 0; + virtual std::shared_ptr random (transaction const & tx) = 0; + virtual void del (write_transaction const & tx, nano::block_hash const &) = 0; + virtual bool exists (transaction const & tx, nano::block_hash const &) = 0; + virtual uint64_t count (transaction const & tx) = 0; + virtual iterator begin (transaction const & tx, nano::block_hash const &) const = 0; + virtual iterator begin (transaction const & tx) const = 0; + virtual iterator end (transaction const & tx) const = 0; + virtual void for_each_par (std::function const & action_a) const = 0; }; } // namespace nano::store diff --git a/nano/store/confirmation_height.cpp b/nano/store/confirmation_height.cpp index dae07d69c..630e72abd 100644 --- a/nano/store/confirmation_height.cpp +++ b/nano/store/confirmation_height.cpp @@ -1,4 +1,7 @@ #include +#include + +template class nano::store::typed_iterator; std::optional nano::store::confirmation_height::get (store::transaction const & transaction, nano::account const & account) { diff --git a/nano/store/confirmation_height.hpp b/nano/store/confirmation_height.hpp index de3cc89e4..4bebe575d 100644 --- a/nano/store/confirmation_height.hpp +++ b/nano/store/confirmation_height.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include @@ -18,7 +18,7 @@ namespace nano::store class confirmation_height { public: - using iterator = store::iterator; + using iterator = typed_iterator; public: virtual void put (store::write_transaction const & transaction_a, nano::account const & account_a, nano::confirmation_height_info const & confirmation_height_info_a) = 0; diff --git a/nano/store/final_vote.cpp b/nano/store/final_vote.cpp index 0b4565c1a..99ccfdbf5 100644 --- a/nano/store/final_vote.cpp +++ b/nano/store/final_vote.cpp @@ -1 +1,4 @@ #include +#include + +template class nano::store::typed_iterator; diff --git a/nano/store/final_vote.hpp b/nano/store/final_vote.hpp index e9f9e3417..f6f96f979 100644 --- a/nano/store/final_vote.hpp +++ b/nano/store/final_vote.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include @@ -18,7 +18,7 @@ namespace nano::store class final_vote { public: - using iterator = store::iterator; + using iterator = typed_iterator; public: virtual bool put (store::write_transaction const & transaction_a, nano::qualified_root const & root_a, nano::block_hash const & hash_a) = 0; diff --git a/nano/store/iterator.cpp b/nano/store/iterator.cpp index 15bf18fac..31b80166c 100644 --- a/nano/store/iterator.cpp +++ b/nano/store/iterator.cpp @@ -1 +1,81 @@ +#include #include + +namespace nano::store +{ +void iterator::update () +{ + std::visit ([&] (auto && arg) { + if (!arg.is_end ()) + { + this->current = arg.span (); + } + else + { + current = std::monostate{}; + } + }, + internals); +} + +iterator::iterator (std::variant && internals) noexcept : + internals{ std::move (internals) } +{ + update (); +} + +iterator::iterator (iterator && other) noexcept : + internals{ std::move (other.internals) } +{ + current = std::move (other.current); +} + +auto iterator::operator= (iterator && other) noexcept -> iterator & +{ + internals = std::move (other.internals); + current = std::move (other.current); + return *this; +} + +auto iterator::operator++ () -> iterator & +{ + std::visit ([] (auto && arg) { + ++arg; + }, + internals); + update (); + return *this; +} + +auto iterator::operator-- () -> iterator & +{ + std::visit ([] (auto && arg) { + --arg; + }, + internals); + update (); + return *this; +} + +auto iterator::operator->() const -> const_pointer +{ + release_assert (!is_end ()); + return std::get_if (¤t); +} + +auto iterator::operator* () const -> const_reference +{ + release_assert (!is_end ()); + return std::get (current); +} + +auto iterator::operator== (iterator const & other) const -> bool +{ + return internals == other.internals; +} + +bool iterator::is_end () const +{ + return std::holds_alternative (current); +} +} diff --git a/nano/store/iterator.hpp b/nano/store/iterator.hpp index 7fe957d72..edef1171a 100644 --- a/nano/store/iterator.hpp +++ b/nano/store/iterator.hpp @@ -1,69 +1,57 @@ #pragma once -#include +#include +#include +#include +#include #include +#include +#include namespace nano::store { /** - * Iterates the key/value pairs of a transaction + * @class iterator + * @brief A generic database iterator for LMDB or RocksDB. + * + * This class represents an iterator for either LMDB or RocksDB (Persistent Key-Value Store) databases. + * It is a circular iterator, meaning that the end() sentinel value is always in the iteration cycle. + * + * Key characteristics: + * - Decrementing the end iterator points to the last key in the database. + * - Incrementing the end iterator points to the first key in the database. + * - Internally uses either an LMDB or RocksDB iterator, abstracted through a std::variant. */ -template class iterator final { public: - iterator (std::nullptr_t) - { - } - iterator (std::unique_ptr> impl_a) : - impl (std::move (impl_a)) - { - impl->fill (current); - } - iterator (iterator && other_a) : - current (std::move (other_a.current)), - impl (std::move (other_a.impl)) - { - } - iterator & operator++ () - { - ++*impl; - impl->fill (current); - return *this; - } - iterator & operator-- () - { - --*impl; - impl->fill (current); - return *this; - } - iterator & operator= (iterator && other_a) noexcept - { - impl = std::move (other_a.impl); - current = std::move (other_a.current); - return *this; - } - iterator & operator= (iterator const &) = delete; - std::pair * operator->() - { - return ¤t; - } - std::pair const & operator* () const - { - return current; - } - bool operator== (iterator const & other_a) const - { - return (impl == nullptr && other_a.impl == nullptr) || (impl != nullptr && *impl == other_a.impl.get ()) || (other_a.impl != nullptr && *other_a.impl == impl.get ()); - } - bool operator!= (iterator const & other_a) const - { - return !(*this == other_a); - } + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::pair, std::span>; + using pointer = value_type *; + using const_pointer = value_type const *; + using reference = value_type &; + using const_reference = value_type const &; private: - std::pair current; - std::unique_ptr> impl; + std::variant internals; + std::variant current; + void update (); + +public: + iterator (std::variant && internals) noexcept; + + iterator (iterator const &) = delete; + auto operator= (iterator const &) -> iterator & = delete; + + iterator (iterator && other) noexcept; + auto operator= (iterator && other) noexcept -> iterator &; + + auto operator++ () -> iterator &; + auto operator-- () -> iterator &; + auto operator->() const -> const_pointer; + auto operator* () const -> const_reference; + auto operator== (iterator const & other) const -> bool; + bool is_end () const; }; } // namespace nano::store diff --git a/nano/store/iterator_impl.cpp b/nano/store/iterator_impl.cpp deleted file mode 100644 index 4abbeb3f2..000000000 --- a/nano/store/iterator_impl.cpp +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/nano/store/iterator_impl.hpp b/nano/store/iterator_impl.hpp deleted file mode 100644 index 8daf89ead..000000000 --- a/nano/store/iterator_impl.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include - -#include - -namespace nano::store -{ -template -class iterator_impl -{ -public: - explicit iterator_impl (transaction const & transaction_a) : - txn{ transaction_a }, - transaction_epoch{ transaction_a.epoch () } - { - } - virtual ~iterator_impl () - { - debug_assert (transaction_epoch == txn.epoch (), "invalid iterator-transaction lifetime detected"); - } - - virtual iterator_impl & operator++ () = 0; - virtual iterator_impl & operator-- () = 0; - virtual bool operator== (iterator_impl const & other_a) const = 0; - virtual bool is_end_sentinal () const = 0; - virtual void fill (std::pair &) const = 0; - iterator_impl & operator= (iterator_impl const &) = delete; - bool operator== (iterator_impl const * other_a) const - { - return (other_a != nullptr && *this == *other_a) || (other_a == nullptr && is_end_sentinal ()); - } - bool operator!= (iterator_impl const & other_a) const - { - return !(*this == other_a); - } - -protected: - transaction const & txn; - transaction::epoch_t const transaction_epoch; -}; -} diff --git a/nano/store/lmdb/account.cpp b/nano/store/lmdb/account.cpp index 766daaa81..872c906c7 100644 --- a/nano/store/lmdb/account.cpp +++ b/nano/store/lmdb/account.cpp @@ -45,22 +45,18 @@ size_t nano::store::lmdb::account::count (store::transaction const & transaction auto nano::store::lmdb::account::begin (store::transaction const & transaction, nano::account const & account) const -> iterator { - return store.make_iterator (transaction, tables::accounts, account); + lmdb::db_val val{ account }; + return iterator{ store::iterator{ lmdb::iterator::lower_bound (store.env.tx (transaction), accounts_handle, val) } }; } auto nano::store::lmdb::account::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::accounts); + return iterator{ store::iterator{ lmdb::iterator::begin (store.env.tx (transaction), accounts_handle) } }; } -auto nano::store::lmdb::account::rbegin (store::transaction const & transaction_a) const -> iterator +auto nano::store::lmdb::account::end (store::transaction const & tx) const -> iterator { - return store.make_iterator (transaction_a, tables::accounts, false); -} - -auto nano::store::lmdb::account::end (store::transaction const & transaction_a) const -> iterator -{ - return iterator{ nullptr }; + return iterator{ store::iterator{ lmdb::iterator::end (store.env.tx (tx), accounts_handle) } }; } void nano::store::lmdb::account::for_each_par (std::function const & action_a) const diff --git a/nano/store/lmdb/account.hpp b/nano/store/lmdb/account.hpp index 283083d8d..d8e8ef34e 100644 --- a/nano/store/lmdb/account.hpp +++ b/nano/store/lmdb/account.hpp @@ -24,7 +24,6 @@ public: size_t count (store::transaction const & transaction_a) override; iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; iterator begin (store::transaction const & transaction_a) const override; - iterator rbegin (store::transaction const & transaction_a) const override; iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; diff --git a/nano/store/lmdb/block.cpp b/nano/store/lmdb/block.cpp index 72c4b0576..218245b31 100644 --- a/nano/store/lmdb/block.cpp +++ b/nano/store/lmdb/block.cpp @@ -137,17 +137,18 @@ uint64_t nano::store::lmdb::block::count (store::transaction const & transaction auto nano::store::lmdb::block::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::blocks); + return iterator{ store::iterator{ lmdb::iterator::begin (store.env.tx (transaction), blocks_handle) } }; } auto nano::store::lmdb::block::begin (store::transaction const & transaction, nano::block_hash const & hash) const -> iterator { - return store.make_iterator (transaction, tables::blocks, hash); + lmdb::db_val val{ hash }; + return iterator{ store::iterator{ lmdb::iterator::lower_bound (store.env.tx (transaction), blocks_handle, val) } }; } auto nano::store::lmdb::block::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ lmdb::iterator::end (store.env.tx (transaction_a), blocks_handle) } }; } void nano::store::lmdb::block::for_each_par (std::function const & action_a) const diff --git a/nano/store/lmdb/confirmation_height.cpp b/nano/store/lmdb/confirmation_height.cpp index c85e47547..a6302ab5a 100644 --- a/nano/store/lmdb/confirmation_height.cpp +++ b/nano/store/lmdb/confirmation_height.cpp @@ -61,17 +61,18 @@ void nano::store::lmdb::confirmation_height::clear (store::write_transaction con auto nano::store::lmdb::confirmation_height::begin (store::transaction const & transaction, nano::account const & account) const -> iterator { - return store.make_iterator (transaction, tables::confirmation_height, account); + lmdb::db_val val{ account }; + return iterator{ store::iterator{ lmdb::iterator::lower_bound (store.env.tx (transaction), confirmation_height_handle, val) } }; } auto nano::store::lmdb::confirmation_height::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::confirmation_height); + return iterator{ store::iterator{ lmdb::iterator::begin (store.env.tx (transaction), confirmation_height_handle) } }; } auto nano::store::lmdb::confirmation_height::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ lmdb::iterator::end (store.env.tx (transaction_a), confirmation_height_handle) } }; } void nano::store::lmdb::confirmation_height::for_each_par (std::function const & action_a) const diff --git a/nano/store/lmdb/final_vote.cpp b/nano/store/lmdb/final_vote.cpp index aed69f25b..c7fdf7aca 100644 --- a/nano/store/lmdb/final_vote.cpp +++ b/nano/store/lmdb/final_vote.cpp @@ -66,17 +66,18 @@ void nano::store::lmdb::final_vote::clear (store::write_transaction const & tran auto nano::store::lmdb::final_vote::begin (store::transaction const & transaction, nano::qualified_root const & root) const -> iterator { - return store.make_iterator (transaction, tables::final_votes, root); + lmdb::db_val val{ root }; + return iterator{ store::iterator{ lmdb::iterator::lower_bound (store.env.tx (transaction), final_votes_handle, val) } }; } auto nano::store::lmdb::final_vote::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::final_votes); + return iterator{ store::iterator{ lmdb::iterator::begin (store.env.tx (transaction), final_votes_handle) } }; } auto nano::store::lmdb::final_vote::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ lmdb::iterator::end (store.env.tx (transaction_a), final_votes_handle) } }; } void nano::store::lmdb::final_vote::for_each_par (std::function const & action_a) const diff --git a/nano/store/lmdb/iterator.cpp b/nano/store/lmdb/iterator.cpp new file mode 100644 index 000000000..76cfc35e5 --- /dev/null +++ b/nano/store/lmdb/iterator.cpp @@ -0,0 +1,133 @@ +#include +#include + +namespace nano::store::lmdb +{ +auto iterator::span () const -> std::pair, std::span> +{ + auto & current = operator* (); + std::span key{ reinterpret_cast (current.first.mv_data), current.first.mv_size }; + std::span value{ reinterpret_cast (current.second.mv_data), current.second.mv_size }; + return std::make_pair (key, value); +} + +auto iterator::is_end () const -> bool +{ + return std::holds_alternative (current); +} + +void iterator::update (int status) +{ + if (status == MDB_SUCCESS) + { + value_type init; + auto status = mdb_cursor_get (cursor, &init.first, &init.second, MDB_GET_CURRENT); + release_assert (status == MDB_SUCCESS); + current = init; + } + else + { + current = std::monostate{}; + } +} + +iterator::iterator (MDB_txn * tx, MDB_dbi dbi) noexcept +{ + auto open_status = mdb_cursor_open (tx, dbi, &cursor); + release_assert (open_status == MDB_SUCCESS); + this->current = std::monostate{}; +} + +auto iterator::begin (MDB_txn * tx, MDB_dbi dbi) -> iterator +{ + iterator result{ tx, dbi }; + ++result; + return result; +} + +auto iterator::end (MDB_txn * tx, MDB_dbi dbi) -> iterator +{ + return iterator{ tx, dbi }; +} + +auto iterator::lower_bound (MDB_txn * tx, MDB_dbi dbi, MDB_val const & lower_bound) -> iterator +{ + iterator result{ tx, dbi }; + auto status = mdb_cursor_get (result.cursor, const_cast (&lower_bound), nullptr, MDB_SET_RANGE); + result.update (status); + return std::move (result); +} + +iterator::iterator (iterator && other) noexcept +{ + *this = std::move (other); +} + +iterator::~iterator () +{ + if (cursor) + { + mdb_cursor_close (cursor); + } +} + +auto iterator::operator= (iterator && other) noexcept -> iterator & +{ + cursor = other.cursor; + other.cursor = nullptr; + current = other.current; + other.current = std::monostate{}; + return *this; +} + +auto iterator::operator++ () -> iterator & +{ + auto operation = is_end () ? MDB_FIRST : MDB_NEXT; + auto status = mdb_cursor_get (cursor, nullptr, nullptr, operation); + release_assert (status == MDB_SUCCESS || status == MDB_NOTFOUND); + update (status); + return *this; +} + +auto iterator::operator-- () -> iterator & +{ + auto operation = is_end () ? MDB_LAST : MDB_PREV; + auto status = mdb_cursor_get (cursor, nullptr, nullptr, operation); + release_assert (status == MDB_SUCCESS || status == MDB_NOTFOUND); + update (status); + return *this; +} + +auto iterator::operator->() const -> const_pointer +{ + release_assert (!is_end ()); + return std::get_if (¤t); +} + +auto iterator::operator* () const -> const_reference +{ + release_assert (!is_end ()); + return std::get (current); +} + +auto iterator::operator== (iterator const & other) const -> bool +{ + if (is_end () != other.is_end ()) + { + return false; + } + if (is_end ()) + { + return true; + } + auto & lhs = std::get (current); + auto & rhs = std::get (other.current); + auto result = lhs.first.mv_data == rhs.first.mv_data; + if (!result) + { + return result; + } + debug_assert (std::make_pair (lhs.first.mv_data, lhs.first.mv_size) == std::make_pair (rhs.first.mv_data, rhs.first.mv_size) && std::make_pair (lhs.second.mv_data, lhs.second.mv_size) == std::make_pair (rhs.second.mv_data, rhs.second.mv_size)); + return result; +} +} // namespace nano::store::lmdb diff --git a/nano/store/lmdb/iterator.hpp b/nano/store/lmdb/iterator.hpp index 621d69808..ff921ca3a 100644 --- a/nano/store/lmdb/iterator.hpp +++ b/nano/store/lmdb/iterator.hpp @@ -1,310 +1,58 @@ #pragma once -#include -#include -#include -#include -#include +#include +#include +#include +#include #include namespace nano::store::lmdb { -template -class iterator : public iterator_impl -{ -public: - iterator (transaction const & transaction_a, env const & env_a, MDB_dbi db_a, MDB_val const & val_a = MDB_val{}, bool const direction_asc = true) : - iterator_impl (transaction_a) - { - auto status (mdb_cursor_open (env_a.tx (transaction_a), db_a, &cursor)); - release_assert (status == 0); - auto operation (MDB_SET_RANGE); - if (val_a.mv_size != 0) - { - current.first = val_a; - } - else - { - operation = direction_asc ? MDB_FIRST : MDB_LAST; - } - auto status2 (mdb_cursor_get (cursor, ¤t.first.value, ¤t.second.value, operation)); - release_assert (status2 == 0 || status2 == MDB_NOTFOUND); - if (status2 != MDB_NOTFOUND) - { - auto status3 (mdb_cursor_get (cursor, ¤t.first.value, ¤t.second.value, MDB_GET_CURRENT)); - release_assert (status3 == 0 || status3 == MDB_NOTFOUND); - if (current.first.size () != sizeof (T)) - { - clear (); - } - } - else - { - clear (); - } - } - - iterator () = default; - - iterator (iterator && other_a) - { - cursor = other_a.cursor; - other_a.cursor = nullptr; - current = other_a.current; - } - - iterator (iterator const &) = delete; - - ~iterator () - { - if (cursor != nullptr) - { - mdb_cursor_close (cursor); - } - } - - iterator_impl & operator++ () override - { - debug_assert (cursor != nullptr); - auto status (mdb_cursor_get (cursor, ¤t.first.value, ¤t.second.value, MDB_NEXT)); - release_assert (status == 0 || status == MDB_NOTFOUND); - if (status == MDB_NOTFOUND) - { - clear (); - } - if (current.first.size () != sizeof (T)) - { - clear (); - } - return *this; - } - - iterator_impl & operator-- () override - { - debug_assert (cursor != nullptr); - auto status (mdb_cursor_get (cursor, ¤t.first.value, ¤t.second.value, MDB_PREV)); - release_assert (status == 0 || status == MDB_NOTFOUND); - if (status == MDB_NOTFOUND) - { - clear (); - } - if (current.first.size () != sizeof (T)) - { - clear (); - } - return *this; - } - - std::pair, store::db_val> * operator->() - { - return ¤t; - } - - bool operator== (iterator const & base_a) const - { - auto const other_a (boost::polymorphic_downcast const *> (&base_a)); - auto result (current.first.data () == other_a->current.first.data ()); - debug_assert (!result || (current.first.size () == other_a->current.first.size ())); - debug_assert (!result || (current.second.data () == other_a->current.second.data ())); - debug_assert (!result || (current.second.size () == other_a->current.second.size ())); - return result; - } - - bool operator== (iterator_impl const & base_a) const override - { - auto const other_a (boost::polymorphic_downcast const *> (&base_a)); - auto result (current.first.data () == other_a->current.first.data ()); - debug_assert (!result || (current.first.size () == other_a->current.first.size ())); - debug_assert (!result || (current.second.data () == other_a->current.second.data ())); - debug_assert (!result || (current.second.size () == other_a->current.second.size ())); - return result; - } - - bool is_end_sentinal () const override - { - return current.first.size () == 0; - } - void fill (std::pair & value_a) const override - { - if (current.first.size () != 0) - { - value_a.first = static_cast (current.first); - } - else - { - value_a.first = T (); - } - if (current.second.size () != 0) - { - value_a.second = static_cast (current.second); - } - else - { - value_a.second = U (); - } - } - void clear () - { - current.first = store::db_val (); - current.second = store::db_val (); - debug_assert (is_end_sentinal ()); - } - - iterator & operator= (iterator && other_a) - { - if (cursor != nullptr) - { - mdb_cursor_close (cursor); - } - cursor = other_a.cursor; - other_a.cursor = nullptr; - current = other_a.current; - other_a.clear (); - return *this; - } - - iterator_impl & operator= (iterator_impl const &) = delete; - MDB_cursor * cursor{ nullptr }; - std::pair, store::db_val> current; -}; - /** - * Iterates the key/value pairs of two stores merged together + * @class iterator + * @brief An LMDB database iterator. + * + * This class represents an iterator for LMDB (Lightning Memory-Mapped Database) databases. + * It is a circular iterator, meaning that the end() sentinel value is always in the iteration cycle. + * + * Key characteristics: + * - Decrementing the end iterator points to the last key in the database. + * - Incrementing the end iterator points to the first key in the database. */ -template -class merge_iterator : public iterator_impl +class iterator { + MDB_cursor * cursor{ nullptr }; + std::variant> current; + void update (int status); + iterator (MDB_txn * tx, MDB_dbi dbi) noexcept; + public: - merge_iterator (transaction const & transaction_a, MDB_dbi db1_a, MDB_dbi db2_a) : - impl1 (std::make_unique> (transaction_a, db1_a)), - impl2 (std::make_unique> (transaction_a, db2_a)) - { - } + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::pair; + using pointer = value_type *; + using const_pointer = value_type const *; + using reference = value_type &; + using const_reference = value_type const &; - merge_iterator () : - impl1 (std::make_unique> ()), - impl2 (std::make_unique> ()) - { - } + static auto begin (MDB_txn * tx, MDB_dbi dbi) -> iterator; + static auto end (MDB_txn * tx, MDB_dbi dbi) -> iterator; + static auto lower_bound (MDB_txn * tx, MDB_dbi dbi, MDB_val const & lower_bound) -> iterator; - merge_iterator (transaction const & transaction_a, MDB_dbi db1_a, MDB_dbi db2_a, MDB_val const & val_a) : - impl1 (std::make_unique> (transaction_a, db1_a, val_a)), - impl2 (std::make_unique> (transaction_a, db2_a, val_a)) - { - } + ~iterator (); - merge_iterator (merge_iterator && other_a) - { - impl1 = std::move (other_a.impl1); - impl2 = std::move (other_a.impl2); - } + iterator (iterator const &) = delete; + auto operator= (iterator const &) -> iterator & = delete; - merge_iterator (merge_iterator const &) = delete; + iterator (iterator && other_a) noexcept; + auto operator= (iterator && other) noexcept -> iterator &; - iterator_impl & operator++ () override - { - ++least_iterator (); - return *this; - } - - iterator_impl & operator-- () override - { - --least_iterator (); - return *this; - } - - std::pair, store::db_val> * operator->() - { - return least_iterator ().operator->(); - } - - bool operator== (merge_iterator const & other) const - { - return *impl1 == *other.impl1 && *impl2 == *other.impl2; - } - - bool operator!= (merge_iterator const & base_a) const - { - return !(*this == base_a); - } - - bool operator== (iterator_impl const & base_a) const override - { - debug_assert ((dynamic_cast const *> (&base_a) != nullptr) && "Incompatible iterator comparison"); - auto & other (static_cast const &> (base_a)); - return *this == other; - } - - bool is_end_sentinal () const override - { - return least_iterator ().is_end_sentinal (); - } - - void fill (std::pair & value_a) const override - { - auto & current (least_iterator ()); - if (current->first.size () != 0) - { - value_a.first = static_cast (current->first); - } - else - { - value_a.first = T (); - } - if (current->second.size () != 0) - { - value_a.second = static_cast (current->second); - } - else - { - value_a.second = U (); - } - } - merge_iterator & operator= (merge_iterator &&) = default; - merge_iterator & operator= (merge_iterator const &) = delete; - - mutable bool from_first_database{ false }; - -private: - iterator & least_iterator () const - { - iterator * result; - if (impl1->is_end_sentinal ()) - { - result = impl2.get (); - from_first_database = false; - } - else if (impl2->is_end_sentinal ()) - { - result = impl1.get (); - from_first_database = true; - } - else - { - auto key_cmp (mdb_cmp (mdb_cursor_txn (impl1->cursor), mdb_cursor_dbi (impl1->cursor), impl1->current.first, impl2->current.first)); - - if (key_cmp < 0) - { - result = impl1.get (); - from_first_database = true; - } - else if (key_cmp > 0) - { - result = impl2.get (); - from_first_database = false; - } - else - { - auto val_cmp (mdb_cmp (mdb_cursor_txn (impl1->cursor), mdb_cursor_dbi (impl1->cursor), impl1->current.second, impl2->current.second)); - result = val_cmp < 0 ? impl1.get () : impl2.get (); - from_first_database = (result == impl1.get ()); - } - } - return *result; - } - - std::unique_ptr> impl1; - std::unique_ptr> impl2; + auto operator++ () -> iterator &; + auto operator-- () -> iterator &; + auto operator->() const -> const_pointer; + auto operator* () const -> const_reference; + auto operator== (iterator const & other) const -> bool; + auto span () const -> std::pair, std::span>; + bool is_end () const; }; } diff --git a/nano/store/lmdb/lmdb.cpp b/nano/store/lmdb/lmdb.cpp index ef467208b..a16d53cb8 100644 --- a/nano/store/lmdb/lmdb.cpp +++ b/nano/store/lmdb/lmdb.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -14,6 +15,8 @@ #include +template class nano::store::typed_iterator; + nano::store::lmdb::component::component (nano::logger & logger_a, std::filesystem::path const & path_a, nano::ledger_constants & constants, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a, nano::lmdb_config const & lmdb_config_a, bool backup_before_upgrade_a) : // clang-format off nano::store::component{ @@ -264,8 +267,8 @@ void nano::store::lmdb::component::upgrade_v22_to_v23 (store::write_transaction auto transaction = tx_begin_read (); // Manually create v22 compatible iterator to read accounts - auto it = make_iterator (transaction, tables::accounts); - auto const end = store::iterator (nullptr); + auto it = typed_iterator{ store::iterator{ iterator::begin (env.tx (transaction), account_store.accounts_handle) } }; + auto const end = typed_iterator{ store::iterator{ iterator::end (env.tx (transaction), account_store.accounts_handle) } }; for (; it != end; ++it) { @@ -457,7 +460,7 @@ void nano::store::lmdb::component::rebuild_db (store::write_transaction const & MDB_dbi temp; mdb_dbi_open (env.tx (transaction_a), "temp_table", MDB_CREATE, &temp); // Copy all values to temporary table - for (auto i (store::iterator (std::make_unique> (transaction_a, env, table))), n (store::iterator (nullptr)); i != n; ++i) + for (typed_iterator i{ store::iterator{ iterator::begin (env.tx (transaction_a), table) } }, n{ store::iterator{ iterator::end (env.tx (transaction_a), table) } }; i != n; ++i) { auto s = mdb_put (env.tx (transaction_a), temp, nano::store::lmdb::db_val (i->first), i->second, MDB_APPEND); release_assert_success (s); @@ -466,7 +469,7 @@ void nano::store::lmdb::component::rebuild_db (store::write_transaction const & // Clear existing table mdb_drop (env.tx (transaction_a), table, 0); // Put values from copy - for (auto i (store::iterator (std::make_unique> (transaction_a, env, temp))), n (store::iterator (nullptr)); i != n; ++i) + for (typed_iterator i{ store::iterator{ iterator::begin (env.tx (transaction_a), temp) } }, n{ store::iterator{ iterator::end (env.tx (transaction_a), temp) } }; i != n; ++i) { auto s = mdb_put (env.tx (transaction_a), table, nano::store::lmdb::db_val (i->first), i->second, MDB_APPEND); release_assert_success (s); @@ -480,7 +483,7 @@ void nano::store::lmdb::component::rebuild_db (store::write_transaction const & MDB_dbi temp; mdb_dbi_open (env.tx (transaction_a), "temp_table", MDB_CREATE, &temp); // Copy all values to temporary table - for (auto i (store::iterator (std::make_unique> (transaction_a, env, pending_store.pending_handle))), n (store::iterator (nullptr)); i != n; ++i) + for (typed_iterator i{ store::iterator{ iterator::begin (env.tx (transaction_a), pending_store.pending_handle) } }, n{ store::iterator{ iterator::end (env.tx (transaction_a), pending_store.pending_handle) } }; i != n; ++i) { auto s = mdb_put (env.tx (transaction_a), temp, nano::store::lmdb::db_val (i->first), nano::store::lmdb::db_val (i->second), MDB_APPEND); release_assert_success (s); @@ -488,7 +491,7 @@ void nano::store::lmdb::component::rebuild_db (store::write_transaction const & release_assert (count (transaction_a, pending_store.pending_handle) == count (transaction_a, temp)); mdb_drop (env.tx (transaction_a), pending_store.pending_handle, 0); // Put values from copy - for (auto i (store::iterator (std::make_unique> (transaction_a, env, temp))), n (store::iterator (nullptr)); i != n; ++i) + for (typed_iterator i{ store::iterator{ iterator::begin (env.tx (transaction_a), temp) } }, n{ store::iterator{ iterator::end (env.tx (transaction_a), temp) } }; i != n; ++i) { auto s = mdb_put (env.tx (transaction_a), pending_store.pending_handle, nano::store::lmdb::db_val (i->first), nano::store::lmdb::db_val (i->second), MDB_APPEND); release_assert_success (s); diff --git a/nano/store/lmdb/lmdb.hpp b/nano/store/lmdb/lmdb.hpp index 5920caa4b..f1e786755 100644 --- a/nano/store/lmdb/lmdb.hpp +++ b/nano/store/lmdb/lmdb.hpp @@ -93,18 +93,6 @@ public: bool copy_db (std::filesystem::path const & destination_file) override; void rebuild_db (store::write_transaction const & transaction_a) override; - template - store::iterator make_iterator (store::transaction const & transaction_a, tables table_a, bool const direction_asc = true) const - { - return store::iterator (std::make_unique> (transaction_a, env, table_to_dbi (table_a), nano::store::lmdb::db_val{}, direction_asc)); - } - - template - store::iterator make_iterator (store::transaction const & transaction_a, tables table_a, nano::store::lmdb::db_val const & key) const - { - return store::iterator (std::make_unique> (transaction_a, env, table_to_dbi (table_a), key)); - } - bool init_error () const override; uint64_t count (store::transaction const &, MDB_dbi) const; diff --git a/nano/store/lmdb/online_weight.cpp b/nano/store/lmdb/online_weight.cpp index a570b3ed8..42c3cd551 100644 --- a/nano/store/lmdb/online_weight.cpp +++ b/nano/store/lmdb/online_weight.cpp @@ -20,17 +20,12 @@ void nano::store::lmdb::online_weight::del (store::write_transaction const & tra auto nano::store::lmdb::online_weight::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::online_weight); -} - -auto nano::store::lmdb::online_weight::rbegin (store::transaction const & transaction) const -> iterator -{ - return store.make_iterator (transaction, tables::online_weight, false); + return iterator{ store::iterator{ lmdb::iterator::begin (store.env.tx (transaction), online_weight_handle) } }; } auto nano::store::lmdb::online_weight::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ lmdb::iterator::end (store.env.tx (transaction_a), online_weight_handle) } }; } size_t nano::store::lmdb::online_weight::count (store::transaction const & transaction) const diff --git a/nano/store/lmdb/online_weight.hpp b/nano/store/lmdb/online_weight.hpp index 07668532c..33db21966 100644 --- a/nano/store/lmdb/online_weight.hpp +++ b/nano/store/lmdb/online_weight.hpp @@ -16,7 +16,6 @@ public: void put (store::write_transaction const & transaction_a, uint64_t time_a, nano::amount const & amount_a) override; void del (store::write_transaction const & transaction_a, uint64_t time_a) override; iterator begin (store::transaction const & transaction_a) const override; - iterator rbegin (store::transaction const & transaction_a) const override; iterator end (store::transaction const & transaction_a) const override; size_t count (store::transaction const & transaction_a) const override; void clear (store::write_transaction const & transaction_a) override; diff --git a/nano/store/lmdb/peer.cpp b/nano/store/lmdb/peer.cpp index e22b9c27a..4730c5a6b 100644 --- a/nano/store/lmdb/peer.cpp +++ b/nano/store/lmdb/peer.cpp @@ -47,10 +47,10 @@ void nano::store::lmdb::peer::clear (store::write_transaction const & transactio auto nano::store::lmdb::peer::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::peers); + return iterator{ store::iterator{ lmdb::iterator::begin (store.env.tx (transaction), peers_handle) } }; } auto nano::store::lmdb::peer::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ lmdb::iterator::end (store.env.tx (transaction_a), peers_handle) } }; } diff --git a/nano/store/lmdb/pending.cpp b/nano/store/lmdb/pending.cpp index fd2e57317..35e9a0932 100644 --- a/nano/store/lmdb/pending.cpp +++ b/nano/store/lmdb/pending.cpp @@ -47,17 +47,18 @@ bool nano::store::lmdb::pending::any (store::transaction const & transaction_a, auto nano::store::lmdb::pending::begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const -> iterator { - return store.make_iterator (transaction_a, tables::pending, key_a); + lmdb::db_val val{ key_a }; + return iterator{ store::iterator{ lmdb::iterator::lower_bound (store.env.tx (transaction_a), pending_handle, val) } }; } auto nano::store::lmdb::pending::begin (store::transaction const & transaction_a) const -> iterator { - return store.make_iterator (transaction_a, tables::pending); + return iterator{ store::iterator{ lmdb::iterator::begin (store.env.tx (transaction_a), pending_handle) } }; } auto nano::store::lmdb::pending::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ lmdb::iterator::end (store.env.tx (transaction_a), pending_handle) } }; } void nano::store::lmdb::pending::for_each_par (std::function const & action_a) const diff --git a/nano/store/lmdb/pruned.cpp b/nano/store/lmdb/pruned.cpp index 960881acc..ca853bcab 100644 --- a/nano/store/lmdb/pruned.cpp +++ b/nano/store/lmdb/pruned.cpp @@ -47,17 +47,18 @@ void nano::store::lmdb::pruned::clear (store::write_transaction const & transact auto nano::store::lmdb::pruned::begin (store::transaction const & transaction, nano::block_hash const & hash) const -> iterator { - return store.make_iterator (transaction, tables::pruned, hash); + lmdb::db_val val{ hash }; + return iterator{ store::iterator{ lmdb::iterator::lower_bound (store.env.tx (transaction), pruned_handle, val) } }; } auto nano::store::lmdb::pruned::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::pruned); + return iterator{ store::iterator{ lmdb::iterator::begin (store.env.tx (transaction), pruned_handle) } }; } auto nano::store::lmdb::pruned::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ lmdb::iterator::end (store.env.tx (transaction_a), pruned_handle) } }; } void nano::store::lmdb::pruned::for_each_par (std::function const & action_a) const diff --git a/nano/store/lmdb/rep_weight.cpp b/nano/store/lmdb/rep_weight.cpp index 02e97a9d8..f44c1e51c 100644 --- a/nano/store/lmdb/rep_weight.cpp +++ b/nano/store/lmdb/rep_weight.cpp @@ -45,17 +45,18 @@ void nano::store::lmdb::rep_weight::del (store::write_transaction const & txn_a, auto nano::store::lmdb::rep_weight::begin (store::transaction const & transaction_a, nano::account const & representative_a) const -> iterator { - return store.make_iterator (transaction_a, tables::rep_weights, representative_a); + lmdb::db_val val{ representative_a }; + return iterator{ store::iterator{ lmdb::iterator::lower_bound (store.env.tx (transaction_a), rep_weights_handle, val) } }; } auto nano::store::lmdb::rep_weight::begin (store::transaction const & transaction_a) const -> iterator { - return store.make_iterator (transaction_a, tables::rep_weights); + return iterator{ store::iterator{ lmdb::iterator::begin (store.env.tx (transaction_a), rep_weights_handle) } }; } auto nano::store::lmdb::rep_weight::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ lmdb::iterator::end (store.env.tx (transaction_a), rep_weights_handle) } }; } void nano::store::lmdb::rep_weight::for_each_par (std::function const & action_a) const diff --git a/nano/store/online_weight.cpp b/nano/store/online_weight.cpp index 230a4f266..4fec344f9 100644 --- a/nano/store/online_weight.cpp +++ b/nano/store/online_weight.cpp @@ -1 +1,18 @@ #include +#include +#include + +template class nano::store::typed_iterator; +template class nano::store::reverse_iterator>; + +auto nano::store::online_weight::rbegin (store::transaction const & tx) const -> reverse_iterator +{ + auto iter = end (tx); + --iter; + return reverse_iterator{ std::move (iter) }; +} + +auto nano::store::online_weight::rend (transaction const & tx) const -> reverse_iterator +{ + return reverse_iterator{ end (tx) }; +} diff --git a/nano/store/online_weight.hpp b/nano/store/online_weight.hpp index e6c90f861..04e0780c8 100644 --- a/nano/store/online_weight.hpp +++ b/nano/store/online_weight.hpp @@ -2,7 +2,8 @@ #include #include -#include +#include +#include #include @@ -18,13 +19,15 @@ namespace nano::store class online_weight { public: - using iterator = store::iterator; + using iterator = typed_iterator; + using reverse_iterator = store::reverse_iterator; public: virtual void put (store::write_transaction const &, uint64_t, nano::amount const &) = 0; virtual void del (store::write_transaction const &, uint64_t) = 0; virtual iterator begin (store::transaction const &) const = 0; - virtual iterator rbegin (store::transaction const &) const = 0; + reverse_iterator rbegin (store::transaction const &) const; + reverse_iterator rend (store::transaction const &) const; virtual iterator end (store::transaction const & transaction_a) const = 0; virtual size_t count (store::transaction const &) const = 0; virtual void clear (store::write_transaction const &) = 0; diff --git a/nano/store/peer.cpp b/nano/store/peer.cpp index e442b5754..c682d3382 100644 --- a/nano/store/peer.cpp +++ b/nano/store/peer.cpp @@ -1 +1,4 @@ #include +#include + +template class nano::store::typed_iterator; diff --git a/nano/store/peer.hpp b/nano/store/peer.hpp index 9a03721c9..970e4c470 100644 --- a/nano/store/peer.hpp +++ b/nano/store/peer.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include @@ -18,7 +18,7 @@ namespace nano::store class peer { public: - using iterator = store::iterator; + using iterator = typed_iterator; public: /// Returns true if the peer was inserted, false if it was already in the container diff --git a/nano/store/pending.cpp b/nano/store/pending.cpp index dd80f3579..0b7731a02 100644 --- a/nano/store/pending.cpp +++ b/nano/store/pending.cpp @@ -1 +1,5 @@ +#include #include +#include + +template class nano::store::typed_iterator; diff --git a/nano/store/pending.hpp b/nano/store/pending.hpp index c9d2fd659..fc7fabcb1 100644 --- a/nano/store/pending.hpp +++ b/nano/store/pending.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include @@ -21,7 +21,7 @@ namespace nano::store class pending { public: - using iterator = store::iterator; + using iterator = typed_iterator; public: virtual void put (store::write_transaction const &, nano::pending_key const &, nano::pending_info const &) = 0; diff --git a/nano/store/pruned.cpp b/nano/store/pruned.cpp index e4342c7b4..7b934566d 100644 --- a/nano/store/pruned.cpp +++ b/nano/store/pruned.cpp @@ -1 +1,4 @@ #include +#include + +template class nano::store::typed_iterator; diff --git a/nano/store/pruned.hpp b/nano/store/pruned.hpp index 448020c23..ff6345cf6 100644 --- a/nano/store/pruned.hpp +++ b/nano/store/pruned.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include @@ -18,7 +18,7 @@ namespace nano::store class pruned { public: - using iterator = store::iterator; + using iterator = typed_iterator; public: virtual void put (store::write_transaction const & transaction_a, nano::block_hash const & hash_a) = 0; diff --git a/nano/store/rep_weight.cpp b/nano/store/rep_weight.cpp new file mode 100644 index 000000000..329e5c829 --- /dev/null +++ b/nano/store/rep_weight.cpp @@ -0,0 +1,4 @@ +#include +#include + +template class nano::store::typed_iterator; diff --git a/nano/store/rep_weight.hpp b/nano/store/rep_weight.hpp index b9fdc704c..8d560ac51 100644 --- a/nano/store/rep_weight.hpp +++ b/nano/store/rep_weight.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include @@ -19,7 +19,7 @@ namespace nano::store class rep_weight { public: - using iterator = store::iterator; + using iterator = typed_iterator; public: virtual ~rep_weight (){}; diff --git a/nano/store/reverse_iterator.hpp b/nano/store/reverse_iterator.hpp new file mode 100644 index 000000000..d15624b27 --- /dev/null +++ b/nano/store/reverse_iterator.hpp @@ -0,0 +1,48 @@ +#pragma once + +namespace nano::store +{ +/** + * @class reverse_iterator + * @brief A reverse iterator adaptor for bidirectional iterators. + * + * This class template adapts any bidirectional iterator to reverse its direction of iteration. + * It inverts the semantics of increment and decrement operations. + * + * Key characteristics: + * - Incrementing (operator++) moves to the previous element in the sequence. + * - Decrementing (operator--) moves to the next element in the sequence. + * - Dereferencing refers to the same element as the adapted iterator. + * - Compatible with any bidirectional iterator, not limited to specific container types. + */ +template +class reverse_iterator +{ +public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = Iter::value_type; + using pointer = value_type *; + using const_pointer = value_type const *; + using reference = value_type &; + using const_reference = value_type const &; + +private: + Iter internal; + +public: + reverse_iterator (Iter && other) noexcept; + + reverse_iterator (reverse_iterator const &) = delete; + auto operator= (reverse_iterator const &) -> reverse_iterator & = delete; + + reverse_iterator (reverse_iterator && other) noexcept; + auto operator= (reverse_iterator && other) noexcept -> reverse_iterator &; + + auto operator++ () -> reverse_iterator &; + auto operator-- () -> reverse_iterator &; + auto operator->() const -> const_pointer; + auto operator* () const -> const_reference; + auto operator== (reverse_iterator const & other) const -> bool; + bool is_end () const; +}; +} diff --git a/nano/store/reverse_iterator_templ.hpp b/nano/store/reverse_iterator_templ.hpp new file mode 100644 index 000000000..c441045f7 --- /dev/null +++ b/nano/store/reverse_iterator_templ.hpp @@ -0,0 +1,63 @@ +#include + +namespace nano::store +{ +template +reverse_iterator::reverse_iterator (Iter && other) noexcept : + internal{ std::move (other) } +{ +} + +template +reverse_iterator::reverse_iterator (reverse_iterator && other) noexcept : + internal{ std::move (other.internal) } +{ +} + +template +auto reverse_iterator::operator= (reverse_iterator && other) noexcept -> reverse_iterator & +{ + internal = std::move (other.internal); + return *this; +} + +template +auto reverse_iterator::operator++ () -> reverse_iterator & +{ + --internal; + return *this; +} + +template +auto reverse_iterator::operator-- () -> reverse_iterator & +{ + ++internal; + return *this; +} + +template +auto reverse_iterator::operator->() const -> const_pointer +{ + release_assert (!is_end ()); + return internal.operator->(); +} + +template +auto reverse_iterator::operator* () const -> const_reference +{ + release_assert (!is_end ()); + return internal.operator* (); +} + +template +auto reverse_iterator::operator== (reverse_iterator const & other) const -> bool +{ + return internal == other.internal; +} + +template +bool reverse_iterator::is_end () const +{ + return internal.is_end (); +} +} diff --git a/nano/store/rocksdb/account.cpp b/nano/store/rocksdb/account.cpp index d0ffa20d9..5583c1657 100644 --- a/nano/store/rocksdb/account.cpp +++ b/nano/store/rocksdb/account.cpp @@ -1,6 +1,7 @@ #include #include #include +#include nano::store::rocksdb::account::account (nano::store::rocksdb::component & store_a) : store (store_a){}; @@ -44,22 +45,18 @@ size_t nano::store::rocksdb::account::count (store::transaction const & transact auto nano::store::rocksdb::account::begin (store::transaction const & transaction, nano::account const & account) const -> iterator { - return store.make_iterator (transaction, tables::accounts, account); + rocksdb::db_val val{ account }; + return iterator{ store::iterator{ rocksdb::iterator::lower_bound (store.db.get (), rocksdb::tx (transaction), store.table_to_column_family (tables::accounts), val) } }; } auto nano::store::rocksdb::account::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::accounts); + return iterator{ store::iterator{ rocksdb::iterator::begin (store.db.get (), rocksdb::tx (transaction), store.table_to_column_family (tables::accounts)) } }; } -auto nano::store::rocksdb::account::rbegin (store::transaction const & transaction_a) const -> iterator +auto nano::store::rocksdb::account::end (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction_a, tables::accounts, false); -} - -auto nano::store::rocksdb::account::end (store::transaction const & transaction_a) const -> iterator -{ - return iterator{ nullptr }; + return iterator{ store::iterator{ rocksdb::iterator::end (store.db.get (), rocksdb::tx (transaction), store.table_to_column_family (tables::accounts)) } }; } void nano::store::rocksdb::account::for_each_par (std::function const & action_a) const diff --git a/nano/store/rocksdb/account.hpp b/nano/store/rocksdb/account.hpp index c0b73bde4..b67ef3ed2 100644 --- a/nano/store/rocksdb/account.hpp +++ b/nano/store/rocksdb/account.hpp @@ -22,7 +22,6 @@ public: size_t count (store::transaction const & transaction_a) override; iterator begin (store::transaction const & transaction_a, nano::account const & account_a) const override; iterator begin (store::transaction const & transaction_a) const override; - iterator rbegin (store::transaction const & transaction_a) const override; iterator end (store::transaction const & transaction_a) const override; void for_each_par (std::function const & action_a) const override; }; diff --git a/nano/store/rocksdb/block.cpp b/nano/store/rocksdb/block.cpp index fcee0ffd3..6385704da 100644 --- a/nano/store/rocksdb/block.cpp +++ b/nano/store/rocksdb/block.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace nano { @@ -136,17 +137,18 @@ uint64_t nano::store::rocksdb::block::count (store::transaction const & transact auto nano::store::rocksdb::block::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::blocks); + return iterator{ store::iterator{ rocksdb::iterator::begin (store.db.get (), rocksdb::tx (transaction), store.table_to_column_family (tables::blocks)) } }; } auto nano::store::rocksdb::block::begin (store::transaction const & transaction, nano::block_hash const & hash) const -> iterator { - return store.make_iterator (transaction, tables::blocks, hash); + rocksdb::db_val val{ hash }; + return iterator{ store::iterator{ rocksdb::iterator::lower_bound (store.db.get (), rocksdb::tx (transaction), store.table_to_column_family (tables::blocks), val) } }; } auto nano::store::rocksdb::block::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ rocksdb::iterator::end (store.db.get (), rocksdb::tx (transaction_a), store.table_to_column_family (tables::blocks)) } }; } void nano::store::rocksdb::block::for_each_par (std::function const & action_a) const diff --git a/nano/store/rocksdb/confirmation_height.cpp b/nano/store/rocksdb/confirmation_height.cpp index 838a36520..8f6578fa4 100644 --- a/nano/store/rocksdb/confirmation_height.cpp +++ b/nano/store/rocksdb/confirmation_height.cpp @@ -1,6 +1,7 @@ #include #include #include +#include nano::store::rocksdb::confirmation_height::confirmation_height (nano::store::rocksdb::component & store) : store{ store } @@ -61,17 +62,18 @@ void nano::store::rocksdb::confirmation_height::clear (store::write_transaction auto nano::store::rocksdb::confirmation_height::begin (store::transaction const & transaction, nano::account const & account) const -> iterator { - return store.make_iterator (transaction, tables::confirmation_height, account); + rocksdb::db_val val{ account }; + return iterator{ store::iterator{ rocksdb::iterator::lower_bound (store.db.get (), rocksdb::tx (transaction), store.table_to_column_family (tables::confirmation_height), val) } }; } auto nano::store::rocksdb::confirmation_height::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::confirmation_height); + return iterator{ store::iterator{ rocksdb::iterator::begin (store.db.get (), rocksdb::tx (transaction), store.table_to_column_family (tables::confirmation_height)) } }; } auto nano::store::rocksdb::confirmation_height::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ rocksdb::iterator::end (store.db.get (), rocksdb::tx (transaction_a), store.table_to_column_family (tables::confirmation_height)) } }; } void nano::store::rocksdb::confirmation_height::for_each_par (std::function const & action_a) const diff --git a/nano/store/rocksdb/final_vote.cpp b/nano/store/rocksdb/final_vote.cpp index 328027ae3..52afdfe34 100644 --- a/nano/store/rocksdb/final_vote.cpp +++ b/nano/store/rocksdb/final_vote.cpp @@ -1,6 +1,7 @@ #include #include #include +#include nano::store::rocksdb::final_vote::final_vote (nano::store::rocksdb::component & store) : store{ store } {}; @@ -66,17 +67,18 @@ void nano::store::rocksdb::final_vote::clear (store::write_transaction const & t auto nano::store::rocksdb::final_vote::begin (store::transaction const & transaction, nano::qualified_root const & root) const -> iterator { - return store.make_iterator (transaction, tables::final_votes, root); + rocksdb::db_val val{ root }; + return iterator{ store::iterator{ rocksdb::iterator::lower_bound (store.db.get (), rocksdb::tx (transaction), store.table_to_column_family (tables::final_votes), val) } }; } auto nano::store::rocksdb::final_vote::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::final_votes); + return iterator{ store::iterator{ rocksdb::iterator::begin (store.db.get (), rocksdb::tx (transaction), store.table_to_column_family (tables::final_votes)) } }; } auto nano::store::rocksdb::final_vote::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ rocksdb::iterator::end (store.db.get (), rocksdb::tx (transaction_a), store.table_to_column_family (tables::final_votes)) } }; } void nano::store::rocksdb::final_vote::for_each_par (std::function const & action_a) const diff --git a/nano/store/rocksdb/iterator.cpp b/nano/store/rocksdb/iterator.cpp new file mode 100644 index 000000000..dde487c42 --- /dev/null +++ b/nano/store/rocksdb/iterator.cpp @@ -0,0 +1,146 @@ +#include +#include + +#include + +namespace nano::store::rocksdb +{ +auto iterator::span () const -> std::pair, std::span> +{ + auto & current = operator* (); + std::span key{ reinterpret_cast (current.first.data ()), current.first.size () }; + std::span value{ reinterpret_cast (current.second.data ()), current.second.size () }; + return std::make_pair (key, value); +} + +auto iterator::is_end () const -> bool +{ + return std::holds_alternative (current); +} + +void iterator::update () +{ + if (iter->Valid ()) + { + current = std::make_pair (iter->key (), iter->value ()); + } + else + { + current = std::monostate{}; + } +} + +iterator::iterator (decltype (iter) && iter) : + iter{ std::move (iter) } +{ + update (); +} + +auto iterator::begin (::rocksdb::DB * db, std::variant<::rocksdb::Transaction *, ::rocksdb::ReadOptions *> snapshot, ::rocksdb::ColumnFamilyHandle * table) -> iterator +{ + auto result = iterator{ make_iterator (db, snapshot, table) }; + ++result; + return result; +} + +auto iterator::end (::rocksdb::DB * db, std::variant<::rocksdb::Transaction *, ::rocksdb::ReadOptions *> snapshot, ::rocksdb::ColumnFamilyHandle * table) -> iterator +{ + return iterator{ make_iterator (db, snapshot, table) }; +} + +auto iterator::lower_bound (::rocksdb::DB * db, std::variant<::rocksdb::Transaction *, ::rocksdb::ReadOptions *> snapshot, ::rocksdb::ColumnFamilyHandle * table, ::rocksdb::Slice const & lower_bound) -> iterator +{ + auto iter = make_iterator (db, snapshot, table); + iter->Seek (lower_bound); + return iterator{ std::move (iter) }; +} + +auto iterator::make_iterator (::rocksdb::DB * db, std::variant<::rocksdb::Transaction *, ::rocksdb::ReadOptions *> snapshot, ::rocksdb::ColumnFamilyHandle * table) -> std::unique_ptr<::rocksdb::Iterator> +{ + return std::unique_ptr<::rocksdb::Iterator>{ std::visit ([&] (auto && ptr) { + using V = std::remove_cvref_t; + if constexpr (std::is_same_v) + { + ::rocksdb::ReadOptions ropts; + ropts.fill_cache = false; + return ptr->GetIterator (ropts, table); + } + else if constexpr (std::is_same_v) + { + ptr->fill_cache = false; + return db->NewIterator (*ptr, table); + } + else + { + static_assert (sizeof (V) == 0, "Missing variant handler for type V"); + } + }, + snapshot) }; +} + +iterator::iterator (iterator && other) noexcept +{ + *this = std::move (other); +} + +auto iterator::operator= (iterator && other) noexcept -> iterator & +{ + iter = std::move (other.iter); + current = other.current; + other.current = std::monostate{}; + return *this; +} + +auto iterator::operator++ () -> iterator & +{ + if (!is_end ()) + { + iter->Next (); + } + else + { + iter->SeekToFirst (); + } + update (); + return *this; +} + +auto iterator::operator-- () -> iterator & +{ + if (!is_end ()) + { + iter->Prev (); + } + else + { + iter->SeekToLast (); + } + update (); + return *this; +} + +auto iterator::operator->() const -> const_pointer +{ + release_assert (!is_end ()); + return std::get_if (¤t); +} + +auto iterator::operator* () const -> const_reference +{ + release_assert (!is_end ()); + return std::get (current); +} + +auto iterator::operator== (iterator const & other) const -> bool +{ + if (is_end () != other.is_end ()) + { + return false; + } + if (is_end ()) + { + return true; + } + return std::get (current) == std::get (other.current); +} +} // namespace nano::store::lmdb diff --git a/nano/store/rocksdb/iterator.hpp b/nano/store/rocksdb/iterator.hpp index bec1c3cd4..5a460563f 100644 --- a/nano/store/rocksdb/iterator.hpp +++ b/nano/store/rocksdb/iterator.hpp @@ -1,196 +1,60 @@ #pragma once -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include -#include -#include #include #include namespace nano::store::rocksdb { -template -class iterator : public iterator_impl +/** + * @class iterator + * @brief A RocksDB database iterator. + * + * This class represents an iterator for RocksDB (Persistent Key-Value Store) databases. + * It is a circular iterator, meaning that the end() sentinel value is always in the iteration cycle. + * + * Key characteristics: + * - Decrementing the end iterator points to the last key in the database. + * - Incrementing the end iterator points to the first key in the database. + */ +class iterator { + std::unique_ptr<::rocksdb::Iterator> iter; + std::variant> current; + void update (); + iterator (decltype (iter) && iter); + static auto make_iterator (::rocksdb::DB * db, std::variant<::rocksdb::Transaction *, ::rocksdb::ReadOptions *> snapshot, ::rocksdb::ColumnFamilyHandle * table) -> std::unique_ptr<::rocksdb::Iterator>; + public: - iterator () = default; + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::pair<::rocksdb::Slice, ::rocksdb::Slice>; + using pointer = value_type *; + using const_pointer = value_type const *; + using reference = value_type &; + using const_reference = value_type const &; - iterator (::rocksdb::DB * db, transaction const & transaction_a, ::rocksdb::ColumnFamilyHandle * handle_a, db_val const * val_a, bool const direction_asc) : - iterator_impl (transaction_a) - { - auto internals = rocksdb::tx (transaction_a); - auto iterator = std::visit ([&] (auto && ptr) { - using V = std::remove_cvref_t; - if constexpr (std::is_same_v) - { - ::rocksdb::ReadOptions ropts; - ropts.fill_cache = false; - return ptr->GetIterator (ropts, handle_a); - } - else if constexpr (std::is_same_v) - { - ptr->fill_cache = false; - return db->NewIterator (*ptr, handle_a); - } - else - { - static_assert (sizeof (V) == 0, "Missing variant handler for type V"); - } - }, - internals); - cursor.reset (iterator); + static auto begin (::rocksdb::DB * db, std::variant<::rocksdb::Transaction *, ::rocksdb::ReadOptions *> snapshot, ::rocksdb::ColumnFamilyHandle * table) -> iterator; + static auto end (::rocksdb::DB * db, std::variant<::rocksdb::Transaction *, ::rocksdb::ReadOptions *> snapshot, ::rocksdb::ColumnFamilyHandle * table) -> iterator; + static auto lower_bound (::rocksdb::DB * db, std::variant<::rocksdb::Transaction *, ::rocksdb::ReadOptions *> snapshot, ::rocksdb::ColumnFamilyHandle * table, ::rocksdb::Slice const & lower_bound) -> iterator; - if (val_a) - { - cursor->Seek (*val_a); - } - else if (direction_asc) - { - cursor->SeekToFirst (); - } - else - { - cursor->SeekToLast (); - } + iterator (iterator const &) = delete; + auto operator= (iterator const &) -> iterator & = delete; - if (cursor->Valid ()) - { - current.first = cursor->key (); - current.second = cursor->value (); - } - else - { - clear (); - } - } + iterator (iterator && other_a) noexcept; + auto operator= (iterator && other) noexcept -> iterator &; - iterator (::rocksdb::DB * db, store::transaction const & transaction_a, ::rocksdb::ColumnFamilyHandle * handle_a) : - iterator (db, transaction_a, handle_a, nullptr) - { - } - - iterator (iterator && other_a) - { - cursor = other_a.cursor; - other_a.cursor = nullptr; - current = other_a.current; - } - - iterator (iterator const &) = delete; - - iterator_impl & operator++ () override - { - cursor->Next (); - if (cursor->Valid ()) - { - current.first = cursor->key (); - current.second = cursor->value (); - - if (current.first.size () != sizeof (T)) - { - clear (); - } - } - else - { - clear (); - } - - return *this; - } - - iterator_impl & operator-- () override - { - cursor->Prev (); - if (cursor->Valid ()) - { - current.first = cursor->key (); - current.second = cursor->value (); - - if (current.first.size () != sizeof (T)) - { - clear (); - } - } - else - { - clear (); - } - - return *this; - } - - std::pair * operator->() - { - return ¤t; - } - - bool operator== (iterator_impl const & base_a) const override - { - auto const other_a (boost::polymorphic_downcast const *> (&base_a)); - - if (!current.first.data () && !other_a->current.first.data ()) - { - return true; - } - else if (!current.first.data () || !other_a->current.first.data ()) - { - return false; - } - - auto result (std::memcmp (current.first.data (), other_a->current.first.data (), current.first.size ()) == 0); - debug_assert (!result || (current.first.size () == other_a->current.first.size ())); - debug_assert (!result || std::memcmp (current.second.data (), other_a->current.second.data (), current.second.size ()) == 0); - debug_assert (!result || (current.second.size () == other_a->current.second.size ())); - return result; - } - - bool is_end_sentinal () const override - { - return current.first.size () == 0; - } - - void fill (std::pair & value_a) const override - { - { - if (current.first.size () != 0) - { - value_a.first = static_cast (current.first); - } - else - { - value_a.first = T (); - } - if (current.second.size () != 0) - { - value_a.second = static_cast (current.second); - } - else - { - value_a.second = U (); - } - } - } - void clear () - { - current.first = nano::store::rocksdb::db_val{}; - current.second = nano::store::rocksdb::db_val{}; - debug_assert (is_end_sentinal ()); - } - iterator & operator= (iterator && other_a) - { - cursor = std::move (other_a.cursor); - current = other_a.current; - return *this; - } - iterator_impl & operator= (iterator_impl const &) = delete; - - std::unique_ptr<::rocksdb::Iterator> cursor; - std::pair current; + auto operator++ () -> iterator &; + auto operator-- () -> iterator &; + auto operator->() const -> const_pointer; + auto operator* () const -> const_reference; + auto operator== (iterator const & other) const -> bool; + auto span () const -> std::pair, std::span>; + bool is_end () const; }; } diff --git a/nano/store/rocksdb/online_weight.cpp b/nano/store/rocksdb/online_weight.cpp index dafd0f51f..5d7a40310 100644 --- a/nano/store/rocksdb/online_weight.cpp +++ b/nano/store/rocksdb/online_weight.cpp @@ -1,5 +1,6 @@ #include #include +#include nano::store::rocksdb::online_weight::online_weight (nano::store::rocksdb::component & store_a) : store{ store_a } @@ -20,17 +21,12 @@ void nano::store::rocksdb::online_weight::del (store::write_transaction const & auto nano::store::rocksdb::online_weight::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::online_weight); -} - -auto nano::store::rocksdb::online_weight::rbegin (store::transaction const & transaction) const -> iterator -{ - return store.make_iterator (transaction, tables::online_weight, false); + return iterator{ store::iterator{ rocksdb::iterator::begin (store.db.get (), rocksdb::tx (transaction), store.table_to_column_family (tables::online_weight)) } }; } auto nano::store::rocksdb::online_weight::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ rocksdb::iterator::end (store.db.get (), rocksdb::tx (transaction_a), store.table_to_column_family (tables::online_weight)) } }; } size_t nano::store::rocksdb::online_weight::count (store::transaction const & transaction) const diff --git a/nano/store/rocksdb/online_weight.hpp b/nano/store/rocksdb/online_weight.hpp index 1b88d329d..1c2d835a4 100644 --- a/nano/store/rocksdb/online_weight.hpp +++ b/nano/store/rocksdb/online_weight.hpp @@ -18,7 +18,6 @@ public: void put (store::write_transaction const & transaction_a, uint64_t time_a, nano::amount const & amount_a) override; void del (store::write_transaction const & transaction_a, uint64_t time_a) override; iterator begin (store::transaction const & transaction_a) const override; - iterator rbegin (store::transaction const & transaction_a) const override; iterator end (store::transaction const & transaction_a) const override; size_t count (store::transaction const & transaction_a) const override; void clear (store::write_transaction const & transaction_a) override; diff --git a/nano/store/rocksdb/peer.cpp b/nano/store/rocksdb/peer.cpp index 0da579102..0a7628a64 100644 --- a/nano/store/rocksdb/peer.cpp +++ b/nano/store/rocksdb/peer.cpp @@ -1,5 +1,6 @@ #include #include +#include nano::store::rocksdb::peer::peer (nano::store::rocksdb::component & store) : store{ store } {}; @@ -47,10 +48,10 @@ void nano::store::rocksdb::peer::clear (store::write_transaction const & transac auto nano::store::rocksdb::peer::begin (store::transaction const & transaction) const -> iterator { - return store.make_iterator (transaction, tables::peers); + return iterator{ store::iterator{ rocksdb::iterator::begin (store.db.get (), rocksdb::tx (transaction), store.table_to_column_family (tables::peers)) } }; } auto nano::store::rocksdb::peer::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ rocksdb::iterator::end (store.db.get (), rocksdb::tx (transaction_a), store.table_to_column_family (tables::peers)) } }; } diff --git a/nano/store/rocksdb/pending.cpp b/nano/store/rocksdb/pending.cpp index 9fc4b1a2e..1fc55e01c 100644 --- a/nano/store/rocksdb/pending.cpp +++ b/nano/store/rocksdb/pending.cpp @@ -1,6 +1,7 @@ #include #include #include +#include nano::store::rocksdb::pending::pending (nano::store::rocksdb::component & store) : store{ store } {}; @@ -47,17 +48,18 @@ bool nano::store::rocksdb::pending::any (store::transaction const & transaction_ auto nano::store::rocksdb::pending::begin (store::transaction const & transaction_a, nano::pending_key const & key_a) const -> iterator { - return store.template make_iterator (transaction_a, tables::pending, key_a); + rocksdb::db_val val{ key_a }; + return iterator{ store::iterator{ rocksdb::iterator::lower_bound (store.db.get (), rocksdb::tx (transaction_a), store.table_to_column_family (tables::pending), val) } }; } auto nano::store::rocksdb::pending::begin (store::transaction const & transaction_a) const -> iterator { - return store.template make_iterator (transaction_a, tables::pending); + return iterator{ store::iterator{ rocksdb::iterator::begin (store.db.get (), rocksdb::tx (transaction_a), store.table_to_column_family (tables::pending)) } }; } auto nano::store::rocksdb::pending::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ rocksdb::iterator::end (store.db.get (), rocksdb::tx (transaction_a), store.table_to_column_family (tables::pending)) } }; } void nano::store::rocksdb::pending::for_each_par (std::function const & action_a) const diff --git a/nano/store/rocksdb/pruned.cpp b/nano/store/rocksdb/pruned.cpp index 3cca20144..b85eae1ab 100644 --- a/nano/store/rocksdb/pruned.cpp +++ b/nano/store/rocksdb/pruned.cpp @@ -1,6 +1,7 @@ #include #include #include +#include nano::store::rocksdb::pruned::pruned (nano::store::rocksdb::component & store_a) : store{ store_a } {}; @@ -47,17 +48,18 @@ void nano::store::rocksdb::pruned::clear (store::write_transaction const & trans auto nano::store::rocksdb::pruned::begin (store::transaction const & transaction_a, nano::block_hash const & hash_a) const -> iterator { - return store.make_iterator (transaction_a, tables::pruned, hash_a); + rocksdb::db_val val{ hash_a }; + return iterator{ store::iterator{ rocksdb::iterator::lower_bound (store.db.get (), rocksdb::tx (transaction_a), store.table_to_column_family (tables::pruned), val) } }; } auto nano::store::rocksdb::pruned::begin (store::transaction const & transaction_a) const -> iterator { - return store.make_iterator (transaction_a, tables::pruned); + return iterator{ store::iterator{ rocksdb::iterator::begin (store.db.get (), rocksdb::tx (transaction_a), store.table_to_column_family (tables::pruned)) } }; } auto nano::store::rocksdb::pruned::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ rocksdb::iterator::end (store.db.get (), rocksdb::tx (transaction_a), store.table_to_column_family (tables::pruned)) } }; } void nano::store::rocksdb::pruned::for_each_par (std::function const & action_a) const diff --git a/nano/store/rocksdb/rep_weight.cpp b/nano/store/rocksdb/rep_weight.cpp index e719ef990..3fc14c172 100644 --- a/nano/store/rocksdb/rep_weight.cpp +++ b/nano/store/rocksdb/rep_weight.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include @@ -44,17 +45,18 @@ void nano::store::rocksdb::rep_weight::del (store::write_transaction const & txn auto nano::store::rocksdb::rep_weight::begin (store::transaction const & txn_a, nano::account const & representative_a) const -> iterator { - return store.make_iterator (txn_a, tables::rep_weights, representative_a); + rocksdb::db_val val{ representative_a }; + return iterator{ store::iterator{ rocksdb::iterator::lower_bound (store.db.get (), rocksdb::tx (txn_a), store.table_to_column_family (tables::rep_weights), val) } }; } auto nano::store::rocksdb::rep_weight::begin (store::transaction const & txn_a) const -> iterator { - return store.make_iterator (txn_a, tables::rep_weights); + return iterator{ store::iterator{ rocksdb::iterator::begin (store.db.get (), rocksdb::tx (txn_a), store.table_to_column_family (tables::rep_weights)) } }; } auto nano::store::rocksdb::rep_weight::end (store::transaction const & transaction_a) const -> iterator { - return iterator{ nullptr }; + return iterator{ store::iterator{ rocksdb::iterator::end (store.db.get (), rocksdb::tx (transaction_a), store.table_to_column_family (tables::rep_weights)) } }; } void nano::store::rocksdb::rep_weight::for_each_par (std::function const & action_a) const diff --git a/nano/store/rocksdb/rocksdb.cpp b/nano/store/rocksdb/rocksdb.cpp index a739bc325..fe6026fdf 100644 --- a/nano/store/rocksdb/rocksdb.cpp +++ b/nano/store/rocksdb/rocksdb.cpp @@ -302,8 +302,8 @@ void nano::store::rocksdb::component::upgrade_v22_to_v23 (store::write_transacti auto transaction = tx_begin_read (); // Manually create v22 compatible iterator to read accounts - auto it = make_iterator (transaction, tables::accounts); - auto const end = store::iterator (nullptr); + auto it = typed_iterator (store::iterator{ rocksdb::iterator::begin (db.get (), rocksdb::tx (transaction), table_to_column_family (tables::accounts)) }); + auto const end = typed_iterator{ store::iterator{ rocksdb::iterator::end (db.get (), rocksdb::tx (transaction), table_to_column_family (tables::accounts)) } }; for (; it != end; ++it) { diff --git a/nano/store/rocksdb/rocksdb.hpp b/nano/store/rocksdb/rocksdb.hpp index 493a26fff..bd5cb6a79 100644 --- a/nano/store/rocksdb/rocksdb.hpp +++ b/nano/store/rocksdb/rocksdb.hpp @@ -85,18 +85,6 @@ public: unsigned max_block_write_batch_num () const override; - template - store::iterator make_iterator (store::transaction const & transaction_a, tables table_a, bool const direction_asc = true) const - { - return store::iterator (std::make_unique> (db.get (), transaction_a, table_to_column_family (table_a), nullptr, direction_asc)); - } - - template - store::iterator make_iterator (store::transaction const & transaction_a, tables table_a, nano::store::rocksdb::db_val const & key) const - { - return store::iterator (std::make_unique> (db.get (), transaction_a, table_to_column_family (table_a), &key, true)); - } - bool init_error () const override; std::string error_string (int status) const override; diff --git a/nano/store/typed_iterator.cpp b/nano/store/typed_iterator.cpp new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/nano/store/typed_iterator.cpp @@ -0,0 +1 @@ + diff --git a/nano/store/typed_iterator.hpp b/nano/store/typed_iterator.hpp new file mode 100644 index 000000000..47f3f2e9d --- /dev/null +++ b/nano/store/typed_iterator.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include + +namespace nano::store +{ +/** + * @class typed_iterator + * @brief A generic typed iterator for key-value stores. + * + * This class represents a typed iterator for key-value store databases, such as RocksDB. + * It supports typing for both keys and values, providing type-safe access to the database contents. + * + * Key characteristics: + * - Generic: Works with various key-value store implementations. + * - Type-safe: Supports strongly typed keys and values. + * - Circular: The end() sentinel value is always in the iteration cycle. + * - Automatic deserialization: When pointing to a valid non-sentinel location, it loads and + * deserializes the database value into the appropriate type. + * + * Behavior: + * - Decrementing the end iterator points to the last key-value pair in the database. + * - Incrementing the end iterator points to the first key-value pair in the database. + */ +template +class typed_iterator final +{ +public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::pair; + using pointer = value_type *; + using const_pointer = value_type const *; + using reference = value_type &; + using const_reference = value_type const &; + +private: + iterator iter; + std::variant current; + void update (); + +public: + typed_iterator (iterator && iter) noexcept; + + typed_iterator (typed_iterator const &) = delete; + auto operator= (typed_iterator const &) -> typed_iterator & = delete; + + typed_iterator (typed_iterator && other) noexcept; + auto operator= (typed_iterator && other) noexcept -> typed_iterator &; + + auto operator++ () -> typed_iterator &; + auto operator-- () -> typed_iterator &; + auto operator->() const -> const_pointer; + auto operator* () const -> const_reference; + auto operator== (typed_iterator const & other) const -> bool; + auto is_end () const -> bool; +}; +} // namespace nano::store diff --git a/nano/store/typed_iterator_templ.hpp b/nano/store/typed_iterator_templ.hpp new file mode 100644 index 000000000..9ce464c16 --- /dev/null +++ b/nano/store/typed_iterator_templ.hpp @@ -0,0 +1,88 @@ +#include +#include +#include +#include + +namespace nano::store +{ +template +void typed_iterator::update () +{ + if (!iter.is_end ()) + { + // FIXME Don't convert via lmdb::db_val, this is just a placeholder + auto const & data = *iter; + lmdb::db_val key_val{ MDB_val{ data.first.size (), const_cast (reinterpret_cast (data.first.data ())) } }; + lmdb::db_val value_val{ MDB_val{ data.second.size (), const_cast (reinterpret_cast (data.second.data ())) } }; + current = std::make_pair (static_cast (key_val), static_cast (value_val)); + } + else + { + current = std::monostate{}; + } +} + +template +typed_iterator::typed_iterator (iterator && iter) noexcept : + iter{ std::move (iter) } +{ + update (); +} + +template +typed_iterator::typed_iterator (typed_iterator && other) noexcept : + iter{ std::move (other.iter) }, + current{ std::move (other.current) } +{ +} + +template +auto typed_iterator::operator= (typed_iterator && other) noexcept -> typed_iterator & +{ + iter = std::move (other.iter); + current = std::move (other.current); + return *this; +} + +template +auto typed_iterator::operator++ () -> typed_iterator & +{ + ++iter; + update (); + return *this; +} + +template +auto typed_iterator::operator-- () -> typed_iterator & +{ + --iter; + update (); + return *this; +} + +template +auto typed_iterator::operator->() const -> const_pointer +{ + release_assert (!is_end ()); + return std::get_if (¤t); +} + +template +auto typed_iterator::operator* () const -> const_reference +{ + release_assert (!is_end ()); + return std::get (current); +} + +template +auto typed_iterator::operator== (typed_iterator const & other) const -> bool +{ + return iter == other.iter; +} + +template +auto typed_iterator::is_end () const -> bool +{ + return std::holds_alternative (current); +} +} From 968092351d95ea25550cd84fa484db2026176604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Sun, 27 Oct 2024 11:20:58 +0100 Subject: [PATCH 43/48] Modify `observer_set` to only accept and pass const ref arguments --- nano/lib/observer_set.hpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/nano/lib/observer_set.hpp b/nano/lib/observer_set.hpp index cc4e02e9c..5630515fa 100644 --- a/nano/lib/observer_set.hpp +++ b/nano/lib/observer_set.hpp @@ -12,21 +12,25 @@ template class observer_set final { public: - void add (std::function const & observer_a) + using observer_type = std::function; + +public: + void add (observer_type observer) { nano::lock_guard lock{ mutex }; - observers.push_back (observer_a); + observers.push_back (observer); } - void notify (T... args) const + void notify (T const &... args) const { + // Make observers copy to allow parallel notifications nano::unique_lock lock{ mutex }; auto observers_copy = observers; lock.unlock (); - for (auto & i : observers_copy) + for (auto const & observer : observers_copy) { - i (args...); + observer (args...); } } @@ -53,7 +57,7 @@ public: private: mutable nano::mutex mutex{ mutex_identifier (mutexes::observer_set) }; - std::vector> observers; + std::vector observers; }; } From dd668ad1880e5b1d90b16f0db429384ec77e4771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Sun, 27 Oct 2024 11:35:03 +0100 Subject: [PATCH 44/48] Tests --- nano/core_test/CMakeLists.txt | 1 + nano/core_test/observer_set.cpp | 129 ++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 nano/core_test/observer_set.cpp diff --git a/nano/core_test/CMakeLists.txt b/nano/core_test/CMakeLists.txt index 1d01f6e79..84b3ec16d 100644 --- a/nano/core_test/CMakeLists.txt +++ b/nano/core_test/CMakeLists.txt @@ -37,6 +37,7 @@ add_executable( node.cpp numbers.cpp object_stream.cpp + observer_set.cpp optimistic_scheduler.cpp processing_queue.cpp processor_service.cpp diff --git a/nano/core_test/observer_set.cpp b/nano/core_test/observer_set.cpp new file mode 100644 index 000000000..14c6d1301 --- /dev/null +++ b/nano/core_test/observer_set.cpp @@ -0,0 +1,129 @@ +#include +#include + +#include + +#include +#include + +using namespace std::chrono_literals; + +TEST (observer_set, notify_one) +{ + nano::observer_set set; + int value{ 0 }; + set.add ([&value] (int v) { + value = v; + }); + set.notify (1); + ASSERT_EQ (1, value); +} + +TEST (observer_set, notify_multiple) +{ + nano::observer_set set; + int value{ 0 }; + set.add ([&value] (int v) { + value = v; + }); + set.add ([&value] (int v) { + value += v; + }); + set.notify (1); + ASSERT_EQ (2, value); +} + +TEST (observer_set, notify_empty) +{ + nano::observer_set set; + set.notify (1); +} + +TEST (observer_set, notify_multiple_types) +{ + nano::observer_set set; + int value{ 0 }; + std::string str; + set.add ([&value, &str] (int v, std::string s) { + value = v; + str = s; + }); + set.notify (1, "test"); + ASSERT_EQ (1, value); + ASSERT_EQ ("test", str); +} + +TEST (observer_set, empty_params) +{ + nano::observer_set<> set; + set.notify (); +} + +// Make sure there are no TSAN warnings +TEST (observer_set, parallel_notify) +{ + nano::observer_set set; + std::atomic value{ 0 }; + set.add ([&value] (int v) { + std::this_thread::sleep_for (100ms); + value = v; + }); + nano::timer timer{ nano::timer_state::started }; + std::vector threads; + for (int i = 0; i < 10; ++i) + { + threads.emplace_back ([&set] { + set.notify (1); + }); + } + for (auto & thread : threads) + { + thread.join (); + } + ASSERT_EQ (1, value); + // Notification should be done in parallel + ASSERT_LT (timer.since_start (), 300ms); +} + +namespace +{ +struct move_only +{ + move_only () = default; + move_only (move_only &&) = default; + move_only & operator= (move_only &&) = default; + move_only (move_only const &) = delete; + move_only & operator= (move_only const &) = delete; +}; + +struct copy_throw +{ + copy_throw () = default; + copy_throw (copy_throw &&) = default; + copy_throw & operator= (copy_throw &&) = default; + copy_throw (copy_throw const &) + { + throw std::runtime_error ("copy_throw"); + } + copy_throw & operator= (copy_throw const &) = delete; +}; +} + +// Ensure that parameters are not unnecessarily copied, this should compile +TEST (observer_set, move_only) +{ + nano::observer_set set; + set.add ([] (move_only const &) { + }); + move_only value; + set.notify (value); +} + +TEST (observer_set, copy_throw) +{ + nano::observer_set set; + set.add ([] (copy_throw const &) { + }); + copy_throw value; + ASSERT_NO_THROW (set.notify (value)); +} \ No newline at end of file From 47539ac7181a8ea8d66dc3a04d87282b9176efcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20W=C3=B3jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Sun, 27 Oct 2024 12:46:34 +0100 Subject: [PATCH 45/48] Enable reporting memory leaks when running sanitizers (#4769) --- .github/workflows/code_sanitizers.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code_sanitizers.yml b/.github/workflows/code_sanitizers.yml index 1a6ae97b7..9e9e7d6cd 100644 --- a/.github/workflows/code_sanitizers.yml +++ b/.github/workflows/code_sanitizers.yml @@ -16,7 +16,7 @@ jobs: - { name: ASAN, ignore_errors: false, leak_check: false } - { name: ASAN_INT, ignore_errors: true, leak_check: false } - { name: TSAN, ignore_errors: false } - - { name: LEAK, ignore_errors: true, leak_check: true } + - { name: LEAK, ignore_errors: false, leak_check: true } exclude: # Bug when running with TSAN: "ThreadSanitizer: CHECK failed: sanitizer_deadlock_detector" - BACKEND: rocksdb From 1fce19b3e92bc4077ca9896f5ed51aa48071ae83 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Sun, 27 Oct 2024 11:50:03 +0000 Subject: [PATCH 46/48] Fixing leak where cursor would not be closed before being overwritten. --- nano/store/lmdb/iterator.cpp | 21 +++++++-------------- nano/store/lmdb/iterator.hpp | 4 +--- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/nano/store/lmdb/iterator.cpp b/nano/store/lmdb/iterator.cpp index 76cfc35e5..5fc87d1d0 100644 --- a/nano/store/lmdb/iterator.cpp +++ b/nano/store/lmdb/iterator.cpp @@ -21,7 +21,7 @@ void iterator::update (int status) if (status == MDB_SUCCESS) { value_type init; - auto status = mdb_cursor_get (cursor, &init.first, &init.second, MDB_GET_CURRENT); + auto status = mdb_cursor_get (cursor.get (), &init.first, &init.second, MDB_GET_CURRENT); release_assert (status == MDB_SUCCESS); current = init; } @@ -33,8 +33,10 @@ void iterator::update (int status) iterator::iterator (MDB_txn * tx, MDB_dbi dbi) noexcept { + MDB_cursor * cursor; auto open_status = mdb_cursor_open (tx, dbi, &cursor); release_assert (open_status == MDB_SUCCESS); + this->cursor.reset (cursor); this->current = std::monostate{}; } @@ -53,7 +55,7 @@ auto iterator::end (MDB_txn * tx, MDB_dbi dbi) -> iterator auto iterator::lower_bound (MDB_txn * tx, MDB_dbi dbi, MDB_val const & lower_bound) -> iterator { iterator result{ tx, dbi }; - auto status = mdb_cursor_get (result.cursor, const_cast (&lower_bound), nullptr, MDB_SET_RANGE); + auto status = mdb_cursor_get (result.cursor.get (), const_cast (&lower_bound), nullptr, MDB_SET_RANGE); result.update (status); return std::move (result); } @@ -63,18 +65,9 @@ iterator::iterator (iterator && other) noexcept *this = std::move (other); } -iterator::~iterator () -{ - if (cursor) - { - mdb_cursor_close (cursor); - } -} - auto iterator::operator= (iterator && other) noexcept -> iterator & { - cursor = other.cursor; - other.cursor = nullptr; + cursor = std::move (other.cursor); current = other.current; other.current = std::monostate{}; return *this; @@ -83,7 +76,7 @@ auto iterator::operator= (iterator && other) noexcept -> iterator & auto iterator::operator++ () -> iterator & { auto operation = is_end () ? MDB_FIRST : MDB_NEXT; - auto status = mdb_cursor_get (cursor, nullptr, nullptr, operation); + auto status = mdb_cursor_get (cursor.get (), nullptr, nullptr, operation); release_assert (status == MDB_SUCCESS || status == MDB_NOTFOUND); update (status); return *this; @@ -92,7 +85,7 @@ auto iterator::operator++ () -> iterator & auto iterator::operator-- () -> iterator & { auto operation = is_end () ? MDB_LAST : MDB_PREV; - auto status = mdb_cursor_get (cursor, nullptr, nullptr, operation); + auto status = mdb_cursor_get (cursor.get (), nullptr, nullptr, operation); release_assert (status == MDB_SUCCESS || status == MDB_NOTFOUND); update (status); return *this; diff --git a/nano/store/lmdb/iterator.hpp b/nano/store/lmdb/iterator.hpp index ff921ca3a..da2280adf 100644 --- a/nano/store/lmdb/iterator.hpp +++ b/nano/store/lmdb/iterator.hpp @@ -22,7 +22,7 @@ namespace nano::store::lmdb */ class iterator { - MDB_cursor * cursor{ nullptr }; + std::unique_ptr cursor{ nullptr, mdb_cursor_close }; std::variant> current; void update (int status); iterator (MDB_txn * tx, MDB_dbi dbi) noexcept; @@ -39,8 +39,6 @@ public: static auto end (MDB_txn * tx, MDB_dbi dbi) -> iterator; static auto lower_bound (MDB_txn * tx, MDB_dbi dbi, MDB_val const & lower_bound) -> iterator; - ~iterator (); - iterator (iterator const &) = delete; auto operator= (iterator const &) -> iterator & = delete; From 5ca6ff70dcdc0ede4eb054f7e7f1dde366e0bf53 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Sun, 27 Oct 2024 14:05:06 +0000 Subject: [PATCH 47/48] Making use of unique_ptr to ensure environment handle never leaks. --- nano/store/lmdb/lmdb.cpp | 8 +++----- nano/store/lmdb/lmdb_env.cpp | 9 ++++----- nano/store/lmdb/lmdb_env.hpp | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/nano/store/lmdb/lmdb.cpp b/nano/store/lmdb/lmdb.cpp index a16d53cb8..07bbc34de 100644 --- a/nano/store/lmdb/lmdb.cpp +++ b/nano/store/lmdb/lmdb.cpp @@ -121,9 +121,7 @@ bool nano::store::lmdb::component::vacuum_after_upgrade (std::filesystem::path c if (vacuum_success) { // Need to close the database to release the file handle - mdb_env_sync (env.environment, true); - mdb_env_close (env.environment); - env.environment = nullptr; + mdb_env_sync (env, true); // Replace the ledger file with the vacuumed one std::filesystem::rename (vacuum_path, path_a); @@ -155,7 +153,7 @@ void nano::store::lmdb::component::serialize_mdb_tracker (boost::property_tree:: void nano::store::lmdb::component::serialize_memory_stats (boost::property_tree::ptree & json) { MDB_stat stats; - auto status (mdb_env_stat (env.environment, &stats)); + auto status (mdb_env_stat (env, &stats)); release_assert (status == 0); json.put ("branch_pages", stats.ms_branch_pages); json.put ("depth", stats.ms_depth); @@ -448,7 +446,7 @@ std::string nano::store::lmdb::component::error_string (int status) const bool nano::store::lmdb::component::copy_db (std::filesystem::path const & destination_file) { - return !mdb_env_copy2 (env.environment, destination_file.string ().c_str (), MDB_CP_COMPACT); + return !mdb_env_copy2 (env, destination_file.string ().c_str (), MDB_CP_COMPACT); } void nano::store::lmdb::component::rebuild_db (store::write_transaction const & transaction_a) diff --git a/nano/store/lmdb/lmdb_env.cpp b/nano/store/lmdb/lmdb_env.cpp index cd1897c80..b30718960 100644 --- a/nano/store/lmdb/lmdb_env.cpp +++ b/nano/store/lmdb/lmdb_env.cpp @@ -19,8 +19,10 @@ void nano::store::lmdb::env::init (bool & error_a, std::filesystem::path const & nano::set_secure_perm_directory (path_a.parent_path (), error_chmod); if (!error_mkdir) { + MDB_env * environment; auto status1 (mdb_env_create (&environment)); release_assert (status1 == 0); + this->environment.reset (environment); auto status2 (mdb_env_set_maxdbs (environment, options_a.config.max_databases)); release_assert (status2 == 0); auto map_size = options_a.config.map_size; @@ -66,13 +68,11 @@ void nano::store::lmdb::env::init (bool & error_a, std::filesystem::path const & else { error_a = true; - environment = nullptr; } } else { error_a = true; - environment = nullptr; } } @@ -81,14 +81,13 @@ nano::store::lmdb::env::~env () if (environment != nullptr) { // Make sure the commits are flushed. This is a no-op unless MDB_NOSYNC is used. - mdb_env_sync (environment, true); - mdb_env_close (environment); + mdb_env_sync (environment.get (), true); } } nano::store::lmdb::env::operator MDB_env * () const { - return environment; + return environment.get (); } nano::store::read_transaction nano::store::lmdb::env::tx_begin_read (store::lmdb::txn_callbacks mdb_txn_callbacks) const diff --git a/nano/store/lmdb/lmdb_env.hpp b/nano/store/lmdb/lmdb_env.hpp index e91265325..07e89ffd2 100644 --- a/nano/store/lmdb/lmdb_env.hpp +++ b/nano/store/lmdb/lmdb_env.hpp @@ -62,7 +62,7 @@ public: store::read_transaction tx_begin_read (txn_callbacks callbacks = txn_callbacks{}) const; store::write_transaction tx_begin_write (txn_callbacks callbacks = txn_callbacks{}) const; MDB_txn * tx (store::transaction const & transaction_a) const; - MDB_env * environment; + std::unique_ptr environment{ nullptr, mdb_env_close }; nano::id_t const store_id{ nano::next_id () }; }; } // namespace nano::store::lmdb From 104b74d2e573d4b995b0d31db64991c8d77436a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20W=C3=B3jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:17:45 +0100 Subject: [PATCH 48/48] Offload block processor notifications (#4763) * Issue block processor batch processed notifications on background thread * Remove `should_log` function * Move `block_processor::context` source to the bottom of the file * Remove unnecessary notify --- nano/lib/thread_roles.cpp | 3 + nano/lib/thread_roles.hpp | 1 + nano/node/blockprocessor.cpp | 115 ++++++++++++---------- nano/node/blockprocessor.hpp | 9 +- nano/node/bootstrap_ascending/service.cpp | 10 +- nano/node/confirming_set.cpp | 13 +-- nano/node/confirming_set.hpp | 4 +- 7 files changed, 86 insertions(+), 69 deletions(-) diff --git a/nano/lib/thread_roles.cpp b/nano/lib/thread_roles.cpp index 76f467cd0..ff6831b4d 100644 --- a/nano/lib/thread_roles.cpp +++ b/nano/lib/thread_roles.cpp @@ -37,6 +37,9 @@ std::string nano::thread_role::get_string (nano::thread_role::name role) case nano::thread_role::name::block_processing: thread_role_name_string = "Blck processing"; break; + case nano::thread_role::name::block_processing_notifications: + thread_role_name_string = "Blck proc notif"; + break; case nano::thread_role::name::request_loop: thread_role_name_string = "Request loop"; break; diff --git a/nano/lib/thread_roles.hpp b/nano/lib/thread_roles.hpp index 5896318c4..a82a58472 100644 --- a/nano/lib/thread_roles.hpp +++ b/nano/lib/thread_roles.hpp @@ -17,6 +17,7 @@ enum class name vote_processing, vote_cache_processing, block_processing, + block_processing_notifications, request_loop, wallet_actions, bootstrap_initiator, diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index d0e871649..34d6956a8 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -12,36 +12,14 @@ #include -/* - * block_processor::context - */ - -nano::block_processor::context::context (std::shared_ptr block, nano::block_source source_a, callback_t callback_a) : - block{ std::move (block) }, - source{ source_a }, - callback{ std::move (callback_a) } -{ - debug_assert (source != nano::block_source::unknown); -} - -auto nano::block_processor::context::get_future () -> std::future -{ - return promise.get_future (); -} - -void nano::block_processor::context::set_result (result_t const & result) -{ - promise.set_value (result); -} - /* * block_processor */ nano::block_processor::block_processor (nano::node & node_a) : config{ node_a.config.block_processor }, - node (node_a), - next_log (std::chrono::steady_clock::now ()) + node{ node_a }, + workers{ 1, nano::thread_role::name::block_processing_notifications } { batch_processed.add ([this] (auto const & items) { // For every batch item: notify the 'processed' observer. @@ -84,12 +62,15 @@ nano::block_processor::~block_processor () { // Thread must be stopped before destruction debug_assert (!thread.joinable ()); + debug_assert (!workers.alive ()); } void nano::block_processor::start () { debug_assert (!thread.joinable ()); + workers.start (); + thread = std::thread ([this] () { nano::thread_role::set (nano::thread_role::name::block_processing); run (); @@ -107,6 +88,7 @@ void nano::block_processor::stop () { thread.join (); } + workers.stop (); } // TODO: Remove and replace all checks with calls to size (block_source) @@ -229,13 +211,24 @@ void nano::block_processor::rollback_competitor (secure::write_transaction const void nano::block_processor::run () { + nano::interval log_interval; nano::unique_lock lock{ mutex }; while (!stopped) { if (!queue.empty ()) { - // TODO: Cleaner periodical logging - if (should_log ()) + // It's possible that ledger processing happens faster than the notifications can be processed by other components, cooldown here + while (workers.queued_tasks () >= config.max_queued_notifications) + { + node.stats.inc (nano::stat::type::blockprocessor, nano::stat::detail::cooldown); + condition.wait_for (lock, 100ms, [this] { return stopped; }); + if (stopped) + { + return; + } + } + + if (log_interval.elapsed (15s)) { node.logger.info (nano::log::type::blockprocessor, "{} blocks (+ {} forced) in processing queue", queue.size (), @@ -244,41 +237,32 @@ void nano::block_processor::run () auto processed = process_batch (lock); debug_assert (!lock.owns_lock ()); - - // Set results for futures when not holding the lock - for (auto & [result, context] : processed) - { - if (context.callback) - { - context.callback (result); - } - context.set_result (result); - } - - batch_processed.notify (processed); - lock.lock (); + + // Queue notifications to be dispatched in the background + workers.post ([this, processed = std::move (processed)] () mutable { + node.stats.inc (nano::stat::type::blockprocessor, nano::stat::detail::notify); + // Set results for futures when not holding the lock + for (auto & [result, context] : processed) + { + if (context.callback) + { + context.callback (result); + } + context.set_result (result); + } + batch_processed.notify (processed); + }); } else { - condition.notify_one (); - condition.wait (lock); + condition.wait (lock, [this] { + return stopped || !queue.empty (); + }); } } } -bool nano::block_processor::should_log () -{ - auto result (false); - auto now (std::chrono::steady_clock::now ()); - if (next_log < now) - { - next_log = now + std::chrono::seconds (15); - result = true; - } - return result; -} - auto nano::block_processor::next () -> context { debug_assert (!mutex.try_lock ()); @@ -315,7 +299,7 @@ auto nano::block_processor::process_batch (nano::unique_lock & lock debug_assert (!mutex.try_lock ()); debug_assert (!queue.empty ()); - auto batch = next_batch (256); + auto batch = next_batch (config.batch_size); lock.unlock (); @@ -466,9 +450,32 @@ nano::container_info nano::block_processor::container_info () const info.put ("blocks", queue.size ()); info.put ("forced", queue.size ({ nano::block_source::forced })); info.add ("queue", queue.container_info ()); + info.add ("workers", workers.container_info ()); return info; } +/* + * block_processor::context + */ + +nano::block_processor::context::context (std::shared_ptr block, nano::block_source source_a, callback_t callback_a) : + block{ std::move (block) }, + source{ source_a }, + callback{ std::move (callback_a) } +{ + debug_assert (source != nano::block_source::unknown); +} + +auto nano::block_processor::context::get_future () -> std::future +{ + return promise.get_future (); +} + +void nano::block_processor::context::set_result (result_t const & result) +{ + promise.set_value (result); +} + /* * block_processor_config */ diff --git a/nano/node/blockprocessor.hpp b/nano/node/blockprocessor.hpp index 837631b0b..cb54711b0 100644 --- a/nano/node/blockprocessor.hpp +++ b/nano/node/blockprocessor.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -46,6 +47,9 @@ public: size_t priority_live{ 1 }; size_t priority_bootstrap{ 8 }; size_t priority_local{ 16 }; + + size_t batch_size{ 256 }; + size_t max_queued_notifications{ 8 }; }; /** @@ -89,7 +93,6 @@ public: bool add (std::shared_ptr const &, nano::block_source = nano::block_source::live, std::shared_ptr const & channel = nullptr, std::function callback = {}); std::optional add_blocking (std::shared_ptr const & block, nano::block_source); void force (std::shared_ptr const &); - bool should_log (); nano::container_info container_info () const; @@ -122,11 +125,11 @@ private: // Dependencies private: nano::fair_queue queue; - std::chrono::steady_clock::time_point next_log; - bool stopped{ false }; nano::condition_variable condition; mutable nano::mutex mutex{ mutex_identifier (mutexes::block_processor) }; std::thread thread; + + nano::thread_pool workers; }; } diff --git a/nano/node/bootstrap_ascending/service.cpp b/nano/node/bootstrap_ascending/service.cpp index 661072b44..bb6f4183e 100644 --- a/nano/node/bootstrap_ascending/service.cpp +++ b/nano/node/bootstrap_ascending/service.cpp @@ -33,7 +33,6 @@ nano::bootstrap_ascending::service::service (nano::node_config const & node_conf scoring{ config, node_config_a.network_params.network }, database_limiter{ config.database_rate_limit, 1.0 } { - // TODO: This is called from a very congested blockprocessor thread. Offload this work to a dedicated processing thread block_processor.batch_processed.add ([this] (auto const & batch) { { nano::lock_guard lock{ mutex }; @@ -217,11 +216,14 @@ void nano::bootstrap_ascending::service::inspect (secure::transaction const & tx { if (source == nano::block_source::bootstrap) { - const auto account = block.previous ().is_zero () ? block.account_field ().value () : ledger.any.block_account (tx, block.previous ()).value (); + const auto account = block.previous ().is_zero () ? block.account_field ().value () : ledger.any.block_account (tx, block.previous ()).value_or (0); const auto source_hash = block.source_field ().value_or (block.link_field ().value_or (0).as_block_hash ()); - // Mark account as blocked because it is missing the source block - accounts.block (account, source_hash); + if (!account.is_zero () && !source_hash.is_zero ()) + { + // Mark account as blocked because it is missing the source block + accounts.block (account, source_hash); + } } } break; diff --git a/nano/node/confirming_set.cpp b/nano/node/confirming_set.cpp index e504b0aca..2921881b5 100644 --- a/nano/node/confirming_set.cpp +++ b/nano/node/confirming_set.cpp @@ -12,7 +12,7 @@ nano::confirming_set::confirming_set (confirming_set_config const & config_a, na ledger{ ledger_a }, stats{ stats_a }, logger{ logger_a }, - notification_workers{ 1, nano::thread_role::name::confirmation_height_notifications } + workers{ 1, nano::thread_role::name::confirmation_height_notifications } { batch_cemented.add ([this] (auto const & cemented) { for (auto const & context : cemented) @@ -55,7 +55,7 @@ void nano::confirming_set::start () return; } - notification_workers.start (); + workers.start (); thread = std::thread{ [this] () { nano::thread_role::set (nano::thread_role::name::confirmation_height); @@ -74,7 +74,7 @@ void nano::confirming_set::stop () { thread.join (); } - notification_workers.stop (); + workers.stop (); } bool nano::confirming_set::contains (nano::block_hash const & hash) const @@ -150,7 +150,7 @@ void nano::confirming_set::run_batch (std::unique_lock & lock) std::unique_lock lock{ mutex }; // It's possible that ledger cementing happens faster than the notifications can be processed by other components, cooldown here - while (notification_workers.queued_tasks () >= config.max_queued_notifications) + while (workers.queued_tasks () >= config.max_queued_notifications) { stats.inc (nano::stat::type::confirming_set, nano::stat::detail::cooldown); condition.wait_for (lock, 100ms, [this] { return stopped.load (); }); @@ -160,7 +160,7 @@ void nano::confirming_set::run_batch (std::unique_lock & lock) } } - notification_workers.post ([this, batch = std::move (batch)] () { + workers.post ([this, batch = std::move (batch)] () { stats.inc (nano::stat::type::confirming_set, nano::stat::detail::notify); batch_cemented.notify (batch); }); @@ -255,6 +255,7 @@ nano::container_info nano::confirming_set::container_info () const nano::container_info info; info.put ("set", set); - info.add ("notification_workers", notification_workers.container_info ()); + info.put ("notifications", workers.queued_tasks ()); + info.add ("workers", workers.container_info ()); return info; } diff --git a/nano/node/confirming_set.hpp b/nano/node/confirming_set.hpp index 99569ce1e..644b241c9 100644 --- a/nano/node/confirming_set.hpp +++ b/nano/node/confirming_set.hpp @@ -105,11 +105,11 @@ private: ordered_entries set; std::unordered_set current; - nano::thread_pool notification_workers; - std::atomic stopped{ false }; mutable std::mutex mutex; std::condition_variable condition; std::thread thread; + + nano::thread_pool workers; }; }