|
|
@ -2208,6 +2208,17 @@ bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, uns |
|
|
|
return (nFound >= nRequired); |
|
|
|
return (nFound >= nRequired); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void PushGetBlocks(CNode* pnode, CBlockIndex* pindexBegin, uint256 hashEnd) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Filter out duplicate requests
|
|
|
|
|
|
|
|
if (pindexBegin == pnode->pindexLastGetBlocksBegin && hashEnd == pnode->hashLastGetBlocksEnd) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
pnode->pindexLastGetBlocksBegin = pindexBegin; |
|
|
|
|
|
|
|
pnode->hashLastGetBlocksEnd = hashEnd; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pnode->PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp) |
|
|
|
bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Check for duplicate
|
|
|
|
// Check for duplicate
|
|
|
@ -2253,7 +2264,7 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl |
|
|
|
mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2)); |
|
|
|
mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2)); |
|
|
|
|
|
|
|
|
|
|
|
// Ask this guy to fill in what we're missing
|
|
|
|
// Ask this guy to fill in what we're missing
|
|
|
|
pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock2)); |
|
|
|
PushGetBlocks(pfrom, pindexBest, GetOrphanRoot(pblock2)); |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
@ -3357,12 +3368,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) |
|
|
|
if (!fImporting && !fReindex) |
|
|
|
if (!fImporting && !fReindex) |
|
|
|
pfrom->AskFor(inv); |
|
|
|
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])); |
|
|
|
PushGetBlocks(pfrom, pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash])); |
|
|
|
} else if (nInv == nLastBlock) { |
|
|
|
} else if (nInv == nLastBlock) { |
|
|
|
// In case we are on a very long side-chain, it is possible that we already have
|
|
|
|
// 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
|
|
|
|
// the last block in an inv bundle sent in response to getblocks. Try to detect
|
|
|
|
// this situation and push another getblocks to continue.
|
|
|
|
// this situation and push another getblocks to continue.
|
|
|
|
pfrom->PushGetBlocks(mapBlockIndex[inv.hash], uint256(0)); |
|
|
|
PushGetBlocks(pfrom, mapBlockIndex[inv.hash], uint256(0)); |
|
|
|
if (fDebug) |
|
|
|
if (fDebug) |
|
|
|
printf("force request: %s\n", inv.ToString().c_str()); |
|
|
|
printf("force request: %s\n", inv.ToString().c_str()); |
|
|
|
} |
|
|
|
} |
|
|
@ -3839,7 +3850,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) |
|
|
|
// Start block sync
|
|
|
|
// Start block sync
|
|
|
|
if (pto->fStartSync && !fImporting && !fReindex) { |
|
|
|
if (pto->fStartSync && !fImporting && !fReindex) { |
|
|
|
pto->fStartSync = false; |
|
|
|
pto->fStartSync = false; |
|
|
|
pto->PushGetBlocks(pindexBest, uint256(0)); |
|
|
|
PushGetBlocks(pto, pindexBest, uint256(0)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Resend wallet transactions that haven't gotten in a block yet
|
|
|
|
// Resend wallet transactions that haven't gotten in a block yet
|
|
|
|