|
|
@ -167,13 +167,14 @@ void static ResendWalletTransactions() |
|
|
|
// mapOrphanTransactions
|
|
|
|
// mapOrphanTransactions
|
|
|
|
//
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
void static AddOrphanTx(const CDataStream& vMsg) |
|
|
|
void AddOrphanTx(const CDataStream& vMsg) |
|
|
|
{ |
|
|
|
{ |
|
|
|
CTransaction tx; |
|
|
|
CTransaction tx; |
|
|
|
CDataStream(vMsg) >> tx; |
|
|
|
CDataStream(vMsg) >> tx; |
|
|
|
uint256 hash = tx.GetHash(); |
|
|
|
uint256 hash = tx.GetHash(); |
|
|
|
if (mapOrphanTransactions.count(hash)) |
|
|
|
if (mapOrphanTransactions.count(hash)) |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg); |
|
|
|
CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg); |
|
|
|
BOOST_FOREACH(const CTxIn& txin, tx.vin) |
|
|
|
BOOST_FOREACH(const CTxIn& txin, tx.vin) |
|
|
|
mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg)); |
|
|
|
mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg)); |
|
|
@ -201,6 +202,23 @@ void static EraseOrphanTx(uint256 hash) |
|
|
|
mapOrphanTransactions.erase(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; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -2473,6 +2491,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) |
|
|
|
{ |
|
|
|
{ |
|
|
|
printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str()); |
|
|
|
printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str()); |
|
|
|
AddOrphanTx(vMsg); |
|
|
|
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); |
|
|
|
} |
|
|
|
} |
|
|
|
if (tx.nDoS) pfrom->Misbehaving(tx.nDoS); |
|
|
|
if (tx.nDoS) pfrom->Misbehaving(tx.nDoS); |
|
|
|
} |
|
|
|
} |
|
|
|