mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 04:52:59 +01:00
Prevent stuck block download in large reorganisations
In cases of very large reorganisations (hundreds of blocks), a situation may appear where an 'inv' is sent as response to a 'getblocks', but the last block mentioned in the inv is already known to the receiver node. However, the supplying node uses a request for this last block as a trigger to send the rest of the inv blocks. If it never comes, the block chain download is stuck. This commit makes the receiver node always request the last inv'ed block, even if it is already known, to prevent this problem.
This commit is contained in:
parent
ef14236539
commit
0aa89c08ff
11
src/main.cpp
11
src/main.cpp
@ -2357,8 +2357,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CTxDB txdb("r");
|
CTxDB txdb("r");
|
||||||
BOOST_FOREACH(const CInv& inv, vInv)
|
for (int nInv = 0; nInv < vInv.size(); nInv++)
|
||||||
{
|
{
|
||||||
|
const CInv &inv = vInv[nInv];
|
||||||
|
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
return true;
|
return true;
|
||||||
pfrom->AddInventoryKnown(inv);
|
pfrom->AddInventoryKnown(inv);
|
||||||
@ -2367,9 +2369,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
if (fDebug)
|
if (fDebug)
|
||||||
printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
|
printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
|
||||||
|
|
||||||
if (!fAlreadyHave)
|
// 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 || (inv.type == MSG_BLOCK && nInv==vInv.size()-1))
|
||||||
pfrom->AskFor(inv);
|
pfrom->AskFor(inv);
|
||||||
else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash))
|
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…
Reference in New Issue
Block a user