mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-05 14:06:27 -05:00
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.
This commit is contained in:
parent
c7dd9ff71b
commit
6efbcec4de
1 changed files with 15 additions and 0 deletions
|
@ -825,12 +825,27 @@ void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid)
|
|||
return;
|
||||
}
|
||||
if (nodestate->fProvidesHeaderAndIDs) {
|
||||
int num_outbound_hb_peers = 0;
|
||||
for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
|
||||
if (*it == nodeid) {
|
||||
lNodesAnnouncingHeaderAndIDs.erase(it);
|
||||
lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
|
||||
return;
|
||||
}
|
||||
CNodeState *state = State(*it);
|
||||
if (state != nullptr && !state->m_is_inbound) ++num_outbound_hb_peers;
|
||||
}
|
||||
if (nodestate->m_is_inbound) {
|
||||
// If we're adding an inbound HB peer, make sure we're not removing
|
||||
// our last outbound HB peer in the process.
|
||||
if (lNodesAnnouncingHeaderAndIDs.size() >= 3 && num_outbound_hb_peers == 1) {
|
||||
CNodeState *remove_node = State(lNodesAnnouncingHeaderAndIDs.front());
|
||||
if (remove_node != nullptr && !remove_node->m_is_inbound) {
|
||||
// Put the HB outbound peer in the second slot, so that it
|
||||
// doesn't get removed.
|
||||
std::swap(lNodesAnnouncingHeaderAndIDs.front(), *std::next(lNodesAnnouncingHeaderAndIDs.begin()));
|
||||
}
|
||||
}
|
||||
}
|
||||
m_connman.ForNode(nodeid, [this](CNode* pfrom) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
|
||||
AssertLockHeld(::cs_main);
|
||||
|
|
Loading…
Add table
Reference in a new issue