@@ -161,12 +161,11 @@ typedef std::vector<uint32_t> KeyPath;
161161/* * Interface for public key objects in descriptors. */
162162struct PubkeyProvider
163163{
164- protected :
164+ public :
165165 // ! Index of this key expression in the descriptor
166166 // ! E.g. If this PubkeyProvider is key1 in multi(2, key1, key2, key3), then m_expr_index = 0
167- uint32_t m_expr_index;
167+ const uint32_t m_expr_index;
168168
169- public:
170169 explicit PubkeyProvider (uint32_t exp_index) : m_expr_index(exp_index) {}
171170
172171 virtual ~PubkeyProvider () = default ;
@@ -229,6 +228,9 @@ struct PubkeyProvider
229228
230229 /* * Whether this PubkeyProvider is a BIP 32 extended key that can be derived from */
231230 virtual bool IsBIP32 () const = 0;
231+
232+ /* * Get the count of keys known by this PubkeyProvider. Usually one, but may be more for key aggregation schemes */
233+ virtual size_t GetKeyCount () const { return 1 ; }
232234};
233235
234236class OriginPubkeyProvider final : public PubkeyProvider
@@ -788,6 +790,10 @@ class MuSigPubkeyProvider final : public PubkeyProvider
788790 // musig() can only be a BIP 32 key if all participants are bip32 too
789791 return std::all_of (m_participants.begin (), m_participants.end (), [](const auto & pubkey) { return pubkey->IsBIP32 (); });
790792 }
793+ size_t GetKeyCount () const override
794+ {
795+ return 1 + m_participants.size ();
796+ }
791797};
792798
793799/* * Base class for all Descriptor implementations. */
@@ -1041,6 +1047,40 @@ class DescriptorImpl : public Descriptor
10411047 }
10421048 return all;
10431049 }
1050+
1051+ uint32_t GetMaxKeyExpr () const final
1052+ {
1053+ uint32_t max_key_expr{0 };
1054+ std::vector<const DescriptorImpl*> todo = {this };
1055+ while (!todo.empty ()) {
1056+ const DescriptorImpl* desc = todo.back ();
1057+ todo.pop_back ();
1058+ for (const auto & p : desc->m_pubkey_args ) {
1059+ max_key_expr = std::max (max_key_expr, p->m_expr_index );
1060+ }
1061+ for (const auto & s : desc->m_subdescriptor_args ) {
1062+ todo.push_back (s.get ());
1063+ }
1064+ }
1065+ return max_key_expr;
1066+ }
1067+
1068+ size_t GetKeyCount () const final
1069+ {
1070+ size_t count{0 };
1071+ std::vector<const DescriptorImpl*> todo = {this };
1072+ while (!todo.empty ()) {
1073+ const DescriptorImpl* desc = todo.back ();
1074+ todo.pop_back ();
1075+ for (const auto & p : desc->m_pubkey_args ) {
1076+ count += p->GetKeyCount ();
1077+ }
1078+ for (const auto & s : desc->m_subdescriptor_args ) {
1079+ todo.push_back (s.get ());
1080+ }
1081+ }
1082+ return count;
1083+ }
10441084};
10451085
10461086/* * A parsed addr(A) descriptor. */
@@ -1833,7 +1873,7 @@ static DeriveType ParseDeriveType(std::vector<std::span<const char>>& split, boo
18331873}
18341874
18351875/* * Parse a public key that excludes origin information. */
1836- std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner (uint32_t key_exp_index, const std::span<const char >& sp, ParseScriptContext ctx, FlatSigningProvider& out, bool & apostrophe, std::string& error)
1876+ std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner (uint32_t & key_exp_index, const std::span<const char >& sp, ParseScriptContext ctx, FlatSigningProvider& out, bool & apostrophe, std::string& error)
18371877{
18381878 std::vector<std::unique_ptr<PubkeyProvider>> ret;
18391879 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
@@ -1858,6 +1898,7 @@ std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_i
18581898 if (pubkey.IsFullyValid ()) {
18591899 if (permit_uncompressed || pubkey.IsCompressed ()) {
18601900 ret.emplace_back (std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, false ));
1901+ ++key_exp_index;
18611902 return ret;
18621903 } else {
18631904 error = " Uncompressed keys are not allowed" ;
@@ -1869,6 +1910,7 @@ std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_i
18691910 pubkey.Set (std::begin (fullkey), std::end (fullkey));
18701911 if (pubkey.IsFullyValid ()) {
18711912 ret.emplace_back (std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, true ));
1913+ ++key_exp_index;
18721914 return ret;
18731915 }
18741916 }
@@ -1881,6 +1923,7 @@ std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_i
18811923 CPubKey pubkey = key.GetPubKey ();
18821924 out.keys .emplace (pubkey.GetID (), key);
18831925 ret.emplace_back (std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1926+ ++key_exp_index;
18841927 return ret;
18851928 } else {
18861929 error = " Uncompressed keys are not allowed" ;
@@ -1904,6 +1947,7 @@ std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_i
19041947 for (auto & path : paths) {
19051948 ret.emplace_back (std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move (path), type, apostrophe));
19061949 }
1950+ ++key_exp_index;
19071951 return ret;
19081952}
19091953
@@ -1961,7 +2005,6 @@ std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index
19612005 max_multipath_len = std::max (max_multipath_len, pk.size ());
19622006
19632007 providers.emplace_back (std::move (pk));
1964- key_exp_index++;
19652008 }
19662009 if (!any_key_parsed) {
19672010 error = " musig(): Must contain key expressions" ;
@@ -2053,6 +2096,7 @@ std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index
20532096 // No multipath derivation, MuSigPubkeyProvider uses the first (and only) participant pubkey providers, and the first (and only) path
20542097 emplace_final_provider (0 , 0 );
20552098 }
2099+ ++key_exp_index; // Increment key expression index for the MuSigPubkeyProvider too
20562100 return ret;
20572101 }
20582102
@@ -2093,7 +2137,7 @@ std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index
20932137 if (providers.empty ()) return {};
20942138 ret.reserve (providers.size ());
20952139 for (auto & prov : providers) {
2096- ret.emplace_back (std::make_unique<OriginPubkeyProvider>(key_exp_index , info, std::move (prov), apostrophe));
2140+ ret.emplace_back (std::make_unique<OriginPubkeyProvider>(prov-> m_expr_index , info, std::move (prov), apostrophe));
20972141 }
20982142 return ret;
20992143}
@@ -2143,12 +2187,12 @@ struct KeyParser {
21432187 mutable std::string m_key_parsing_error;
21442188 // ! The script context we're operating within (Tapscript or P2WSH).
21452189 const miniscript::MiniscriptContext m_script_ctx;
2146- // ! The number of keys that were parsed before starting to parse this Miniscript descriptor.
2147- uint32_t m_offset ;
2190+ // ! The current key expression index
2191+ uint32_t & m_expr_index ;
21482192
21492193 KeyParser (FlatSigningProvider* out LIFETIMEBOUND, const SigningProvider* in LIFETIMEBOUND,
2150- miniscript::MiniscriptContext ctx, uint32_t offset = 0 )
2151- : m_out(out), m_in(in), m_script_ctx(ctx), m_offset(offset ) {}
2194+ miniscript::MiniscriptContext ctx, uint32_t & key_exp_index LIFETIMEBOUND )
2195+ : m_out(out), m_in(in), m_script_ctx(ctx), m_expr_index(key_exp_index ) {}
21522196
21532197 bool KeyCompare (const Key& a, const Key& b) const {
21542198 return *m_keys.at (a).at (0 ) < *m_keys.at (b).at (0 );
@@ -2162,12 +2206,11 @@ struct KeyParser {
21622206 assert (false );
21632207 }
21642208
2165- template < typename I> std::optional<Key> FromString (I begin, I end ) const
2209+ std::optional<Key> FromString (std::span< const char >& in ) const
21662210 {
21672211 assert (m_out);
21682212 Key key = m_keys.size ();
2169- uint32_t exp_index = m_offset + key;
2170- auto pk = ParsePubkey (exp_index, {&*begin, &*end}, ParseContext (), *m_out, m_key_parsing_error);
2213+ auto pk = ParsePubkey (m_expr_index, in, ParseContext (), *m_out, m_key_parsing_error);
21712214 if (pk.empty ()) return {};
21722215 m_keys.emplace_back (std::move (pk));
21732216 return key;
@@ -2239,7 +2282,6 @@ std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index
22392282 error = strprintf (" pk(): %s" , error);
22402283 return {};
22412284 }
2242- ++key_exp_index;
22432285 for (auto & pubkey : pubkeys) {
22442286 ret.emplace_back (std::make_unique<PKDescriptor>(std::move (pubkey), ctx == ParseScriptContext::P2TR));
22452287 }
@@ -2251,7 +2293,6 @@ std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index
22512293 error = strprintf (" pkh(): %s" , error);
22522294 return {};
22532295 }
2254- ++key_exp_index;
22552296 for (auto & pubkey : pubkeys) {
22562297 ret.emplace_back (std::make_unique<PKHDescriptor>(std::move (pubkey)));
22572298 }
@@ -2263,7 +2304,6 @@ std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index
22632304 error = strprintf (" combo(): %s" , error);
22642305 return {};
22652306 }
2266- ++key_exp_index;
22672307 for (auto & pubkey : pubkeys) {
22682308 ret.emplace_back (std::make_unique<ComboDescriptor>(std::move (pubkey)));
22692309 }
@@ -2303,7 +2343,6 @@ std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index
23032343 script_size += pks.at (0 )->GetSize () + 1 ;
23042344 max_providers_len = std::max (max_providers_len, pks.size ());
23052345 providers.emplace_back (std::move (pks));
2306- key_exp_index++;
23072346 }
23082347 if ((multi || sortedmulti) && (providers.empty () || providers.size () > MAX_PUBKEYS_PER_MULTISIG)) {
23092348 error = strprintf (" Cannot have %u keys in multisig; must have between 1 and %d keys, inclusive" , providers.size (), MAX_PUBKEYS_PER_MULTISIG);
@@ -2373,7 +2412,6 @@ std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index
23732412 error = strprintf (" wpkh(): %s" , error);
23742413 return {};
23752414 }
2376- key_exp_index++;
23772415 for (auto & pubkey : pubkeys) {
23782416 ret.emplace_back (std::make_unique<WPKHDescriptor>(std::move (pubkey)));
23792417 }
@@ -2426,7 +2464,6 @@ std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index
24262464 return {};
24272465 }
24282466 size_t max_providers_len = internal_keys.size ();
2429- ++key_exp_index;
24302467 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts; // !< list of multipath expanded script subexpressions
24312468 std::vector<int > depths; // !< depth in the tree of each subexpression (same length subscripts)
24322469 if (expr.size ()) {
@@ -2530,7 +2567,6 @@ std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index
25302567 error = strprintf (" rawtr(): %s" , error);
25312568 return {};
25322569 }
2533- ++key_exp_index;
25342570 for (auto & pubkey : output_keys) {
25352571 ret.emplace_back (std::make_unique<RawTRDescriptor>(std::move (pubkey)));
25362572 }
@@ -2594,7 +2630,6 @@ std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index
25942630 // A signature check is required for a miniscript to be sane. Therefore no sane miniscript
25952631 // may have an empty list of public keys.
25962632 CHECK_NONFATAL (!parser.m_keys .empty ());
2597- key_exp_index += parser.m_keys .size ();
25982633 // Make sure all vecs are of the same length, or exactly length 1
25992634 // For length 1 vectors, clone subdescs until vector is the same length
26002635 size_t num_multipath = std::max_element (parser.m_keys .begin (), parser.m_keys .end (),
@@ -2769,7 +2804,8 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
27692804
27702805 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
27712806 const auto script_ctx{ctx == ParseScriptContext::P2WSH ? miniscript::MiniscriptContext::P2WSH : miniscript::MiniscriptContext::TAPSCRIPT};
2772- KeyParser parser (/* out = */ nullptr , /* in = */ &provider, /* ctx = */ script_ctx);
2807+ uint32_t key_exp_index = 0 ;
2808+ KeyParser parser (/* out = */ nullptr , /* in = */ &provider, /* ctx = */ script_ctx, key_exp_index);
27732809 auto node = miniscript::FromScript (script, parser);
27742810 if (node && node->IsSane ()) {
27752811 std::vector<std::unique_ptr<PubkeyProvider>> keys;
0 commit comments