DoS fix for mapOrphanTransactions

This commit is contained in:
Gavin Andresen
2012-02-29 10:14:18 -05:00
committed by Luke Dashjr
parent feb3c15335
commit 3108aed0f2
2 changed files with 25 additions and 1 deletions

View File

@@ -159,13 +159,14 @@ void static ResendWalletTransactions()
// mapOrphanTransactions
//
void static AddOrphanTx(const CDataStream& vMsg)
void AddOrphanTx(const CDataStream& vMsg)
{
CTransaction tx;
CDataStream(vMsg) >> tx;
uint256 hash = tx.GetHash();
if (mapOrphanTransactions.count(hash))
return;
CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);
BOOST_FOREACH(const CTxIn& txin, tx.vin)
mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
@@ -193,6 +194,23 @@ void static EraseOrphanTx(uint256 hash)
mapOrphanTransactions.erase(hash);
}
int LimitOrphanTxSize(int nMaxOrphans)
{
int nEvicted = 0;
while (mapOrphanTransactions.size() > nMaxOrphans)
{
// Evict a random orphan:
std::vector<unsigned char> randbytes(32);
RAND_bytes(&randbytes[0], 32);
uint256 randomhash(randbytes);
map<uint256, CDataStream*>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
if (it == mapOrphanTransactions.end())
it = mapOrphanTransactions.begin();
EraseOrphanTx(it->first);
++nEvicted;
}
return nEvicted;
}
@@ -2183,6 +2201,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{
printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
AddOrphanTx(vMsg);
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded
int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS);
if (nEvicted > 0)
printf("mapOrphan overflow, removed %d tx\n", nEvicted);
}
}

View File

@@ -30,6 +30,7 @@ class CBlockIndex;
static const unsigned int MAX_BLOCK_SIZE = 1000000;
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
static const int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
static const int64 COIN = 100000000;
static const int64 CENT = 1000000;
static const int64 MIN_TX_FEE = 50000;