Skip to content

Commit

Permalink
Merge bitcoin#14626: Select orphan transaction uniformly for eviction
Browse files Browse the repository at this point in the history
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
Signed-off-by: pasta <pasta@dashboost.org>

# Conflicts:
#	src/net_processing.cpp
  • Loading branch information
MarcoFalke authored and PastaPastaPasta committed Jul 18, 2021
1 parent f6f78e8 commit 378ef2b
Showing 1 changed file with 20 additions and 6 deletions.
26 changes: 20 additions & 6 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ struct COrphanTx {
CTransactionRef tx;
NodeId fromPeer;
int64_t nTimeExpire;
size_t list_pos;
size_t nTxSize;
};
CCriticalSection g_cs_orphans;
Expand Down Expand Up @@ -213,6 +214,8 @@ namespace {
};
std::map<COutPoint, std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(g_cs_orphans);

std::vector<std::map<uint256, COrphanTx>::iterator> g_orphan_list GUARDED_BY(g_cs_orphans); //! For random eviction

static size_t vExtraTxnForCompactIt GUARDED_BY(g_cs_orphans) = 0;
static std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact GUARDED_BY(g_cs_orphans);
} // namespace
Expand Down Expand Up @@ -956,8 +959,9 @@ bool AddOrphanTx(const CTransactionRef& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRE
return false;
}

auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME, sz});
auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME, g_orphan_list.size(), sz});
assert(ret.second);
g_orphan_list.push_back(ret.first);
for (const CTxIn& txin : tx->vin) {
mapOrphanTransactionsByPrev[txin.prevout].insert(ret.first);
}
Expand Down Expand Up @@ -987,6 +991,18 @@ int static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans)
if (itPrev->second.empty())
mapOrphanTransactionsByPrev.erase(itPrev);
}

size_t old_pos = it->second.list_pos;
assert(g_orphan_list[old_pos] == it);
if (old_pos + 1 != g_orphan_list.size()) {
// Unless we're deleting the last entry in g_orphan_list, move the last
// entry to the position we're deleting.
auto it_last = g_orphan_list.back();
g_orphan_list[old_pos] = it_last;
it_last->second.list_pos = old_pos;
}
g_orphan_list.pop_back();

assert(nMapOrphanTransactionsSize >= it->second.nTxSize);
nMapOrphanTransactionsSize -= it->second.nTxSize;
mapOrphanTransactions.erase(it);
Expand Down Expand Up @@ -1037,14 +1053,12 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphansSize)
nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL;
if (nErased > 0) LogPrint(BCLog::MEMPOOL, "Erased %d orphan tx due to expiration\n", nErased);
}
FastRandomContext rng;
while (!mapOrphanTransactions.empty() && nMapOrphanTransactionsSize > nMaxOrphansSize)
{
// Evict a random orphan:
uint256 randomhash = GetRandHash();
std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
if (it == mapOrphanTransactions.end())
it = mapOrphanTransactions.begin();
EraseOrphanTx(it->first);
size_t randompos = rng.randrange(g_orphan_list.size());
EraseOrphanTx(g_orphan_list[randompos]->first);
++nEvicted;
}
return nEvicted;
Expand Down

0 comments on commit 378ef2b

Please sign in to comment.