Skip to content

Commit 33275a9

Browse files
committed
refactor: move uncompressed-permitted logic into ParsePubkey*
This is a preparation for parsing xonly pubkeys, which will complicate this logic. It's cleaner to put the decision logic close to the public key parsing itself.
1 parent 17e006f commit 33275a9

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

src/script/descriptor.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -821,9 +821,10 @@ class WSHDescriptor final : public DescriptorImpl
821821
////////////////////////////////////////////////////////////////////////////
822822

823823
enum class ParseScriptContext {
824-
TOP,
825-
P2SH,
826-
P2WSH,
824+
TOP, //!< Top-level context (script goes directly in scriptPubKey)
825+
P2SH, //!< Inside sh() (script becomes P2SH redeemScript)
826+
P2WPKH, //!< Inside wpkh() (no script, pubkey only)
827+
P2WSH, //!< Inside wsh() (script becomes v0 witness script)
827828
};
828829

829830
/** Parse a key path, being passed a split list of elements (the first element is ignored). */
@@ -850,10 +851,11 @@ enum class ParseScriptContext {
850851
}
851852

852853
/** Parse a public key that excludes origin information. */
853-
std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const Span<const char>& sp, bool permit_uncompressed, FlatSigningProvider& out, std::string& error)
854+
std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
854855
{
855856
using namespace spanparsing;
856857

858+
bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
857859
auto split = Split(sp, '/');
858860
std::string str(split[0].begin(), split[0].end());
859861
if (str.size() == 0) {
@@ -911,7 +913,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const S
911913
}
912914

913915
/** Parse a public key including origin information (if enabled). */
914-
std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<const char>& sp, bool permit_uncompressed, FlatSigningProvider& out, std::string& error)
916+
std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
915917
{
916918
using namespace spanparsing;
917919

@@ -920,7 +922,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<c
920922
error = "Multiple ']' characters found for a single pubkey";
921923
return nullptr;
922924
}
923-
if (origin_split.size() == 1) return ParsePubkeyInner(key_exp_index, origin_split[0], permit_uncompressed, out, error);
925+
if (origin_split.size() == 1) return ParsePubkeyInner(key_exp_index, origin_split[0], ctx, out, error);
924926
if (origin_split[0].empty() || origin_split[0][0] != '[') {
925927
error = strprintf("Key origin start '[ character expected but not found, got '%c' instead",
926928
origin_split[0].empty() ? /** empty, implies split char */ ']' : origin_split[0][0]);
@@ -942,7 +944,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<c
942944
assert(fpr_bytes.size() == 4);
943945
std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint);
944946
if (!ParseKeyPath(slash_split, info.path, error)) return nullptr;
945-
auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], permit_uncompressed, out, error);
947+
auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], ctx, out, error);
946948
if (!provider) return nullptr;
947949
return std::make_unique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider));
948950
}
@@ -955,19 +957,19 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
955957
auto expr = Expr(sp);
956958
bool sorted_multi = false;
957959
if (Func("pk", expr)) {
958-
auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2WSH, out, error);
960+
auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
959961
if (!pubkey) return nullptr;
960962
++key_exp_index;
961963
return std::make_unique<PKDescriptor>(std::move(pubkey));
962964
}
963965
if (Func("pkh", expr)) {
964-
auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2WSH, out, error);
966+
auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
965967
if (!pubkey) return nullptr;
966968
++key_exp_index;
967969
return std::make_unique<PKHDescriptor>(std::move(pubkey));
968970
}
969971
if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
970-
auto pubkey = ParsePubkey(key_exp_index, expr, true, out, error);
972+
auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
971973
if (!pubkey) return nullptr;
972974
++key_exp_index;
973975
return std::make_unique<ComboDescriptor>(std::move(pubkey));
@@ -990,7 +992,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
990992
return nullptr;
991993
}
992994
auto arg = Expr(expr);
993-
auto pk = ParsePubkey(key_exp_index, arg, ctx != ParseScriptContext::P2WSH, out, error);
995+
auto pk = ParsePubkey(key_exp_index, arg, ctx, out, error);
994996
if (!pk) return nullptr;
995997
script_size += pk->GetSize() + 1;
996998
providers.emplace_back(std::move(pk));
@@ -1021,7 +1023,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
10211023
return std::make_unique<MultisigDescriptor>(thres, std::move(providers), sorted_multi);
10221024
}
10231025
if (ctx != ParseScriptContext::P2WSH && Func("wpkh", expr)) {
1024-
auto pubkey = ParsePubkey(key_exp_index, expr, false, out, error);
1026+
auto pubkey = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH, out, error);
10251027
if (!pubkey) return nullptr;
10261028
key_exp_index++;
10271029
return std::make_unique<WPKHDescriptor>(std::move(pubkey));

0 commit comments

Comments
 (0)