diff --git a/src/test/script_p2sh_tests.cpp b/src/test/script_p2sh_tests.cpp index 858723d46ad..0bb2ba410fb 100644 --- a/src/test/script_p2sh_tests.cpp +++ b/src/test/script_p2sh_tests.cpp @@ -292,7 +292,7 @@ BOOST_AUTO_TEST_CASE(ValidateInputsStandardness) keys.push_back(key[i].GetPubKey()); CMutableTransaction txFrom; - txFrom.vout.resize(7); + txFrom.vout.resize(10); // First three are standard: CScript pay1 = GetScriptForDestination(PKHash(key[0].GetPubKey())); @@ -334,7 +334,24 @@ BOOST_AUTO_TEST_CASE(ValidateInputsStandardness) CScript twentySigops; twentySigops << OP_CHECKMULTISIG; BOOST_CHECK(keystore.AddCScript(twentySigops)); txFrom.vout[6].scriptPubKey = GetScriptForDestination(ScriptHash(twentySigops)); - txFrom.vout[6].nValue = 6000; + txFrom.vout[6].nValue = 3000; + + // vout[7] is non-standard because it lacks sigops + CScript no_sigops; + txFrom.vout[7].scriptPubKey = no_sigops; + txFrom.vout[7].nValue = 1000; + + // vout [8] is non-standard because it contains OP_RETURN in its redeemScript. + static const unsigned char op_return[] = {OP_RETURN}; + const auto op_return_script = CScript(op_return, op_return + sizeof(op_return)); + txFrom.vout[8].scriptPubKey = GetScriptForDestination(ScriptHash(op_return_script)); + txFrom.vout[8].nValue = 1000; + + // vout[9] is non-standard because its witness is unknown + CScript witnessUnknown; + witnessUnknown << OP_16 << ToByteVector(uint256::ONE); + txFrom.vout[9].scriptPubKey = witnessUnknown; + txFrom.vout[9].nValue = 1000; AddCoins(coins, CTransaction(txFrom), 0); @@ -370,6 +387,7 @@ BOOST_AUTO_TEST_CASE(ValidateInputsStandardness) BOOST_CHECK(coinbase_tx.IsCoinBase()); BOOST_CHECK_EQUAL(GetP2SHSigOpCount(coinbase_tx, coins), 0U); + // TxoutType::SCRIPTHASH CMutableTransaction txToNonStd1; txToNonStd1.vout.resize(1); txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[1].GetPubKey())); @@ -379,7 +397,11 @@ BOOST_AUTO_TEST_CASE(ValidateInputsStandardness) txToNonStd1.vin[0].prevout.hash = txFrom.GetHash(); txToNonStd1.vin[0].scriptSig << std::vector(sixteenSigops.begin(), sixteenSigops.end()); - BOOST_CHECK(::ValidateInputsStandardness(CTransaction(txToNonStd1), coins).IsInvalid()); + const auto txToNonStd1_res = ::ValidateInputsStandardness(CTransaction(txToNonStd1), coins); + BOOST_CHECK(txToNonStd1_res.IsInvalid()); + BOOST_CHECK_EQUAL(txToNonStd1_res.GetRejectReason(), "bad-txns-nonstandard-inputs"); + BOOST_CHECK_EQUAL(txToNonStd1_res.GetDebugMessage(), "p2sh redeemscript sigops exceed limit (input 0: 16 > 15)"); + BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txToNonStd1), coins), 16U); CMutableTransaction txToNonStd2; @@ -391,8 +413,67 @@ BOOST_AUTO_TEST_CASE(ValidateInputsStandardness) txToNonStd2.vin[0].prevout.hash = txFrom.GetHash(); txToNonStd2.vin[0].scriptSig << std::vector(twentySigops.begin(), twentySigops.end()); - BOOST_CHECK(::ValidateInputsStandardness(CTransaction(txToNonStd2), coins).IsInvalid()); + const auto txToNonStd2_res = ::ValidateInputsStandardness(CTransaction(txToNonStd2), coins); + BOOST_CHECK(txToNonStd2_res.IsInvalid()); + BOOST_CHECK_EQUAL(txToNonStd2_res.GetRejectReason(), "bad-txns-nonstandard-inputs"); + BOOST_CHECK_EQUAL(txToNonStd2_res.GetDebugMessage(), "p2sh redeemscript sigops exceed limit (input 0: 20 > 15)"); BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txToNonStd2), coins), 20U); + + CMutableTransaction txToNonStd2_no_scriptSig; + txToNonStd2_no_scriptSig.vout.resize(1); + txToNonStd2_no_scriptSig.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[1].GetPubKey())); + txToNonStd2_no_scriptSig.vout[0].nValue = 1000; + txToNonStd2_no_scriptSig.vin.resize(1); + txToNonStd2_no_scriptSig.vin[0].prevout.n = 6; + txToNonStd2_no_scriptSig.vin[0].prevout.hash = txFrom.GetHash(); + + const auto txToNonStd2_no_scriptSig_res = ::ValidateInputsStandardness(CTransaction(txToNonStd2_no_scriptSig), coins); + BOOST_CHECK(txToNonStd2_no_scriptSig_res.IsInvalid()); + BOOST_CHECK_EQUAL(txToNonStd2_no_scriptSig_res.GetRejectReason(), "bad-txns-nonstandard-inputs"); + BOOST_CHECK_EQUAL(txToNonStd2_no_scriptSig_res.GetDebugMessage(), "input 0 P2SH redeemscript missing"); + BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txToNonStd2), coins), 20U); + + // TxoutType::NONSTANDARD + CMutableTransaction txToNonStd3; + txToNonStd3.vout.resize(1); + txToNonStd3.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[1].GetPubKey())); + txToNonStd3.vout[0].nValue = 1000; + txToNonStd3.vin.resize(1); + txToNonStd3.vin[0].prevout.n = 7; + txToNonStd3.vin[0].prevout.hash = txFrom.GetHash(); + + const auto txToNonStd3_res = ::ValidateInputsStandardness(CTransaction(txToNonStd3), coins); + BOOST_CHECK(txToNonStd3_res.IsInvalid()); + BOOST_CHECK_EQUAL(txToNonStd3_res.GetRejectReason(), "bad-txns-nonstandard-inputs"); + BOOST_CHECK_EQUAL(txToNonStd3_res.GetDebugMessage(), "input 0 script unknown"); + + // TxoutType::INCORRECT_SCRIPTSIG + CMutableTransaction txToNonStd4; + txToNonStd4.vout.resize(1); + txToNonStd4.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[1].GetPubKey())); + txToNonStd4.vout[0].nValue = 1000; + txToNonStd4.vin.resize(1); + txToNonStd4.vin[0].prevout.n = 8; + txToNonStd4.vin[0].prevout.hash = txFrom.GetHash(); + txToNonStd4.vin[0].scriptSig = op_return_script; + + const auto txToNonStd4_res = ::ValidateInputsStandardness(CTransaction(txToNonStd4), coins); + BOOST_CHECK(txToNonStd4_res.IsInvalid()); + BOOST_CHECK_EQUAL(txToNonStd4_res.GetRejectReason(), "bad-txns-nonstandard-inputs"); + BOOST_CHECK_EQUAL(txToNonStd4_res.GetDebugMessage(), "p2sh scriptsig malformed (input 0: OP_RETURN was encountered)"); + + // TxoutType::WITNESS_UNKNOWN + CMutableTransaction txWitnessUnknown; + txWitnessUnknown.vout.resize(1); + txWitnessUnknown.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[1].GetPubKey())); + txWitnessUnknown.vout[0].nValue = 1000; + txWitnessUnknown.vin.resize(1); + txWitnessUnknown.vin[0].prevout.n = 9; + txWitnessUnknown.vin[0].prevout.hash = txFrom.GetHash(); + const auto txWitnessUnknown_res = ::ValidateInputsStandardness(CTransaction(txWitnessUnknown), coins); + BOOST_CHECK(txWitnessUnknown_res.IsInvalid()); + BOOST_CHECK_EQUAL(txWitnessUnknown_res.GetRejectReason(), "bad-txns-nonstandard-inputs"); + BOOST_CHECK_EQUAL(txWitnessUnknown_res.GetDebugMessage(), "input 0 witness program is undefined"); } BOOST_AUTO_TEST_SUITE_END()