Browse Source

Prevent stuck download: correct solution

Pull request #948 introduced a fix for nodes stuck on a long side branch
of the main chain. The fix was non-functional however, as the additional
getdata request was created in a first step of processing, but dropped
in a second step as it was considered redundant. This commits fixes it
by sending the request directly.
miguelfreitas
Pieter Wuille 13 years ago
parent
commit
6860133373
  1. 16
      src/main.cpp

16
src/main.cpp

@ -2391,6 +2391,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
return error("message inv size() = %d", vInv.size()); return error("message inv size() = %d", vInv.size());
} }
// 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)
nLastBlock = vInv.size() - 1 - nInv;
}
CTxDB txdb("r"); CTxDB txdb("r");
for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
{ {
@ -2407,9 +2413,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// Always request the last block in an inv bundle (even if we already have it), as it is the // 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, // 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. // this is necessary to connect earlier received orphan blocks to the chain again.
if (!fAlreadyHave || (inv.type == MSG_BLOCK && nInv==vInv.size()-1)) 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); pfrom->AskFor(inv);
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])); pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
// Track requests for our stuff // Track requests for our stuff

Loading…
Cancel
Save