Fix getblocks: serve main chain to fork peers instead of banning them
Build All Platforms / test-linux-unit (push) Failing after 40s
Build All Platforms / test-linux-sanitizers (push) Failing after 40s
Build All Platforms / build-linux-qt (push) Failing after 40s
Build All Platforms / build-linux-daemon (push) Failing after 40s
Build All Platforms / build-windows-qt (push) Has been cancelled
Build All Platforms / build-windows-daemon (push) Has been cancelled
Build All Platforms / build-macos (push) Has been cancelled
Build All Platforms / release (push) Has been cancelled
Build All Platforms / Trigger TRI-PI ARM64 Build (push) Has been cancelled
Build All Platforms / test-linux-unit (push) Failing after 40s
Build All Platforms / test-linux-sanitizers (push) Failing after 40s
Build All Platforms / build-linux-qt (push) Failing after 40s
Build All Platforms / build-linux-daemon (push) Failing after 40s
Build All Platforms / build-windows-qt (push) Has been cancelled
Build All Platforms / build-windows-daemon (push) Has been cancelled
Build All Platforms / build-macos (push) Has been cancelled
Build All Platforms / release (push) Has been cancelled
Build All Platforms / Trigger TRI-PI ARM64 Build (push) Has been cancelled
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.
This commit is contained in:
+14
-8
@@ -4372,19 +4372,25 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
// GetBlockIndex() fell through to genesis (no locator hash matched
|
// GetBlockIndex() fell through to genesis (no locator hash matched
|
||||||
// our main chain). If the peer's tip isn't our genesis,
|
// our main chain). If the peer's tip isn't our genesis,
|
||||||
// they're on a completely different fork.
|
// 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 &&
|
if (!locator.IsNull() && pindex == pindexGenesisBlock &&
|
||||||
pindexGenesisBlock && locator.GetTipHash() != pindexGenesisBlock->GetBlockHash())
|
pindexGenesisBlock && locator.GetTipHash() != pindexGenesisBlock->GetBlockHash())
|
||||||
{
|
{
|
||||||
pfrom->nIncompatibleGetblocks++;
|
pfrom->nIncompatibleGetblocks++;
|
||||||
if (pfrom->nIncompatibleGetblocks >= 3)
|
// 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
|
||||||
printf("WARNING: peer %s sent %d getblocks with no common blocks — disconnecting (incompatible fork)\n",
|
// learning about the main chain from us.
|
||||||
pfrom->addr.ToString().c_str(), pfrom->nIncompatibleGetblocks);
|
if (pfrom->nIncompatibleGetblocks > 10)
|
||||||
pfrom->Misbehaving(100);
|
pfrom->nIncompatibleGetblocks = 0;
|
||||||
return true;
|
// 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 (%d/3 before ban)\n",
|
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);
|
pfrom->addr.ToString().c_str(), pfrom->nIncompatibleGetblocks);
|
||||||
|
pindex = pindexGenesisBlock;
|
||||||
}
|
}
|
||||||
else if (pindex && pindex != pindexGenesisBlock)
|
else if (pindex && pindex != pindexGenesisBlock)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user