Skip to content

Commit

Permalink
Remove RelayMessage use RelayTransaction
Browse files Browse the repository at this point in the history
  • Loading branch information
iamunick committed May 27, 2014
1 parent dffe963 commit f493460
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 69 deletions.
57 changes: 25 additions & 32 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
set<pair<COutPoint, unsigned int> > setStakeSeenOrphan;
map<uint256, uint256> mapProofOfStake;

map<uint256, CDataStream*> mapOrphanTransactions;
map<uint256, map<uint256, CDataStream*> > mapOrphanTransactionsByPrev;
map<uint256, CTransaction> mapOrphanTransactions;
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;

// Constant stuff for coinbase transactions we create:
CScript COINBASE_FLAGS;
Expand Down Expand Up @@ -187,33 +187,31 @@ void ResendWalletTransactions()
// mapOrphanTransactions
//

bool AddOrphanTx(const CDataStream& vMsg)
bool AddOrphanTx(const CTransaction& tx)
{
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)

size_t nSize = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);

if (nSize > 5000)
{
printf("ignoring large orphan tx (size: %"PRIszu", hash: %s)\n", pvMsg->size(), hash.ToString().substr(0,10).c_str());
delete pvMsg;
printf("ignoring large orphan tx (size: %"PRIszu", hash: %s)\n", nSize, hash.ToString().substr(0,10).c_str());
return false;
}

mapOrphanTransactions[hash] = pvMsg;
mapOrphanTransactions[hash] = tx;
BOOST_FOREACH(const CTxIn& txin, tx.vin)
mapOrphanTransactionsByPrev[txin.prevout.hash].insert(make_pair(hash, pvMsg));
mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);

printf("stored orphan tx %s (mapsz %"PRIszu")\n", hash.ToString().substr(0,10).c_str(),
mapOrphanTransactions.size());
Expand All @@ -224,16 +222,13 @@ void static EraseOrphanTx(uint256 hash)
{
if (!mapOrphanTransactions.count(hash))
return;
const CDataStream* pvMsg = mapOrphanTransactions[hash];
CTransaction tx;
CDataStream(*pvMsg) >> tx;
const CTransaction& tx = mapOrphanTransactions[hash];
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);
}

Expand All @@ -244,7 +239,7 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
{
// Evict a random orphan:
uint256 randomhash = GetRandHash();
map<uint256, CDataStream*>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
map<uint256, CTransaction>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
if (it == mapOrphanTransactions.end())
it = mapOrphanTransactions.begin();
EraseOrphanTx(it->first);
Expand Down Expand Up @@ -3270,7 +3265,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs))
{
SyncWithWallets(tx, NULL, true);
RelayMessage(inv, vMsg);
RelayTransaction(tx, inv.hash);
mapAlreadyAskedFor.erase(inv);
vWorkQueue.push_back(inv.hash);
vEraseQueue.push_back(inv.hash);
Expand All @@ -3279,30 +3274,28 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
for (unsigned int i = 0; i < vWorkQueue.size(); i++)
{
uint256 hashPrev = vWorkQueue[i];
for (map<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev[hashPrev].begin();
for (set<uint256>::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());
const uint256& orphanTxHash = *mi;
CTransaction& orphanTx = mapOrphanTransactions[orphanTxHash];
bool fMissingInputs2 = false;

if (tx.AcceptToMemoryPool(txdb, true, &fMissingInputs2))
if (orphanTx.AcceptToMemoryPool(txdb, true, &fMissingInputs2))
{
printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
printf(" accepted orphan tx %s\n", orphanTxHash.ToString().substr(0,10).c_str());
SyncWithWallets(tx, NULL, true);
RelayMessage(inv, vMsg);
mapAlreadyAskedFor.erase(inv);
vWorkQueue.push_back(inv.hash);
vEraseQueue.push_back(inv.hash);
RelayTransaction(orphanTx, orphanTxHash);
mapAlreadyAskedFor.erase(CInv(MSG_TX, orphanTxHash));
vWorkQueue.push_back(orphanTxHash);
vEraseQueue.push_back(orphanTxHash);
}
else if (!fMissingInputs2)
{
// invalid orphan
vEraseQueue.push_back(inv.hash);
printf(" removed invalid orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
vEraseQueue.push_back(orphanTxHash);
printf(" removed invalid orphan tx %s\n", orphanTxHash.ToString().substr(0,10).c_str());
}
}
}
Expand All @@ -3312,7 +3305,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
else if (fMissingInputs)
{
AddOrphanTx(vMsg);
AddOrphanTx(tx);

// DoS prevention: do not allow mapOrphanTransactions to grow unbounded
unsigned int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS);
Expand Down
30 changes: 0 additions & 30 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,6 @@ class CNode
}



void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
bool IsSubscribed(unsigned int nChannel);
void Subscribe(unsigned int nChannel, unsigned int nHops=0);
Expand Down Expand Up @@ -654,35 +653,6 @@ inline void RelayInventory(const CInv& inv)
}
}

template<typename T>
void RelayMessage(const CInv& inv, const T& a)
{
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(10000);
ss << a;
RelayMessage(inv, ss);
}

template<>
inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
{
{
LOCK(cs_mapRelay);
// Expire old relay messages
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
{
mapRelay.erase(vRelayExpiration.front().second);
vRelayExpiration.pop_front();
}

// Save original serialized message so newer versions are preserved
mapRelay.insert(std::make_pair(inv, ss));
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
}

RelayInventory(inv);
}

class CTransaction;
void RelayTransaction(const CTransaction& tx, const uint256& hash);
void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss);
Expand Down
2 changes: 1 addition & 1 deletion src/rpcrawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ Value sendrawtransaction(const Array& params, bool fHelp)

SyncWithWallets(tx, NULL, true);
}
RelayMessage(CInv(MSG_TX, hashTx), tx);
RelayTransaction(tx, hashTx);

return hashTx.GetHex();
}
8 changes: 2 additions & 6 deletions src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,7 @@ void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
{
uint256 hash = tx.GetHash();
if (!txdb.ContainsTx(hash))
RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx);
RelayTransaction((CTransaction)tx, hash);
}
}
if (!(IsCoinBase() || IsCoinStake()))
Expand All @@ -883,7 +883,7 @@ void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
if (!txdb.ContainsTx(hash))
{
printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
RelayTransaction((CTransaction)*this, hash);
}
}
}
Expand Down Expand Up @@ -939,10 +939,6 @@ void CWallet::ResendWalletTransactions()
}






//////////////////////////////////////////////////////////////////////////////
//
// Actions
Expand Down

0 comments on commit f493460

Please sign in to comment.