From f12f5d54fbd2fc70fa388b23fc0a7c1377918cde Mon Sep 17 00:00:00 2001 From: clemahieu Date: Mon, 11 Jul 2022 20:18:42 +0100 Subject: [PATCH 1/6] Merging block work validity checks in to an early-return pattern. --- nano/node/bootstrap/bootstrap_bulk_pull.cpp | 21 +++++++++++---------- nano/node/bootstrap/bootstrap_bulk_push.cpp | 21 +++++++++++---------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.cpp b/nano/node/bootstrap/bootstrap_bulk_pull.cpp index 751ab60e1e..750e537b41 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.cpp @@ -208,8 +208,17 @@ void nano::bulk_pull_client::received_block (boost::system::error_code const & e { nano::bufferstream stream (connection->receive_buffer->data (), size_a); auto block (nano::deserialize_block (stream, type_a)); - if (block != nullptr && !connection->node->network_params.work.validate_entry (*block)) + if (block != nullptr) { + if (connection->node->network_params.work.validate_entry (*block)) + { + if (connection->node->config.logging.bulk_pull_logging ()) + { + connection->node->logger.try_log (boost::str (boost::format ("Insufficient work for bulk pull block: %1%") % block->hash ().to_string ())); + } + connection->node->stats.inc_detail_only (nano::stat::type::error, nano::stat::detail::insufficient_work); + return; + } auto hash (block->hash ()); if (connection->node->config.logging.bulk_pull_logging ()) { @@ -256,7 +265,7 @@ void nano::bulk_pull_client::received_block (boost::system::error_code const & e connection->connections.pool_connection (connection); } } - else if (block == nullptr) + else { if (connection->node->config.logging.bulk_pull_logging ()) { @@ -264,14 +273,6 @@ void nano::bulk_pull_client::received_block (boost::system::error_code const & e } connection->node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_deserialize_receive_block, nano::stat::dir::in); } - else // Work invalid - { - if (connection->node->config.logging.bulk_pull_logging ()) - { - connection->node->logger.try_log (boost::str (boost::format ("Insufficient work for bulk pull block: %1%") % block->hash ().to_string ())); - } - connection->node->stats.inc_detail_only (nano::stat::type::error, nano::stat::detail::insufficient_work); - } } else { diff --git a/nano/node/bootstrap/bootstrap_bulk_push.cpp b/nano/node/bootstrap/bootstrap_bulk_push.cpp index e14b3f2920..8d4f81614a 100644 --- a/nano/node/bootstrap/bootstrap_bulk_push.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_push.cpp @@ -233,25 +233,26 @@ void nano::bulk_push_server::received_block (boost::system::error_code const & e { nano::bufferstream stream (receive_buffer->data (), size_a); auto block (nano::deserialize_block (stream, type_a)); - if (block != nullptr && !connection->node->network_params.work.validate_entry (*block)) + if (block != nullptr) { + if (connection->node->network_params.work.validate_entry (*block)) + { + if (connection->node->config.logging.bulk_pull_logging ()) + { + connection->node->logger.try_log (boost::str (boost::format ("Insufficient work for bulk push block: %1%") % block->hash ().to_string ())); + } + connection->node->stats.inc_detail_only (nano::stat::type::error, nano::stat::detail::insufficient_work); + return; + } connection->node->process_active (std::move (block)); throttled_receive (); } - else if (block == nullptr) + else { if (connection->node->config.logging.bulk_pull_logging ()) { connection->node->logger.try_log ("Error deserializing block received from pull request"); } } - else // Work invalid - { - if (connection->node->config.logging.bulk_pull_logging ()) - { - connection->node->logger.try_log (boost::str (boost::format ("Insufficient work for bulk push block: %1%") % block->hash ().to_string ())); - } - connection->node->stats.inc_detail_only (nano::stat::type::error, nano::stat::detail::insufficient_work); - } } } From 15b394551164cf6866055d2eecded1c3097ca319 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Tue, 12 Jul 2022 05:44:14 +0100 Subject: [PATCH 2/6] When the node is constructed outside of a nano::system, if the test fails, the node will not be shut down and can result in other tests failing further on. --- nano/core_test/bootstrap.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/nano/core_test/bootstrap.cpp b/nano/core_test/bootstrap.cpp index 51dec034c8..22cbcf5de4 100644 --- a/nano/core_test/bootstrap.cpp +++ b/nano/core_test/bootstrap.cpp @@ -1434,13 +1434,13 @@ TEST (bootstrap_processor, wallet_lazy_pending) .work (*node0->work_generate_blocking (receive1->hash ())) .build_shared (); - // Processing test chain + // Processing test c`hain node0->block_processor.add (send1); node0->block_processor.add (receive1); node0->block_processor.add (send2); node0->block_processor.flush (); // Start wallet lazy bootstrap - auto node1 (std::make_shared (system.io_ctx, nano::get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 = system.add_node (); node1->network.udp_channels.insert (node0->network.endpoint (), node1->network_params.network.protocol_version); auto wallet (node1->wallets.create (nano::random_wallet_id ())); ASSERT_NE (nullptr, wallet); @@ -1448,7 +1448,6 @@ TEST (bootstrap_processor, wallet_lazy_pending) node1->bootstrap_wallet (); // Check processed blocks ASSERT_TIMELY (10s, node1->ledger.block_or_pruned_exists (send2->hash ())); - node1->stop (); } TEST (bootstrap_processor, multiple_attempts) From d36093af55b8769899527458db15503129b17421 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Tue, 12 Jul 2022 06:16:39 +0100 Subject: [PATCH 3/6] Adding block_deserializer class which handles deserializing type-prefixed block streams. --- nano/core_test/bootstrap.cpp | 6 ++ nano/node/CMakeLists.txt | 2 + nano/node/bootstrap/block_deserializer.cpp | 65 ++++++++++++++++++++++ nano/node/bootstrap/block_deserializer.hpp | 47 ++++++++++++++++ 4 files changed, 120 insertions(+) create mode 100644 nano/node/bootstrap/block_deserializer.cpp create mode 100644 nano/node/bootstrap/block_deserializer.hpp diff --git a/nano/core_test/bootstrap.cpp b/nano/core_test/bootstrap.cpp index 22cbcf5de4..02d77876f3 100644 --- a/nano/core_test/bootstrap.cpp +++ b/nano/core_test/bootstrap.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -2032,3 +2033,8 @@ TEST (bulk_pull_account, basics) ASSERT_EQ (nullptr, block_data.second.get ()); } } + +TEST (block_deserializer, construction) +{ + auto deserializer = std::make_shared (); +} diff --git a/nano/node/CMakeLists.txt b/nano/node/CMakeLists.txt index ba02c0f19e..47830d23a4 100644 --- a/nano/node/CMakeLists.txt +++ b/nano/node/CMakeLists.txt @@ -18,6 +18,8 @@ add_library( active_transactions.cpp blockprocessor.hpp blockprocessor.cpp + bootstrap/block_deserializer.hpp + bootstrap/block_deserializer.cpp bootstrap/bootstrap_attempt.hpp bootstrap/bootstrap_attempt.cpp bootstrap/bootstrap_bulk_pull.hpp diff --git a/nano/node/bootstrap/block_deserializer.cpp b/nano/node/bootstrap/block_deserializer.cpp new file mode 100644 index 0000000000..34b6370cf7 --- /dev/null +++ b/nano/node/bootstrap/block_deserializer.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include + +nano::bootstrap::block_deserializer::block_deserializer () : + read_buffer{ std::make_shared> () } +{ +} + +void nano::bootstrap::block_deserializer::read (nano::socket & socket, callback_type const && callback) +{ + debug_assert (callback); + read_buffer->resize (1); + socket.async_read (read_buffer, 1, [this_l = shared_from_this (), &socket, callback = std::move (callback)] (boost::system::error_code const & ec, std::size_t size_a) { + if (ec) + { + callback (ec, nullptr); + return; + } + if (size_a != 1) + { + callback (boost::asio::error::fault, nullptr); + return; + } + this_l->received_type (socket, std::move (callback)); + }); +} + +void nano::bootstrap::block_deserializer::received_type (nano::socket & socket, callback_type const && callback) +{ + nano::block_type type = static_cast (read_buffer->data ()[0]); + if (type == nano::block_type::not_a_block) + { + callback (boost::system::error_code{}, nullptr); + return; + } + auto size = nano::block::size (type); + if (size == 0) + { + callback (boost::asio::error::fault, nullptr); + return; + } + read_buffer->resize (size); + socket.async_read (read_buffer, size, [this_l = shared_from_this (), size, type, callback = std::move (callback)] (boost::system::error_code const & ec, std::size_t size_a) { + if (ec) + { + callback (ec, nullptr); + return; + } + if (size_a != size) + { + callback (boost::asio::error::fault, nullptr); + return; + } + this_l->received_block (type, std::move (callback)); + }); +} + +void nano::bootstrap::block_deserializer::received_block (nano::block_type type, callback_type const && callback) +{ + nano::bufferstream stream{ read_buffer->data (), read_buffer->size () }; + auto block = nano::deserialize_block (stream, type); + callback (boost::system::error_code{}, block); +} diff --git a/nano/node/bootstrap/block_deserializer.hpp b/nano/node/bootstrap/block_deserializer.hpp new file mode 100644 index 0000000000..84720bae03 --- /dev/null +++ b/nano/node/bootstrap/block_deserializer.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include + +#include + +#include +#include + +namespace nano +{ +class block; +class socket; +namespace bootstrap +{ + /** + * Class to read a block-type byte followed by a serialised block from a stream. + * It is typically used to used to read a series of block-types and blocks terminated by a not-a-block type. + */ + class block_deserializer : public std::enable_shared_from_this + { + public: + using callback_type = std::function)>; + + block_deserializer (); + /** + * Read a type-prefixed block from 'socket' and pass the result, or an error, to 'callback' + * A normal end to series of blocks is a marked by return no error and a nullptr for block. + */ + void read (nano::socket & socket, callback_type const && callback); + + private: + /** + * Called by read method on receipt of a block type byte. + * The type byte will be in the read_buffer. + */ + void received_type (nano::socket & socket, callback_type const && callback); + + /** + * Called by received_type when a block is received, it parses the block and calls the callback. + */ + void received_block (nano::block_type type, callback_type const && callback); + + std::shared_ptr> read_buffer; + }; +} +} From a1432635d0dba55f3777e897c09a12aca57798bb Mon Sep 17 00:00:00 2001 From: clemahieu Date: Tue, 12 Jul 2022 07:19:39 +0100 Subject: [PATCH 4/6] Cleaning up initialization of bulk_pull_client. --- nano/node/bootstrap/bootstrap_bulk_pull.cpp | 9 +++---- nano/node/bootstrap/bootstrap_bulk_pull.hpp | 29 +++++++++++++++++---- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.cpp b/nano/node/bootstrap/bootstrap_bulk_pull.cpp index 750e537b41..06a54f5eac 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.cpp @@ -19,12 +19,9 @@ nano::pull_info::pull_info (nano::hash_or_account const & account_or_head_a, nan } nano::bulk_pull_client::bulk_pull_client (std::shared_ptr const & connection_a, std::shared_ptr const & attempt_a, nano::pull_info const & pull_a) : - connection (connection_a), - attempt (attempt_a), - known_account{}, - pull (pull_a), - pull_blocks (0), - unexpected_count (0) + connection{ connection_a }, + attempt{ attempt_a }, + pull{ pull_a } { attempt->condition.notify_all (); } diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.hpp b/nano/node/bootstrap/bootstrap_bulk_pull.hpp index 762dc38c4e..e92cc5b242 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.hpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.hpp @@ -42,12 +42,31 @@ class bulk_pull_client final : public std::enable_shared_from_this connection; std::shared_ptr attempt; - nano::block_hash expected; - nano::account known_account; - nano::pull_info pull; - uint64_t pull_blocks; - uint64_t unexpected_count; bool network_error{ false }; + +private: + /** + * Tracks the next block expected to be received starting with the block hash that was expected and followed by previous blocks for this account chain + */ + nano::block_hash expected{ 0 }; + /** + * Tracks the account number for this account chain + * Used when an account chain has a mix between state blocks and legacy blocks which do not encode the account number in the block + * 0 if the account is unknown + */ + nano::account known_account{ 0 }; + /** + * Original pull request + */ + nano::pull_info pull; + /** + * Tracks the number of blocks successfully deserialized + */ + uint64_t pull_blocks{ 0 }; + /** + * Tracks the number of times an unexpected block was received + */ + uint64_t unexpected_count{ 0 }; }; class bootstrap_attempt_wallet; class bulk_pull_account_client final : public std::enable_shared_from_this From 0824bdf9efeda59a7f874b81848cf8258e2a129e Mon Sep 17 00:00:00 2001 From: clemahieu Date: Tue, 12 Jul 2022 10:20:18 +0100 Subject: [PATCH 5/6] Converting received_block function to use early-return pattern. --- nano/node/bootstrap/bootstrap_bulk_pull.cpp | 127 +++++++++----------- 1 file changed, 59 insertions(+), 68 deletions(-) diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.cpp b/nano/node/bootstrap/bootstrap_bulk_pull.cpp index 06a54f5eac..d0ddee0c40 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.cpp @@ -201,84 +201,75 @@ void nano::bulk_pull_client::received_type () void nano::bulk_pull_client::received_block (boost::system::error_code const & ec, std::size_t size_a, nano::block_type type_a) { - if (!ec) + if (ec) { - nano::bufferstream stream (connection->receive_buffer->data (), size_a); - auto block (nano::deserialize_block (stream, type_a)); - if (block != nullptr) + network_error = true; + return; + } + nano::bufferstream stream{ connection->receive_buffer->data (), size_a }; + auto block = nano::deserialize_block (stream, type_a); + if (block == nullptr) + { + // Avoid re-using slow peers, or peers that sent the wrong blocks. + if (!connection->pending_stop && (expected == pull.end || (pull.count != 0 && pull.count == pull_blocks))) { - if (connection->node->network_params.work.validate_entry (*block)) - { - if (connection->node->config.logging.bulk_pull_logging ()) - { - connection->node->logger.try_log (boost::str (boost::format ("Insufficient work for bulk pull block: %1%") % block->hash ().to_string ())); - } - connection->node->stats.inc_detail_only (nano::stat::type::error, nano::stat::detail::insufficient_work); - return; - } - auto hash (block->hash ()); - if (connection->node->config.logging.bulk_pull_logging ()) - { - std::string block_l; - block->serialize_json (block_l, connection->node->config.logging.single_line_record ()); - connection->node->logger.try_log (boost::str (boost::format ("Pulled block %1% %2%") % hash.to_string () % block_l)); - } - // 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 (connection->node->flags.disable_legacy_bootstrap && pull_blocks == 0 && pull.retry_limit <= connection->node->network_params.bootstrap.lazy_retry_limit && expected == pull.account_or_head && block->account () == pull.account_or_head); - if (hash == expected || unconfirmed_account_head) - { - expected = block->previous (); - block_expected = true; - } - else - { - unexpected_count++; - } - if (pull_blocks == 0 && block_expected) - { - known_account = block->account (); - } - if (connection->block_count++ == 0) - { - connection->set_start_time (std::chrono::steady_clock::now ()); - } - attempt->total_blocks++; - pull_blocks++; - bool stop_pull (attempt->process_block (block, known_account, pull_blocks, pull.count, block_expected, pull.retry_limit)); - if (!stop_pull && !connection->hard_stop.load ()) - { - /* Process block in lazy pull if not stopped - Stop usual pull request with unexpected block & more than 16k blocks processed - to prevent spam */ - if (attempt->mode != nano::bootstrap_mode::legacy || unexpected_count < 16384) - { - throttled_receive_block (); - } - } - else if (stop_pull && block_expected) - { - connection->connections.pool_connection (connection); - } + connection->connections.pool_connection (connection); } - else + return; + } + if (connection->node->network_params.work.validate_entry (*block)) + { + if (connection->node->config.logging.bulk_pull_logging ()) { - if (connection->node->config.logging.bulk_pull_logging ()) - { - connection->node->logger.try_log ("Error deserializing block received from pull request"); - } - connection->node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_deserialize_receive_block, nano::stat::dir::in); + connection->node->logger.try_log (boost::str (boost::format ("Insufficient work for bulk pull block: %1%") % block->hash ().to_string ())); } + connection->node->stats.inc_detail_only (nano::stat::type::error, nano::stat::detail::insufficient_work); + return; + } + auto hash (block->hash ()); + if (connection->node->config.logging.bulk_pull_logging ()) + { + std::string block_l; + block->serialize_json (block_l, connection->node->config.logging.single_line_record ()); + connection->node->logger.try_log (boost::str (boost::format ("Pulled block %1% %2%") % hash.to_string () % block_l)); + } + // 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 (connection->node->flags.disable_legacy_bootstrap && pull_blocks == 0 && pull.retry_limit <= connection->node->network_params.bootstrap.lazy_retry_limit && expected == pull.account_or_head && block->account () == pull.account_or_head); + if (hash == expected || unconfirmed_account_head) + { + expected = block->previous (); + block_expected = true; } else { - if (connection->node->config.logging.bulk_pull_logging ()) + unexpected_count++; + } + if (pull_blocks == 0 && block_expected) + { + known_account = block->account (); + } + if (connection->block_count++ == 0) + { + connection->set_start_time (std::chrono::steady_clock::now ()); + } + attempt->total_blocks++; + pull_blocks++; + bool stop_pull (attempt->process_block (block, known_account, pull_blocks, pull.count, block_expected, pull.retry_limit)); + if (!stop_pull && !connection->hard_stop.load ()) + { + /* Process block in lazy pull if not stopped + Stop usual pull request with unexpected block & more than 16k blocks processed + to prevent spam */ + if (attempt->mode != nano::bootstrap_mode::legacy || unexpected_count < 16384) { - connection->node->logger.try_log (boost::str (boost::format ("Error bulk receiving block: %1%") % ec.message ())); + throttled_receive_block (); } - connection->node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_receive_block_failure, nano::stat::dir::in); - network_error = true; + } + else if (stop_pull && block_expected) + { + connection->connections.pool_connection (connection); } } From 946fc1c6a2a1fd032c694dcf2d99f2c8a5714138 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Tue, 12 Jul 2022 15:05:58 +0100 Subject: [PATCH 6/6] Connecting the block deserializer in to the bulk_pull_client. --- nano/core_test/bootstrap.cpp | 2 +- nano/node/bootstrap/bootstrap_bulk_pull.cpp | 92 ++------------------- nano/node/bootstrap/bootstrap_bulk_pull.hpp | 8 +- 3 files changed, 15 insertions(+), 87 deletions(-) diff --git a/nano/core_test/bootstrap.cpp b/nano/core_test/bootstrap.cpp index 02d77876f3..76c9e961ae 100644 --- a/nano/core_test/bootstrap.cpp +++ b/nano/core_test/bootstrap.cpp @@ -1435,7 +1435,7 @@ TEST (bootstrap_processor, wallet_lazy_pending) .work (*node0->work_generate_blocking (receive1->hash ())) .build_shared (); - // Processing test c`hain + // Processing test chain node0->block_processor.add (send1); node0->block_processor.add (receive1); node0->block_processor.add (send2); diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.cpp b/nano/node/bootstrap/bootstrap_bulk_pull.cpp index d0ddee0c40..e7ff328dca 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -21,7 +22,8 @@ nano::pull_info::pull_info (nano::hash_or_account const & account_or_head_a, nan nano::bulk_pull_client::bulk_pull_client (std::shared_ptr const & connection_a, std::shared_ptr const & attempt_a, nano::pull_info const & pull_a) : connection{ connection_a }, attempt{ attempt_a }, - pull{ pull_a } + pull{ pull_a }, + block_deserializer{ std::make_shared () } { attempt->condition.notify_all (); } @@ -118,96 +120,18 @@ void nano::bulk_pull_client::throttled_receive_block () void nano::bulk_pull_client::receive_block () { - auto this_l (shared_from_this ()); - connection->socket->async_read (connection->receive_buffer, 1, [this_l] (boost::system::error_code const & ec, std::size_t size_a) { - if (!ec) - { - this_l->received_type (); - } - else - { - if (this_l->connection->node->config.logging.bulk_pull_logging ()) - { - this_l->connection->node->logger.try_log (boost::str (boost::format ("Error receiving block type: %1%") % ec.message ())); - } - this_l->connection->node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_receive_block_failure, nano::stat::dir::in); - this_l->network_error = true; - } + block_deserializer->read (*connection->socket, [this_l = shared_from_this ()] (boost::system::error_code ec, std::shared_ptr block) { + this_l->received_block (ec, block); }); } -void nano::bulk_pull_client::received_type () -{ - auto this_l (shared_from_this ()); - nano::block_type type (static_cast (connection->receive_buffer->data ()[0])); - - auto const & socket_l = connection->socket; - switch (type) - { - case nano::block_type::send: - { - socket_l->async_read (connection->receive_buffer, nano::send_block::size, [this_l, type] (boost::system::error_code const & ec, std::size_t size_a) { - this_l->received_block (ec, size_a, type); - }); - break; - } - case nano::block_type::receive: - { - socket_l->async_read (connection->receive_buffer, nano::receive_block::size, [this_l, type] (boost::system::error_code const & ec, std::size_t size_a) { - this_l->received_block (ec, size_a, type); - }); - break; - } - case nano::block_type::open: - { - socket_l->async_read (connection->receive_buffer, nano::open_block::size, [this_l, type] (boost::system::error_code const & ec, std::size_t size_a) { - this_l->received_block (ec, size_a, type); - }); - break; - } - case nano::block_type::change: - { - socket_l->async_read (connection->receive_buffer, nano::change_block::size, [this_l, type] (boost::system::error_code const & ec, std::size_t size_a) { - this_l->received_block (ec, size_a, type); - }); - break; - } - case nano::block_type::state: - { - socket_l->async_read (connection->receive_buffer, nano::state_block::size, [this_l, type] (boost::system::error_code const & ec, std::size_t size_a) { - this_l->received_block (ec, size_a, type); - }); - break; - } - case nano::block_type::not_a_block: - { - // Avoid re-using slow peers, or peers that sent the wrong blocks. - if (!connection->pending_stop && (expected == pull.end || (pull.count != 0 && pull.count == pull_blocks))) - { - connection->connections.pool_connection (connection); - } - break; - } - default: - { - if (connection->node->config.logging.network_packet_logging ()) - { - connection->node->logger.try_log (boost::str (boost::format ("Unknown type received as block type: %1%") % static_cast (type))); - } - break; - } - } -} - -void nano::bulk_pull_client::received_block (boost::system::error_code const & ec, std::size_t size_a, nano::block_type type_a) +void nano::bulk_pull_client::received_block (boost::system::error_code ec, std::shared_ptr block) { if (ec) { network_error = true; return; } - nano::bufferstream stream{ connection->receive_buffer->data (), size_a }; - auto block = nano::deserialize_block (stream, type_a); if (block == nullptr) { // Avoid re-using slow peers, or peers that sent the wrong blocks. @@ -226,7 +150,7 @@ void nano::bulk_pull_client::received_block (boost::system::error_code const & e connection->node->stats.inc_detail_only (nano::stat::type::error, nano::stat::detail::insufficient_work); return; } - auto hash (block->hash ()); + auto hash = block->hash (); if (connection->node->config.logging.bulk_pull_logging ()) { std::string block_l; @@ -267,7 +191,7 @@ void nano::bulk_pull_client::received_block (boost::system::error_code const & e throttled_receive_block (); } } - else if (stop_pull && block_expected) + else if (!stop_pull && block_expected) { connection->connections.pool_connection (connection); } diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.hpp b/nano/node/bootstrap/bootstrap_bulk_pull.hpp index e92cc5b242..0c789ccdd7 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.hpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.hpp @@ -8,6 +8,10 @@ namespace nano { class bootstrap_attempt; +namespace bootstrap +{ + class block_deserializer; +}; class pull_info { public: @@ -37,8 +41,7 @@ class bulk_pull_client final : public std::enable_shared_from_this block); nano::block_hash first (); std::shared_ptr connection; std::shared_ptr attempt; @@ -67,6 +70,7 @@ class bulk_pull_client final : public std::enable_shared_from_this block_deserializer; }; class bootstrap_attempt_wallet; class bulk_pull_account_client final : public std::enable_shared_from_this