diff options
Diffstat (limited to 'src/test/script_tests.cpp')
-rw-r--r-- | src/test/script_tests.cpp | 98 |
1 files changed, 57 insertions, 41 deletions
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index c5a8f2dfbc..59eb90bd27 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -35,6 +35,8 @@ // Uncomment if you want to output updated JSON tests. // #define UPDATE_JSON_TESTS +using namespace util::hex_literals; + static const unsigned int gFlags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; unsigned int ParseScriptFlags(std::string strFlags); @@ -110,8 +112,7 @@ static ScriptError_t ParseScriptError(const std::string& name) return SCRIPT_ERR_UNKNOWN_ERROR; } -BOOST_FIXTURE_TEST_SUITE(script_tests, BasicTestingSetup) - +struct ScriptTest : BasicTestingSetup { void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScriptWitness& scriptWitness, uint32_t flags, const std::string& message, int scriptError, CAmount nValue = 0) { bool expect = (scriptError == SCRIPT_ERR_OK); @@ -122,13 +123,12 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript ScriptError err; const CTransaction txCredit{BuildCreditingTransaction(scriptPubKey, nValue)}; CMutableTransaction tx = BuildSpendingTransaction(scriptSig, scriptWitness, txCredit); - CMutableTransaction tx2 = tx; BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err) == expect, message); BOOST_CHECK_MESSAGE(err == scriptError, FormatScriptError(err) + " where " + FormatScriptError((ScriptError_t)scriptError) + " expected: " + message); // Verify that removing flags from a passing test or adding flags to a failing test does not change the result. for (int i = 0; i < 16; ++i) { - uint32_t extra_flags(InsecureRandBits(16)); + uint32_t extra_flags(m_rng.randbits(16)); uint32_t combined_flags{expect ? (flags & ~extra_flags) : (flags | extra_flags)}; // Weed out some invalid flag combinations. if (combined_flags & SCRIPT_VERIFY_CLEANSTACK && ~combined_flags & (SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS)) continue; @@ -136,6 +136,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript 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)); } } +}; // struct ScriptTest void static NegateSignatureS(std::vector<unsigned char>& vchSig) { // Parse the signature. @@ -369,11 +370,11 @@ public: return *this; } - TestBuilder& Test() + TestBuilder& Test(ScriptTest& test) { TestBuilder copy = *this; // Make a copy so we can rollback the push. DoPush(); - DoTest(creditTx->vout[0].scriptPubKey, spendTx.vin[0].scriptSig, scriptWitness, flags, comment, scriptError, nValue); + test.DoTest(creditTx->vout[0].scriptPubKey, spendTx.vin[0].scriptSig, scriptWitness, flags, comment, scriptError, nValue); *this = copy; return *this; } @@ -425,6 +426,8 @@ std::string JSONPrettyPrint(const UniValue& univalue) } } // namespace +BOOST_FIXTURE_TEST_SUITE(script_tests, ScriptTest) + BOOST_AUTO_TEST_CASE(script_build) { const KeyData keys; @@ -884,7 +887,7 @@ BOOST_AUTO_TEST_CASE(script_build) std::string strGen; #endif for (TestBuilder& test : tests) { - test.Test(); + test.Test(*this); std::string str = JSONPrettyPrint(test.GetJSON()); #ifdef UPDATE_JSON_TESTS strGen += str + ",\n"; @@ -1265,7 +1268,7 @@ BOOST_AUTO_TEST_CASE(sign_invalid_miniscript) // 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")}; + const auto invalid_pubkey{"173d36c8c9c9c9ffffffffffff0200000000021e1e37373721361818181818181e1e1e1e19000000000000000000b19292929292926b006c9b9b9292"_hex_u8}; TaprootBuilder builder; builder.Add(0, {invalid_pubkey}, 0xc0); builder.Finalize(XOnlyPubKey::NUMS_H); @@ -1352,10 +1355,23 @@ BOOST_AUTO_TEST_CASE(script_GetScriptAsm) BOOST_CHECK_EQUAL(derSig + "83 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83")) << vchPubKey)); } +template <typename T> +CScript ToScript(const T& byte_container) +{ + auto span{MakeUCharSpan(byte_container)}; + return {span.begin(), span.end()}; +} + static CScript ScriptFromHex(const std::string& str) { - std::vector<unsigned char> data = ParseHex(str); - return CScript(data.begin(), data.end()); + return ToScript(*Assert(TryParseHex(str))); +} + +BOOST_AUTO_TEST_CASE(script_byte_array_u8_vector_equivalence) +{ + const CScript scriptPubKey1 = CScript() << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex_v_u8 << OP_CHECKSIG; + const CScript scriptPubKey2 = CScript() << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex << OP_CHECKSIG; + BOOST_CHECK(scriptPubKey1 == scriptPubKey2); } BOOST_AUTO_TEST_CASE(script_FindAndDelete) @@ -1383,60 +1399,60 @@ BOOST_AUTO_TEST_CASE(script_FindAndDelete) BOOST_CHECK_EQUAL(FindAndDelete(s, d), 4); BOOST_CHECK(s == expect); - s = ScriptFromHex("0302ff03"); // PUSH 0x02ff03 onto stack - d = ScriptFromHex("0302ff03"); + s = ToScript("0302ff03"_hex); // PUSH 0x02ff03 onto stack + d = ToScript("0302ff03"_hex); expect = CScript(); BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1); BOOST_CHECK(s == expect); - s = ScriptFromHex("0302ff030302ff03"); // PUSH 0x2ff03 PUSH 0x2ff03 - d = ScriptFromHex("0302ff03"); + s = ToScript("0302ff030302ff03"_hex); // PUSH 0x02ff03 PUSH 0x02ff03 + d = ToScript("0302ff03"_hex); expect = CScript(); BOOST_CHECK_EQUAL(FindAndDelete(s, d), 2); BOOST_CHECK(s == expect); - s = ScriptFromHex("0302ff030302ff03"); - d = ScriptFromHex("02"); + s = ToScript("0302ff030302ff03"_hex); + d = ToScript("02"_hex); expect = s; // FindAndDelete matches entire opcodes BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0); BOOST_CHECK(s == expect); - s = ScriptFromHex("0302ff030302ff03"); - d = ScriptFromHex("ff"); + s = ToScript("0302ff030302ff03"_hex); + d = ToScript("ff"_hex); expect = s; BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0); BOOST_CHECK(s == expect); // This is an odd edge case: strip of the push-three-bytes // prefix, leaving 02ff03 which is push-two-bytes: - s = ScriptFromHex("0302ff030302ff03"); - d = ScriptFromHex("03"); - expect = CScript() << ParseHex("ff03") << ParseHex("ff03"); + s = ToScript("0302ff030302ff03"_hex); + d = ToScript("03"_hex); + expect = CScript() << "ff03"_hex << "ff03"_hex; BOOST_CHECK_EQUAL(FindAndDelete(s, d), 2); BOOST_CHECK(s == expect); // Byte sequence that spans multiple opcodes: - s = ScriptFromHex("02feed5169"); // PUSH(0xfeed) OP_1 OP_VERIFY - d = ScriptFromHex("feed51"); + s = ToScript("02feed5169"_hex); // PUSH(0xfeed) OP_1 OP_VERIFY + d = ToScript("feed51"_hex); expect = s; BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0); // doesn't match 'inside' opcodes BOOST_CHECK(s == expect); - s = ScriptFromHex("02feed5169"); // PUSH(0xfeed) OP_1 OP_VERIFY - d = ScriptFromHex("02feed51"); - expect = ScriptFromHex("69"); + s = ToScript("02feed5169"_hex); // PUSH(0xfeed) OP_1 OP_VERIFY + d = ToScript("02feed51"_hex); + expect = ToScript("69"_hex); BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1); BOOST_CHECK(s == expect); - s = ScriptFromHex("516902feed5169"); - d = ScriptFromHex("feed51"); + s = ToScript("516902feed5169"_hex); + d = ToScript("feed51"_hex); expect = s; BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0); BOOST_CHECK(s == expect); - s = ScriptFromHex("516902feed5169"); - d = ScriptFromHex("02feed51"); - expect = ScriptFromHex("516969"); + s = ToScript("516902feed5169"_hex); + d = ToScript("02feed51"_hex); + expect = ToScript("516969"_hex); BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1); BOOST_CHECK(s == expect); @@ -1454,15 +1470,15 @@ BOOST_AUTO_TEST_CASE(script_FindAndDelete) // Another weird edge case: // End with invalid push (not enough data)... - s = ScriptFromHex("0003feed"); - d = ScriptFromHex("03feed"); // ... can remove the invalid push - expect = ScriptFromHex("00"); + s = ToScript("0003feed"_hex); + d = ToScript("03feed"_hex); // ... can remove the invalid push + expect = ToScript("00"_hex); BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1); BOOST_CHECK(s == expect); - s = ScriptFromHex("0003feed"); - d = ScriptFromHex("00"); - expect = ScriptFromHex("03feed"); + s = ToScript("0003feed"_hex); + d = ToScript("00"_hex); + expect = ToScript("03feed"_hex); BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1); BOOST_CHECK(s == expect); } @@ -1471,13 +1487,13 @@ BOOST_AUTO_TEST_CASE(script_HasValidOps) { // Exercise the HasValidOps functionality CScript script; - script = ScriptFromHex("76a9141234567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac"); // Normal script + script = ToScript("76a9141234567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac"_hex); // Normal script BOOST_CHECK(script.HasValidOps()); - script = ScriptFromHex("76a914ff34567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac"); + script = ToScript("76a914ff34567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac"_hex); BOOST_CHECK(script.HasValidOps()); - script = ScriptFromHex("ff88ac"); // Script with OP_INVALIDOPCODE explicit + script = ToScript("ff88ac"_hex); // Script with OP_INVALIDOPCODE explicit BOOST_CHECK(!script.HasValidOps()); - script = ScriptFromHex("88acc0"); // Script with undefined opcode + script = ToScript("88acc0"_hex); // Script with undefined opcode BOOST_CHECK(!script.HasValidOps()); } |