Skip to content

Commit 18bacec

Browse files
committed
Make check to distinguish between orphan txs and old txs more efficient.
Checking for the existence in the CCoinsViewCache of the outputs of a new tx will result in a disk hit for every output since they will not be found. On the other hand if those outputs exist already, then the inputs must also have been missing, so we can move this check inside the input existence check so in the common case of a new tx it doesn't need to run. The purpose of the check is to avoid spamming the orphanMap with slightly old txs which we have already seen in a block, but it is already only optimistic (depending on the outputs not being spent), so make it even more efficient by only checking the cache and not the entire pcoinsTip.
1 parent ac52492 commit 18bacec

File tree

1 file changed

+8
-12
lines changed

1 file changed

+8
-12
lines changed

src/validation.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -491,24 +491,20 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
491491
CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
492492
view.SetBackend(viewMemPool);
493493

494-
// do we already have it?
495-
for (size_t out = 0; out < tx.vout.size(); out++) {
496-
COutPoint outpoint(hash, out);
497-
bool had_coin_in_cache = pcoinsTip->HaveCoinInCache(outpoint);
498-
if (view.HaveCoin(outpoint)) {
499-
if (!had_coin_in_cache) {
500-
coins_to_uncache.push_back(outpoint);
501-
}
502-
return state.Invalid(false, REJECT_DUPLICATE, "txn-already-known");
503-
}
504-
}
505-
506494
// do all inputs exist?
507495
for (const CTxIn txin : tx.vin) {
508496
if (!pcoinsTip->HaveCoinInCache(txin.prevout)) {
509497
coins_to_uncache.push_back(txin.prevout);
510498
}
511499
if (!view.HaveCoin(txin.prevout)) {
500+
// Are inputs missing because we already have the tx?
501+
for (size_t out = 0; out < tx.vout.size(); out++) {
502+
// Optimistically just do efficient check of cache for outputs
503+
if (pcoinsTip->HaveCoinInCache(COutPoint(hash, out))) {
504+
return state.Invalid(false, REJECT_DUPLICATE, "txn-already-known");
505+
}
506+
}
507+
// Otherwise assume this might be an orphan tx for which we just haven't seen parents yet
512508
if (pfMissingInputs) {
513509
*pfMissingInputs = true;
514510
}

0 commit comments

Comments
 (0)