Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bootstrap cleanup #3809

Merged
merged 13 commits into from
May 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions nano/node/bootstrap/bootstrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <boost/format.hpp>

#include <algorithm>
#include <memory>

nano::bootstrap_initiator::bootstrap_initiator (nano::node & node_a) :
node (node_a)
Expand Down Expand Up @@ -233,16 +234,16 @@ std::shared_ptr<nano::bootstrap_attempt> nano::bootstrap_initiator::current_atte
return find_attempt (nano::bootstrap_mode::legacy);
}

std::shared_ptr<nano::bootstrap_attempt> nano::bootstrap_initiator::current_lazy_attempt ()
std::shared_ptr<nano::bootstrap_attempt_lazy> nano::bootstrap_initiator::current_lazy_attempt ()
{
nano::lock_guard<nano::mutex> lock (mutex);
return find_attempt (nano::bootstrap_mode::lazy);
return std::dynamic_pointer_cast<nano::bootstrap_attempt_lazy> (find_attempt (nano::bootstrap_mode::lazy));
}

std::shared_ptr<nano::bootstrap_attempt> nano::bootstrap_initiator::current_wallet_attempt ()
std::shared_ptr<nano::bootstrap_attempt_wallet> nano::bootstrap_initiator::current_wallet_attempt ()
{
nano::lock_guard<nano::mutex> lock (mutex);
return find_attempt (nano::bootstrap_mode::wallet_lazy);
return std::dynamic_pointer_cast<nano::bootstrap_attempt_wallet> (find_attempt (nano::bootstrap_mode::wallet_lazy));
}

void nano::bootstrap_initiator::stop_attempts ()
Expand Down
6 changes: 4 additions & 2 deletions nano/node/bootstrap/bootstrap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class bootstrap_attempts final
std::map<uint64_t, std::shared_ptr<nano::bootstrap_attempt>> attempts;
};

class bootstrap_attempt_lazy;
class bootstrap_attempt_wallet;
/**
* Client side portion to initiate bootstrap sessions. Prevents multiple legacy-type bootstrap sessions from being started at the same time. Does permit
* lazy/wallet bootstrap sessions to overlap with legacy sessions.
Expand All @@ -103,8 +105,8 @@ class bootstrap_initiator final
bool has_new_attempts ();
void remove_attempt (std::shared_ptr<nano::bootstrap_attempt>);
std::shared_ptr<nano::bootstrap_attempt> current_attempt ();
std::shared_ptr<nano::bootstrap_attempt> current_lazy_attempt ();
std::shared_ptr<nano::bootstrap_attempt> current_wallet_attempt ();
std::shared_ptr<nano::bootstrap_attempt_lazy> current_lazy_attempt ();
std::shared_ptr<nano::bootstrap_attempt_wallet> current_wallet_attempt ();
nano::pulls_cache cache;
nano::bootstrap_attempts attempts;
void stop ();
Expand Down
71 changes: 0 additions & 71 deletions nano/node/bootstrap/bootstrap_attempt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,27 +113,6 @@ std::string nano::bootstrap_attempt::mode_text ()
return mode_text;
}

void nano::bootstrap_attempt::add_frontier (nano::pull_info const &)
{
debug_assert (mode == nano::bootstrap_mode::legacy);
}

void nano::bootstrap_attempt::add_bulk_push_target (nano::block_hash const &, nano::block_hash const &)
{
debug_assert (mode == nano::bootstrap_mode::legacy);
}

bool nano::bootstrap_attempt::request_bulk_push_target (std::pair<nano::block_hash, nano::block_hash> &)
{
debug_assert (mode == nano::bootstrap_mode::legacy);
return true;
}

void nano::bootstrap_attempt::set_start_account (nano::account const &)
{
debug_assert (mode == nano::bootstrap_mode::legacy);
}

bool nano::bootstrap_attempt::process_block (std::shared_ptr<nano::block> const & block_a, nano::account const & known_account_a, uint64_t pull_blocks_processed, nano::bulk_pull::count_t max_blocks, bool block_expected, unsigned retry_limit)
{
bool stop_pull (false);
Expand All @@ -149,53 +128,3 @@ bool nano::bootstrap_attempt::process_block (std::shared_ptr<nano::block> const
}
return stop_pull;
}

bool nano::bootstrap_attempt::lazy_start (nano::hash_or_account const &, bool)
{
debug_assert (mode == nano::bootstrap_mode::lazy);
return false;
}

void nano::bootstrap_attempt::lazy_add (nano::pull_info const &)
{
debug_assert (mode == nano::bootstrap_mode::lazy);
}

void nano::bootstrap_attempt::lazy_requeue (nano::block_hash const &, nano::block_hash const &)
{
debug_assert (mode == nano::bootstrap_mode::lazy);
}

uint32_t nano::bootstrap_attempt::lazy_batch_size ()
{
debug_assert (mode == nano::bootstrap_mode::lazy);
return node->network_params.bootstrap.lazy_min_pull_blocks;
}

bool nano::bootstrap_attempt::lazy_processed_or_exists (nano::block_hash const &)
{
debug_assert (mode == nano::bootstrap_mode::lazy);
return false;
}

bool nano::bootstrap_attempt::lazy_has_expired () const
{
debug_assert (mode == nano::bootstrap_mode::lazy);
return true;
}

void nano::bootstrap_attempt::requeue_pending (nano::account const &)
{
debug_assert (mode == nano::bootstrap_mode::wallet_lazy);
}

void nano::bootstrap_attempt::wallet_start (std::deque<nano::account> &)
{
debug_assert (mode == nano::bootstrap_mode::wallet_lazy);
}

std::size_t nano::bootstrap_attempt::wallet_size ()
{
debug_assert (mode == nano::bootstrap_mode::wallet_lazy);
return 0;
}
13 changes: 0 additions & 13 deletions nano/node/bootstrap/bootstrap_attempt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,7 @@ class bootstrap_attempt : public std::enable_shared_from_this<bootstrap_attempt>
void pull_finished ();
bool should_log ();
std::string mode_text ();
virtual void add_frontier (nano::pull_info const &);
virtual void add_bulk_push_target (nano::block_hash const &, nano::block_hash const &);
virtual bool request_bulk_push_target (std::pair<nano::block_hash, nano::block_hash> &);
virtual void set_start_account (nano::account const &);
virtual bool lazy_start (nano::hash_or_account const &, bool confirmed = true);
virtual void lazy_add (nano::pull_info const &);
virtual void lazy_requeue (nano::block_hash const &, nano::block_hash const &);
virtual uint32_t lazy_batch_size ();
virtual bool lazy_has_expired () const;
virtual bool lazy_processed_or_exists (nano::block_hash const &);
virtual bool process_block (std::shared_ptr<nano::block> const &, nano::account const &, uint64_t, nano::bulk_pull::count_t, bool, unsigned);
virtual void requeue_pending (nano::account const &);
virtual void wallet_start (std::deque<nano::account> &);
virtual std::size_t wallet_size ();
virtual void get_information (boost::property_tree::ptree &) = 0;
nano::mutex next_log_mutex;
std::chrono::steady_clock::time_point next_log{ std::chrono::steady_clock::now () };
Expand Down
2 changes: 1 addition & 1 deletion nano/node/bootstrap/bootstrap_bulk_pull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ void nano::bulk_pull_client::received_block (boost::system::error_code const & e
}
}

nano::bulk_pull_account_client::bulk_pull_account_client (std::shared_ptr<nano::bootstrap_client> const & connection_a, std::shared_ptr<nano::bootstrap_attempt> const & attempt_a, nano::account const & account_a) :
nano::bulk_pull_account_client::bulk_pull_account_client (std::shared_ptr<nano::bootstrap_client> const & connection_a, std::shared_ptr<nano::bootstrap_attempt_wallet> const & attempt_a, nano::account const & account_a) :
connection (connection_a),
attempt (attempt_a),
account (account_a),
Expand Down
5 changes: 3 additions & 2 deletions nano/node/bootstrap/bootstrap_bulk_pull.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,16 @@ class bulk_pull_client final : public std::enable_shared_from_this<nano::bulk_pu
uint64_t unexpected_count;
bool network_error{ false };
};
class bootstrap_attempt_wallet;
class bulk_pull_account_client final : public std::enable_shared_from_this<nano::bulk_pull_account_client>
{
public:
bulk_pull_account_client (std::shared_ptr<nano::bootstrap_client> const &, std::shared_ptr<nano::bootstrap_attempt> const &, nano::account const &);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may be misunderstanding this but it seems strange to me to limit the bulk pull to a wallet bootstrap attempt only.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bulk_pull_account call which is a different network messages from bulk_pull. It is only used by bootstrap_attempt_wallet.

bulk_pull_account_client (std::shared_ptr<nano::bootstrap_client> const &, std::shared_ptr<nano::bootstrap_attempt_wallet> const &, nano::account const &);
~bulk_pull_account_client ();
void request ();
void receive_pending ();
std::shared_ptr<nano::bootstrap_client> connection;
std::shared_ptr<nano::bootstrap_attempt> attempt;
std::shared_ptr<nano::bootstrap_attempt_wallet> attempt;
nano::account account;
uint64_t pull_blocks;
};
Expand Down
3 changes: 2 additions & 1 deletion nano/node/bootstrap/bootstrap_bulk_push.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#include <nano/node/bootstrap/bootstrap_attempt.hpp>
#include <nano/node/bootstrap/bootstrap_bulk_push.hpp>
#include <nano/node/bootstrap/bootstrap_legacy.hpp>
#include <nano/node/node.hpp>
#include <nano/node/transport/tcp.hpp>

#include <boost/format.hpp>

nano::bulk_push_client::bulk_push_client (std::shared_ptr<nano::bootstrap_client> const & connection_a, std::shared_ptr<nano::bootstrap_attempt> const & attempt_a) :
nano::bulk_push_client::bulk_push_client (std::shared_ptr<nano::bootstrap_client> const & connection_a, std::shared_ptr<nano::bootstrap_attempt_legacy> const & attempt_a) :
connection (connection_a),
attempt (attempt_a)
{
Expand Down
6 changes: 3 additions & 3 deletions nano/node/bootstrap/bootstrap_bulk_push.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace nano
{
class bootstrap_attempt;
class bootstrap_attempt_legacy;
class bootstrap_client;

/**
Expand All @@ -15,14 +15,14 @@ class bootstrap_client;
class bulk_push_client final : public std::enable_shared_from_this<nano::bulk_push_client>
{
public:
explicit bulk_push_client (std::shared_ptr<nano::bootstrap_client> const &, std::shared_ptr<nano::bootstrap_attempt> const &);
explicit bulk_push_client (std::shared_ptr<nano::bootstrap_client> const &, std::shared_ptr<nano::bootstrap_attempt_legacy> const &);
~bulk_push_client ();
void start ();
void push ();
void push_block (nano::block const &);
void send_finished ();
std::shared_ptr<nano::bootstrap_client> connection;
std::shared_ptr<nano::bootstrap_attempt> attempt;
std::shared_ptr<nano::bootstrap_attempt_legacy> attempt;
std::promise<bool> promise;
std::pair<nano::block_hash, nano::block_hash> current_target;
};
Expand Down
25 changes: 16 additions & 9 deletions nano/node/bootstrap/bootstrap_connections.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#include <nano/node/bootstrap/bootstrap.hpp>
#include <nano/node/bootstrap/bootstrap_attempt.hpp>
#include <nano/node/bootstrap/bootstrap_connections.hpp>
#include <nano/node/bootstrap/bootstrap_lazy.hpp>
#include <nano/node/common.hpp>
#include <nano/node/node.hpp>
#include <nano/node/transport/tcp.hpp>

#include <boost/format.hpp>

#include <memory>

constexpr double nano::bootstrap_limits::bootstrap_connection_scale_target_blocks;
constexpr double nano::bootstrap_limits::bootstrap_minimum_blocks_per_sec;
constexpr double nano::bootstrap_limits::bootstrap_minimum_termination_time_sec;
Expand Down Expand Up @@ -348,10 +351,13 @@ void nano::bootstrap_connections::request_pull (nano::unique_lock<nano::mutex> &
pulls.pop_front ();
attempt_l = node.bootstrap_initiator.attempts.find (pull.bootstrap_id);
// Check if lazy pull is obsolete (head was processed or head is 0 for destinations requests)
if (attempt_l != nullptr && attempt_l->mode == nano::bootstrap_mode::lazy && !pull.head.is_zero () && attempt_l->lazy_processed_or_exists (pull.head))
if (auto lazy = std::dynamic_pointer_cast<nano::bootstrap_attempt_lazy> (attempt_l))
{
attempt_l->pull_finished ();
attempt_l = nullptr;
if (!pull.head.is_zero () && lazy->lazy_processed_or_exists (pull.head))
{
attempt_l->pull_finished ();
attempt_l = nullptr;
}
}
}
if (attempt_l != nullptr)
Expand Down Expand Up @@ -383,10 +389,11 @@ void nano::bootstrap_connections::requeue_pull (nano::pull_info const & pull_a,
auto attempt_l (node.bootstrap_initiator.attempts.find (pull.bootstrap_id));
if (attempt_l != nullptr)
{
auto lazy = std::dynamic_pointer_cast<nano::bootstrap_attempt_lazy> (attempt_l);
++attempt_l->requeued_pulls;
if (attempt_l->mode == nano::bootstrap_mode::lazy)
if (lazy)
{
pull.count = attempt_l->lazy_batch_size ();
pull.count = lazy->lazy_batch_size ();
}
if (attempt_l->mode == nano::bootstrap_mode::legacy && (pull.attempts < pull.retry_limit + (pull.processed / nano::bootstrap_limits::requeued_pulls_processed_blocks_factor)))
{
Expand All @@ -397,10 +404,10 @@ void nano::bootstrap_connections::requeue_pull (nano::pull_info const & pull_a,
attempt_l->pull_started ();
condition.notify_all ();
}
else if (attempt_l->mode == nano::bootstrap_mode::lazy && (pull.attempts <= pull.retry_limit + (pull.processed / node.network_params.bootstrap.lazy_max_pull_blocks)))
else if (lazy && (pull.attempts <= pull.retry_limit + (pull.processed / node.network_params.bootstrap.lazy_max_pull_blocks)))
{
debug_assert (pull.account_or_head == pull.head);
if (!attempt_l->lazy_processed_or_exists (pull.account_or_head.as_block_hash ()))
if (!lazy->lazy_processed_or_exists (pull.account_or_head.as_block_hash ()))
{
{
nano::lock_guard<nano::mutex> lock (mutex);
Expand All @@ -418,9 +425,9 @@ void nano::bootstrap_connections::requeue_pull (nano::pull_info const & pull_a,
}
node.stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_failed_account, nano::stat::dir::in);

if (attempt_l->mode == nano::bootstrap_mode::lazy && pull.processed > 0)
if (lazy && pull.processed > 0)
{
attempt_l->lazy_add (pull);
lazy->lazy_add (pull);
}
else if (attempt_l->mode == nano::bootstrap_mode::legacy)
{
Expand Down
3 changes: 2 additions & 1 deletion nano/node/bootstrap/bootstrap_frontier.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <nano/node/bootstrap/bootstrap_attempt.hpp>
#include <nano/node/bootstrap/bootstrap_frontier.hpp>
#include <nano/node/bootstrap/bootstrap_legacy.hpp>
#include <nano/node/node.hpp>
#include <nano/node/transport/tcp.hpp>

Expand Down Expand Up @@ -40,7 +41,7 @@ void nano::frontier_req_client::run (nano::account const & start_account_a, uint
nano::buffer_drop_policy::no_limiter_drop);
}

nano::frontier_req_client::frontier_req_client (std::shared_ptr<nano::bootstrap_client> const & connection_a, std::shared_ptr<nano::bootstrap_attempt> const & attempt_a) :
nano::frontier_req_client::frontier_req_client (std::shared_ptr<nano::bootstrap_client> const & connection_a, std::shared_ptr<nano::bootstrap_attempt_legacy> const & attempt_a) :
connection (connection_a),
attempt (attempt_a),
count (0),
Expand Down
6 changes: 3 additions & 3 deletions nano/node/bootstrap/bootstrap_frontier.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace nano
{
class bootstrap_attempt;
class bootstrap_attempt_legacy;
class bootstrap_client;

/**
Expand All @@ -16,15 +16,15 @@ class bootstrap_client;
class frontier_req_client final : public std::enable_shared_from_this<nano::frontier_req_client>
{
public:
explicit frontier_req_client (std::shared_ptr<nano::bootstrap_client> const &, std::shared_ptr<nano::bootstrap_attempt> const &);
explicit frontier_req_client (std::shared_ptr<nano::bootstrap_client> const &, std::shared_ptr<nano::bootstrap_attempt_legacy> const &);
void run (nano::account const & start_account_a, uint32_t const frontiers_age_a, uint32_t const count_a);
void receive_frontier ();
void received_frontier (boost::system::error_code const &, std::size_t);
bool bulk_push_available ();
void unsynced (nano::block_hash const &, nano::block_hash const &);
void next ();
std::shared_ptr<nano::bootstrap_client> connection;
std::shared_ptr<nano::bootstrap_attempt> attempt;
std::shared_ptr<nano::bootstrap_attempt_legacy> attempt;
nano::account current;
nano::block_hash frontier;
unsigned count;
Expand Down
5 changes: 2 additions & 3 deletions nano/node/bootstrap/bootstrap_lazy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,9 @@ void nano::bootstrap_attempt_lazy::run ()
while ((still_pulling () || !lazy_finished ()) && !lazy_has_expired ())
{
unsigned iterations (0);
auto this_l (shared_from_this ());
while (still_pulling () && !lazy_has_expired ())
{
condition.wait (lock, [&stopped = stopped, &pulling = pulling, &lazy_pulls = lazy_pulls, this_l] { return stopped || pulling == 0 || (pulling < nano::bootstrap_limits::bootstrap_connection_scale_target_blocks && !lazy_pulls.empty ()) || this_l->lazy_has_expired (); });
condition.wait (lock, [this, &stopped = stopped, &pulling = pulling, &lazy_pulls = lazy_pulls] { return stopped || pulling == 0 || (pulling < nano::bootstrap_limits::bootstrap_connection_scale_target_blocks && !lazy_pulls.empty ()) || lazy_has_expired (); });
++iterations;
// Flushing lazy pulls
lazy_pull_flush (lock);
Expand Down Expand Up @@ -489,7 +488,7 @@ void nano::bootstrap_attempt_wallet::request_pending (nano::unique_lock<nano::mu
auto account (wallet_accounts.front ());
wallet_accounts.pop_front ();
++pulling;
auto this_l (shared_from_this ());
clemahieu marked this conversation as resolved.
Show resolved Hide resolved
auto this_l = std::dynamic_pointer_cast<nano::bootstrap_attempt_wallet> (shared_from_this ());
// The bulk_pull_account_client destructor attempt to requeue_pull which can cause a deadlock if this is the last reference
// Dispatch request in an external thread in case it needs to be destroyed
node->background ([connection_l, this_l, account] () {
Expand Down
18 changes: 9 additions & 9 deletions nano/node/bootstrap/bootstrap_lazy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ class bootstrap_attempt_lazy final : public bootstrap_attempt
~bootstrap_attempt_lazy ();
bool process_block (std::shared_ptr<nano::block> const &, nano::account const &, uint64_t, nano::bulk_pull::count_t, bool, unsigned) override;
void run () override;
bool lazy_start (nano::hash_or_account const &, bool confirmed = true) override;
bool lazy_start (nano::hash_or_account const &, bool confirmed = true);
void lazy_add (nano::hash_or_account const &, unsigned);
void lazy_add (nano::pull_info const &) override;
void lazy_requeue (nano::block_hash const &, nano::block_hash const &) override;
void lazy_add (nano::pull_info const &);
void lazy_requeue (nano::block_hash const &, nano::block_hash const &);
bool lazy_finished ();
bool lazy_has_expired () const override;
uint32_t lazy_batch_size () override;
bool lazy_has_expired () const;
uint32_t lazy_batch_size ();
void lazy_pull_flush (nano::unique_lock<nano::mutex> & lock_a);
bool process_block_lazy (std::shared_ptr<nano::block> const &, nano::account const &, uint64_t, nano::bulk_pull::count_t, unsigned);
void lazy_block_state (std::shared_ptr<nano::block> const &, unsigned);
Expand All @@ -50,7 +50,7 @@ class bootstrap_attempt_lazy final : public bootstrap_attempt
void lazy_blocks_insert (nano::block_hash const &);
void lazy_blocks_erase (nano::block_hash const &);
bool lazy_blocks_processed (nano::block_hash const &);
bool lazy_processed_or_exists (nano::block_hash const &) override;
bool lazy_processed_or_exists (nano::block_hash const &);
unsigned lazy_retry_limit_confirmed ();
void get_information (boost::property_tree::ptree &) override;
std::unordered_set<std::size_t> lazy_blocks;
Expand All @@ -75,11 +75,11 @@ class bootstrap_attempt_wallet final : public bootstrap_attempt
explicit bootstrap_attempt_wallet (std::shared_ptr<nano::node> const & node_a, uint64_t incremental_id_a, std::string id_a = "");
~bootstrap_attempt_wallet ();
void request_pending (nano::unique_lock<nano::mutex> &);
void requeue_pending (nano::account const &) override;
void requeue_pending (nano::account const &);
void run () override;
void wallet_start (std::deque<nano::account> &) override;
void wallet_start (std::deque<nano::account> &);
bool wallet_finished ();
std::size_t wallet_size () override;
std::size_t wallet_size ();
void get_information (boost::property_tree::ptree &) override;
std::deque<nano::account> wallet_accounts;
};
Expand Down
Loading