mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-02-05 11:24:19 +00:00
orphaned tx makes no sense anymore
This commit is contained in:
parent
3cc155526a
commit
943bff5921
@ -78,6 +78,12 @@ uint256 CTransaction::GetHash() const
|
|||||||
return SerializeHash(*this);
|
return SerializeHash(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint256 CTransaction::GetUsernameHash() const
|
||||||
|
{
|
||||||
|
return SerializeHash(userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string CTransaction::ToString() const
|
std::string CTransaction::ToString() const
|
||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
|
@ -215,6 +215,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint256 GetHash() const;
|
uint256 GetHash() const;
|
||||||
|
uint256 GetUsernameHash() const;
|
||||||
|
|
||||||
bool IsSpamMessage() const
|
bool IsSpamMessage() const
|
||||||
{
|
{
|
||||||
|
138
src/main.cpp
138
src/main.cpp
@ -54,9 +54,6 @@ CMedianFilter<int> cPeerBlockCounts(8, 0); // Amount of blocks that other nodes
|
|||||||
map<uint256, CBlock*> mapOrphanBlocks;
|
map<uint256, CBlock*> mapOrphanBlocks;
|
||||||
multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
|
multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
|
||||||
|
|
||||||
map<uint256, CDataStream*> mapOrphanTransactions;
|
|
||||||
map<uint256, map<uint256, CDataStream*> > mapOrphanTransactionsByPrev;
|
|
||||||
|
|
||||||
// Constant stuff for coinbase transactions we create:
|
// Constant stuff for coinbase transactions we create:
|
||||||
CScript COINBASE_FLAGS;
|
CScript COINBASE_FLAGS;
|
||||||
|
|
||||||
@ -389,84 +386,6 @@ bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) {
|
|||||||
CCoinsViewCache *pcoinsTip = NULL;
|
CCoinsViewCache *pcoinsTip = NULL;
|
||||||
CBlockTreeDB *pblocktree = NULL;
|
CBlockTreeDB *pblocktree = NULL;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// mapOrphanTransactions
|
|
||||||
//
|
|
||||||
|
|
||||||
bool AddOrphanTx(const CDataStream& vMsg)
|
|
||||||
{
|
|
||||||
CTransaction tx;
|
|
||||||
CDataStream(vMsg) >> tx;
|
|
||||||
uint256 hash = tx.GetHash();
|
|
||||||
if (mapOrphanTransactions.count(hash))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CDataStream* pvMsg = new CDataStream(vMsg);
|
|
||||||
|
|
||||||
// Ignore big transactions, to avoid a
|
|
||||||
// send-big-orphans memory exhaustion attack. If a peer has a legitimate
|
|
||||||
// large transaction with a missing parent then we assume
|
|
||||||
// it will rebroadcast it later, after the parent transaction(s)
|
|
||||||
// have been mined or received.
|
|
||||||
// 10,000 orphans, each of which is at most 5,000 bytes big is
|
|
||||||
// at most 500 megabytes of orphans:
|
|
||||||
if (pvMsg->size() > 5000)
|
|
||||||
{
|
|
||||||
printf("ignoring large orphan tx (size: %"PRIszu", hash: %s)\n", pvMsg->size(), hash.ToString().c_str());
|
|
||||||
delete pvMsg;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapOrphanTransactions[hash] = pvMsg;
|
|
||||||
/* [MF]
|
|
||||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
|
||||||
mapOrphanTransactionsByPrev[txin.prevout.hash].insert(make_pair(hash, pvMsg));
|
|
||||||
*/
|
|
||||||
printf("stored orphan tx %s (mapsz %"PRIszu")\n", hash.ToString().c_str(),
|
|
||||||
mapOrphanTransactions.size());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void static EraseOrphanTx(uint256 hash)
|
|
||||||
{
|
|
||||||
if (!mapOrphanTransactions.count(hash))
|
|
||||||
return;
|
|
||||||
const CDataStream* pvMsg = mapOrphanTransactions[hash];
|
|
||||||
CTransaction tx;
|
|
||||||
CDataStream(*pvMsg) >> tx;
|
|
||||||
/* [MF]
|
|
||||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
|
||||||
{
|
|
||||||
mapOrphanTransactionsByPrev[txin.prevout.hash].erase(hash);
|
|
||||||
if (mapOrphanTransactionsByPrev[txin.prevout.hash].empty())
|
|
||||||
mapOrphanTransactionsByPrev.erase(txin.prevout.hash);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
delete pvMsg;
|
|
||||||
mapOrphanTransactions.erase(hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
|
|
||||||
{
|
|
||||||
unsigned int nEvicted = 0;
|
|
||||||
while (mapOrphanTransactions.size() > nMaxOrphans)
|
|
||||||
{
|
|
||||||
// Evict a random orphan:
|
|
||||||
uint256 randomhash = GetRandHash();
|
|
||||||
map<uint256, CDataStream*>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
|
|
||||||
if (it == mapOrphanTransactions.end())
|
|
||||||
it = mapOrphanTransactions.begin();
|
|
||||||
EraseOrphanTx(it->first);
|
|
||||||
++nEvicted;
|
|
||||||
}
|
|
||||||
return nEvicted;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool IsStandardTx(const CTransaction& tx, string& reason)
|
bool IsStandardTx(const CTransaction& tx, string& reason)
|
||||||
@ -2785,7 +2704,7 @@ bool static AlreadyHave(const CInv& inv)
|
|||||||
LOCK(mempool.cs);
|
LOCK(mempool.cs);
|
||||||
txInMap = mempool.exists(inv.hash);
|
txInMap = mempool.exists(inv.hash);
|
||||||
}
|
}
|
||||||
return txInMap || mapOrphanTransactions.count(inv.hash) ||
|
return txInMap ||
|
||||||
pcoinsTip->HaveCoins(inv.hash);
|
pcoinsTip->HaveCoins(inv.hash);
|
||||||
}
|
}
|
||||||
case MSG_BLOCK:
|
case MSG_BLOCK:
|
||||||
@ -3248,8 +3167,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
|
|
||||||
else if (strCommand == "tx")
|
else if (strCommand == "tx")
|
||||||
{
|
{
|
||||||
vector<uint256> vWorkQueue;
|
|
||||||
vector<uint256> vEraseQueue;
|
|
||||||
CDataStream vMsg(vRecv);
|
CDataStream vMsg(vRecv);
|
||||||
CTransaction tx;
|
CTransaction tx;
|
||||||
vRecv >> tx;
|
vRecv >> tx;
|
||||||
@ -3273,53 +3190,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
{
|
{
|
||||||
RelayTransaction(tx, inv.hash, vMsg);
|
RelayTransaction(tx, inv.hash, vMsg);
|
||||||
mapAlreadyAskedFor.erase(inv);
|
mapAlreadyAskedFor.erase(inv);
|
||||||
vWorkQueue.push_back(inv.hash);
|
|
||||||
vEraseQueue.push_back(inv.hash);
|
|
||||||
|
|
||||||
// Recursively process any orphan transactions that depended on this one
|
|
||||||
for (unsigned int i = 0; i < vWorkQueue.size(); i++)
|
|
||||||
{
|
|
||||||
uint256 hashPrev = vWorkQueue[i];
|
|
||||||
for (map<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev[hashPrev].begin();
|
|
||||||
mi != mapOrphanTransactionsByPrev[hashPrev].end();
|
|
||||||
++mi)
|
|
||||||
{
|
|
||||||
const CDataStream& vMsg = *((*mi).second);
|
|
||||||
CTransaction tx;
|
|
||||||
CDataStream(vMsg) >> tx;
|
|
||||||
CInv inv(MSG_TX, tx.GetHash());
|
|
||||||
bool fMissingInputs2 = false;
|
|
||||||
// Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get anyone relaying LegitTxX banned)
|
|
||||||
CValidationState stateDummy;
|
|
||||||
|
|
||||||
if (mempool.accept(stateDummy, tx, true, &fMissingInputs2))
|
|
||||||
{
|
|
||||||
printf(" accepted orphan tx %s\n", inv.hash.ToString().c_str());
|
|
||||||
RelayTransaction(tx, inv.hash, vMsg);
|
|
||||||
mapAlreadyAskedFor.erase(inv);
|
|
||||||
vWorkQueue.push_back(inv.hash);
|
|
||||||
vEraseQueue.push_back(inv.hash);
|
|
||||||
}
|
|
||||||
else if (!fMissingInputs2)
|
|
||||||
{
|
|
||||||
// invalid or too-little-fee orphan
|
|
||||||
vEraseQueue.push_back(inv.hash);
|
|
||||||
printf(" removed orphan tx %s\n", inv.hash.ToString().c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FOREACH(uint256 hash, vEraseQueue)
|
|
||||||
EraseOrphanTx(hash);
|
|
||||||
}
|
|
||||||
else if (fMissingInputs)
|
|
||||||
{
|
|
||||||
AddOrphanTx(vMsg);
|
|
||||||
|
|
||||||
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded
|
|
||||||
unsigned int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS);
|
|
||||||
if (nEvicted > 0)
|
|
||||||
printf("mapOrphan overflow, removed %u tx\n", nEvicted);
|
|
||||||
}
|
}
|
||||||
int nDoS;
|
int nDoS;
|
||||||
if (state.IsInvalid(nDoS))
|
if (state.IsInvalid(nDoS))
|
||||||
@ -4315,11 +4185,5 @@ public:
|
|||||||
for (; it2 != mapOrphanBlocks.end(); it2++)
|
for (; it2 != mapOrphanBlocks.end(); it2++)
|
||||||
delete (*it2).second;
|
delete (*it2).second;
|
||||||
mapOrphanBlocks.clear();
|
mapOrphanBlocks.clear();
|
||||||
|
|
||||||
// orphan transactions
|
|
||||||
std::map<uint256, CDataStream*>::iterator it3 = mapOrphanTransactions.begin();
|
|
||||||
for (; it3 != mapOrphanTransactions.end(); it3++)
|
|
||||||
delete (*it3).second;
|
|
||||||
mapOrphanTransactions.clear();
|
|
||||||
}
|
}
|
||||||
} instance_of_cmaincleanup;
|
} instance_of_cmaincleanup;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user