@@ -821,9 +821,10 @@ class WSHDescriptor final : public DescriptorImpl
821
821
// //////////////////////////////////////////////////////////////////////////
822
822
823
823
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)
827
828
};
828
829
829
830
/* * Parse a key path, being passed a split list of elements (the first element is ignored). */
@@ -850,10 +851,11 @@ enum class ParseScriptContext {
850
851
}
851
852
852
853
/* * 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)
854
855
{
855
856
using namespace spanparsing ;
856
857
858
+ bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
857
859
auto split = Split (sp, ' /' );
858
860
std::string str (split[0 ].begin (), split[0 ].end ());
859
861
if (str.size () == 0 ) {
@@ -911,7 +913,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const S
911
913
}
912
914
913
915
/* * 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)
915
917
{
916
918
using namespace spanparsing ;
917
919
@@ -920,7 +922,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<c
920
922
error = " Multiple ']' characters found for a single pubkey" ;
921
923
return nullptr ;
922
924
}
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);
924
926
if (origin_split[0 ].empty () || origin_split[0 ][0 ] != ' [' ) {
925
927
error = strprintf (" Key origin start '[ character expected but not found, got '%c' instead" ,
926
928
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
942
944
assert (fpr_bytes.size () == 4 );
943
945
std::copy (fpr_bytes.begin (), fpr_bytes.end (), info.fingerprint );
944
946
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);
946
948
if (!provider) return nullptr ;
947
949
return std::make_unique<OriginPubkeyProvider>(key_exp_index, std::move (info), std::move (provider));
948
950
}
@@ -955,19 +957,19 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
955
957
auto expr = Expr (sp);
956
958
bool sorted_multi = false ;
957
959
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);
959
961
if (!pubkey) return nullptr ;
960
962
++key_exp_index;
961
963
return std::make_unique<PKDescriptor>(std::move (pubkey));
962
964
}
963
965
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);
965
967
if (!pubkey) return nullptr ;
966
968
++key_exp_index;
967
969
return std::make_unique<PKHDescriptor>(std::move (pubkey));
968
970
}
969
971
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);
971
973
if (!pubkey) return nullptr ;
972
974
++key_exp_index;
973
975
return std::make_unique<ComboDescriptor>(std::move (pubkey));
@@ -990,7 +992,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
990
992
return nullptr ;
991
993
}
992
994
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);
994
996
if (!pk) return nullptr ;
995
997
script_size += pk->GetSize () + 1 ;
996
998
providers.emplace_back (std::move (pk));
@@ -1021,7 +1023,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
1021
1023
return std::make_unique<MultisigDescriptor>(thres, std::move (providers), sorted_multi);
1022
1024
}
1023
1025
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);
1025
1027
if (!pubkey) return nullptr ;
1026
1028
key_exp_index++;
1027
1029
return std::make_unique<WPKHDescriptor>(std::move (pubkey));
0 commit comments