@@ -821,9 +821,10 @@ class WSHDescriptor final : public DescriptorImpl
821821// //////////////////////////////////////////////////////////////////////////
822822
823823enum 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