diff --git a/src/cryptonote_basic/connection_context.h b/src/cryptonote_basic/connection_context.h index dfc59631f..a735ae06b 100644 --- a/src/cryptonote_basic/connection_context.h +++ b/src/cryptonote_basic/connection_context.h @@ -44,7 +44,7 @@ namespace cryptonote cryptonote_connection_context(): m_state(state_before_handshake), m_remote_blockchain_height(0), m_last_response_height(0), m_last_request_time(boost::date_time::not_a_date_time), m_callback_request_count(0), m_last_known_hash(crypto::null_hash), m_pruning_seed(0), m_rpc_port(0), m_rpc_credits_per_hash(0), m_anchor(false), m_score(0), - m_expect_response(0) {} + m_expect_response(0), m_num_requested(0) {} enum state { @@ -70,6 +70,7 @@ namespace cryptonote int32_t m_score; int m_expect_response; uint64_t m_expect_height; + size_t m_num_requested; }; inline std::string get_protocol_state_string(cryptonote_connection_context::state s) diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.h b/src/cryptonote_protocol/cryptonote_protocol_handler.h index 0599c69f9..f06614056 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.h +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.h @@ -149,7 +149,7 @@ namespace cryptonote bool update_sync_search(); int try_add_next_blocks(cryptonote_connection_context &context); void notify_new_stripe(cryptonote_connection_context &context, uint32_t stripe); - void skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const; + size_t skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const; bool request_txpool_complement(cryptonote_connection_context &context); void hit_score(cryptonote_connection_context &context, int32_t score); diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 15734cf29..aa0e870b6 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -409,6 +409,7 @@ namespace cryptonote ++context.m_callback_request_count; m_p2p->request_callback(context); MLOG_PEER_STATE("requesting callback"); + context.m_num_requested = 0; return true; } //------------------------------------------------------------------------------------------------------------------------ @@ -1990,7 +1991,7 @@ skip: } //------------------------------------------------------------------------------------------------------------------------ template - void t_cryptonote_protocol_handler::skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const + size_t t_cryptonote_protocol_handler::skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const { // take out blocks we already have size_t skip = 0; @@ -2007,6 +2008,7 @@ skip: MDEBUG(context << "skipping " << skip << "/" << context.m_needed_objects.size() << " blocks"); context.m_needed_objects = std::vector>(context.m_needed_objects.begin() + skip, context.m_needed_objects.end()); } + return skip; } //------------------------------------------------------------------------------------------------------------------------ template @@ -2060,7 +2062,11 @@ skip: const size_t block_queue_size_threshold = m_block_download_max_size ? m_block_download_max_size : BLOCK_QUEUE_SIZE_THRESHOLD; bool queue_proceed = nspans < BLOCK_QUEUE_NSPANS_THRESHOLD || size < block_queue_size_threshold; // get rid of blocks we already requested, or already have - skip_unneeded_hashes(context, true); + if (skip_unneeded_hashes(context, true) && context.m_needed_objects.empty() && context.m_num_requested == 0) + { + MERROR(context << "Nothing we can request from this peer, and we did not request anything previously"); + return false; + } uint64_t next_needed_height = m_block_queue.get_next_needed_height(bc_height); uint64_t next_block_height; if (context.m_needed_objects.empty()) @@ -2196,7 +2202,11 @@ skip: context.m_last_response_height = 0; goto skip; } - skip_unneeded_hashes(context, false); + if (skip_unneeded_hashes(context, false) && context.m_needed_objects.empty() && context.m_num_requested == 0) + { + MERROR(context << "Nothing we can request from this peer, and we did not request anything previously"); + return false; + } const uint64_t first_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1; static const uint64_t bp_fork_height = m_core.get_earliest_ideal_height_for_version(8); @@ -2293,6 +2303,7 @@ skip: << "/" << tools::get_pruning_stripe(span.first + span.second - 1, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES) << ", ours " << tools::get_pruning_stripe(m_core.get_blockchain_pruning_seed()) << ", peer stripe " << tools::get_pruning_stripe(context.m_pruning_seed)); + context.m_num_requested += req.blocks.size(); post_notify(req, context); MLOG_PEER_STATE("requesting objects"); return true; @@ -2607,6 +2618,7 @@ skip: if (arg.total_height > m_core.get_target_blockchain_height()) m_core.set_target_blockchain_height(arg.total_height); + context.m_num_requested = 0; return 1; } //------------------------------------------------------------------------------------------------------------------------