diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 1dcfe0a09..e0bd59e00 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -618,8 +618,10 @@ namespace cryptonote } // Log block info + const uint64_t new_block_height = get_block_height(new_block); + const uint64_t peer_height = arg.current_blockchain_height; MLOG_P2P_MESSAGE(context << "Received NOTIFY_NEW_FLUFFY_BLOCK " << new_block_hash << " (height " - << arg.current_blockchain_height << ", " << arg.b.txs.size() << " txes)"); + << new_block_height << ", " << arg.b.txs.size() << " txes, peer's height: " << peer_height << ")"); // Pause mining and resume after block verification to prevent wasted mining cycles while // validating the next block. Needs more research into if this is a DoS vector or not. Invalid @@ -708,7 +710,7 @@ namespace cryptonote MDEBUG(" tx " << new_block.tx_hashes[txidx]); NOTIFY_REQUEST_FLUFFY_MISSING_TX::request missing_tx_req; missing_tx_req.block_hash = new_block_hash; - missing_tx_req.current_blockchain_height = arg.current_blockchain_height; + missing_tx_req.current_blockchain_height = new_block_height + 1; missing_tx_req.missing_tx_indices = std::move(need_tx_indices); // Post NOTIFY_REQUEST_FLUFFY_MISSING_TX request to peer @@ -725,6 +727,7 @@ namespace cryptonote } else if( bvc.m_added_to_main_chain ) { + arg.current_blockchain_height = new_block_height + 1; // Relay an empty block arg.b.txs.clear(); relay_block(arg, context); @@ -744,6 +747,15 @@ namespace cryptonote MLOG_PEER_STATE("requesting chain"); } + if (bvc.m_added_to_main_chain || bvc.m_already_exists) + { + // Update peer's sync height using this block we just validated + // Note: peer_height is not guaranteed to be the height of the block we just validated + 1. + // See https://github.com/monero-project/monero/pull/11048#discussion_r3720736824 + if (peer_height == (new_block_height + 1)) + context.m_remote_blockchain_height = peer_height; + } + // load json & DNS checkpoints every 10min/hour respectively, // and verify them with respect to what blocks we already have CHECK_AND_ASSERT_MES(m_core.update_checkpoints(), 1, "One or more checkpoints loaded from json or dns conflicted with existing checkpoints."); diff --git a/src/cryptonote_protocol/levin_notify.cpp b/src/cryptonote_protocol/levin_notify.cpp index 0fbc7248b..f5e48d329 100644 --- a/src/cryptonote_protocol/levin_notify.cpp +++ b/src/cryptonote_protocol/levin_notify.cpp @@ -147,7 +147,9 @@ namespace levin of waiting in here. */ p2p.foreach_connection([&outs, blockchain_height] (detail::p2p_context& context) { - if (!context.m_is_income && context.m_remote_blockchain_height >= blockchain_height) + // Give a +2 allowable window for candidate peers, since we may not have updated the peer's + // known sync height yet (e.g. if we haven't received or finished processing their new block(s) yet) + if (!context.m_is_income && (context.m_remote_blockchain_height + 2) >= blockchain_height) outs.emplace_back(context.m_connection_id); return true; });