aboutsummaryrefslogtreecommitdiff
path: root/src/script
diff options
context:
space:
mode:
authorPieter Wuille <pieter@wuille.net>2021-02-06 17:47:52 -0800
committerPieter Wuille <pieter@wuille.net>2021-03-29 17:38:41 -0700
commit6ba5dda0c9de75196c6a427d9e59d39e5a41bff7 (patch)
treef88edd0640d613aecc250619d8bec1259eafd8db /src/script
parent4441c6f3c046c0b28ce3f0ca6d938af71d797586 (diff)
downloadbitcoin-6ba5dda0c9de75196c6a427d9e59d39e5a41bff7.tar.xz
Account for key cache indices in subexpressions
This has no effect for now, as the only fragments with sub-script expressions (sh, wsh) only allow one, and don't have key expressions in them. A future Taproot descriptor will however violate both, and we want the keys in different sub-scripts to be assigned non-overlapping cache indices.
Diffstat (limited to 'src/script')
-rw-r--r--src/script/descriptor.cpp9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index 5fbc740608..a1ef23ea1a 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -939,7 +939,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<c
}
/** Parse a script in a particular context. */
-std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
+std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
{
using namespace spanparsing;
@@ -948,16 +948,19 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
if (Func("pk", expr)) {
auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2WSH, out, error);
if (!pubkey) return nullptr;
+ ++key_exp_index;
return std::make_unique<PKDescriptor>(std::move(pubkey));
}
if (Func("pkh", expr)) {
auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2WSH, out, error);
if (!pubkey) return nullptr;
+ ++key_exp_index;
return std::make_unique<PKHDescriptor>(std::move(pubkey));
}
if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
auto pubkey = ParsePubkey(key_exp_index, expr, true, out, error);
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";
@@ -1011,6 +1014,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
if (ctx != ParseScriptContext::P2WSH && Func("wpkh", expr)) {
auto pubkey = ParsePubkey(key_exp_index, expr, false, 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";
@@ -1177,7 +1181,8 @@ std::unique_ptr<Descriptor> Parse(const std::string& descriptor, FlatSigningProv
{
Span<const char> sp{descriptor};
if (!CheckChecksum(sp, require_checksum, error)) return nullptr;
- auto ret = ParseScript(0, sp, ParseScriptContext::TOP, out, error);
+ uint32_t key_exp_index = 0;
+ auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
if (sp.size() == 0 && ret) return std::unique_ptr<Descriptor>(std::move(ret));
return nullptr;
}