aboutsummaryrefslogtreecommitdiff
path: root/src/test/miniscript_tests.cpp
diff options
context:
space:
mode:
authorAndrew Chow <github@achow101.com>2023-07-17 19:08:56 -0400
committerAndrew Chow <github@achow101.com>2023-07-17 19:16:09 -0400
commitbc88f3ab903f8a748a7570a6e17579dc4e9ba791 (patch)
tree690ff2f9c0a2e7e5096a10a1b422ab64b4a314c7 /src/test/miniscript_tests.cpp
parent306157ae92f47b36a7ad438cf76969a1ab6ef401 (diff)
parentc7db88af71b3204171f33399aa4f33b40a4f7cd9 (diff)
downloadbitcoin-bc88f3ab903f8a748a7570a6e17579dc4e9ba791.tar.xz
Merge bitcoin/bitcoin#27997: Descriptors: rule out unspendable miniscript descriptors
c7db88af71b3204171f33399aa4f33b40a4f7cd9 descriptor: assert we never parse a sane miniscript with no pubkey (Antoine Poinsot) a49402a9ec7431c286139b76f8759719a99a8551 qa: make sure we don't let unspendable Miniscript descriptors be imported (Antoine Poinsot) 639e3b6c9759a7a582c5c86fdbfa5ea99cb7bb16 descriptor: refuse to parse unspendable miniscript descriptors (Antoine Poinsot) e3280eae1b53006d74d11f3cf9d7a9dc7ff2c39e miniscript: make GetStackSize() and GetOps() return optionals (Antoine Poinsot) Pull request description: `IsSane()` in Miniscript does not ensure a Script is actually spendable. This is an issue as we would accept any sane Miniscript when parsing a descriptor. Fix this by explicitly checking a Miniscript descriptor is both sane and spendable when parsing it. This bug was exposed due to a check added in #22838 (https://github.com/bitcoin/bitcoin/pull/22838#discussion_r1226859880) that triggered a fuzz crash (https://github.com/bitcoin/bitcoin/pull/22838#issuecomment-1612510057). ACKs for top commit: sipa: utACK c7db88af71b3204171f33399aa4f33b40a4f7cd9 achow101: ACK c7db88af71b3204171f33399aa4f33b40a4f7cd9 Tree-SHA512: e79bc9f7842e98a4e8f358f05811fca51b15b4b80a171c0d2b17cf4bb1f578a18e4397bc2ece9817d392e0de0196ee6a054b7318441fd3566dd22e1f03eb64a5
Diffstat (limited to 'src/test/miniscript_tests.cpp')
-rw-r--r--src/test/miniscript_tests.cpp10
1 files changed, 5 insertions, 5 deletions
diff --git a/src/test/miniscript_tests.cpp b/src/test/miniscript_tests.cpp
index 42e441c41a..2d183c8844 100644
--- a/src/test/miniscript_tests.cpp
+++ b/src/test/miniscript_tests.cpp
@@ -297,7 +297,7 @@ void TestSatisfy(const std::string& testcase, const NodeRef& node) {
if (nonmal_success) {
// Non-malleable satisfactions are bounded by GetStackSize().
- BOOST_CHECK(witness_nonmal.stack.size() <= node->GetStackSize());
+ BOOST_CHECK(witness_nonmal.stack.size() <= *node->GetStackSize());
// If a non-malleable satisfaction exists, the malleable one must also exist, and be identical to it.
BOOST_CHECK(mal_success);
BOOST_CHECK(witness_nonmal.stack == witness_mal.stack);
@@ -375,8 +375,8 @@ void Test(const std::string& ms, const std::string& hexscript, int mode, int ops
auto inferred_miniscript = miniscript::FromScript(computed_script, CONVERTER);
BOOST_CHECK_MESSAGE(inferred_miniscript, "Cannot infer miniscript from script: " + ms);
BOOST_CHECK_MESSAGE(inferred_miniscript->ToScript(CONVERTER) == computed_script, "Roundtrip failure: miniscript->script != miniscript->script->miniscript->script: " + ms);
- if (opslimit != -1) BOOST_CHECK_MESSAGE((int)node->GetOps() == opslimit, "Ops limit mismatch: " << ms << " (" << node->GetOps() << " vs " << opslimit << ")");
- if (stacklimit != -1) BOOST_CHECK_MESSAGE((int)node->GetStackSize() == stacklimit, "Stack limit mismatch: " << ms << " (" << node->GetStackSize() << " vs " << stacklimit << ")");
+ if (opslimit != -1) BOOST_CHECK_MESSAGE((int)*node->GetOps() == opslimit, "Ops limit mismatch: " << ms << " (" << *node->GetOps() << " vs " << opslimit << ")");
+ if (stacklimit != -1) BOOST_CHECK_MESSAGE((int)*node->GetStackSize() == stacklimit, "Stack limit mismatch: " << ms << " (" << *node->GetStackSize() << " vs " << stacklimit << ")");
TestSatisfy(ms, node);
}
}
@@ -498,8 +498,8 @@ BOOST_AUTO_TEST_CASE(fixed_tests)
// For CHECKMULTISIG the OP cost is the number of keys, but the stack size is the number of sigs (+1)
const auto ms_multi = miniscript::FromString("multi(1,03d30199d74fb5a22d47b6e054e2f378cedacffcb89904a61d75d0dbd407143e65,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)", CONVERTER);
BOOST_CHECK(ms_multi);
- BOOST_CHECK_EQUAL(ms_multi->GetOps(), 4); // 3 pubkeys + CMS
- BOOST_CHECK_EQUAL(ms_multi->GetStackSize(), 3); // 1 sig + dummy elem + script push
+ BOOST_CHECK_EQUAL(*ms_multi->GetOps(), 4); // 3 pubkeys + CMS
+ BOOST_CHECK_EQUAL(*ms_multi->GetStackSize(), 3); // 1 sig + dummy elem + script push
// The 'd:' wrapper leaves on the stack what was DUP'ed at the beginning of its execution.
// Since it contains an OP_IF just after on the same element, we can make sure that the element
// in question must be OP_1 if OP_IF enforces that its argument must only be OP_1 or the empty