dncurrency/nano/node/bootstrap/bootstrap_attempt.cpp
2023-01-13 22:51:06 +01:00

124 lines
3.4 KiB
C++

#include <nano/node/bootstrap/bootstrap.hpp>
#include <nano/node/bootstrap/bootstrap_attempt.hpp>
#include <nano/node/bootstrap/bootstrap_bulk_push.hpp>
#include <nano/node/node.hpp>
#include <nano/node/websocket.hpp>
#include <boost/format.hpp>
constexpr unsigned nano::bootstrap_limits::requeued_pulls_limit;
constexpr unsigned nano::bootstrap_limits::requeued_pulls_limit_dev;
nano::bootstrap_attempt::bootstrap_attempt (std::shared_ptr<nano::node> const & node_a, nano::bootstrap_mode mode_a, uint64_t incremental_id_a, std::string id_a) :
node (node_a),
incremental_id (incremental_id_a),
id (id_a),
mode (mode_a)
{
if (id.empty ())
{
id = nano::hardened_constants::get ().random_128.to_string ();
}
node->logger.always_log (boost::str (boost::format ("Starting %1% bootstrap attempt with ID %2%") % mode_text () % id));
node->bootstrap_initiator.notify_listeners (true);
if (node->websocket_server)
{
nano::websocket::message_builder builder;
node->websocket_server->broadcast (builder.bootstrap_started (id, mode_text ()));
}
}
nano::bootstrap_attempt::~bootstrap_attempt ()
{
node->logger.always_log (boost::str (boost::format ("Exiting %1% bootstrap attempt with ID %2%") % mode_text () % id));
node->bootstrap_initiator.notify_listeners (false);
if (node->websocket_server)
{
nano::websocket::message_builder builder;
node->websocket_server->broadcast (builder.bootstrap_exited (id, mode_text (), attempt_start, total_blocks));
}
}
bool nano::bootstrap_attempt::should_log ()
{
nano::lock_guard<nano::mutex> guard{ next_log_mutex };
auto result (false);
auto now (std::chrono::steady_clock::now ());
if (next_log < now)
{
result = true;
next_log = now + std::chrono::seconds (15);
}
return result;
}
bool nano::bootstrap_attempt::still_pulling ()
{
debug_assert (!mutex.try_lock ());
auto running (!stopped);
auto still_pulling (pulling > 0);
return running && still_pulling;
}
void nano::bootstrap_attempt::pull_started ()
{
{
nano::lock_guard<nano::mutex> guard{ mutex };
++pulling;
}
condition.notify_all ();
}
void nano::bootstrap_attempt::pull_finished ()
{
{
nano::lock_guard<nano::mutex> guard{ mutex };
--pulling;
}
condition.notify_all ();
}
void nano::bootstrap_attempt::stop ()
{
{
nano::lock_guard<nano::mutex> lock{ mutex };
stopped = true;
}
condition.notify_all ();
node->bootstrap_initiator.connections->clear_pulls (incremental_id);
}
char const * nano::bootstrap_attempt::mode_text ()
{
switch (mode)
{
case nano::bootstrap_mode::legacy:
return "legacy";
case nano::bootstrap_mode::lazy:
return "lazy";
case nano::bootstrap_mode::wallet_lazy:
return "wallet_lazy";
}
return "unknown";
}
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);
// If block already exists in the ledger, then we can avoid next part of long account chain
if (pull_blocks_processed % nano::bootstrap_limits::pull_count_per_check == 0 && node->ledger.block_or_pruned_exists (block_a->hash ()))
{
stop_pull = true;
}
else
{
nano::unchecked_info info (block_a);
node->block_processor.add (info);
}
return stop_pull;
}
void nano::bootstrap_attempt::block_processed (nano::transaction const & tx, nano::process_return const & result, nano::block const & block)
{
}