diff --git a/nano/node/bootstrap/bootstrap.cpp b/nano/node/bootstrap/bootstrap.cpp index 1e1d39c3..f12f9d6b 100644 --- a/nano/node/bootstrap/bootstrap.cpp +++ b/nano/node/bootstrap/bootstrap.cpp @@ -884,6 +884,7 @@ void nano::bootstrap_attempt::lazy_pull_flush () batch_count = std::max (node->network_params.bootstrap.lazy_min_pull_blocks, batch_count_min); } } + uint64_t read_count (0); size_t count (0); auto transaction (node->store.tx_begin_read ()); while (!lazy_pulls.empty () && count < max_pulls) @@ -896,6 +897,12 @@ void nano::bootstrap_attempt::lazy_pull_flush () ++count; } lazy_pulls.pop_front (); + // We don't want to open read transactions for too long + ++read_count; + if (read_count % batch_read_size == 0) + { + transaction.refresh (); + } } } } @@ -907,6 +914,7 @@ bool nano::bootstrap_attempt::lazy_finished () return true; } bool result (true); + uint64_t read_count (0); auto transaction (node->store.tx_begin_read ()); nano::lock_guard lazy_lock (lazy_mutex); for (auto it (lazy_keys.begin ()), end (lazy_keys.end ()); it != end && !stopped;) @@ -921,6 +929,12 @@ bool nano::bootstrap_attempt::lazy_finished () break; // No need to increment `it` as we break above. } + // We don't want to open read transactions for too long + ++read_count; + if (read_count % batch_read_size == 0) + { + transaction.refresh (); + } } // Finish lazy bootstrap without lazy pulls (in combination with still_pulling ()) if (!result && lazy_pulls.empty () && lazy_state_backlog.empty ()) @@ -1201,6 +1215,7 @@ void nano::bootstrap_attempt::lazy_block_state_backlog_check (std::shared_ptrstore.tx_begin_read ()); nano::lock_guard lazy_lock (lazy_mutex); for (auto it (lazy_state_backlog.begin ()), end (lazy_state_backlog.end ()); it != end && !stopped;) @@ -1223,6 +1238,12 @@ void nano::bootstrap_attempt::lazy_backlog_cleanup () lazy_add (it->first, it->second.retry_limit); ++it; } + // We don't want to open read transactions for too long + ++read_count; + if (read_count % batch_read_size == 0) + { + transaction.refresh (); + } } } diff --git a/nano/node/bootstrap/bootstrap.hpp b/nano/node/bootstrap/bootstrap.hpp index 0ab83194..e4377928 100644 --- a/nano/node/bootstrap/bootstrap.hpp +++ b/nano/node/bootstrap/bootstrap.hpp @@ -164,6 +164,8 @@ public: std::mutex lazy_mutex; // Wallet lazy bootstrap std::deque wallet_accounts; + /** The maximum number of records to be read in while iterating over long lazy containers */ + static uint64_t constexpr batch_read_size = 256; }; class bootstrap_client final : public std::enable_shared_from_this { diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.cpp b/nano/node/bootstrap/bootstrap_bulk_pull.cpp index af887bf7..58e60bf0 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.cpp @@ -366,8 +366,7 @@ void nano::bulk_pull_account_client::receive_pending () { if (!pending.is_zero ()) { - auto transaction (this_l->connection->node->store.tx_begin_read ()); - if (!this_l->connection->node->store.block_exists (transaction, pending)) + if (!this_l->connection->node->ledger.block_exists (pending)) { this_l->connection->attempt->lazy_start (pending); } @@ -552,8 +551,7 @@ std::shared_ptr nano::bulk_pull_server::get_next () if (send_current) { - auto transaction (connection->node->store.tx_begin_read ()); - result = connection->node->store.block_get (transaction, current); + result = connection->node->block (current); if (result != nullptr && set_current_to_end == false) { auto previous (result->previous ()); diff --git a/nano/node/bootstrap/bootstrap_bulk_push.cpp b/nano/node/bootstrap/bootstrap_bulk_push.cpp index 95eb49b6..a739eae0 100644 --- a/nano/node/bootstrap/bootstrap_bulk_push.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_push.cpp @@ -20,10 +20,9 @@ void nano::bulk_push_client::start () auto this_l (shared_from_this ()); connection->channel->send ( message, [this_l](boost::system::error_code const & ec, size_t size_a) { - auto transaction (this_l->connection->node->store.tx_begin_read ()); if (!ec) { - this_l->push (transaction); + this_l->push (); } else { @@ -36,7 +35,7 @@ void nano::bulk_push_client::start () false); // is bootstrap traffic is_droppable false } -void nano::bulk_push_client::push (nano::transaction const & transaction_a) +void nano::bulk_push_client::push () { std::shared_ptr block; bool finished (false); @@ -57,7 +56,7 @@ void nano::bulk_push_client::push (nano::transaction const & transaction_a) } if (!finished) { - block = connection->node->store.block_get (transaction_a, current_target.first); + block = connection->node->block (current_target.first); if (block == nullptr) { current_target.first = nano::block_hash (0); @@ -108,8 +107,7 @@ void nano::bulk_push_client::push_block (nano::block const & block_a) connection->channel->send_buffer (nano::shared_const_buffer (std::move (buffer)), nano::stat::detail::all, [this_l](boost::system::error_code const & ec, size_t size_a) { if (!ec) { - auto transaction (this_l->connection->node->store.tx_begin_read ()); - this_l->push (transaction); + this_l->push (); } else { diff --git a/nano/node/bootstrap/bootstrap_bulk_push.hpp b/nano/node/bootstrap/bootstrap_bulk_push.hpp index 114a0235..b84eaac6 100644 --- a/nano/node/bootstrap/bootstrap_bulk_push.hpp +++ b/nano/node/bootstrap/bootstrap_bulk_push.hpp @@ -6,7 +6,6 @@ namespace nano { -class transaction; class bootstrap_client; class bulk_push_client final : public std::enable_shared_from_this { @@ -14,7 +13,7 @@ public: explicit bulk_push_client (std::shared_ptr const &); ~bulk_push_client (); void start (); - void push (nano::transaction const &); + void push (); void push_block (nano::block const &); void send_finished (); std::shared_ptr connection; diff --git a/nano/node/bootstrap/bootstrap_frontier.cpp b/nano/node/bootstrap/bootstrap_frontier.cpp index ad51fed1..70918e87 100644 --- a/nano/node/bootstrap/bootstrap_frontier.cpp +++ b/nano/node/bootstrap/bootstrap_frontier.cpp @@ -42,8 +42,7 @@ current (0), count (0), bulk_push_cost (0) { - auto transaction (connection->node->store.tx_begin_read ()); - next (transaction); + next (); } nano::frontier_req_client::~frontier_req_client () @@ -123,14 +122,13 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con { connection->node->logger.always_log (boost::str (boost::format ("Received %1% frontiers from %2%") % std::to_string (count) % connection->channel->to_string ())); } - auto transaction (connection->node->store.tx_begin_read ()); if (!account.is_zero ()) { while (!current.is_zero () && current < account) { // We know about an account they don't. unsynced (frontier, 0); - next (transaction); + next (); } if (!current.is_zero ()) { @@ -142,7 +140,7 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con } else { - if (connection->node->store.block_exists (transaction, latest)) + if (connection->node->ledger.block_exists (latest)) { // We know about a block they don't. unsynced (frontier, latest); @@ -155,7 +153,7 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con bulk_push_cost += 5; } } - next (transaction); + next (); } else { @@ -175,7 +173,7 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con { // We know about an account they don't. unsynced (frontier, 0); - next (transaction); + next (); } if (connection->node->config.logging.bulk_pull_logging ()) { @@ -202,13 +200,14 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con } } -void nano::frontier_req_client::next (nano::transaction const & transaction_a) +void nano::frontier_req_client::next () { // Filling accounts deque to prevent often read transactions if (accounts.empty ()) { size_t max_size (128); - for (auto i (connection->node->store.latest_begin (transaction_a, current.number () + 1)), n (connection->node->store.latest_end ()); i != n && accounts.size () != max_size; ++i) + auto transaction (connection->node->store.tx_begin_read ()); + for (auto i (connection->node->store.latest_begin (transaction, current.number () + 1)), n (connection->node->store.latest_end ()); i != n && accounts.size () != max_size; ++i) { nano::account_info const & info (i->second); nano::account const & account (i->first); diff --git a/nano/node/bootstrap/bootstrap_frontier.hpp b/nano/node/bootstrap/bootstrap_frontier.hpp index b6b788d0..ad3c4962 100644 --- a/nano/node/bootstrap/bootstrap_frontier.hpp +++ b/nano/node/bootstrap/bootstrap_frontier.hpp @@ -7,7 +7,6 @@ namespace nano { -class transaction; class bootstrap_client; class frontier_req_client final : public std::enable_shared_from_this { @@ -18,7 +17,7 @@ public: void receive_frontier (); void received_frontier (boost::system::error_code const &, size_t); void unsynced (nano::block_hash const &, nano::block_hash const &); - void next (nano::transaction const &); + void next (); std::shared_ptr connection; nano::account current; nano::block_hash frontier;