diff options
Diffstat (limited to 'src/test/script_tests.cpp')
-rw-r--r-- | src/test/script_tests.cpp | 249 |
1 files changed, 24 insertions, 225 deletions
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 1f674408b2..39b53295e7 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -23,10 +23,6 @@ #include <util/fs.h> #include <util/strencodings.h> -#if defined(HAVE_CONSENSUS_LIB) -#include <script/bitcoinconsensus.h> -#endif - #include <cstdint> #include <fstream> #include <string> @@ -139,21 +135,6 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript if (combined_flags & SCRIPT_VERIFY_WITNESS && ~combined_flags & SCRIPT_VERIFY_P2SH) continue; BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, combined_flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err) == expect, message + strprintf(" (with flags %x)", combined_flags)); } - -#if defined(HAVE_CONSENSUS_LIB) - DataStream stream; - stream << TX_WITH_WITNESS(tx2); - uint32_t libconsensus_flags{flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL}; - if (libconsensus_flags == flags) { - int expectedSuccessCode = expect ? 1 : 0; - if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) { - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), txCredit.vout[0].nValue, UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); - } else { - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), 0, UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); - } - } -#endif } void static NegateSignatureS(std::vector<unsigned char>& vchSig) { @@ -415,7 +396,7 @@ public: wit.push_back(HexStr(scriptWitness.stack[i])); } wit.push_back(ValueFromAmount(nValue)); - array.push_back(wit); + array.push_back(std::move(wit)); } array.push_back(FormatScript(spendTx.vin[0].scriptSig)); array.push_back(FormatScript(creditTx->vout[0].scriptPubKey)); @@ -1273,6 +1254,29 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) BOOST_CHECK(combined.scriptSig == partial3c); } +/** + * Reproduction of an exception incorrectly raised when parsing a public key inside a TapMiniscript. + */ +BOOST_AUTO_TEST_CASE(sign_invalid_miniscript) +{ + FillableSigningProvider keystore; + SignatureData sig_data; + CMutableTransaction prev, curr; + + // Create a Taproot output which contains a leaf in which a non-32 bytes push is used where a public key is expected + // by the Miniscript parser. This offending Script was found by the RPC fuzzer. + const auto invalid_pubkey{ParseHex("173d36c8c9c9c9ffffffffffff0200000000021e1e37373721361818181818181e1e1e1e19000000000000000000b19292929292926b006c9b9b9292")}; + TaprootBuilder builder; + builder.Add(0, {invalid_pubkey}, 0xc0); + builder.Finalize(XOnlyPubKey::NUMS_H); + prev.vout.emplace_back(0, GetScriptForDestination(builder.GetOutput())); + curr.vin.emplace_back(COutPoint{prev.GetHash(), 0}); + sig_data.tr_spenddata = builder.GetSpendData(); + + // SignSignature can fail but it shouldn't raise an exception (nor crash). + BOOST_CHECK(!SignSignature(keystore, CTransaction(prev), curr, 0, SIGHASH_ALL, sig_data)); +} + BOOST_AUTO_TEST_CASE(script_standard_push) { ScriptError err; @@ -1494,179 +1498,6 @@ static CScriptWitness ScriptWitnessFromJSON(const UniValue& univalue) return scriptwitness; } -#if defined(HAVE_CONSENSUS_LIB) - -/* Test simple (successful) usage of bitcoinconsensus_verify_script */ -BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_returns_true) -{ - unsigned int libconsensus_flags = 0; - int nIn = 0; - - CScript scriptPubKey; - CScript scriptSig; - CScriptWitness wit; - - scriptPubKey << OP_1; - CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)}; - CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)}; - - DataStream stream; - stream << TX_WITH_WITNESS(spendTx); - - bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err); - BOOST_CHECK_EQUAL(result, 1); - BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_OK); -} - -/* Test bitcoinconsensus_verify_script returns invalid tx index err*/ -BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_index_err) -{ - unsigned int libconsensus_flags = 0; - int nIn = 3; - - CScript scriptPubKey; - CScript scriptSig; - CScriptWitness wit; - - scriptPubKey << OP_EQUAL; - CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)}; - CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)}; - - DataStream stream; - stream << TX_WITH_WITNESS(spendTx); - - bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err); - BOOST_CHECK_EQUAL(result, 0); - BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_INDEX); -} - -/* Test bitcoinconsensus_verify_script returns tx size mismatch err*/ -BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_size) -{ - unsigned int libconsensus_flags = 0; - int nIn = 0; - - CScript scriptPubKey; - CScript scriptSig; - CScriptWitness wit; - - scriptPubKey << OP_EQUAL; - CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)}; - CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)}; - - DataStream stream; - stream << TX_WITH_WITNESS(spendTx); - - bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size() * 2, nIn, libconsensus_flags, &err); - BOOST_CHECK_EQUAL(result, 0); - BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH); -} - -/* Test bitcoinconsensus_verify_script returns invalid tx serialization error */ -BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_serialization) -{ - unsigned int libconsensus_flags = 0; - int nIn = 0; - - CScript scriptPubKey; - CScript scriptSig; - CScriptWitness wit; - - scriptPubKey << OP_EQUAL; - CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)}; - CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)}; - - DataStream stream; - stream << 0xffffffff; - - bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err); - BOOST_CHECK_EQUAL(result, 0); - BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_DESERIALIZE); -} - -/* Test bitcoinconsensus_verify_script returns amount required error */ -BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_amount_required_err) -{ - unsigned int libconsensus_flags = bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS; - int nIn = 0; - - CScript scriptPubKey; - CScript scriptSig; - CScriptWitness wit; - - scriptPubKey << OP_EQUAL; - CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)}; - CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)}; - - DataStream stream; - stream << TX_WITH_WITNESS(spendTx); - - bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err); - BOOST_CHECK_EQUAL(result, 0); - BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED); -} - -/* Test bitcoinconsensus_verify_script returns invalid flags err */ -BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_invalid_flags) -{ - unsigned int libconsensus_flags = 1 << 3; - int nIn = 0; - - CScript scriptPubKey; - CScript scriptSig; - CScriptWitness wit; - - scriptPubKey << OP_EQUAL; - CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)}; - CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)}; - - DataStream stream; - stream << TX_WITH_WITNESS(spendTx); - - bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err); - BOOST_CHECK_EQUAL(result, 0); - BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_INVALID_FLAGS); -} - -/* Test bitcoinconsensus_verify_script returns spent outputs required err */ -BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_spent_outputs_required_err) -{ - unsigned int libconsensus_flags{bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT}; - const int nIn{0}; - - CScript scriptPubKey; - CScript scriptSig; - CScriptWitness wit; - - scriptPubKey << OP_EQUAL; - CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)}; - CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)}; - - DataStream stream; - stream << TX_WITH_WITNESS(spendTx); - - bitcoinconsensus_error err; - int result{bitcoinconsensus_verify_script_with_spent_outputs(scriptPubKey.data(), scriptPubKey.size(), creditTx.vout[0].nValue, UCharCast(stream.data()), stream.size(), nullptr, 0, nIn, libconsensus_flags, &err)}; - BOOST_CHECK_EQUAL(result, 0); - BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_SPENT_OUTPUTS_REQUIRED); - - result = bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), creditTx.vout[0].nValue, UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err); - BOOST_CHECK_EQUAL(result, 0); - BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_SPENT_OUTPUTS_REQUIRED); - - result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err); - BOOST_CHECK_EQUAL(result, 0); - BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_SPENT_OUTPUTS_REQUIRED); -} - -#endif // defined(HAVE_CONSENSUS_LIB) - static std::vector<unsigned int> AllConsensusFlags() { std::vector<unsigned int> ret; @@ -1714,28 +1545,12 @@ static void AssetTest(const UniValue& test) txdata.Init(tx, std::vector<CTxOut>(prevouts)); CachingTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, true, txdata); -#if defined(HAVE_CONSENSUS_LIB) - DataStream stream; - stream << TX_WITH_WITNESS(tx); - std::vector<UTXO> utxos; - utxos.resize(prevouts.size()); - for (size_t i = 0; i < prevouts.size(); i++) { - utxos[i].scriptPubKey = prevouts[i].scriptPubKey.data(); - utxos[i].scriptPubKeySize = prevouts[i].scriptPubKey.size(); - utxos[i].value = prevouts[i].nValue; - } -#endif - for (const auto flags : ALL_CONSENSUS_FLAGS) { // "final": true tests are valid for all flags. Others are only valid with flags that are // a subset of test_flags. if (fin || ((flags & test_flags) == flags)) { bool ret = VerifyScript(tx.vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.vin[idx].scriptWitness, flags, txcheck, nullptr); BOOST_CHECK(ret); -#if defined(HAVE_CONSENSUS_LIB) - int lib_ret = bitcoinconsensus_verify_script_with_spent_outputs(prevouts[idx].scriptPubKey.data(), prevouts[idx].scriptPubKey.size(), prevouts[idx].nValue, UCharCast(stream.data()), stream.size(), utxos.data(), utxos.size(), idx, flags, nullptr); - BOOST_CHECK(lib_ret == 1); -#endif } } } @@ -1748,27 +1563,11 @@ static void AssetTest(const UniValue& test) txdata.Init(tx, std::vector<CTxOut>(prevouts)); CachingTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, true, txdata); -#if defined(HAVE_CONSENSUS_LIB) - DataStream stream; - stream << TX_WITH_WITNESS(tx); - std::vector<UTXO> utxos; - utxos.resize(prevouts.size()); - for (size_t i = 0; i < prevouts.size(); i++) { - utxos[i].scriptPubKey = prevouts[i].scriptPubKey.data(); - utxos[i].scriptPubKeySize = prevouts[i].scriptPubKey.size(); - utxos[i].value = prevouts[i].nValue; - } -#endif - for (const auto flags : ALL_CONSENSUS_FLAGS) { // If a test is supposed to fail with test_flags, it should also fail with any superset thereof. if ((flags & test_flags) == test_flags) { bool ret = VerifyScript(tx.vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.vin[idx].scriptWitness, flags, txcheck, nullptr); BOOST_CHECK(!ret); -#if defined(HAVE_CONSENSUS_LIB) - int lib_ret = bitcoinconsensus_verify_script_with_spent_outputs(prevouts[idx].scriptPubKey.data(), prevouts[idx].scriptPubKey.size(), prevouts[idx].nValue, UCharCast(stream.data()), stream.size(), utxos.data(), utxos.size(), idx, flags, nullptr); - BOOST_CHECK(lib_ret == 0); -#endif } } } |