From 67d838433dedc48f6b9531edfd969b9641570829 Mon Sep 17 00:00:00 2001 From: Krystie Date: Sun, 24 May 2026 22:36:13 -0700 Subject: [PATCH] Fix getblocks: serve main chain to fork peers instead of banning them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fork nodes (DNS3/DNS2 stuck on block 570 chain) send locators that don't match any main chain block. Instead of disconnecting/ banning after 3 failed getblocks attempts, this change: - Serves main chain blocks from genesis when locator has no match - Resets nIncompatibleGetblocks counter after 10 (so we never ban) - Fork nodes will receive, validate, and automatically reorg to the longer/higher-work main chain once they see it This fixes the 'no common blocks' deadlock while preserving chain integrity — only a genuinely longer chain can trigger the reorg. --- src/main.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 83e3e83..affb3e2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4372,19 +4372,25 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // GetBlockIndex() fell through to genesis (no locator hash matched // our main chain). If the peer's tip isn't our genesis, // they're on a completely different fork. + // + // triangles fix: instead of banning or disconnecting, always respond + // with our main chain blocks so a fork node can learn the canonical + // chain and reorganize. The fork node's client will automatically + // reorg when it receives blocks that form a longer or higher-work chain. if (!locator.IsNull() && pindex == pindexGenesisBlock && pindexGenesisBlock && locator.GetTipHash() != pindexGenesisBlock->GetBlockHash()) { pfrom->nIncompatibleGetblocks++; - if (pfrom->nIncompatibleGetblocks >= 3) - { - printf("WARNING: peer %s sent %d getblocks with no common blocks — disconnecting (incompatible fork)\n", - pfrom->addr.ToString().c_str(), pfrom->nIncompatibleGetblocks); - pfrom->Misbehaving(100); - return true; - } - printf("WARNING: peer %s getblocks locator has no common blocks (%d/3 before ban)\n", + // triangles: after many failed attempts, reset — the peer may now be + // on the correct chain and we don't want to ban a node that's just + // learning about the main chain from us. + if (pfrom->nIncompatibleGetblocks > 10) + pfrom->nIncompatibleGetblocks = 0; + // triangles: NO return/ban here — fall through and serve main chain + // blocks so the forking peer can reorg to our chain. + printf("WARNING: peer %s getblocks locator has no common blocks — serving main chain from genesis (counter=%d, will reset after 10)\\n", pfrom->addr.ToString().c_str(), pfrom->nIncompatibleGetblocks); + pindex = pindexGenesisBlock; } else if (pindex && pindex != pindexGenesisBlock) {