From 23b7327461873bd7c56608fca9f5c9763ab0a7fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Tue, 3 Mar 2026 19:34:44 -0500 Subject: [PATCH 1/6] miniscript: add HasBranchingOpcodes() to Node --- src/script/miniscript.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/script/miniscript.h b/src/script/miniscript.h index 8b9364dec95e..7d9a951cd7bd 100644 --- a/src/script/miniscript.h +++ b/src/script/miniscript.h @@ -1642,6 +1642,28 @@ struct Node { //! Check whether this node is safe as a script on its own. bool IsSane() const { return IsValidTopLevel() && IsSaneSubexpression() && NeedsSignature(); } + //! Check whether this node or any sub-node contains OP_IF/NOTIF-emitting fragments + //! (WRAP_D, WRAP_J, ANDOR, OR_C, OR_D, OR_I). In Tapscript, these should be replaced + //! by separate Taptree leaves for better privacy and efficiency. + bool HasBranchingOpcodes(size_t depth = 0) const { + if (depth > 100) return true; + switch (fragment) { + case Fragment::WRAP_D: + case Fragment::WRAP_J: + case Fragment::ANDOR: + case Fragment::OR_C: + case Fragment::OR_D: + case Fragment::OR_I: + return true; + default: + break; + } + for (const auto& sub : subs) { + if (sub->HasBranchingOpcodes(depth + 1)) return true; + } + return false; + } + //! Produce a witness for this script, if possible and given the information available in the context. //! The non-malleable satisfaction is guaranteed to be valid if it exists, and ValidSatisfaction() //! is true. If IsSane() holds, this satisfaction is guaranteed to succeed in case the node's From 43f190a6c4cff1a5ca13a0538326022a5dbf7440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Tue, 3 Mar 2026 19:39:13 -0500 Subject: [PATCH 2/6] Add policy type and parser for spending policies --- src/CMakeLists.txt | 1 + src/script/policy.cpp | 5 + src/script/policy.h | 295 ++++++++++++++++++++++++++++++++++++++ src/test/CMakeLists.txt | 1 + src/test/policy_tests.cpp | 127 ++++++++++++++++ 5 files changed, 429 insertions(+) create mode 100644 src/script/policy.cpp create mode 100644 src/script/policy.h create mode 100644 src/test/policy_tests.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a456cb1ad4c4..692800d2da95 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -181,6 +181,7 @@ add_library(bitcoin_common STATIC EXCLUDE_FROM_ALL script/descriptor.cpp script/miniscript.cpp script/parsing.cpp + script/policy.cpp script/sign.cpp script/signingprovider.cpp script/solver.cpp diff --git a/src/script/policy.cpp b/src/script/policy.cpp new file mode 100644 index 000000000000..a4ff30144d9e --- /dev/null +++ b/src/script/policy.cpp @@ -0,0 +1,5 @@ +// Copyright (c) 2026 The Bitcoin Knots developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include