mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-21 15:50:07 +01:00
DoS fix for mapOrphanTransactions
This commit is contained in:
committed by
Luke Dashjr
parent
feb3c15335
commit
3108aed0f2
25
src/main.cpp
25
src/main.cpp
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user