diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2012-05-07 21:36:30 +0200 |
---|---|---|
committer | Luke Dashjr <luke-jr+git@utopios.org> | 2012-05-17 23:45:49 +0000 |
commit | c455aec6997ad9164f1083e93bb51095a25180cd (patch) | |
tree | ed980147b825c7632e9b3e56b8c1c060c48dafcb | |
parent | 18b4eccddb7146522b18c5a6add113544a80df99 (diff) | |
download | bitcoin-c455aec6997ad9164f1083e93bb51095a25180cd.tar.xz |
Hopefully final fix for the stuck blockchain issue
Immediately issue a "getblocks", instead of a "getdata" (which will
trigger the relevant "inv" to be sent anyway), and only do so when
the previous set of invs led us into a known and attached part of
the block tree.
-rw-r--r-- | src/main.cpp | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/src/main.cpp b/src/main.cpp index a2fc7387fb..0abba822a8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2180,8 +2180,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // find last block in inv vector unsigned int nLastBlock = (unsigned int)(-1); for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) { - if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) + if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) { nLastBlock = vInv.size() - 1 - nInv; + break; + } } CTxDB txdb("r"); for (int nInv = 0; nInv < vInv.size(); nInv++) @@ -2196,19 +2198,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (fDebug) printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new"); - // Always request the last block in an inv bundle (even if we already have it), as it is the - // trigger for the other side to send further invs. If we are stuck on a (very long) side chain, - // this is necessary to connect earlier received orphan blocks to the chain again. - if (fAlreadyHave && nInv == nLastBlock) { - // bypass mapAskFor, and send request directly; it must go through. - std::vector<CInv> vGetData(1,inv); - pfrom->PushMessage("getdata", vGetData); - } - if (!fAlreadyHave) pfrom->AskFor(inv); - else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) + else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) { pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash])); + } else if (nInv == nLastBlock) { + // In case we are on a very long side-chain, it is possible that we already have + // the last block in an inv bundle sent in response to getblocks. Try to detect + // this situation and push another getblocks to continue. + std::vector<CInv> vGetData(1,inv); + pfrom->PushGetBlocks(mapBlockIndex[inv.hash], uint256(0)); + if (fDebug) + printf("force request: %s\n", inv.ToString().c_str()); + } // Track requests for our stuff Inventory(inv.hash); |