|
|
|
@ -1054,6 +1054,31 @@ uint256 static GetOrphanRoot(const uint256& hash)
@@ -1054,6 +1054,31 @@ uint256 static GetOrphanRoot(const uint256& hash)
|
|
|
|
|
} while(true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Remove a random orphan block (which does not have any dependent orphans).
|
|
|
|
|
void static PruneOrphanBlocks() |
|
|
|
|
{ |
|
|
|
|
if (mapOrphanBlocksByPrev.size() <= MAX_ORPHAN_BLOCKS) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
// Pick a random orphan block.
|
|
|
|
|
int pos = insecure_rand() % mapOrphanBlocksByPrev.size(); |
|
|
|
|
std::multimap<uint256, COrphanBlock*>::iterator it = mapOrphanBlocksByPrev.begin(); |
|
|
|
|
while (pos--) it++; |
|
|
|
|
|
|
|
|
|
// As long as this block has other orphans depending on it, move to one of those successors.
|
|
|
|
|
do { |
|
|
|
|
std::multimap<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocksByPrev.find(it->second->hashBlock); |
|
|
|
|
if (it2 == mapOrphanBlocksByPrev.end()) |
|
|
|
|
break; |
|
|
|
|
it = it2; |
|
|
|
|
} while(1); |
|
|
|
|
|
|
|
|
|
uint256 hash = it->second->hashBlock; |
|
|
|
|
delete it->second; |
|
|
|
|
mapOrphanBlocksByPrev.erase(it); |
|
|
|
|
mapOrphanBlocks.erase(hash); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int64_t GetBlockValue(int nHeight, int64_t nFees) |
|
|
|
|
{ |
|
|
|
|
int64_t nSubsidy = 50 * COIN; |
|
|
|
@ -2373,10 +2398,11 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
@@ -2373,10 +2398,11 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
|
|
|
|
|
// If we don't already have its previous block, shunt it off to holding area until we get it
|
|
|
|
|
if (pblock->hashPrevBlock != 0 && !mapBlockIndex.count(pblock->hashPrevBlock)) |
|
|
|
|
{ |
|
|
|
|
LogPrintf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString()); |
|
|
|
|
LogPrintf("ProcessBlock: ORPHAN BLOCK %lu, prev=%s\n", (unsigned long)mapOrphanBlocks.size(), pblock->hashPrevBlock.ToString()); |
|
|
|
|
|
|
|
|
|
// Accept orphans as long as there is a node to request its parents from
|
|
|
|
|
if (pfrom) { |
|
|
|
|
PruneOrphanBlocks(); |
|
|
|
|
COrphanBlock* pblock2 = new COrphanBlock(); |
|
|
|
|
{ |
|
|
|
|
CDataStream ss(SER_DISK, CLIENT_VERSION); |
|
|
|
|