Merge hd-wallet into master: I2P process integration + HD wallet + reconcile with origin/master v5.9.15
This commit is contained in:
+53
-1
@@ -4500,8 +4500,60 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
{
|
||||
// Find the last block the caller has in the main chain
|
||||
pindex = locator.GetBlockIndex();
|
||||
|
||||
// triangles fix: handle broken pnext chain.
|
||||
// GetBlockIndex() returns pindexGenesisBlock when no locator
|
||||
// hash matches our main chain (peer is on a different fork or
|
||||
// a stale local state). pindexGenesisBlock->pnext is always
|
||||
// null, which would cause the for-loop below to send ZERO
|
||||
// headers, leaving the peer stuck (logged as "getheaders -1").
|
||||
//
|
||||
// Mirror the getblocks handler: if the locator matches nothing
|
||||
// on our main chain, serve our headers from genesis so the peer
|
||||
// can discover the canonical chain. Then fall back to a tip-
|
||||
// backwards walk if pnext is null for any other reason (this
|
||||
// happens when LoadBlockIndex() didn't fully heal pnext links,
|
||||
// or the chain was bootstrapped from a snapshot).
|
||||
//
|
||||
// pitfall #61 guard: if pindexFinalized is set (from the startup
|
||||
// hardcoded-checkpoint init in init.cpp), serve from there instead
|
||||
// of genesis. This prevents a fork peer from feeding us their
|
||||
// short chain back via getheaders — the peer only learns our
|
||||
// canonical chain from the finalized point forward, and their
|
||||
// conflicting fork gets rejected at the reorg check in
|
||||
// Reorganize() because the fork point is below pindexFinalized.
|
||||
if (!locator.IsNull() && pindex == pindexGenesisBlock &&
|
||||
pindexGenesisBlock && locator.GetTipHash() != pindexGenesisBlock->GetBlockHash())
|
||||
{
|
||||
if (pindexFinalized && pindexFinalized->pnext)
|
||||
{
|
||||
printf("getheaders: fork detected from peer %s, serving headers from finalized block %d (not genesis) — pitfall #61 guard\n",
|
||||
pfrom->addr.ToString().c_str(), pindexFinalized->nHeight);
|
||||
pindex = pindexFinalized;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WARNING: peer getheaders locator has no common blocks — serving headers from genesis (peer may be on a fork)\n");
|
||||
pindex = pindexGenesisBlock;
|
||||
}
|
||||
}
|
||||
|
||||
if (pindex)
|
||||
pindex = pindex->pnext;
|
||||
{
|
||||
if (pindex->pnext)
|
||||
{
|
||||
pindex = pindex->pnext;
|
||||
}
|
||||
else
|
||||
{
|
||||
// pnext is null — fall back to walking from pindexBest
|
||||
// backwards to find the block immediately after pindex
|
||||
CBlockIndex* pWalk = pindexBest;
|
||||
while (pWalk && pWalk->pprev != pindex)
|
||||
pWalk = pWalk->pprev;
|
||||
pindex = pWalk; // null if pindex is already the tip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<CBlock> vHeaders;
|
||||
|
||||
Reference in New Issue
Block a user