Skip to content

Commit c60fd71

Browse files
committed
Disconnecting from bad outbound peers in IBD
When in IBD, we'd like to use all our outbound peers to help us sync the chain. Disconnect any outbound peers whose headers have insufficient work.
1 parent 326a565 commit c60fd71

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

src/net_processing.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,6 +2383,24 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
23832383
}
23842384
}
23852385
}
2386+
// If we're in IBD, we want outbound peers that will serve us a useful
2387+
// chain. Disconnect peers that are on chains with insufficient work.
2388+
if (IsInitialBlockDownload() && nCount != MAX_HEADERS_RESULTS) {
2389+
// When nCount < MAX_HEADERS_RESULTS, we know we have no more
2390+
// headers to fetch from this peer.
2391+
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
2392+
// This peer has too little work on their headers chain to help
2393+
// us sync -- disconnect if using an outbound slot (unless
2394+
// whitelisted or addnode).
2395+
// Note: We compare their tip to nMinimumChainWork (rather than
2396+
// chainActive.Tip()) because we won't start block download
2397+
// until we have a headers chain that has at least
2398+
// nMinimumChainWork, even if a peer has a chain past our tip,
2399+
if (!(pfrom->fInbound || pfrom->fWhitelisted || pfrom->m_manual_connection)) {
2400+
pfrom->fDisconnect = true;
2401+
}
2402+
}
2403+
}
23862404
}
23872405
}
23882406

test/functional/minchainwork.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class MinimumChainWorkTest(BitcoinTestFramework):
2727
def set_test_params(self):
2828
self.setup_clean_chain = True
2929
self.num_nodes = 3
30+
3031
self.extra_args = [[], ["-minimumchainwork=0x65"], ["-minimumchainwork=0x65"]]
3132
self.node_min_work = [0, 101, 101]
3233

@@ -74,6 +75,13 @@ def run_test(self):
7475
self.nodes[0].generate(1)
7576

7677
self.log.info("Verifying nodes are all synced")
78+
79+
# Because nodes in regtest are all manual connections (eg using
80+
# addnode), node1 should not have disconnected node0. If not for that,
81+
# we'd expect node1 to have disconnected node0 for serving an
82+
# insufficient work chain, in which case we'd need to reconnect them to
83+
# continue the test.
84+
7785
self.sync_all()
7886
self.log.info("Blockcounts: %s", [n.getblockcount() for n in self.nodes])
7987

0 commit comments

Comments
 (0)