diff options
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp index a7298ea..17e446e 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -249,6 +249,26 @@ void AddOrphanTx(const CDataStream& vMsg) | |||
| 249 | CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg); | 249 | CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg); |
| 250 | foreach(const CTxIn& txin, tx.vin) | 250 | foreach(const CTxIn& txin, tx.vin) |
| 251 | mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg)); | 251 | mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg)); |
| 252 | LimitOrphanTx(MAX_ORPHAN_TRANSACTIONS); | ||
| 253 | } | ||
| 254 | |||
| 255 | // Orphans cost nothing to create -- a transaction naming a parent that does | ||
| 256 | // not exist is never validated, just held -- so without a ceiling any peer can | ||
| 257 | // grow this map until the node runs out of memory. Evict at random rather than | ||
| 258 | // in map order, so an attacker cannot keep its own orphans resident by | ||
| 259 | // choosing hashes that sort low. | ||
| 260 | void LimitOrphanTx(unsigned int nMaxOrphans) | ||
| 261 | { | ||
| 262 | while (mapOrphanTransactions.size() > nMaxOrphans) | ||
| 263 | { | ||
| 264 | uint256 randomhash; | ||
| 265 | for (int i = 0; i < 4; i++) | ||
| 266 | ((uint64*)&randomhash)[i] = GetRand(_UI64_MAX); | ||
| 267 | map<uint256, CDataStream*>::iterator it = mapOrphanTransactions.lower_bound(randomhash); | ||
| 268 | if (it == mapOrphanTransactions.end()) | ||
| 269 | it = mapOrphanTransactions.begin(); | ||
| 270 | EraseOrphanTx(it->first); | ||
| 271 | } | ||
| 252 | } | 272 | } |
| 253 | 273 | ||
| 254 | void EraseOrphanTx(uint256 hash) | 274 | void EraseOrphanTx(uint256 hash) |