changeset 2996:0a7ba0bc28d0 draft

Merge branch '0.4.x' into 0.5.x
author Luke Dashjr <luke-jr+git@utopios.org>
date Mon, 07 May 2012 02:46:14 +0000
parents 116bad5f9ba5 (current diff) dd5a9271101d (diff)
children f59c34abfbfa
files src/main.cpp
diffstat 1 files changed, 18 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2213,9 +2213,17 @@
             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");
-        BOOST_FOREACH(const CInv& inv, vInv)
+        for (int nInv = 0; nInv < vInv.size(); nInv++)
         {
+            const CInv &inv = vInv[nInv];
+
             if (fShutdown)
                 return true;
             pfrom->AddInventoryKnown(inv);
@@ -2224,6 +2232,15 @@
             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))