Skip to content

Commit

Permalink
Added excess orphan block pruning
Browse files Browse the repository at this point in the history
  • Loading branch information
John Smith committed Aug 18, 2014
1 parent 921fb25 commit afd8ef7
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
5 changes: 3 additions & 2 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -611,8 +611,9 @@ std::string HelpMessage()
" -dnsseed \t " + _("Find peers using DNS lookup (default: 1)") + "\n" +
" -banscore=<n> \t " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" +
" -bantime=<n> \t " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" +
" -maxreceivebuffer=<n>\t " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)") + "\n" +
" -maxsendbuffer=<n>\t " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)") + "\n" +
" -maxreceivebuffer=<n>\t " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)") + "\n" +
" -maxsendbuffer=<n>\t " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)") + "\n" +
" -maxorphanblocks=<n>\t " + _("Maximum number of orphan blocks to store in the memory (default: 750)") + "\n" +
#ifdef USE_UPNP
#if USE_UPNP
" -upnp \t " + _("Use Universal Plug and Play to map the listening port (default: 1)") + "\n" +
Expand Down
57 changes: 52 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <math.h> /* pow */
#include <cstdlib> /* std::rand() */

#include "dcrypt.h"

Expand Down Expand Up @@ -72,7 +73,20 @@ const uint64 POB_POS_TARGET_SWITCH_TIME = 1407110400; //Mon, 04 Aug 2014 00:00:0
CMedianFilter<int> cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have

map<uint256, CBlock*> mapOrphanBlocks;
multimap<uint256, CBlock*> mapOrphanBlocksByPrev;

struct CBlockOrphan
{
CBlockOrphan(uint256 hash, CBlock *blockptr)
{
hashBlock = hash;
pblock = blockptr;
}

uint256 hashBlock;
CBlock *pblock;
};
multimap<uint256, CBlockOrphan> mapOrphanBlocksByPrev;

set<pair<COutPoint, unsigned int> > setStakeSeenOrphan;
map<uint256, uint256> mapProofOfStake;
set<pair<COutPoint, unsigned int> > setStakeSeen;
Expand Down Expand Up @@ -945,6 +959,36 @@ uint256 static GetOrphanRoot(const CBlock *pblock)
return pblock->GetHash();
}

// Remove a random orphan block (which does not have any dependent orphans).
void static PruneOrphanBlocks()
{
if(mapOrphanBlocksByPrev.size() <= (size_t)std::max((int64)0, GetArg("-maxorphanblocks", DEFAULT_MAX_ORPHAN_BLOCKS)))
return;

// Pick a random orphan block.
int pos = std::rand() % mapOrphanBlocksByPrev.size();
multimap<uint256, CBlockOrphan>::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
{
multimap<uint256, CBlockOrphan>::iterator it2 = mapOrphanBlocksByPrev.find(it->second.hashBlock);

if (it2 == mapOrphanBlocksByPrev.end())
break;
it = it2;
}while(1);

delete it->second.pblock;

uint256 hash = it->second.hashBlock;
mapOrphanBlocksByPrev.erase(it);
mapOrphanBlocks.erase(hash);
printf("PruneOrphanBlocks() : Removed orphan block %s\n", hash.ToString().c_str());
}

// slimcoin: find block wanted by given orphan block
uint256 WantedByOrphan(const CBlock *pblockOrphan)
{
Expand Down Expand Up @@ -2594,6 +2638,9 @@ bool ProcessBlock(CNode *pfrom, CBlock *pblock)
//If we do not already have its previous block, shunt it off to holding area until we get it
if(!mapBlockIndex.count(pblock->hashPrevBlock))
{
//makes space for this orphan block if there are more than DEFAULT_MAX_ORPHAN_BLOCKS orphan blocks
PruneOrphanBlocks();

printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str());
CBlock *pblock2 = new CBlock(*pblock);

Expand Down Expand Up @@ -2628,7 +2675,7 @@ bool ProcessBlock(CNode *pfrom, CBlock *pblock)
}

mapOrphanBlocks.insert(make_pair(hash, pblock2));
mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2));
mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, CBlockOrphan(hash, pblock2)));

// Ask this guy to fill in what we're missing
if(pfrom)
Expand All @@ -2655,11 +2702,11 @@ bool ProcessBlock(CNode *pfrom, CBlock *pblock)
{
uint256 hashPrev = vWorkQueue[i];

for(multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
for(multimap<uint256, CBlockOrphan>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
mi != mapOrphanBlocksByPrev.upper_bound(hashPrev); ++mi)
{
CBlock *pblockOrphan = (*mi).second;
uint256 pblockOrphanHash = pblockOrphan->GetHash();
uint256 pblockOrphanHash = (*mi).second.hashBlock;
CBlock *pblockOrphan = (*mi).second.pblock;

if(pblockOrphan->AcceptBlock())
vWorkQueue.push_back(pblockOrphanHash);
Expand Down
2 changes: 2 additions & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ static const int64 MAX_MONEY = 250000000 * COIN;
static const int64 MAX_MINT_PROOF_OF_WORK = 50 * COIN;
static const int64 MAX_MINT_PROOF_OF_BURN = 250 * COIN;
static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE;
// Default for -maxorphanblocks, maximum number of orphan blocks kept in memory
static const unsigned int DEFAULT_MAX_ORPHAN_BLOCKS = 750;
inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
static const int COINBASE_MATURITY_SLM = 500;
// Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp.
Expand Down

0 comments on commit afd8ef7

Please sign in to comment.