aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2012-05-07 21:36:30 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2012-05-15 17:53:46 +0200
commit385f730f31ab7218d8c0fcc76f5c7a2b35783c6a (patch)
tree8dcac2bad7eba078e1b20a83fcc82df347151aac
parent790fe2e558d93572f87b7f4117a54d899903c5bf (diff)
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.cpp24
1 files changed, 13 insertions, 11 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 29c407f4a0..e40acf6d32 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2482,8 +2482,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 (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
@@ -2498,19 +2500,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);