mempool: Store iterators into mapTx in mapNextTx

This takes the same amount of space as CTransaction pointers, and saves a map
lookup in many common uses.
This commit is contained in:
Suhas Daftuar committed 2025-10-14 14:03:42 -04:00
1 parent 51430680ec
commit 6c73e47448
2 files changed
+12 -15

No files matched your search

+11 -14
View File
@@ -137,12 +137,11 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<Txid>& vHashesToU
{ {
WITH_FRESH_EPOCH(m_epoch); WITH_FRESH_EPOCH(m_epoch);
for (; iter != mapNextTx.end() && iter->first->hash == hash; ++iter) { for (; iter != mapNextTx.end() && iter->first->hash == hash; ++iter) {
const Txid &childHash = iter->second->GetHash(); txiter childIter = iter->second;
txiter childIter = mapTx.find(childHash);
assert(childIter != mapTx.end()); assert(childIter != mapTx.end());
// We can skip updating entries we've encountered before or that // We can skip updating entries we've encountered before or that
// are in the block (which are already accounted for). // are in the block (which are already accounted for).
if (!visited(childIter) && !setAlreadyIncluded.count(childHash)) { if (!visited(childIter) && !setAlreadyIncluded.count(iter->second->GetTx().GetHash())) {
UpdateChild(it, childIter, true); UpdateChild(it, childIter, true);
UpdateParent(childIter, it, true); UpdateParent(childIter, it, true);
} }
@@ -486,7 +485,7 @@ void CTxMemPool::addNewTransaction(CTxMemPool::txiter newit, CTxMemPool::setEntr
const CTransaction& tx = newit->GetTx(); const CTransaction& tx = newit->GetTx();
std::set<Txid> setParentTransactions; std::set<Txid> setParentTransactions;
for (unsigned int i = 0; i < tx.vin.size(); i++) { for (unsigned int i = 0; i < tx.vin.size(); i++) {
mapNextTx.insert(std::make_pair(&tx.vin[i].prevout, &tx)); mapNextTx.insert(std::make_pair(&tx.vin[i].prevout, newit));
setParentTransactions.insert(tx.vin[i].prevout.hash); setParentTransactions.insert(tx.vin[i].prevout.hash);
} }
// Don't bother worrying about child transactions of this one. // Don't bother worrying about child transactions of this one.
@@ -611,7 +610,7 @@ void CTxMemPool::removeRecursive(const CTransaction &origTx, MemPoolRemovalReaso
auto it = mapNextTx.find(COutPoint(origTx.GetHash(), i)); auto it = mapNextTx.find(COutPoint(origTx.GetHash(), i));
if (it == mapNextTx.end()) if (it == mapNextTx.end())
continue; continue;
txiter nextit = mapTx.find(it->second->GetHash()); txiter nextit = it->second;
assert(nextit != mapTx.end()); assert(nextit != mapTx.end());
txToRemove.insert(nextit); txToRemove.insert(nextit);
} }
@@ -652,7 +651,7 @@ void CTxMemPool::removeConflicts(const CTransaction &tx)
for (const CTxIn &txin : tx.vin) { for (const CTxIn &txin : tx.vin) {
auto it = mapNextTx.find(txin.prevout); auto it = mapNextTx.find(txin.prevout);
if (it != mapNextTx.end()) { if (it != mapNextTx.end()) {
const CTransaction &txConflict = *it->second; const CTransaction &txConflict = it->second->GetTx();
if (Assume(txConflict.GetHash() != tx.GetHash())) if (Assume(txConflict.GetHash() != tx.GetHash()))
{ {
ClearPrioritisation(txConflict.GetHash()); ClearPrioritisation(txConflict.GetHash());
@@ -729,7 +728,7 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
auto it3 = mapNextTx.find(txin.prevout); auto it3 = mapNextTx.find(txin.prevout);
assert(it3 != mapNextTx.end()); assert(it3 != mapNextTx.end());
assert(it3->first == &txin.prevout); assert(it3->first == &txin.prevout);
assert(it3->second == &tx); assert(&it3->second->GetTx() == &tx);
} }
auto comp = [](const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) -> bool { auto comp = [](const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) -> bool {
return a.GetTx().GetHash() == b.GetTx().GetHash(); return a.GetTx().GetHash() == b.GetTx().GetHash();
@@ -762,7 +761,7 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
auto iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0)); auto iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0));
int32_t child_sizes{0}; int32_t child_sizes{0};
for (; iter != mapNextTx.end() && iter->first->hash == it->GetTx().GetHash(); ++iter) { for (; iter != mapNextTx.end() && iter->first->hash == it->GetTx().GetHash(); ++iter) {
txiter childit = mapTx.find(iter->second->GetHash()); txiter childit = iter->second;
assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions
if (setChildrenCheck.insert(*childit).second) { if (setChildrenCheck.insert(*childit).second) {
child_sizes += childit->GetTxSize(); child_sizes += childit->GetTxSize();
@@ -781,11 +780,9 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
for (const auto& input: tx.vin) mempoolDuplicate.SpendCoin(input.prevout); for (const auto& input: tx.vin) mempoolDuplicate.SpendCoin(input.prevout);
AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max()); AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
} }
for (const auto& [_, next_tx] : mapNextTx) { for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) {
auto it = mapTx.find(next_tx->GetHash()); indexed_transaction_set::const_iterator it2 = it->second;
const CTransaction& tx = it->GetTx(); assert(it2 != mapTx.end());
assert(it != mapTx.end());
assert(&tx == next_tx);
} }
assert(totalTxSize == checkTotal); assert(totalTxSize == checkTotal);
@@ -956,7 +953,7 @@ std::vector<CTxMemPool::delta_info> CTxMemPool::GetPrioritisedTransactions() con
const CTransaction* CTxMemPool::GetConflictTx(const COutPoint& prevout) const const CTransaction* CTxMemPool::GetConflictTx(const COutPoint& prevout) const
{ {
const auto it = mapNextTx.find(prevout); const auto it = mapNextTx.find(prevout);
return it == mapNextTx.end() ? nullptr : it->second; return it == mapNextTx.end() ? nullptr : &(it->second->GetTx());
} }
std::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const Txid& txid) const std::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const Txid& txid) const
+1 -1
View File
@@ -413,7 +413,7 @@ private:
} }
public: public:
indirectmap<COutPoint, const CTransaction*> mapNextTx GUARDED_BY(cs); indirectmap<COutPoint, txiter> mapNextTx GUARDED_BY(cs);
std::map<Txid, CAmount> mapDeltas GUARDED_BY(cs); std::map<Txid, CAmount> mapDeltas GUARDED_BY(cs);
using Options = kernel::MemPoolOptions; using Options = kernel::MemPoolOptions;