diff options
author | Alex Morcos <morcos@chaincode.com> | 2017-06-08 10:41:19 -0400 |
---|---|---|
committer | Alex Morcos <morcos@chaincode.com> | 2017-06-27 14:14:15 -0400 |
commit | 18bacec6c2c8493fd6b7011778446b3c7473bb25 (patch) | |
tree | 8a6f2be4ec128d74dc9f0add6342a794cafcb1cb /src/validation.cpp | |
parent | ac52492cd22782d7b09c78c198fb6fd8eb1da57c (diff) | |
download | bitcoin-18bacec6c2c8493fd6b7011778446b3c7473bb25.tar.xz |
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.
Diffstat (limited to 'src/validation.cpp')
-rw-r--r-- | src/validation.cpp | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/src/validation.cpp b/src/validation.cpp index eb6ea42b63..c160da64ab 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -491,24 +491,20 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool CCoinsViewMemPool viewMemPool(pcoinsTip, pool); view.SetBackend(viewMemPool); - // do we already have it? - for (size_t out = 0; out < tx.vout.size(); out++) { - COutPoint outpoint(hash, out); - bool had_coin_in_cache = pcoinsTip->HaveCoinInCache(outpoint); - if (view.HaveCoin(outpoint)) { - if (!had_coin_in_cache) { - coins_to_uncache.push_back(outpoint); - } - return state.Invalid(false, REJECT_DUPLICATE, "txn-already-known"); - } - } - // do all inputs exist? for (const CTxIn txin : tx.vin) { if (!pcoinsTip->HaveCoinInCache(txin.prevout)) { coins_to_uncache.push_back(txin.prevout); } if (!view.HaveCoin(txin.prevout)) { + // Are inputs missing because we already have the tx? + for (size_t out = 0; out < tx.vout.size(); out++) { + // Optimistically just do efficient check of cache for outputs + if (pcoinsTip->HaveCoinInCache(COutPoint(hash, out))) { + return state.Invalid(false, REJECT_DUPLICATE, "txn-already-known"); + } + } + // Otherwise assume this might be an orphan tx for which we just haven't seen parents yet if (pfMissingInputs) { *pfMissingInputs = true; } |