Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 715 Lines • ▼ Show 20 Lines | for (const CTxIn &txin : tx.vin) { | ||||
CCoinsView dummy; | CCoinsView dummy; | ||||
CCoinsViewCache view(&dummy); | CCoinsViewCache view(&dummy); | ||||
Amount nValueIn = Amount::zero(); | Amount nValueIn = Amount::zero(); | ||||
LockPoints lp; | LockPoints lp; | ||||
CCoinsViewMemPool viewMemPool(pcoinsTip, pool); | CCoinsViewMemPool viewMemPool(pcoinsTip, pool); | ||||
view.SetBackend(viewMemPool); | view.SetBackend(viewMemPool); | ||||
// Do we already have it? | |||||
for (size_t out = 0; out < tx.vout.size(); out++) { | |||||
COutPoint outpoint(txid, 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_ALREADY_KNOWN, | |||||
"txn-already-known"); | |||||
} | |||||
} | |||||
// Do all inputs exist? | // Do all inputs exist? | ||||
for (const CTxIn txin : tx.vin) { | for (const CTxIn txin : tx.vin) { | ||||
if (!pcoinsTip->HaveCoinInCache(txin.prevout)) { | if (!pcoinsTip->HaveCoinInCache(txin.prevout)) { | ||||
coins_to_uncache.push_back(txin.prevout); | coins_to_uncache.push_back(txin.prevout); | ||||
} | } | ||||
if (!view.HaveCoin(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(txid, 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) { | if (pfMissingInputs) { | ||||
*pfMissingInputs = true; | *pfMissingInputs = true; | ||||
} | } | ||||
// fMissingInputs and !state.IsInvalid() is used to detect this | // fMissingInputs and !state.IsInvalid() is used to detect this | ||||
// condition, don't set state.Invalid() | // condition, don't set state.Invalid() | ||||
return false; | return false; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 4,743 Lines • Show Last 20 Lines |