merge #13868: Remove unused fScriptChecks parameter from CheckInputs

This commit is contained in:
Konstantin Akimov 2019-09-02 15:36:57 +08:00 committed by PastaPastaPasta
parent 15a9783e52
commit ce3e8072a7
2 changed files with 88 additions and 95 deletions

View File

@ -12,7 +12,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks); bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks);
BOOST_AUTO_TEST_SUITE(txvalidationcache_tests) BOOST_AUTO_TEST_SUITE(txvalidationcache_tests)
@ -118,7 +118,7 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail
// script/interpreter.cpp // script/interpreter.cpp
test_flags |= SCRIPT_VERIFY_P2SH; test_flags |= SCRIPT_VERIFY_P2SH;
} }
bool ret = CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), true, test_flags, true, add_to_cache, txdata, nullptr); bool ret = CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, nullptr);
// CheckInputs should succeed iff test_flags doesn't intersect with // CheckInputs should succeed iff test_flags doesn't intersect with
// failing_flags // failing_flags
bool expected_return_value = !(test_flags & failing_flags); bool expected_return_value = !(test_flags & failing_flags);
@ -128,13 +128,13 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail
if (ret && add_to_cache) { if (ret && add_to_cache) {
// Check that we get a cache hit if the tx was valid // Check that we get a cache hit if the tx was valid
std::vector<CScriptCheck> scriptchecks; std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), true, test_flags, true, add_to_cache, txdata, &scriptchecks)); BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks));
BOOST_CHECK(scriptchecks.empty()); BOOST_CHECK(scriptchecks.empty());
} else { } else {
// Check that we get script executions to check, if the transaction // Check that we get script executions to check, if the transaction
// was invalid, or we didn't add to cache. // was invalid, or we didn't add to cache.
std::vector<CScriptCheck> scriptchecks; std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), true, test_flags, true, add_to_cache, txdata, &scriptchecks)); BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks));
BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size()); BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size());
} }
} }
@ -196,13 +196,13 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
CValidationState state; CValidationState state;
PrecomputedTransactionData ptd_spend_tx; PrecomputedTransactionData ptd_spend_tx;
BOOST_CHECK(!CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr)); BOOST_CHECK(!CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr));
// If we call again asking for scriptchecks (as happens in // If we call again asking for scriptchecks (as happens in
// ConnectBlock), we should add a script check object for this -- we're // ConnectBlock), we should add a script check object for this -- we're
// not caching invalidity (if that changes, delete this test case). // not caching invalidity (if that changes, delete this test case).
std::vector<CScriptCheck> scriptchecks; std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks)); BOOST_CHECK(CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
BOOST_CHECK_EQUAL(scriptchecks.size(), 1U); BOOST_CHECK_EQUAL(scriptchecks.size(), 1U);
// Test that CheckInputs returns true iff DERSIG-enforcing flags are // Test that CheckInputs returns true iff DERSIG-enforcing flags are
@ -264,7 +264,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100; invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
CValidationState state; CValidationState state;
PrecomputedTransactionData txdata; PrecomputedTransactionData txdata;
BOOST_CHECK(CheckInputs(CTransaction(invalid_with_cltv_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr)); BOOST_CHECK(CheckInputs(CTransaction(invalid_with_cltv_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr));
} }
// TEST CHECKSEQUENCEVERIFY // TEST CHECKSEQUENCEVERIFY
@ -292,7 +292,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100; invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
CValidationState state; CValidationState state;
PrecomputedTransactionData txdata; PrecomputedTransactionData txdata;
BOOST_CHECK(CheckInputs(CTransaction(invalid_with_csv_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr)); BOOST_CHECK(CheckInputs(CTransaction(invalid_with_csv_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr));
} }
// TODO: add tests for remaining script flags // TODO: add tests for remaining script flags

View File

@ -201,7 +201,7 @@ std::unique_ptr<CBlockTreeDB> pblocktree;
// See definition for documentation // See definition for documentation
static void FindFilesToPruneManual(ChainstateManager& chainman, std::set<int>& setFilesToPrune, int nManualPruneHeight); static void FindFilesToPruneManual(ChainstateManager& chainman, std::set<int>& setFilesToPrune, int nManualPruneHeight);
static void FindFilesToPrune(ChainstateManager& chainman, std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight); static void FindFilesToPrune(ChainstateManager& chainman, std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight);
bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks = nullptr); bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks = nullptr);
static FILE* OpenUndoFile(const FlatFilePos &pos, bool fReadOnly = false); static FILE* OpenUndoFile(const FlatFilePos &pos, bool fReadOnly = false);
static FlatFileSeq BlockFileSeq(); static FlatFileSeq BlockFileSeq();
static FlatFileSeq UndoFileSeq(); static FlatFileSeq UndoFileSeq();
@ -503,7 +503,7 @@ static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, CValidationSt
} }
// Call CheckInputs() to cache signature and script validity against current tip consensus rules. // Call CheckInputs() to cache signature and script validity against current tip consensus rules.
return CheckInputs(tx, state, view, true, flags, /* cacheSigStore = */ true, /* cacheFullSciptStore = */ true, txdata); return CheckInputs(tx, state, view, flags, /* cacheSigStore = */ true, /* cacheFullSciptStore = */ true, txdata);
} }
/** /**
@ -731,7 +731,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
// Check against previous transactions // Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks. // This is done last to help prevent CPU exhaustion denial-of-service attacks.
PrecomputedTransactionData txdata; PrecomputedTransactionData txdata;
if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, false, txdata)) { if (!CheckInputs(tx, state, view, scriptVerifyFlags, true, false, txdata)) {
assert(IsTransactionReason(state.GetReason())); assert(IsTransactionReason(state.GetReason()));
return false; // state filled in by CheckInputs return false; // state filled in by CheckInputs
} }
@ -1415,24 +1415,15 @@ void InitScriptExecutionCache() {
* *
* Non-static (and re-declared) in src/test/txvalidationcache_tests.cpp * Non-static (and re-declared) in src/test/txvalidationcache_tests.cpp
*/ */
bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks) EXCLUSIVE_LOCKS_REQUIRED(cs_main) bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{ {
boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time(); boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time();
if (!tx.IsCoinBase()) if (tx.IsCoinBase()) return true;
{
if (pvChecks) if (pvChecks) {
pvChecks->reserve(tx.vin.size()); pvChecks->reserve(tx.vin.size());
}
// The first loop above does all the inexpensive checks.
// Only if ALL inputs pass do we perform expensive ECDSA signature checks.
// Helps prevent CPU exhaustion attacks.
// Skip script verification when connecting blocks under the
// assumevalid block. Assuming the assumevalid block is valid this
// is safe because block merkle hashes are still computed and checked,
// Of course, if an assumed valid block is invalid due to false scriptSigs
// this optimization would allow an invalid chain to be accepted.
if (fScriptChecks) {
// First check if script executions have been cached with the same // First check if script executions have been cached with the same
// flags. Note that this assumes that the inputs provided are // flags. Note that this assumes that the inputs provided are
// correct (ie that the transaction hash which is in tx's prevouts // correct (ie that the transaction hash which is in tx's prevouts
@ -1502,13 +1493,10 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
// cache the result. Do so now. // cache the result. Do so now.
g_scriptExecutionCache.insert(hashCacheEntry); g_scriptExecutionCache.insert(hashCacheEntry);
} }
}
}
boost::posix_time::ptime finish = boost::posix_time::microsec_clock::local_time(); boost::posix_time::ptime finish = boost::posix_time::microsec_clock::local_time();
boost::posix_time::time_duration diff = finish - start; boost::posix_time::time_duration diff = finish - start;
statsClient.timing("CheckInputs_ms", diff.total_milliseconds(), 1.0f); statsClient.timing("CheckInputs_ms", diff.total_milliseconds(), 1.0f);
return true; return true;
} }
@ -2055,6 +2043,11 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
pindexBestHeader->GetAncestor(pindex->nHeight) == pindex && pindexBestHeader->GetAncestor(pindex->nHeight) == pindex &&
pindexBestHeader->nChainWork >= nMinimumChainWork) { pindexBestHeader->nChainWork >= nMinimumChainWork) {
// This block is a member of the assumed verified chain and an ancestor of the best header. // This block is a member of the assumed verified chain and an ancestor of the best header.
// Script verification is skipped when connecting blocks under the
// assumevalid block. Assuming the assumevalid block is valid this
// is safe because block merkle hashes are still computed and checked,
// Of course, if an assumed valid block is invalid due to false scriptSigs
// this optimization would allow an invalid chain to be accepted.
// The equivalent time check discourages hash power from extorting the network via DOS attack // The equivalent time check discourages hash power from extorting the network via DOS attack
// into accepting an invalid block through telling users they must manually set assumevalid. // into accepting an invalid block through telling users they must manually set assumevalid.
// Requiring a software change or burying the invalid block, regardless of the setting, makes // Requiring a software change or burying the invalid block, regardless of the setting, makes
@ -2252,7 +2245,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
std::vector<CScriptCheck> vChecks; std::vector<CScriptCheck> vChecks;
bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */ bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */
if (fScriptChecks && !CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, fCacheResults, txsdata[i], g_parallel_script_checks ? &vChecks : nullptr)) { if (fScriptChecks && !CheckInputs(tx, state, view, flags, fCacheResults, fCacheResults, txsdata[i], g_parallel_script_checks ? &vChecks : nullptr)) {
if (state.GetReason() == ValidationInvalidReason::TX_NOT_STANDARD) { if (state.GetReason() == ValidationInvalidReason::TX_NOT_STANDARD) {
// CheckInputs may return NOT_STANDARD for extra flags we passed, // CheckInputs may return NOT_STANDARD for extra flags we passed,
// but we can't return that, as it's not defined for a block, so // but we can't return that, as it's not defined for a block, so