|
|
@ -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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|