Skip to content

Commit 6ba5dda

Browse files
committed
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.
1 parent 4441c6f commit 6ba5dda

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

src/script/descriptor.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<c
939939
}
940940

941941
/** Parse a script in a particular context. */
942-
std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
942+
std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
943943
{
944944
using namespace spanparsing;
945945

@@ -948,16 +948,19 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
948948
if (Func("pk", expr)) {
949949
auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2WSH, out, error);
950950
if (!pubkey) return nullptr;
951+
++key_exp_index;
951952
return std::make_unique<PKDescriptor>(std::move(pubkey));
952953
}
953954
if (Func("pkh", expr)) {
954955
auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2WSH, out, error);
955956
if (!pubkey) return nullptr;
957+
++key_exp_index;
956958
return std::make_unique<PKHDescriptor>(std::move(pubkey));
957959
}
958960
if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
959961
auto pubkey = ParsePubkey(key_exp_index, expr, true, out, error);
960962
if (!pubkey) return nullptr;
963+
++key_exp_index;
961964
return std::make_unique<ComboDescriptor>(std::move(pubkey));
962965
} else if (ctx != ParseScriptContext::TOP && Func("combo", expr)) {
963966
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
10111014
if (ctx != ParseScriptContext::P2WSH && Func("wpkh", expr)) {
10121015
auto pubkey = ParsePubkey(key_exp_index, expr, false, out, error);
10131016
if (!pubkey) return nullptr;
1017+
key_exp_index++;
10141018
return std::make_unique<WPKHDescriptor>(std::move(pubkey));
10151019
} else if (ctx == ParseScriptContext::P2WSH && Func("wpkh", expr)) {
10161020
error = "Cannot have wpkh within wsh";
@@ -1177,7 +1181,8 @@ std::unique_ptr<Descriptor> Parse(const std::string& descriptor, FlatSigningProv
11771181
{
11781182
Span<const char> sp{descriptor};
11791183
if (!CheckChecksum(sp, require_checksum, error)) return nullptr;
1180-
auto ret = ParseScript(0, sp, ParseScriptContext::TOP, out, error);
1184+
uint32_t key_exp_index = 0;
1185+
auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
11811186
if (sp.size() == 0 && ret) return std::unique_ptr<Descriptor>(std::move(ret));
11821187
return nullptr;
11831188
}

0 commit comments

Comments
 (0)