diff --git a/src/test/miniscript_tests.cpp b/src/test/miniscript_tests.cpp index f253562a2f6..0a32727f37e 100644 --- a/src/test/miniscript_tests.cpp +++ b/src/test/miniscript_tests.cpp @@ -297,28 +297,29 @@ using miniscript::operator""_mst; using Node = miniscript::Node; /** Compute all challenges (pubkeys, hashes, timelocks) that occur in a given Miniscript. */ -// NOLINTNEXTLINE(misc-no-recursion) -std::set FindChallenges(const NodeRef& ref) { +std::set FindChallenges(const Node* root) +{ std::set chal; - for (const auto& key : ref->keys) { - chal.emplace(ChallengeType::PK, ChallengeNumber(key)); - } - if (ref->fragment == miniscript::Fragment::OLDER) { - chal.emplace(ChallengeType::OLDER, ref->k); - } else if (ref->fragment == miniscript::Fragment::AFTER) { - chal.emplace(ChallengeType::AFTER, ref->k); - } else if (ref->fragment == miniscript::Fragment::SHA256) { - chal.emplace(ChallengeType::SHA256, ChallengeNumber(ref->data)); - } else if (ref->fragment == miniscript::Fragment::RIPEMD160) { - chal.emplace(ChallengeType::RIPEMD160, ChallengeNumber(ref->data)); - } else if (ref->fragment == miniscript::Fragment::HASH256) { - chal.emplace(ChallengeType::HASH256, ChallengeNumber(ref->data)); - } else if (ref->fragment == miniscript::Fragment::HASH160) { - chal.emplace(ChallengeType::HASH160, ChallengeNumber(ref->data)); - } - for (const auto& sub : ref->subs) { - auto sub_chal = FindChallenges(sub); - chal.insert(sub_chal.begin(), sub_chal.end()); + + for (std::vector stack{root}; !stack.empty();) { + const auto* ref{stack.back()}; + stack.pop_back(); + + for (const auto& key : ref->keys) { + chal.emplace(ChallengeType::PK, ChallengeNumber(key)); + } + switch (ref->fragment) { + case Fragment::OLDER: chal.emplace(ChallengeType::OLDER, ref->k); break; + case Fragment::AFTER: chal.emplace(ChallengeType::AFTER, ref->k); break; + case Fragment::SHA256: chal.emplace(ChallengeType::SHA256, ChallengeNumber(ref->data)); break; + case Fragment::RIPEMD160: chal.emplace(ChallengeType::RIPEMD160, ChallengeNumber(ref->data)); break; + case Fragment::HASH256: chal.emplace(ChallengeType::HASH256, ChallengeNumber(ref->data)); break; + case Fragment::HASH160: chal.emplace(ChallengeType::HASH160, ChallengeNumber(ref->data)); break; + default: break; + } + for (const auto& sub : ref->subs) { + stack.push_back(sub.get()); + } } return chal; } @@ -347,7 +348,7 @@ struct MiniScriptTest : BasicTestingSetup { /** Run random satisfaction tests. */ void TestSatisfy(const KeyConverter& converter, const std::string& testcase, const NodeRef& node) { auto script = node->ToScript(converter); - auto challenges = FindChallenges(node); // Find all challenges in the generated miniscript. + const auto challenges{FindChallenges(node.get())}; // Find all challenges in the generated miniscript. std::vector challist(challenges.begin(), challenges.end()); for (int iter = 0; iter < 3; ++iter) { std::shuffle(challist.begin(), challist.end(), m_rng);