Skip to content

Commit cd8ca8b

Browse files
author
MarcoFalke
committed
Merge #14626: Select orphan transaction uniformly for eviction
7257353 Select orphan transaction uniformly for eviction (Pieter Wuille) Pull request description: The previous code was biased towards evicting transactions whose txid has a larger gap (lexicographically) with the previous txid in the orphan pool. Tree-SHA512: e35f700aea5ed79d1bc57f64bffcb623424b40156fd0a12f05f74f981a8aa4175d5c18d042989243f7559242bdf1d6d720bcf588d28f43d74a798a4843f09c70
2 parents b7456e6 + 7257353 commit cd8ca8b

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

src/net_processing.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct COrphanTx {
8585
CTransactionRef tx;
8686
NodeId fromPeer;
8787
int64_t nTimeExpire;
88+
size_t list_pos;
8889
};
8990
CCriticalSection g_cs_orphans;
9091
std::map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(g_cs_orphans);
@@ -186,6 +187,8 @@ namespace {
186187
};
187188
std::map<COutPoint, std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(g_cs_orphans);
188189

190+
std::vector<std::map<uint256, COrphanTx>::iterator> g_orphan_list GUARDED_BY(g_cs_orphans); //! For random eviction
191+
189192
static size_t vExtraTxnForCompactIt GUARDED_BY(g_cs_orphans) = 0;
190193
static std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact GUARDED_BY(g_cs_orphans);
191194
} // namespace
@@ -837,8 +840,9 @@ bool AddOrphanTx(const CTransactionRef& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRE
837840
return false;
838841
}
839842

840-
auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME});
843+
auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME, g_orphan_list.size()});
841844
assert(ret.second);
845+
g_orphan_list.push_back(ret.first);
842846
for (const CTxIn& txin : tx->vin) {
843847
mapOrphanTransactionsByPrev[txin.prevout].insert(ret.first);
844848
}
@@ -864,6 +868,18 @@ int static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans)
864868
if (itPrev->second.empty())
865869
mapOrphanTransactionsByPrev.erase(itPrev);
866870
}
871+
872+
size_t old_pos = it->second.list_pos;
873+
assert(g_orphan_list[old_pos] == it);
874+
if (old_pos + 1 != g_orphan_list.size()) {
875+
// Unless we're deleting the last entry in g_orphan_list, move the last
876+
// entry to the position we're deleting.
877+
auto it_last = g_orphan_list.back();
878+
g_orphan_list[old_pos] = it_last;
879+
it_last->second.list_pos = old_pos;
880+
}
881+
g_orphan_list.pop_back();
882+
867883
mapOrphanTransactions.erase(it);
868884
return 1;
869885
}
@@ -914,11 +930,8 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
914930
while (mapOrphanTransactions.size() > nMaxOrphans)
915931
{
916932
// Evict a random orphan:
917-
uint256 randomhash = rng.rand256();
918-
std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
919-
if (it == mapOrphanTransactions.end())
920-
it = mapOrphanTransactions.begin();
921-
EraseOrphanTx(it->first);
933+
size_t randompos = rng.randrange(g_orphan_list.size());
934+
EraseOrphanTx(g_orphan_list[randompos]->first);
922935
++nEvicted;
923936
}
924937
return nEvicted;

0 commit comments

Comments
 (0)