@@ -1054,6 +1054,31 @@ uint256 static GetOrphanRoot(const uint256& hash)
1054
1054
} while (true );
1055
1055
}
1056
1056
1057
+ // Remove a random orphan block (which does not have any dependent orphans).
1058
+ void static PruneOrphanBlocks ()
1059
+ {
1060
+ if (mapOrphanBlocksByPrev.size () <= MAX_ORPHAN_BLOCKS)
1061
+ return ;
1062
+
1063
+ // Pick a random orphan block.
1064
+ int pos = insecure_rand () % mapOrphanBlocksByPrev.size ();
1065
+ std::multimap<uint256, COrphanBlock*>::iterator it = mapOrphanBlocksByPrev.begin ();
1066
+ while (pos--) it++;
1067
+
1068
+ // As long as this block has other orphans depending on it, move to one of those successors.
1069
+ do {
1070
+ std::multimap<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocksByPrev.find (it->second ->hashBlock );
1071
+ if (it2 == mapOrphanBlocksByPrev.end ())
1072
+ break ;
1073
+ it = it2;
1074
+ } while (1 );
1075
+
1076
+ uint256 hash = it->second ->hashBlock ;
1077
+ delete it->second ;
1078
+ mapOrphanBlocksByPrev.erase (it);
1079
+ mapOrphanBlocks.erase (hash);
1080
+ }
1081
+
1057
1082
int64_t GetBlockValue (int nHeight, int64_t nFees)
1058
1083
{
1059
1084
int64_t nSubsidy = 50 * COIN;
@@ -2373,10 +2398,11 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
2373
2398
// If we don't already have its previous block, shunt it off to holding area until we get it
2374
2399
if (pblock->hashPrevBlock != 0 && !mapBlockIndex.count (pblock->hashPrevBlock ))
2375
2400
{
2376
- LogPrintf (" ProcessBlock: ORPHAN BLOCK, prev=%s\n " , pblock->hashPrevBlock .ToString ());
2401
+ LogPrintf (" ProcessBlock: ORPHAN BLOCK %lu , prev=%s\n " , ( unsigned long )mapOrphanBlocks. size () , pblock->hashPrevBlock .ToString ());
2377
2402
2378
2403
// Accept orphans as long as there is a node to request its parents from
2379
2404
if (pfrom) {
2405
+ PruneOrphanBlocks ();
2380
2406
COrphanBlock* pblock2 = new COrphanBlock ();
2381
2407
{
2382
2408
CDataStream ss (SER_DISK, CLIENT_VERSION);
0 commit comments