diff options
author | Pieter Wuille <pieter@wuille.net> | 2021-02-07 19:31:46 -0800 |
---|---|---|
committer | Pieter Wuille <pieter@wuille.net> | 2021-03-29 17:44:13 -0700 |
commit | 0b188b751f970027c52729e0c223cc9257669322 (patch) | |
tree | 27197bbcfa9663cbf008a074d7d621949fe904ba /src/script/descriptor.cpp | |
parent | 33275a96490445e293c322a29a3b146ccb91083c (diff) | |
download | bitcoin-0b188b751f970027c52729e0c223cc9257669322.tar.xz |
Clean up context dependent checks in descriptor parsing
This changes all context dependent checks in the parser to be
disjunctions of equality checks, rather than also including inequalities.
This makes sure that adding a new context enum in the future won't change
semantics for existing checks.
The error messages are also made a bit more consistent.
Diffstat (limited to 'src/script/descriptor.cpp')
-rw-r--r-- | src/script/descriptor.cpp | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index 59c3b2e0a6..5f085d233a 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -973,8 +973,8 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const if (!pubkey) return nullptr; ++key_exp_index; return std::make_unique<ComboDescriptor>(std::move(pubkey)); - } else if (ctx != ParseScriptContext::TOP && Func("combo", expr)) { - error = "Cannot have combo in non-top level"; + } else if (Func("combo", expr)) { + error = "Can only have combo() at top level"; return nullptr; } if ((sorted_multi = Func("sortedmulti", expr)) || Func("multi", expr)) { @@ -1022,29 +1022,29 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const } return std::make_unique<MultisigDescriptor>(thres, std::move(providers), sorted_multi); } - if (ctx != ParseScriptContext::P2WSH && Func("wpkh", expr)) { + if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wpkh", expr)) { auto pubkey = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH, out, error); if (!pubkey) return nullptr; key_exp_index++; return std::make_unique<WPKHDescriptor>(std::move(pubkey)); - } else if (ctx == ParseScriptContext::P2WSH && Func("wpkh", expr)) { - error = "Cannot have wpkh within wsh"; + } else if (Func("wpkh", expr)) { + error = "Can only have wpkh() at top level or inside sh()"; return nullptr; } if (ctx == ParseScriptContext::TOP && Func("sh", expr)) { auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out, error); if (!desc || expr.size()) return nullptr; return std::make_unique<SHDescriptor>(std::move(desc)); - } else if (ctx != ParseScriptContext::TOP && Func("sh", expr)) { - error = "Cannot have sh in non-top level"; + } else if (Func("sh", expr)) { + error = "Can only have sh() at top level"; return nullptr; } - if (ctx != ParseScriptContext::P2WSH && Func("wsh", expr)) { + if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wsh", expr)) { auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH, out, error); if (!desc || expr.size()) return nullptr; return std::make_unique<WSHDescriptor>(std::move(desc)); - } else if (ctx == ParseScriptContext::P2WSH && Func("wsh", expr)) { - error = "Cannot have wsh within wsh"; + } else if (Func("wsh", expr)) { + error = "Can only have wsh() at top level or inside sh()"; return nullptr; } if (ctx == ParseScriptContext::TOP && Func("addr", expr)) { @@ -1054,6 +1054,9 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const return nullptr; } return std::make_unique<AddressDescriptor>(std::move(dest)); + } else if (Func("addr", expr)) { + error = "Can only have addr() at top level"; + return nullptr; } if (ctx == ParseScriptContext::TOP && Func("raw", expr)) { std::string str(expr.begin(), expr.end()); @@ -1063,6 +1066,9 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const } auto bytes = ParseHex(str); return std::make_unique<RawDescriptor>(CScript(bytes.begin(), bytes.end())); + } else if (Func("raw", expr)) { + error = "Can only have raw() at top level"; + return nullptr; } if (ctx == ParseScriptContext::P2SH) { error = "A function is needed within P2SH"; |