Merge pull request #2272

f90bbe2a cryptonote_protocol: keep target in sync with dropped connections (moneromooo-monero)
This commit is contained in:
Riccardo Spagni 2017-08-15 20:51:35 +02:00
commit e0df740bc9
No known key found for this signature in database
GPG Key ID: 55432DF31CCD4FCD
2 changed files with 56 additions and 67 deletions

View File

@ -130,6 +130,8 @@ namespace cryptonote
size_t get_synchronizing_connections_count(); size_t get_synchronizing_connections_count();
bool on_connection_synchronized(); bool on_connection_synchronized();
bool should_download_next_span(cryptonote_connection_context& context) const; bool should_download_next_span(cryptonote_connection_context& context) const;
void drop_connection(cryptonote_connection_context &context, bool add_fail, bool flush_all_spans);
t_core& m_core; t_core& m_core;
nodetool::p2p_endpoint_stub<connection_context> m_p2p_stub; nodetool::p2p_endpoint_stub<connection_context> m_p2p_stub;

View File

@ -344,10 +344,9 @@ namespace cryptonote
if(tvc.m_verifivation_failed) if(tvc.m_verifivation_failed)
{ {
LOG_PRINT_CCONTEXT_L1("Block verification failed: transaction verification failed, dropping connection"); LOG_PRINT_CCONTEXT_L1("Block verification failed: transaction verification failed, dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_core.cleanup_handle_incoming_blocks(); m_core.cleanup_handle_incoming_blocks();
m_core.resume_mine(); m_core.resume_mine();
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
} }
@ -359,9 +358,7 @@ namespace cryptonote
if(bvc.m_verifivation_failed) if(bvc.m_verifivation_failed)
{ {
LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection"); LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection");
m_p2p->drop_connection(context); drop_connection(context, true, false);
m_p2p->add_host_fail(context.m_remote_address);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
if(bvc.m_added_to_main_chain) if(bvc.m_added_to_main_chain)
@ -414,8 +411,7 @@ namespace cryptonote
<< ", dropping connection" << ", dropping connection"
); );
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
m_core.resume_mine(); m_core.resume_mine();
return 1; return 1;
} }
@ -448,8 +444,7 @@ namespace cryptonote
<< ", dropping connection" << ", dropping connection"
); );
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
m_core.resume_mine(); m_core.resume_mine();
return 1; return 1;
} }
@ -463,8 +458,7 @@ namespace cryptonote
<< ", dropping connection" << ", dropping connection"
); );
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
m_core.resume_mine(); m_core.resume_mine();
return 1; return 1;
} }
@ -488,8 +482,7 @@ namespace cryptonote
<< "dropping connection" << "dropping connection"
); );
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
m_core.resume_mine(); m_core.resume_mine();
return 1; return 1;
} }
@ -506,8 +499,7 @@ namespace cryptonote
if(!m_core.handle_incoming_tx(tx_blob, tvc, true, true, false) || tvc.m_verifivation_failed) if(!m_core.handle_incoming_tx(tx_blob, tvc, true, true, false) || tvc.m_verifivation_failed)
{ {
LOG_PRINT_CCONTEXT_L1("Block verification failed: transaction verification failed, dropping connection"); LOG_PRINT_CCONTEXT_L1("Block verification failed: transaction verification failed, dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
m_core.resume_mine(); m_core.resume_mine();
return 1; return 1;
} }
@ -529,8 +521,7 @@ namespace cryptonote
<< ", dropping connection" << ", dropping connection"
); );
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
m_core.resume_mine(); m_core.resume_mine();
return 1; return 1;
} }
@ -550,8 +541,7 @@ namespace cryptonote
<< ", dropping connection" << ", dropping connection"
); );
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
m_core.resume_mine(); m_core.resume_mine();
return 1; return 1;
} }
@ -628,9 +618,7 @@ namespace cryptonote
if( bvc.m_verifivation_failed ) if( bvc.m_verifivation_failed )
{ {
LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection"); LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection");
m_p2p->drop_connection(context); drop_connection(context, true, false);
m_p2p->add_host_fail(context.m_remote_address);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
if( bvc.m_added_to_main_chain ) if( bvc.m_added_to_main_chain )
@ -663,8 +651,7 @@ namespace cryptonote
); );
m_core.resume_mine(); m_core.resume_mine();
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
@ -684,8 +671,7 @@ namespace cryptonote
if (!m_core.get_block_by_hash(arg.block_hash, b)) if (!m_core.get_block_by_hash(arg.block_hash, b))
{ {
LOG_ERROR_CCONTEXT("failed to find block: " << arg.block_hash << ", dropping connection"); LOG_ERROR_CCONTEXT("failed to find block: " << arg.block_hash << ", dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
@ -712,8 +698,7 @@ namespace cryptonote
<< ", dropping connection" << ", dropping connection"
); );
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
} }
@ -724,16 +709,14 @@ namespace cryptonote
{ {
LOG_ERROR_CCONTEXT("Failed to handle request NOTIFY_REQUEST_FLUFFY_MISSING_TX, " LOG_ERROR_CCONTEXT("Failed to handle request NOTIFY_REQUEST_FLUFFY_MISSING_TX, "
<< "failed to get requested transactions"); << "failed to get requested transactions");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
if (!missed.empty() || txs.size() != txids.size()) if (!missed.empty() || txs.size() != txids.size())
{ {
LOG_ERROR_CCONTEXT("Failed to handle request NOTIFY_REQUEST_FLUFFY_MISSING_TX, " LOG_ERROR_CCONTEXT("Failed to handle request NOTIFY_REQUEST_FLUFFY_MISSING_TX, "
<< missed.size() << " requested transactions not found" << ", dropping connection"); << missed.size() << " requested transactions not found" << ", dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
@ -776,8 +759,7 @@ namespace cryptonote
if(tvc.m_verifivation_failed) if(tvc.m_verifivation_failed)
{ {
LOG_PRINT_CCONTEXT_L1("Tx verification failed, dropping connection"); LOG_PRINT_CCONTEXT_L1("Tx verification failed, dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
if(tvc.m_should_be_relayed) if(tvc.m_should_be_relayed)
@ -803,8 +785,7 @@ namespace cryptonote
if(!m_core.handle_get_objects(arg, rsp, context)) if(!m_core.handle_get_objects(arg, rsp, context))
{ {
LOG_ERROR_CCONTEXT("failed to handle request NOTIFY_REQUEST_GET_OBJECTS, dropping connection"); LOG_ERROR_CCONTEXT("failed to handle request NOTIFY_REQUEST_GET_OBJECTS, dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_RESPONSE_GET_OBJECTS: blocks.size()=" << rsp.blocks.size() << ", txs.size()=" << rsp.txs.size() LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_RESPONSE_GET_OBJECTS: blocks.size()=" << rsp.blocks.size() << ", txs.size()=" << rsp.txs.size()
@ -871,8 +852,7 @@ namespace cryptonote
{ {
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_HAVE_OBJECTS: arg.m_current_blockchain_height=" << arg.current_blockchain_height LOG_ERROR_CCONTEXT("sent wrong NOTIFY_HAVE_OBJECTS: arg.m_current_blockchain_height=" << arg.current_blockchain_height
<< " < m_last_response_height=" << context.m_last_response_height << ", dropping connection"); << " < m_last_response_height=" << context.m_last_response_height << ", dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
@ -894,16 +874,14 @@ namespace cryptonote
{ {
LOG_ERROR_CCONTEXT("sent wrong block: failed to parse and validate block: " LOG_ERROR_CCONTEXT("sent wrong block: failed to parse and validate block: "
<< epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << ", dropping connection"); << epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << ", dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
if (b.miner_tx.vin.size() != 1 || b.miner_tx.vin.front().type() != typeid(txin_gen)) if (b.miner_tx.vin.size() != 1 || b.miner_tx.vin.front().type() != typeid(txin_gen))
{ {
LOG_ERROR_CCONTEXT("sent wrong block: block: miner tx does not have exactly one txin_gen input" LOG_ERROR_CCONTEXT("sent wrong block: block: miner tx does not have exactly one txin_gen input"
<< epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << ", dropping connection"); << epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << ", dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
if (start_height == std::numeric_limits<uint64_t>::max()) if (start_height == std::numeric_limits<uint64_t>::max())
@ -915,16 +893,14 @@ namespace cryptonote
{ {
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block)) LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block))
<< " wasn't requested, dropping connection"); << " wasn't requested, dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
if(b.tx_hashes.size() != block_entry.txs.size()) if(b.tx_hashes.size() != block_entry.txs.size())
{ {
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block)) LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block))
<< ", tx_hashes.size()=" << b.tx_hashes.size() << " mismatch with block_complete_entry.m_txs.size()=" << block_entry.txs.size() << ", dropping connection"); << ", tx_hashes.size()=" << b.tx_hashes.size() << " mismatch with block_complete_entry.m_txs.size()=" << block_entry.txs.size() << ", dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
@ -936,8 +912,7 @@ namespace cryptonote
{ {
MERROR("returned not all requested objects (context.m_requested_objects.size()=" MERROR("returned not all requested objects (context.m_requested_objects.size()="
<< context.m_requested_objects.size() << "), dropping connection"); << context.m_requested_objects.size() << "), dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
@ -1056,8 +1031,7 @@ namespace cryptonote
if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{ if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{
LOG_ERROR_CCONTEXT("transaction verification failed on NOTIFY_RESPONSE_GET_OBJECTS, tx_id = " LOG_ERROR_CCONTEXT("transaction verification failed on NOTIFY_RESPONSE_GET_OBJECTS, tx_id = "
<< epee::string_tools::pod_to_hex(get_blob_hash(*it)) << ", dropping connection"); << epee::string_tools::pod_to_hex(get_blob_hash(*it)) << ", dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, true);
m_block_queue.flush_spans(context.m_connection_id, true);
return true; return true;
})) }))
LOG_ERROR_CCONTEXT("span connection id not found"); LOG_ERROR_CCONTEXT("span connection id not found");
@ -1082,9 +1056,7 @@ namespace cryptonote
{ {
if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{ if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{
LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection"); LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection");
m_p2p->drop_connection(context); drop_connection(context, true, true);
m_p2p->add_host_fail(context.m_remote_address);
m_block_queue.flush_spans(context.m_connection_id, true);
return true; return true;
})) }))
LOG_ERROR_CCONTEXT("span connection id not found"); LOG_ERROR_CCONTEXT("span connection id not found");
@ -1098,9 +1070,7 @@ namespace cryptonote
{ {
if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{ if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{
LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection"); LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection");
m_p2p->drop_connection(context); drop_connection(context, true, true);
m_p2p->add_host_fail(context.m_remote_address);
m_block_queue.flush_spans(context.m_connection_id, true);
return true; return true;
})) }))
LOG_ERROR_CCONTEXT("span connection id not found"); LOG_ERROR_CCONTEXT("span connection id not found");
@ -1150,8 +1120,7 @@ skip:
if (!request_missing_objects(context, true, force_next_span)) if (!request_missing_objects(context, true, force_next_span))
{ {
LOG_ERROR_CCONTEXT("Failed to request missing objects, dropping connection"); LOG_ERROR_CCONTEXT("Failed to request missing objects, dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
return 1; return 1;
@ -1171,8 +1140,7 @@ skip:
if(!m_core.find_blockchain_supplement(arg.block_ids, r)) if(!m_core.find_blockchain_supplement(arg.block_ids, r))
{ {
LOG_ERROR_CCONTEXT("Failed to handle NOTIFY_REQUEST_CHAIN."); LOG_ERROR_CCONTEXT("Failed to handle NOTIFY_REQUEST_CHAIN.");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_RESPONSE_CHAIN_ENTRY: m_start_height=" << r.start_height << ", m_total_height=" << r.total_height << ", m_block_ids.size()=" << r.m_block_ids.size()); LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_RESPONSE_CHAIN_ENTRY: m_start_height=" << r.start_height << ", m_total_height=" << r.total_height << ", m_block_ids.size()=" << r.m_block_ids.size());
@ -1501,9 +1469,7 @@ skip:
if(!arg.m_block_ids.size()) if(!arg.m_block_ids.size())
{ {
LOG_ERROR_CCONTEXT("sent empty m_block_ids, dropping connection"); LOG_ERROR_CCONTEXT("sent empty m_block_ids, dropping connection");
m_p2p->drop_connection(context); drop_connection(context, true, false);
m_p2p->add_host_fail(context.m_remote_address);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
@ -1514,8 +1480,7 @@ skip:
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_CHAIN_ENTRY, with m_total_height=" << arg.total_height LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_CHAIN_ENTRY, with m_total_height=" << arg.total_height
<< ", m_start_height=" << arg.start_height << ", m_start_height=" << arg.start_height
<< ", m_block_ids.size()=" << arg.m_block_ids.size()); << ", m_block_ids.size()=" << arg.m_block_ids.size());
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
@ -1527,8 +1492,7 @@ skip:
if (!request_missing_objects(context, false)) if (!request_missing_objects(context, false))
{ {
LOG_ERROR_CCONTEXT("Failed to request missing objects, dropping connection"); LOG_ERROR_CCONTEXT("Failed to request missing objects, dropping connection");
m_p2p->drop_connection(context); drop_connection(context, false, false);
m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
return 1; return 1;
@ -1584,6 +1548,29 @@ skip:
m_core.on_transaction_relayed(*tx_blob_it); m_core.on_transaction_relayed(*tx_blob_it);
return relay_post_notify<NOTIFY_NEW_TRANSACTIONS>(arg, exclude_context); return relay_post_notify<NOTIFY_NEW_TRANSACTIONS>(arg, exclude_context);
} }
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
void t_cryptonote_protocol_handler<t_core>::drop_connection(cryptonote_connection_context &context, bool add_fail, bool flush_all_spans)
{
if (add_fail)
m_p2p->add_host_fail(context.m_remote_address);
m_p2p->drop_connection(context);
uint64_t target = 0;
m_p2p->for_each_connection([&](const connection_context& cntxt, nodetool::peerid_type peer_id, uint32_t support_flags) {
if (cntxt.m_state >= cryptonote_connection_context::state_synchronizing && cntxt.m_connection_id != context.m_connection_id)
target = std::max(target, cntxt.m_remote_blockchain_height);
return true;
});
const uint64_t previous_target = m_core.get_target_blockchain_height();
if (target < previous_target)
{
MINFO("Target height decreasing from " << previous_target << " to " << target);
m_core.set_target_blockchain_height(target);
}
m_block_queue.flush_spans(context.m_connection_id, flush_all_spans);
}
//------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------
template<class t_core> template<class t_core>