Skip to content

Commit 6efbcec

Browse files
committed
Protect last outbound HB compact block peer
If all our high-bandwidth compact block serving peers (BIP 152) stall block download, then we can be denied a block for (potentially) a long time. As inbound connections are much more likely to be adversarial than outbound connections, mitigate this risk by never removing our last outbound HB peer if it would be replaced by an inbound.
1 parent c7dd9ff commit 6efbcec

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

src/net_processing.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,12 +825,27 @@ void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid)
825825
return;
826826
}
827827
if (nodestate->fProvidesHeaderAndIDs) {
828+
int num_outbound_hb_peers = 0;
828829
for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
829830
if (*it == nodeid) {
830831
lNodesAnnouncingHeaderAndIDs.erase(it);
831832
lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
832833
return;
833834
}
835+
CNodeState *state = State(*it);
836+
if (state != nullptr && !state->m_is_inbound) ++num_outbound_hb_peers;
837+
}
838+
if (nodestate->m_is_inbound) {
839+
// If we're adding an inbound HB peer, make sure we're not removing
840+
// our last outbound HB peer in the process.
841+
if (lNodesAnnouncingHeaderAndIDs.size() >= 3 && num_outbound_hb_peers == 1) {
842+
CNodeState *remove_node = State(lNodesAnnouncingHeaderAndIDs.front());
843+
if (remove_node != nullptr && !remove_node->m_is_inbound) {
844+
// Put the HB outbound peer in the second slot, so that it
845+
// doesn't get removed.
846+
std::swap(lNodesAnnouncingHeaderAndIDs.front(), *std::next(lNodesAnnouncingHeaderAndIDs.begin()));
847+
}
848+
}
834849
}
835850
m_connman.ForNode(nodeid, [this](CNode* pfrom) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
836851
AssertLockHeld(::cs_main);

0 commit comments

Comments
 (0)