aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_protocol/cryptonote_protocol_handler.inl
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_protocol/cryptonote_protocol_handler.inl')
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler.inl67
1 files changed, 52 insertions, 15 deletions
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
index a64ba622a..48ba963f2 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
@@ -239,6 +239,8 @@ namespace cryptonote
cnx.connection_id = cntxt.m_connection_id;
+ cnx.height = cntxt.m_remote_blockchain_height;
+
connections.push_back(cnx);
return true;
@@ -264,6 +266,8 @@ namespace cryptonote
return false;
}
+ context.m_remote_blockchain_height = hshd.current_height;
+
uint64_t target = m_core.get_target_blockchain_height();
if (target == 0)
target = m_core.get_current_blockchain_height();
@@ -293,7 +297,6 @@ namespace cryptonote
}
LOG_PRINT_L1("Remote blockchain height: " << hshd.current_height << ", id: " << hshd.top_id);
context.m_state = cryptonote_connection_context::state_synchronizing;
- context.m_remote_blockchain_height = hshd.current_height;
//let the socket to send response to handshake, but request callback, to let send request data after response
LOG_PRINT_CCONTEXT_L2("requesting callback");
++context.m_callback_request_count;
@@ -922,7 +925,8 @@ namespace cryptonote
}
{
- MLOG_YELLOW(el::Level::Debug, "Got NEW BLOCKS inside of " << __FUNCTION__ << ": size: " << arg.blocks.size());
+ MLOG_YELLOW(el::Level::Debug, context << " Got NEW BLOCKS inside of " << __FUNCTION__ << ": size: " << arg.blocks.size()
+ << ", blocks: " << start_height << " - " << (start_height + arg.blocks.size() - 1));
// add that new span to the block queue
const boost::posix_time::time_duration dt = now - context.m_last_request_time;
@@ -930,6 +934,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
@@ -953,7 +959,6 @@ namespace cryptonote
uint64_t start_height;
std::list<cryptonote::block_complete_entry> blocks;
boost::uuids::uuid span_connection_id;
- m_block_queue.mark_last_block(previous_height - 1);
if (!m_block_queue.get_next_span(start_height, blocks, span_connection_id))
{
MDEBUG(context << " no next span found, going back to download");
@@ -961,9 +966,41 @@ namespace cryptonote
}
MDEBUG(context << " next span in the queue has blocks " << start_height << "-" << (start_height + blocks.size() - 1)
<< ", we need " << previous_height);
- if (previous_height < start_height || previous_height >= start_height + blocks.size())
+
+
+ block new_block;
+ if (!parse_and_validate_block_from_blob(blocks.front().block, new_block))
{
- MDEBUG(context << " this span is not what we need, going back to download");
+ 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;
}
@@ -1053,7 +1090,7 @@ namespace cryptonote
m_core.cleanup_handle_incoming_blocks();
- m_block_queue.mark_last_block(m_core.get_current_blockchain_height() - 1);
+ m_block_queue.remove_spans(span_connection_id, start_height);
if (m_core.get_current_blockchain_height() > previous_height)
{
@@ -1169,8 +1206,6 @@ skip:
template<class t_core>
bool t_cryptonote_protocol_handler<t_core>::request_missing_objects(cryptonote_connection_context& context, bool check_having_blocks, bool force_next_span)
{
- m_block_queue.mark_last_block(m_core.get_current_blockchain_height() - 1);
-
// flush stale spans
std::set<boost::uuids::uuid> live_connections;
m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool{
@@ -1276,8 +1311,13 @@ skip:
context.m_last_response_height = 0;
goto skip;
}
+ // take out blocks we already have
+ while (!context.m_needed_objects.empty() && m_core.have_block(context.m_needed_objects.front()))
+ {
+ context.m_needed_objects.pop_front();
+ }
const uint64_t first_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1;
- span = m_block_queue.reserve_span(first_block_height, context.m_last_response_height, count_limit, context.m_connection_id);
+ span = m_block_queue.reserve_span(first_block_height, context.m_last_response_height, count_limit, context.m_connection_id, context.m_needed_objects);
MDEBUG(context << " span from " << first_block_height << ": " << span.first << "/" << span.second);
}
if (span.second == 0 && !force_next_span)
@@ -1328,8 +1368,6 @@ skip:
auto j = it++;
context.m_needed_objects.erase(j);
}
-
- m_block_queue.set_span_hashes(span.first, context.m_connection_id, hashes);
}
context.m_last_request_time = boost::posix_time::microsec_clock::universal_time();
@@ -1352,10 +1390,9 @@ skip:
if (!start_from_current_chain)
{
- // we'll want to start off from where we are on the download side, which may not be added yet
- crypto::hash last_known_hash = m_block_queue.get_last_known_hash();
- if (last_known_hash != cryptonote::null_hash && r.block_ids.front() != last_known_hash)
- r.block_ids.push_front(last_known_hash);
+ // we'll want to start off from where we are on that peer, which may not be added yet
+ if (context.m_last_known_hash != cryptonote::null_hash && r.block_ids.front() != context.m_last_known_hash)
+ r.block_ids.push_front(context.m_last_known_hash);
}
handler_request_blocks_history( r.block_ids ); // change the limit(?), sleep(?)