aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2017-08-15 16:54:08 +0100
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2017-08-15 16:54:08 +0100
commit3da1edfde573d7ff21f9c2f986046e4d5c026259 (patch)
tree7664c3753a9b80845f5539e6514fb3ae704d38cf /src
parentblock_queue: do not add empty spans (diff)
downloadmonero-3da1edfde573d7ff21f9c2f986046e4d5c026259.tar.xz
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.
Diffstat (limited to 'src')
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler.inl37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
index b5a307208..e9dcd135f 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);