Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 622 Lines • ▼ Show 20 Lines | bool IsUAHFenabled(const Config &config, const CBlockIndex *pindexPrev) { | ||||
return IsUAHFenabled(config, pindexPrev->GetMedianTimePast()); | return IsUAHFenabled(config, pindexPrev->GetMedianTimePast()); | ||||
} | } | ||||
bool IsUAHFenabledForCurrentBlock(const Config &config) { | bool IsUAHFenabledForCurrentBlock(const Config &config) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
return IsUAHFenabled(config, chainActive.Tip()); | return IsUAHFenabled(config, chainActive.Tip()); | ||||
} | } | ||||
// Used to avoid mempool polluting consensus critical paths if CCoinsViewMempool | |||||
// were somehow broken and returning the wrong scriptPubKeys | |||||
static bool CheckInputsFromMempoolAndCache(const CTransaction &tx, | |||||
CValidationState &state, | |||||
const CCoinsViewCache &view, | |||||
CTxMemPool &pool, uint32_t flags, | |||||
bool cacheSigStore, | |||||
PrecomputedTransactionData &txdata) { | |||||
AssertLockHeld(cs_main); | |||||
// pool.cs should be locked already, but go ahead and re-take the lock here | |||||
// to enforce that mempool doesn't change between when we check the view and | |||||
// when we actually call through to CheckInputs | |||||
LOCK(pool.cs); | |||||
assert(!tx.IsCoinBase()); | |||||
for (const CTxIn &txin : tx.vin) { | |||||
const Coin &coin = view.AccessCoin(txin.prevout); | |||||
// At this point we haven't actually checked if the coins are all | |||||
// available (or shouldn't assume we have, since CheckInputs does). So | |||||
// we just return failure if the inputs are not available here, and then | |||||
// only have to check equivalence for available inputs. | |||||
if (coin.IsSpent()) { | |||||
return false; | |||||
} | |||||
const CTransactionRef &txFrom = pool.get(txin.prevout.hash); | |||||
if (txFrom) { | |||||
assert(txFrom->GetHash() == txin.prevout.hash); | |||||
assert(txFrom->vout.size() > txin.prevout.n); | |||||
assert(txFrom->vout[txin.prevout.n] == coin.GetTxOut()); | |||||
} else { | |||||
const Coin &coinFromDisk = pcoinsTip->AccessCoin(txin.prevout); | |||||
assert(!coinFromDisk.IsSpent()); | |||||
assert(coinFromDisk.GetTxOut() == coin.GetTxOut()); | |||||
} | |||||
} | |||||
return CheckInputs(tx, state, view, true, flags, cacheSigStore, true, | |||||
txdata); | |||||
} | |||||
static bool AcceptToMemoryPoolWorker( | static bool AcceptToMemoryPoolWorker( | ||||
const Config &config, CTxMemPool &pool, CValidationState &state, | const Config &config, CTxMemPool &pool, CValidationState &state, | ||||
const CTransactionRef &ptx, bool fLimitFree, bool *pfMissingInputs, | const CTransactionRef &ptx, bool fLimitFree, bool *pfMissingInputs, | ||||
int64_t nAcceptTime, std::list<CTransactionRef> *plTxnReplaced, | int64_t nAcceptTime, std::list<CTransactionRef> *plTxnReplaced, | ||||
bool fOverrideMempoolLimit, const CAmount &nAbsurdFee, | bool fOverrideMempoolLimit, const CAmount &nAbsurdFee, | ||||
std::vector<COutPoint> &coins_to_uncache) { | std::vector<COutPoint> &coins_to_uncache) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
▲ Show 20 Lines • Show All 260 Lines • ▼ Show 20 Lines | // Check for conflicts with in-memory transactions | ||||
// instance the STRICTENC flag was incorrectly allowing certain CHECKSIG | // instance the STRICTENC flag was incorrectly allowing certain CHECKSIG | ||||
// NOT scripts to pass, even though they were invalid. | // NOT scripts to pass, even though they were invalid. | ||||
// | // | ||||
// There is a similar check in CreateNewBlock() to prevent creating | // There is a similar check in CreateNewBlock() to prevent creating | ||||
// invalid blocks (using TestBlockValidity), however allowing such | // invalid blocks (using TestBlockValidity), however allowing such | ||||
// transactions into the mempool can be exploited as a DoS attack. | // transactions into the mempool can be exploited as a DoS attack. | ||||
uint32_t currentBlockScriptVerifyFlags = | uint32_t currentBlockScriptVerifyFlags = | ||||
GetBlockScriptFlags(chainActive.Tip(), config); | GetBlockScriptFlags(chainActive.Tip(), config); | ||||
if (!CheckInputs(tx, state, view, true, currentBlockScriptVerifyFlags, | if (!CheckInputsFromMempoolAndCache(tx, state, view, pool, | ||||
true, true, txdata)) { | currentBlockScriptVerifyFlags, true, | ||||
txdata)) { | |||||
// If we're using promiscuousmempoolflags, we may hit this normally. | // If we're using promiscuousmempoolflags, we may hit this normally. | ||||
// Check if current block has some flags that scriptVerifyFlags does | // Check if current block has some flags that scriptVerifyFlags does | ||||
// not before printing an ominous warning. | // not before printing an ominous warning. | ||||
if (!(~scriptVerifyFlags & currentBlockScriptVerifyFlags)) { | if (!(~scriptVerifyFlags & currentBlockScriptVerifyFlags)) { | ||||
return error( | return error( | ||||
"%s: BUG! PLEASE REPORT THIS! ConnectInputs failed against " | "%s: BUG! PLEASE REPORT THIS! ConnectInputs failed against " | ||||
"MANDATORY but not STANDARD flags %s, %s", | "MANDATORY but not STANDARD flags %s, %s", | ||||
__func__, txid.ToString(), FormatStateMessage(state)); | __func__, txid.ToString(), FormatStateMessage(state)); | ||||
▲ Show 20 Lines • Show All 4,104 Lines • Show Last 20 Lines |