diff --git a/src/bench/ccoins_caching.cpp b/src/bench/ccoins_caching.cpp --- a/src/bench/ccoins_caching.cpp +++ b/src/bench/ccoins_caching.cpp @@ -80,7 +80,8 @@ // Benchmark. while (state.KeepRunning()) { CTransaction t(t1); - bool success = AreInputsStandard(t, coins); + bool success = + AreInputsStandard(t, coins, STANDARD_SCRIPT_VERIFY_FLAGS); assert(success); Amount value = coins.GetValueIn(t); assert(value == (50 + 21 + 22) * CENT); diff --git a/src/policy/policy.h b/src/policy/policy.h --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -129,8 +129,8 @@ * spending * @return True if all inputs (scriptSigs) use only standard transaction forms */ -bool AreInputsStandard(const CTransaction &tx, - const CCoinsViewCache &mapInputs); +bool AreInputsStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs, + uint32_t flags); extern CFeeRate dustRelayFee; extern uint32_t nBytesPerSigOp; diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -140,8 +140,8 @@ * expensive-to-check-upon-redemption script like: * DUP CHECKSIG DROP ... repeated 100 times... OP_1 */ -bool AreInputsStandard(const CTransaction &tx, - const CCoinsViewCache &mapInputs) { +bool AreInputsStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs, + uint32_t flags) { if (tx.IsCoinBase()) { // Coinbases don't use vin normally. return true; @@ -155,19 +155,7 @@ if (whichType == TX_NONSTANDARD) { return false; } else if (whichType == TX_SCRIPTHASH) { - std::vector> stack; - // convert the scriptSig into a stack, so we can inspect the - // redeemScript - if (!EvalScript(stack, in.scriptSig, SCRIPT_VERIFY_NONE, - BaseSignatureChecker())) { - return false; - } - if (stack.empty()) { - return false; - } - - CScript subscript(stack.back().begin(), stack.back().end()); - if (subscript.GetSigOpCount(STANDARD_SCRIPT_VERIFY_FLAGS, true) > + if (prev.scriptPubKey.GetSigOpCount(flags, in.scriptSig) > MAX_P2SH_SIGOPS) { return false; } diff --git a/src/test/script_p2sh_tests.cpp b/src/test/script_p2sh_tests.cpp --- a/src/test/script_p2sh_tests.cpp +++ b/src/test/script_p2sh_tests.cpp @@ -415,7 +415,8 @@ txTo.vin[4].scriptSig << std::vector(fifteenSigops.begin(), fifteenSigops.end()); - BOOST_CHECK(::AreInputsStandard(CTransaction(txTo), coins)); + BOOST_CHECK(::AreInputsStandard(CTransaction(txTo), coins, + STANDARD_SCRIPT_VERIFY_FLAGS)); // 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4] BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txTo), coins, STANDARD_SCRIPT_VERIFY_FLAGS), @@ -434,7 +435,8 @@ txToNonStd1.vin[0].scriptSig << std::vector(sixteenSigops.begin(), sixteenSigops.end()); - BOOST_CHECK(!::AreInputsStandard(CTransaction(txToNonStd1), coins)); + BOOST_CHECK(!::AreInputsStandard(CTransaction(txToNonStd1), coins, + STANDARD_SCRIPT_VERIFY_FLAGS)); BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txToNonStd1), coins, STANDARD_SCRIPT_VERIFY_FLAGS), 16U); @@ -453,7 +455,8 @@ txToNonStd2.vin[0].scriptSig << std::vector(twentySigops.begin(), twentySigops.end()); - BOOST_CHECK(!::AreInputsStandard(CTransaction(txToNonStd2), coins)); + BOOST_CHECK(!::AreInputsStandard(CTransaction(txToNonStd2), coins, + STANDARD_SCRIPT_VERIFY_FLAGS)); BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txToNonStd2), coins, STANDARD_SCRIPT_VERIFY_FLAGS), 20U); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -334,7 +334,8 @@ t1.vout[0].nValue = 90 * CENT; t1.vout[0].scriptPubKey << OP_1; - BOOST_CHECK(AreInputsStandard(CTransaction(t1), coins)); + BOOST_CHECK(AreInputsStandard(CTransaction(t1), coins, + STANDARD_SCRIPT_VERIFY_FLAGS)); BOOST_CHECK_EQUAL(coins.GetValueIn(CTransaction(t1)), (50 + 21 + 22) * CENT); } diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -661,8 +661,12 @@ tx.GetId().ToString(), FormatStateMessage(state)); } + const uint32_t nextBlockScriptVerifyFlags = + GetNextBlockScriptFlags(consensusParams, chainActive.Tip()); + // Check for non-standard pay-to-script-hash in inputs - if (fRequireStandard && !AreInputsStandard(tx, view)) { + if (fRequireStandard && + !AreInputsStandard(tx, view, nextBlockScriptVerifyFlags)) { return state.Invalid(false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs"); } @@ -681,10 +685,6 @@ break; } } - - const uint32_t nextBlockScriptVerifyFlags = - GetNextBlockScriptFlags(consensusParams, chainActive.Tip()); - auto nSigOpsCount = GetTransactionSigOpCount(tx, view, nextBlockScriptVerifyFlags);