@@ -32,6 +32,7 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
3232 nTxSize = ::GetSerializeSize (tx, SER_NETWORK, PROTOCOL_VERSION);
3333 nModSize = tx.CalculateModifiedSize (nTxSize);
3434 nUsageSize = tx.DynamicMemoryUsage ();
35+ feeRate = CFeeRate (nFee, nTxSize);
3536}
3637
3738CTxMemPoolEntry::CTxMemPoolEntry (const CTxMemPoolEntry& other)
@@ -96,8 +97,8 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
9697 // Used by main.cpp AcceptToMemoryPool(), which DOES do
9798 // all the appropriate checks.
9899 LOCK (cs);
99- mapTx[hash] = entry;
100- const CTransaction& tx = mapTx[hash]. GetTx ();
100+ mapTx. insert ( entry) ;
101+ const CTransaction& tx = mapTx. find (hash)-> GetTx ();
101102 for (unsigned int i = 0 ; i < tx.vin .size (); i++)
102103 mapNextTx[tx.vin [i].prevout ] = CInPoint (&tx, i);
103104 nTransactionsUpdated++;
@@ -134,7 +135,7 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem
134135 txToRemove.pop_front ();
135136 if (!mapTx.count (hash))
136137 continue ;
137- const CTransaction& tx = mapTx[hash]. GetTx ();
138+ const CTransaction& tx = mapTx. find (hash)-> GetTx ();
138139 if (fRecursive ) {
139140 for (unsigned int i = 0 ; i < tx.vout .size (); i++) {
140141 std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find (COutPoint (hash, i));
@@ -147,8 +148,8 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem
147148 mapNextTx.erase (txin.prevout );
148149
149150 removed.push_back (tx);
150- totalTxSize -= mapTx[hash]. GetTxSize ();
151- cachedInnerUsage -= mapTx[hash]. DynamicMemoryUsage ();
151+ totalTxSize -= mapTx. find (hash)-> GetTxSize ();
152+ cachedInnerUsage -= mapTx. find (hash)-> DynamicMemoryUsage ();
152153 mapTx.erase (hash);
153154 nTransactionsUpdated++;
154155 minerPolicyEstimator->removeTx (hash);
@@ -161,10 +162,10 @@ void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned in
161162 // Remove transactions spending a coinbase which are now immature
162163 LOCK (cs);
163164 list<CTransaction> transactionsToRemove;
164- for (std::map<uint256, CTxMemPoolEntry> ::const_iterator it = mapTx.begin (); it != mapTx.end (); it++) {
165- const CTransaction& tx = it->second . GetTx ();
165+ for (indexed_transaction_set ::const_iterator it = mapTx.begin (); it != mapTx.end (); it++) {
166+ const CTransaction& tx = it->GetTx ();
166167 BOOST_FOREACH (const CTxIn& txin, tx.vin ) {
167- std::map<uint256, CTxMemPoolEntry> ::const_iterator it2 = mapTx.find (txin.prevout .hash );
168+ indexed_transaction_set ::const_iterator it2 = mapTx.find (txin.prevout .hash );
168169 if (it2 != mapTx.end ())
169170 continue ;
170171 const CCoins *coins = pcoins->AccessCoins (txin.prevout .hash );
@@ -209,8 +210,10 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i
209210 BOOST_FOREACH (const CTransaction& tx, vtx)
210211 {
211212 uint256 hash = tx.GetHash ();
212- if (mapTx.count (hash))
213- entries.push_back (mapTx[hash]);
213+
214+ indexed_transaction_set::iterator i = mapTx.find (hash);
215+ if (i != mapTx.end ())
216+ entries.push_back (*i);
214217 }
215218 BOOST_FOREACH (const CTransaction& tx, vtx)
216219 {
@@ -247,17 +250,17 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
247250
248251 LOCK (cs);
249252 list<const CTxMemPoolEntry*> waitingOnDependants;
250- for (std::map<uint256, CTxMemPoolEntry> ::const_iterator it = mapTx.begin (); it != mapTx.end (); it++) {
253+ for (indexed_transaction_set ::const_iterator it = mapTx.begin (); it != mapTx.end (); it++) {
251254 unsigned int i = 0 ;
252- checkTotal += it->second . GetTxSize ();
253- innerUsage += it->second . DynamicMemoryUsage ();
254- const CTransaction& tx = it->second . GetTx ();
255+ checkTotal += it->GetTxSize ();
256+ innerUsage += it->DynamicMemoryUsage ();
257+ const CTransaction& tx = it->GetTx ();
255258 bool fDependsWait = false ;
256259 BOOST_FOREACH (const CTxIn &txin, tx.vin ) {
257260 // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
258- std::map<uint256, CTxMemPoolEntry> ::const_iterator it2 = mapTx.find (txin.prevout .hash );
261+ indexed_transaction_set ::const_iterator it2 = mapTx.find (txin.prevout .hash );
259262 if (it2 != mapTx.end ()) {
260- const CTransaction& tx2 = it2->second . GetTx ();
263+ const CTransaction& tx2 = it2->GetTx ();
261264 assert (tx2.vout .size () > txin.prevout .n && !tx2.vout [txin.prevout .n ].IsNull ());
262265 fDependsWait = true ;
263266 } else {
@@ -272,7 +275,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
272275 i++;
273276 }
274277 if (fDependsWait )
275- waitingOnDependants.push_back (&it-> second );
278+ waitingOnDependants.push_back (&(*it) );
276279 else {
277280 CValidationState state;
278281 assert (CheckInputs (tx, state, mempoolDuplicate, false , 0 , false , NULL ));
@@ -296,8 +299,8 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
296299 }
297300 for (std::map<COutPoint, CInPoint>::const_iterator it = mapNextTx.begin (); it != mapNextTx.end (); it++) {
298301 uint256 hash = it->second .ptx ->GetHash ();
299- map<uint256, CTxMemPoolEntry> ::const_iterator it2 = mapTx.find (hash);
300- const CTransaction& tx = it2->second . GetTx ();
302+ indexed_transaction_set ::const_iterator it2 = mapTx.find (hash);
303+ const CTransaction& tx = it2->GetTx ();
301304 assert (it2 != mapTx.end ());
302305 assert (&tx == it->second .ptx );
303306 assert (tx.vin .size () > it->second .n );
@@ -314,16 +317,16 @@ void CTxMemPool::queryHashes(vector<uint256>& vtxid)
314317
315318 LOCK (cs);
316319 vtxid.reserve (mapTx.size ());
317- for (map<uint256, CTxMemPoolEntry> ::iterator mi = mapTx.begin (); mi != mapTx.end (); ++mi)
318- vtxid.push_back ((*mi). first );
320+ for (indexed_transaction_set ::iterator mi = mapTx.begin (); mi != mapTx.end (); ++mi)
321+ vtxid.push_back (mi-> GetTx (). GetHash () );
319322}
320323
321324bool CTxMemPool::lookup (uint256 hash, CTransaction& result) const
322325{
323326 LOCK (cs);
324- map<uint256, CTxMemPoolEntry> ::const_iterator i = mapTx.find (hash);
327+ indexed_transaction_set ::const_iterator i = mapTx.find (hash);
325328 if (i == mapTx.end ()) return false ;
326- result = i->second . GetTx ();
329+ result = i->GetTx ();
327330 return true ;
328331}
329332
@@ -429,5 +432,6 @@ bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const {
429432
430433size_t CTxMemPool::DynamicMemoryUsage () const {
431434 LOCK (cs);
432- return memusage::DynamicUsage (mapTx) + memusage::DynamicUsage (mapNextTx) + memusage::DynamicUsage (mapDeltas) + cachedInnerUsage;
435+ // Estimate the overhead of mapTx to be 5 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented.
436+ return memusage::MallocUsage (sizeof (CTxMemPoolEntry) + 5 * sizeof (void *)) * mapTx.size () + memusage::DynamicUsage (mapNextTx) + memusage::DynamicUsage (mapDeltas) + cachedInnerUsage;
433437}
0 commit comments