diff options
author | Antoine Poinsot <darosior@protonmail.com> | 2022-04-15 14:03:37 +0200 |
---|---|---|
committer | Antoine Poinsot <darosior@protonmail.com> | 2022-04-18 16:03:29 +0200 |
commit | 74175941870347458ba8a0074f88b22cb94d0235 (patch) | |
tree | d1745d112fafeda3b4d68b3611331e5389bb1a86 /src/script | |
parent | e14f0fa6a346afecbb1d5470aef5226a8cc33e57 (diff) | |
download | bitcoin-74175941870347458ba8a0074f88b22cb94d0235.tar.xz |
miniscript: the 'd:' wrapper must not be 'u'
The value it leaves on the stack depends on the last element on the
stack. However, we can't make sure this element is OP_1 (which would
give us the 'u' property) without the MINIMALIF rule.
MINIMALIF is only policy for P2WSH, therefore giving 'd:' the 'u'
property breaks consensus soundness: it makes it possible (by consensus
but not policy) for instance to satisfy a thresh() without satisfying
at least k of its subs.
This bug was found and reported by Andrew Poelstra.
Diffstat (limited to 'src/script')
-rw-r--r-- | src/script/miniscript.cpp | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/src/script/miniscript.cpp b/src/script/miniscript.cpp index d0bb937885..019f02f159 100644 --- a/src/script/miniscript.cpp +++ b/src/script/miniscript.cpp @@ -116,7 +116,8 @@ Type ComputeType(Fragment nodetype, Type x, Type y, Type z, const std::vector<Ty "e"_mst.If(x << "f"_mst) | // e=f_x (x & "ghijk"_mst) | // g=g_x, h=h_x, i=i_x, j=j_x, k=k_x (x & "ms"_mst) | // m=m_x, s=s_x - "nudx"_mst; // n, u, d, x + // NOTE: 'd:' is not 'u' under P2WSH as MINIMALIF is only a policy rule there. + "ndx"_mst; // n, d, x case Fragment::WRAP_V: return "V"_mst.If(x << "B"_mst) | // V=B_x (x & "ghijk"_mst) | // g=g_x, h=h_x, i=i_x, j=j_x, k=k_x |