From 6edb1b3e468e4ea5eca131114ee3ff26af3bcba0 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 15 Aug 2017 11:38:59 +0100 Subject: [PATCH 1/3] block_queue: do not add empty spans --- src/cryptonote_protocol/block_queue.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cryptonote_protocol/block_queue.cpp b/src/cryptonote_protocol/block_queue.cpp index 61063763..4f760582 100644 --- a/src/cryptonote_protocol/block_queue.cpp +++ b/src/cryptonote_protocol/block_queue.cpp @@ -189,6 +189,8 @@ std::pair block_queue::reserve_span(uint64_t first_block_hei ++i; ++span_length; } + if (span_length == 0) + return std::make_pair(0, 0); MDEBUG("Reserving span " << span_start_height << " - " << (span_start_height + span_length - 1) << " for " << connection_id); add_blocks(span_start_height, span_length, connection_id, time); set_span_hashes(span_start_height, connection_id, hashes); From 3da1edfde573d7ff21f9c2f986046e4d5c026259 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 15 Aug 2017 16:54:08 +0100 Subject: [PATCH 2/3] cryptonote_protocol: fix out of order addition This was broken by the reorg fix, since we now have to add blocks regardless of their starting height. We now check whether we know the parent for the first block in the next span, or whether it was requested. If neither, it's an orphan. If it is not known, but was requested, we wait to get that block. --- .../cryptonote_protocol_handler.inl | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index b5a30720..e9dcd135 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -990,6 +990,43 @@ namespace cryptonote MDEBUG(context << " next span in the queue has blocks " << start_height << "-" << (start_height + blocks.size() - 1) << ", we need " << previous_height); + + block new_block; + if (!parse_and_validate_block_from_blob(blocks.front().block, new_block)) + { + MERROR("Failed to parse block, but it should already have been parsed"); + break; + } + bool parent_known = m_core.have_block(new_block.prev_id); + if (!parent_known) + { + // it could be: + // - later in the current chain + // - later in an alt chain + // - orphan + // if it was requested, then it'll be resolved later, otherwise it's an orphan + bool parent_requested = false; + m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool{ + if (context.m_requested_objects.find(new_block.prev_id) != context.m_requested_objects.end()) + { + parent_requested = true; + return false; + } + return true; + }); + if (!parent_requested) + { + LOG_ERROR_CCONTEXT("Got block with unknown parent which was not requested - dropping connection"); + // in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it + m_block_queue.remove_spans(span_connection_id, start_height); + return 1; + } + + // parent was requested, so we wait for it to be retrieved + MINFO(context << " parent was requested, we'll get back to it"); + break; + } + const boost::posix_time::ptime start = boost::posix_time::microsec_clock::universal_time(); m_core.prepare_handle_incoming_blocks(blocks); From 35e01a6e505fc614484f6d880bcc7b83f35e6486 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 15 Aug 2017 17:49:06 +0100 Subject: [PATCH 3/3] cryptonote_protocol: fix "holes" in block download schedule --- src/cryptonote_protocol/cryptonote_protocol_handler.inl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index e9dcd135..0e79c0e4 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -959,6 +959,8 @@ namespace cryptonote MDEBUG(context << " adding span: " << arg.blocks.size() << " at height " << start_height << ", " << dt.total_microseconds()/1e6 << " seconds, " << (rate/1e3) << " kB/s, size now " << (m_block_queue.get_data_size() + blocks_size) / 1048576.f << " MB"); m_block_queue.add_blocks(start_height, arg.blocks, context.m_connection_id, rate, blocks_size); + context.m_last_known_hash = cryptonote::get_blob_hash(arg.blocks.back().block); + if (m_core.get_test_drop_download() && m_core.get_test_drop_download_height()) { // DISCARD BLOCKS for testing // We try to lock the sync lock. If we can, it means no other thread is @@ -1521,7 +1523,6 @@ skip: { context.m_needed_objects.push_back(bl_id); } - context.m_last_known_hash = context.m_needed_objects.back(); if (!request_missing_objects(context, false)) {