Run CheckInputs (using pcoinsTip) on the given transaction, for all script flags. Test that CheckInputs passes for all flags that don't overlap with the failing_flags argument, but otherwise fails. CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY (and future NOP codes that may get reassigned) have an interaction with DISCOURAGE_UPGRADABLE_NOPS: if the script flags used contain DISCOURAGE_UPGRADABLE_NO
| 103 | // Capture this interaction with the upgraded_nop argument: set it when evaluating |
| 104 | // any script flag that is implemented as an upgraded NOP code. |
| 105 | static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t failing_flags, bool add_to_cache) |
| 106 | { |
| 107 | PrecomputedTransactionData txdata(tx); |
| 108 | // If we add many more flags, this loop can get too expensive, but we can |
| 109 | // rewrite in the future to randomly pick a set of flags to evaluate. |
| 110 | for (uint32_t test_flags=0; test_flags < (1U << 17); test_flags += 1) { |
| 111 | CValidationState state; |
| 112 | // Filter out incompatible flag choices |
| 113 | if ((test_flags & SCRIPT_VERIFY_CLEANSTACK)) { |
| 114 | // CLEANSTACK requires P2SH and WITNESS, see VerifyScript() in |
| 115 | // script/interpreter.cpp |
| 116 | test_flags |= SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS; |
| 117 | } |
| 118 | if ((test_flags & SCRIPT_VERIFY_WITNESS)) { |
| 119 | // WITNESS requires P2SH |
| 120 | test_flags |= SCRIPT_VERIFY_P2SH; |
| 121 | } |
| 122 | bool ret = CheckInputs(tx, state, pcoinsTip.get(), true, test_flags | SCRIPT_FORKID_DISABLED, true, add_to_cache, txdata, nullptr); |
| 123 | // CheckInputs should succeed iff test_flags doesn't intersect with |
| 124 | // failing_flags |
| 125 | bool expected_return_value = !(test_flags & failing_flags); |
| 126 | BOOST_CHECK_EQUAL(ret, expected_return_value); |
| 127 | |
| 128 | // Test the caching |
| 129 | if (ret && add_to_cache) { |
| 130 | // Check that we get a cache hit if the tx was valid |
| 131 | std::vector<CScriptCheck> scriptchecks; |
| 132 | BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, test_flags | SCRIPT_FORKID_DISABLED, true, add_to_cache, txdata, &scriptchecks)); |
| 133 | BOOST_CHECK(scriptchecks.empty()); |
| 134 | } else { |
| 135 | // Check that we get script executions to check, if the transaction |
| 136 | // was invalid, or we didn't add to cache. |
| 137 | std::vector<CScriptCheck> scriptchecks; |
| 138 | BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, test_flags | SCRIPT_FORKID_DISABLED, true, add_to_cache, txdata, &scriptchecks)); |
| 139 | BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size()); |
| 140 | } |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) |
| 145 | { |
no test coverage detected