Bitcoin Core 31.99.0
P2P Digital Currency
descriptor.cpp
Go to the documentation of this file.
1// Copyright (c) 2018-present The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <script/descriptor.h>
6
7#include <addresstype.h>
8#include <attributes.h>
10#include <crypto/hex_base.h>
11#include <crypto/sha256.h>
12#include <hash.h>
13#include <key.h>
14#include <key_io.h>
15#include <musig.h>
17#include <pubkey.h>
18#include <script/interpreter.h>
19#include <script/keyorigin.h>
20#include <script/miniscript.h>
21#include <script/parsing.h>
22#include <script/script.h>
24#include <script/solver.h>
25#include <serialize.h>
26#include <tinyformat.h>
27#include <uint256.h>
28#include <util/bip32.h>
29#include <util/check.h>
30#include <util/strencodings.h>
31#include <util/string.h>
32#include <util/vector.h>
33
34#include <algorithm>
35#include <iterator>
36#include <map>
37#include <memory>
38#include <numeric>
39#include <optional>
40#include <span>
41#include <stdexcept>
42#include <string>
43#include <tuple>
44#include <unordered_set>
45#include <utility>
46#include <vector>
47
48using util::Split;
49
50namespace {
51
53// Checksum //
55
56// This section implements a checksum algorithm for descriptors with the
57// following properties:
58// * Mistakes in a descriptor string are measured in "symbol errors". The higher
59// the number of symbol errors, the harder it is to detect:
60// * An error substituting a character from 0123456789()[],'/*abcdefgh@:$%{} for
61// another in that set always counts as 1 symbol error.
62// * Note that hex encoded keys are covered by these characters. Xprvs and
63// xpubs use other characters too, but already have their own checksum
64// mechanism.
65// * Function names like "multi()" use other characters, but mistakes in
66// these would generally result in an unparsable descriptor.
67// * A case error always counts as 1 symbol error.
68// * Any other 1 character substitution error counts as 1 or 2 symbol errors.
69// * Any 1 symbol error is always detected.
70// * Any 2 or 3 symbol error in a descriptor of up to 49154 characters is always detected.
71// * Any 4 symbol error in a descriptor of up to 507 characters is always detected.
72// * Any 5 symbol error in a descriptor of up to 77 characters is always detected.
73// * Is optimized to minimize the chance a 5 symbol error in a descriptor up to 387 characters is undetected
74// * Random errors have a chance of 1 in 2**40 of being undetected.
75//
76// These properties are achieved by expanding every group of 3 (non checksum) characters into
77// 4 GF(32) symbols, over which a cyclic code is defined.
78
79/*
80 * Interprets c as 8 groups of 5 bits which are the coefficients of a degree 8 polynomial over GF(32),
81 * multiplies that polynomial by x, computes its remainder modulo a generator, and adds the constant term val.
82 *
83 * This generator is G(x) = x^8 + {30}x^7 + {23}x^6 + {15}x^5 + {14}x^4 + {10}x^3 + {6}x^2 + {12}x + {9}.
84 * It is chosen to define an cyclic error detecting code which is selected by:
85 * - Starting from all BCH codes over GF(32) of degree 8 and below, which by construction guarantee detecting
86 * 3 errors in windows up to 19000 symbols.
87 * - Taking all those generators, and for degree 7 ones, extend them to degree 8 by adding all degree-1 factors.
88 * - Selecting just the set of generators that guarantee detecting 4 errors in a window of length 512.
89 * - Selecting one of those with best worst-case behavior for 5 errors in windows of length up to 512.
90 *
91 * The generator and the constants to implement it can be verified using this Sage code:
92 * B = GF(2) # Binary field
93 * BP.<b> = B[] # Polynomials over the binary field
94 * F_mod = b**5 + b**3 + 1
95 * F.<f> = GF(32, modulus=F_mod, repr='int') # GF(32) definition
96 * FP.<x> = F[] # Polynomials over GF(32)
97 * E_mod = x**3 + x + F.fetch_int(8)
98 * E.<e> = F.extension(E_mod) # Extension field definition
99 * alpha = e**2743 # Choice of an element in extension field
100 * for p in divisors(E.order() - 1): # Verify alpha has order 32767.
101 * assert((alpha**p == 1) == (p % 32767 == 0))
102 * G = lcm([(alpha**i).minpoly() for i in [1056,1057,1058]] + [x + 1])
103 * print(G) # Print out the generator
104 * for i in [1,2,4,8,16]: # Print out {1,2,4,8,16}*(G mod x^8), packed in hex integers.
105 * v = 0
106 * for coef in reversed((F.fetch_int(i)*(G % x**8)).coefficients(sparse=True)):
107 * v = v*32 + coef.integer_representation()
108 * print("0x%x" % v)
109 */
110uint64_t PolyMod(uint64_t c, int val)
111{
112 uint8_t c0 = c >> 35;
113 c = ((c & 0x7ffffffff) << 5) ^ val;
114 if (c0 & 1) c ^= 0xf5dee51989;
115 if (c0 & 2) c ^= 0xa9fdca3312;
116 if (c0 & 4) c ^= 0x1bab10e32d;
117 if (c0 & 8) c ^= 0x3706b1677a;
118 if (c0 & 16) c ^= 0x644d626ffd;
119 return c;
120}
121
122std::string DescriptorChecksum(const std::span<const char>& span)
123{
137 static const std::string INPUT_CHARSET =
138 "0123456789()[],'/*abcdefgh@:$%{}"
139 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
140 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
141
143 static const std::string CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
144
145 uint64_t c = 1;
146 int cls = 0;
147 int clscount = 0;
148 for (auto ch : span) {
149 auto pos = INPUT_CHARSET.find(ch);
150 if (pos == std::string::npos) return "";
151 c = PolyMod(c, pos & 31); // Emit a symbol for the position inside the group, for every character.
152 cls = cls * 3 + (pos >> 5); // Accumulate the group numbers
153 if (++clscount == 3) {
154 // Emit an extra symbol representing the group numbers, for every 3 characters.
155 c = PolyMod(c, cls);
156 cls = 0;
157 clscount = 0;
158 }
159 }
160 if (clscount > 0) c = PolyMod(c, cls);
161 for (int j = 0; j < 8; ++j) c = PolyMod(c, 0); // Shift further to determine the checksum.
162 c ^= 1; // Prevent appending zeroes from not affecting the checksum.
163
164 std::string ret(8, ' ');
165 for (int j = 0; j < 8; ++j) ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
166 return ret;
167}
168
169std::string AddChecksum(const std::string& str) { return str + "#" + DescriptorChecksum(str); }
170
172// Internal representation //
174
175typedef std::vector<uint32_t> KeyPath;
176
178struct PubkeyProvider
179{
180public:
183 const uint32_t m_expr_index;
184
185 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
186
187 virtual ~PubkeyProvider() = default;
188
192 bool operator<(PubkeyProvider& other) const {
194
195 std::optional<CPubKey> a = GetPubKey(0, dummy, dummy);
196 std::optional<CPubKey> b = other.GetPubKey(0, dummy, dummy);
197
198 return a < b;
199 }
200
206 virtual std::optional<CPubKey> GetPubKey(int pos, const SigningProvider& arg, FlatSigningProvider& out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const = 0;
207
209 virtual bool IsRange() const = 0;
210
212 virtual size_t GetSize() const = 0;
213
214 enum class StringType {
215 PUBLIC,
216 COMPAT // string calculation that mustn't change over time to stay compatible with previous software versions
217 };
218
220 virtual std::string ToString(StringType type=StringType::PUBLIC) const = 0;
221
227 virtual bool ToPrivateString(const SigningProvider& arg, std::string& out) const = 0;
228
232 virtual bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache = nullptr) const = 0;
233
235 virtual void GetPrivKey(int pos, const SigningProvider& arg, FlatSigningProvider& out) const = 0;
236
238 virtual bool HavePrivateKeys(const SigningProvider& arg) const
239 {
240 FlatSigningProvider tmp_provider;
241 GetPrivKey(/*pos=*/0, arg, tmp_provider);
242 return !tmp_provider.keys.empty();
243 }
244
246 virtual std::optional<CPubKey> GetRootPubKey() const = 0;
248 virtual std::optional<CExtPubKey> GetRootExtPubKey() const = 0;
249
251 virtual std::unique_ptr<PubkeyProvider> Clone() const = 0;
252
254 virtual bool IsBIP32() const = 0;
255
257 virtual size_t GetKeyCount() const { return 1; }
258
260 virtual bool CanSelfExpand() const = 0;
261};
262
263class OriginPubkeyProvider final : public PubkeyProvider
264{
265 KeyOriginInfo m_origin;
266 std::unique_ptr<PubkeyProvider> m_provider;
267 bool m_apostrophe;
268
269 std::string OriginString(StringType type, bool normalized=false) const
270 {
271 // If StringType==COMPAT, always use the apostrophe to stay compatible with previous versions
272 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
273 return HexStr(m_origin.fingerprint) + FormatHDKeypath(m_origin.path, use_apostrophe);
274 }
275
276public:
277 OriginPubkeyProvider(uint32_t exp_index, KeyOriginInfo info, std::unique_ptr<PubkeyProvider> provider, bool apostrophe) : PubkeyProvider(exp_index), m_origin(std::move(info)), m_provider(std::move(provider)), m_apostrophe(apostrophe) {}
278 std::optional<CPubKey> GetPubKey(int pos, const SigningProvider& arg, FlatSigningProvider& out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
279 {
280 std::optional<CPubKey> pub = m_provider->GetPubKey(pos, arg, out, read_cache, write_cache);
281 if (!pub) return std::nullopt;
282 Assert(out.pubkeys.contains(pub->GetID()));
283 auto& [pubkey, suborigin] = out.origins[pub->GetID()];
284 Assert(pubkey == *pub); // m_provider must have a valid origin by this point.
285 suborigin.fingerprint = m_origin.fingerprint;
286 suborigin.path.insert(suborigin.path.begin(), m_origin.path.begin(), m_origin.path.end());
287 return pub;
288 }
289 bool IsRange() const override { return m_provider->IsRange(); }
290 size_t GetSize() const override { return m_provider->GetSize(); }
291 bool IsBIP32() const override { return m_provider->IsBIP32(); }
292 std::string ToString(StringType type) const override { return "[" + OriginString(type) + "]" + m_provider->ToString(type); }
293 bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
294 {
295 std::string sub;
296 bool has_priv_key{m_provider->ToPrivateString(arg, sub)};
297 ret = "[" + OriginString(StringType::PUBLIC) + "]" + std::move(sub);
298 return has_priv_key;
299 }
300 bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
301 {
302 std::string sub;
303 if (!m_provider->ToNormalizedString(arg, sub, cache)) return false;
304 // If m_provider is a BIP32PubkeyProvider, we may get a string formatted like a OriginPubkeyProvider
305 // In that case, we need to strip out the leading square bracket and fingerprint from the substring,
306 // and append that to our own origin string.
307 if (sub[0] == '[') {
308 sub = sub.substr(9);
309 ret = "[" + OriginString(StringType::PUBLIC, /*normalized=*/true) + std::move(sub);
310 } else {
311 ret = "[" + OriginString(StringType::PUBLIC, /*normalized=*/true) + "]" + std::move(sub);
312 }
313 return true;
314 }
315 void GetPrivKey(int pos, const SigningProvider& arg, FlatSigningProvider& out) const override
316 {
317 m_provider->GetPrivKey(pos, arg, out);
318 }
319 std::optional<CPubKey> GetRootPubKey() const override
320 {
321 return m_provider->GetRootPubKey();
322 }
323 std::optional<CExtPubKey> GetRootExtPubKey() const override
324 {
325 return m_provider->GetRootExtPubKey();
326 }
327 std::unique_ptr<PubkeyProvider> Clone() const override
328 {
329 return std::make_unique<OriginPubkeyProvider>(m_expr_index, m_origin, m_provider->Clone(), m_apostrophe);
330 }
331 bool CanSelfExpand() const override { return m_provider->CanSelfExpand(); }
332};
333
335class ConstPubkeyProvider final : public PubkeyProvider
336{
337 CPubKey m_pubkey;
338 bool m_xonly;
339
340 std::optional<CKey> GetPrivKey(const SigningProvider& arg) const
341 {
342 CKey key;
343 if (!(m_xonly ? arg.GetKeyByXOnly(XOnlyPubKey(m_pubkey), key) :
344 arg.GetKey(m_pubkey.GetID(), key))) return std::nullopt;
345 return key;
346 }
347
348public:
349 ConstPubkeyProvider(uint32_t exp_index, const CPubKey& pubkey, bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
350 std::optional<CPubKey> GetPubKey(int pos, const SigningProvider&, FlatSigningProvider& out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
351 {
352 KeyOriginInfo info;
353 CKeyID keyid = m_pubkey.GetID();
354 info.fingerprint = keyid.fingerprint();
355 out.origins.emplace(keyid, std::make_pair(m_pubkey, info));
356 out.pubkeys.emplace(keyid, m_pubkey);
357 return m_pubkey;
358 }
359 bool IsRange() const override { return false; }
360 size_t GetSize() const override { return m_pubkey.size(); }
361 bool IsBIP32() const override { return false; }
362 std::string ToString(StringType type) const override { return m_xonly ? HexStr(m_pubkey).substr(2) : HexStr(m_pubkey); }
363 bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
364 {
365 std::optional<CKey> key = GetPrivKey(arg);
366 if (!key) {
367 ret = ToString(StringType::PUBLIC);
368 return false;
369 }
370 ret = EncodeSecret(*key);
371 return true;
372 }
373 bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
374 {
375 ret = ToString(StringType::PUBLIC);
376 return true;
377 }
378 void GetPrivKey(int pos, const SigningProvider& arg, FlatSigningProvider& out) const override
379 {
380 std::optional<CKey> key = GetPrivKey(arg);
381 if (!key) return;
382 out.keys.emplace(key->GetPubKey().GetID(), *key);
383 }
384 std::optional<CPubKey> GetRootPubKey() const override
385 {
386 return m_pubkey;
387 }
388 std::optional<CExtPubKey> GetRootExtPubKey() const override
389 {
390 return std::nullopt;
391 }
392 std::unique_ptr<PubkeyProvider> Clone() const override
393 {
394 return std::make_unique<ConstPubkeyProvider>(m_expr_index, m_pubkey, m_xonly);
395 }
396 bool CanSelfExpand() const final { return true; }
397};
398
399enum class DeriveType {
400 NON_RANGED,
401 UNHARDENED_RANGED,
402 HARDENED_RANGED,
403};
404
406class BIP32PubkeyProvider final : public PubkeyProvider
407{
408 // Root xpub, path, and final derivation step type being used, if any
409 CExtPubKey m_root_extkey;
410 KeyPath m_path;
411 DeriveType m_derive;
412 // Whether ' or h is used in harded derivation
413 bool m_apostrophe;
414
415 bool GetExtKey(const SigningProvider& arg, CExtKey& ret) const
416 {
417 CKey key;
418 if (!arg.GetKey(m_root_extkey.pubkey.GetID(), key)) return false;
419 ret.nDepth = m_root_extkey.nDepth;
420 ret.fingerprint = m_root_extkey.fingerprint;
421 ret.nChild = m_root_extkey.nChild;
422 ret.chaincode = m_root_extkey.chaincode;
423 ret.key = key;
424 return true;
425 }
426
427 // Derives the last xprv
428 bool GetDerivedExtKey(const SigningProvider& arg, CExtKey& xprv, CExtKey& last_hardened) const
429 {
430 if (!GetExtKey(arg, xprv)) return false;
431 for (auto entry : m_path) {
432 if (!xprv.Derive(xprv, entry)) return false;
433 if (entry >> 31) {
434 last_hardened = xprv;
435 }
436 }
437 return true;
438 }
439
440 bool IsHardened() const
441 {
442 if (m_derive == DeriveType::HARDENED_RANGED) return true;
443 for (auto entry : m_path) {
444 if (entry >> 31) return true;
445 }
446 return false;
447 }
448
449public:
450 BIP32PubkeyProvider(uint32_t exp_index, const CExtPubKey& extkey, KeyPath path, DeriveType derive, bool apostrophe) : PubkeyProvider(exp_index), m_root_extkey(extkey), m_path(std::move(path)), m_derive(derive), m_apostrophe(apostrophe) {}
451 bool IsRange() const override { return m_derive != DeriveType::NON_RANGED; }
452 size_t GetSize() const override { return 33; }
453 bool IsBIP32() const override { return true; }
454 std::optional<CPubKey> GetPubKey(int pos, const SigningProvider& arg, FlatSigningProvider& out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
455 {
456 KeyOriginInfo info;
457 info.fingerprint = m_root_extkey.id_key_fingerprint();
458 info.path = m_path;
459 if (m_derive == DeriveType::UNHARDENED_RANGED) info.path.push_back((uint32_t)pos);
460 if (m_derive == DeriveType::HARDENED_RANGED) info.path.push_back(((uint32_t)pos) | 0x80000000L);
461
462 // Derive keys or fetch them from cache
463 CExtPubKey final_extkey = m_root_extkey;
464 CExtPubKey parent_extkey = m_root_extkey;
465 CExtPubKey last_hardened_extkey;
466 bool der = true;
467 if (read_cache) {
468 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
469 if (m_derive == DeriveType::HARDENED_RANGED) return std::nullopt;
470 // Try to get the derivation parent
471 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey)) return std::nullopt;
472 final_extkey = parent_extkey;
473 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.Derive(final_extkey, pos);
474 }
475 } else if (IsHardened()) {
476 CExtKey xprv;
477 CExtKey lh_xprv;
478 if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return std::nullopt;
479 parent_extkey = xprv.Neuter();
480 if (m_derive == DeriveType::UNHARDENED_RANGED) der = xprv.Derive(xprv, pos);
481 if (m_derive == DeriveType::HARDENED_RANGED) der = xprv.Derive(xprv, pos | 0x80000000UL);
482 final_extkey = xprv.Neuter();
483 if (lh_xprv.key.IsValid()) {
484 last_hardened_extkey = lh_xprv.Neuter();
485 }
486 } else {
487 for (auto entry : m_path) {
488 if (!parent_extkey.Derive(parent_extkey, entry)) return std::nullopt;
489 }
490 final_extkey = parent_extkey;
491 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.Derive(final_extkey, pos);
492 assert(m_derive != DeriveType::HARDENED_RANGED);
493 }
494 if (!der) return std::nullopt;
495
496 out.origins.emplace(final_extkey.pubkey.GetID(), std::make_pair(final_extkey.pubkey, info));
497 out.pubkeys.emplace(final_extkey.pubkey.GetID(), final_extkey.pubkey);
498
499 if (write_cache) {
500 // Only cache parent if there is any unhardened derivation
501 if (m_derive != DeriveType::HARDENED_RANGED) {
502 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
503 // Cache last hardened xpub if we have it
504 if (last_hardened_extkey.pubkey.IsValid()) {
505 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
506 }
507 } else if (info.path.size() > 0) {
508 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
509 }
510 }
511
512 return final_extkey.pubkey;
513 }
514 std::string ToString(StringType type, bool normalized) const
515 {
516 // If StringType==COMPAT, always use the apostrophe to stay compatible with previous versions
517 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
518 std::string ret = EncodeExtPubKey(m_root_extkey) + FormatHDKeypath(m_path, /*apostrophe=*/use_apostrophe);
519 if (IsRange()) {
520 ret += "/*";
521 if (m_derive == DeriveType::HARDENED_RANGED) ret += use_apostrophe ? '\'' : 'h';
522 }
523 return ret;
524 }
525 std::string ToString(StringType type=StringType::PUBLIC) const override
526 {
527 return ToString(type, /*normalized=*/false);
528 }
529 bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
530 {
531 CExtKey key;
532 if (!GetExtKey(arg, key)) {
533 out = ToString(StringType::PUBLIC);
534 return false;
535 }
536 out = EncodeExtKey(key) + FormatHDKeypath(m_path, /*apostrophe=*/m_apostrophe);
537 if (IsRange()) {
538 out += "/*";
539 if (m_derive == DeriveType::HARDENED_RANGED) out += m_apostrophe ? '\'' : 'h';
540 }
541 return true;
542 }
543 bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override
544 {
545 if (m_derive == DeriveType::HARDENED_RANGED) {
546 out = ToString(StringType::PUBLIC, /*normalized=*/true);
547
548 return true;
549 }
550 // Step backwards to find the last hardened step in the path
551 int i = (int)m_path.size() - 1;
552 for (; i >= 0; --i) {
553 if (m_path.at(i) >> 31) {
554 break;
555 }
556 }
557 // Either no derivation or all unhardened derivation
558 if (i == -1) {
559 out = ToString();
560 return true;
561 }
562 // Get the path to the last hardened stup
563 KeyOriginInfo origin;
564 int k = 0;
565 for (; k <= i; ++k) {
566 // Add to the path
567 origin.path.push_back(m_path.at(k));
568 }
569 // Build the remaining path
570 KeyPath end_path;
571 for (; k < (int)m_path.size(); ++k) {
572 end_path.push_back(m_path.at(k));
573 }
574 origin.fingerprint = m_root_extkey.id_key_fingerprint();
575
576 CExtPubKey xpub;
577 CExtKey lh_xprv;
578 // If we have the cache, just get the parent xpub
579 if (cache != nullptr) {
580 cache->GetCachedLastHardenedExtPubKey(m_expr_index, xpub);
581 }
582 if (!xpub.pubkey.IsValid()) {
583 // Cache miss, or nor cache, or need privkey
584 CExtKey xprv;
585 if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return false;
586 xpub = lh_xprv.Neuter();
587 }
588 assert(xpub.pubkey.IsValid());
589
590 // Build the string
591 std::string origin_str = HexStr(origin.fingerprint) + FormatHDKeypath(origin.path);
592 out = "[" + origin_str + "]" + EncodeExtPubKey(xpub) + FormatHDKeypath(end_path);
593 if (IsRange()) {
594 out += "/*";
595 assert(m_derive == DeriveType::UNHARDENED_RANGED);
596 }
597 return true;
598 }
599 void GetPrivKey(int pos, const SigningProvider& arg, FlatSigningProvider& out) const override
600 {
601 CExtKey extkey;
602 CExtKey dummy;
603 if (!GetDerivedExtKey(arg, extkey, dummy)) return;
604 if (m_derive == DeriveType::UNHARDENED_RANGED && !extkey.Derive(extkey, pos)) return;
605 if (m_derive == DeriveType::HARDENED_RANGED && !extkey.Derive(extkey, pos | 0x80000000UL)) return;
606 out.keys.emplace(extkey.key.GetPubKey().GetID(), extkey.key);
607 }
608 std::optional<CPubKey> GetRootPubKey() const override
609 {
610 return std::nullopt;
611 }
612 std::optional<CExtPubKey> GetRootExtPubKey() const override
613 {
614 return m_root_extkey;
615 }
616 std::unique_ptr<PubkeyProvider> Clone() const override
617 {
618 return std::make_unique<BIP32PubkeyProvider>(m_expr_index, m_root_extkey, m_path, m_derive, m_apostrophe);
619 }
620 bool CanSelfExpand() const override { return !IsHardened(); }
621};
622
624class MuSigPubkeyProvider final : public PubkeyProvider
625{
626private:
628 const std::vector<std::unique_ptr<PubkeyProvider>> m_participants;
630 const KeyPath m_path;
632 mutable std::unique_ptr<PubkeyProvider> m_aggregate_provider;
633 mutable std::optional<CPubKey> m_aggregate_pubkey;
634 const DeriveType m_derive;
635 const bool m_ranged_participants;
636
637 bool IsRangedDerivation() const { return m_derive != DeriveType::NON_RANGED; }
638
639public:
640 MuSigPubkeyProvider(
641 uint32_t exp_index,
642 std::vector<std::unique_ptr<PubkeyProvider>> providers,
643 KeyPath path,
644 DeriveType derive
645 )
646 : PubkeyProvider(exp_index),
647 m_participants(std::move(providers)),
648 m_path(std::move(path)),
649 m_derive(derive),
650 m_ranged_participants(std::any_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) { return pubkey->IsRange(); }))
651 {
652 if (!Assume(!(m_ranged_participants && IsRangedDerivation()))) {
653 throw std::runtime_error("musig(): Cannot have both ranged participants and ranged derivation");
654 }
655 if (!Assume(m_derive != DeriveType::HARDENED_RANGED)) {
656 throw std::runtime_error("musig(): Cannot have hardened derivation");
657 }
658 }
659
660 std::optional<CPubKey> GetPubKey(int pos, const SigningProvider& arg, FlatSigningProvider& out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
661 {
663 // If the participants are not ranged, we can compute and cache the aggregate pubkey by creating a PubkeyProvider for it
664 if (!m_aggregate_provider && !m_ranged_participants) {
665 // Retrieve the pubkeys from the providers
666 std::vector<CPubKey> pubkeys;
667 for (const auto& prov : m_participants) {
668 std::optional<CPubKey> pubkey = prov->GetPubKey(0, arg, dummy, read_cache, write_cache);
669 if (!pubkey.has_value()) {
670 return std::nullopt;
671 }
672 pubkeys.push_back(pubkey.value());
673 }
674 std::sort(pubkeys.begin(), pubkeys.end());
675
676 // Aggregate the pubkey
677 m_aggregate_pubkey = MuSig2AggregatePubkeys(pubkeys);
678 if (!Assume(m_aggregate_pubkey.has_value())) return std::nullopt;
679
680 // Make our pubkey provider
681 if (IsRangedDerivation() || !m_path.empty()) {
682 // Make the synthetic xpub and construct the BIP32PubkeyProvider
683 CExtPubKey extpub = CreateMuSig2SyntheticXpub(m_aggregate_pubkey.value());
684 m_aggregate_provider = std::make_unique<BIP32PubkeyProvider>(m_expr_index, extpub, m_path, m_derive, /*apostrophe=*/false);
685 } else {
686 m_aggregate_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, m_aggregate_pubkey.value(), /*xonly=*/false);
687 }
688 }
689
690 // Retrieve all participant pubkeys
691 std::vector<CPubKey> pubkeys;
692 for (const auto& prov : m_participants) {
693 std::optional<CPubKey> pub = prov->GetPubKey(pos, arg, out, read_cache, write_cache);
694 if (!pub) return std::nullopt;
695 pubkeys.emplace_back(*pub);
696 }
697 std::sort(pubkeys.begin(), pubkeys.end());
698
699 CPubKey pubout;
700 if (m_aggregate_provider) {
701 // When we have a cached aggregate key, we are either returning it or deriving from it
702 // Either way, we can passthrough to its GetPubKey
703 // Use a dummy signing provider as private keys do not exist for the aggregate pubkey
704 std::optional<CPubKey> pub = m_aggregate_provider->GetPubKey(pos, dummy, out, read_cache, write_cache);
705 if (!pub) return std::nullopt;
706 pubout = *pub;
707 out.aggregate_pubkeys.emplace(m_aggregate_pubkey.value(), pubkeys);
708 } else {
709 if (!Assume(m_ranged_participants) || !Assume(m_path.empty())) return std::nullopt;
710 // Compute aggregate key from derived participants
711 std::optional<CPubKey> aggregate_pubkey = MuSig2AggregatePubkeys(pubkeys);
712 if (!aggregate_pubkey) return std::nullopt;
713 pubout = *aggregate_pubkey;
714
715 std::unique_ptr<ConstPubkeyProvider> this_agg_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, aggregate_pubkey.value(), /*xonly=*/false);
716 this_agg_provider->GetPubKey(0, dummy, out, read_cache, write_cache);
717 out.aggregate_pubkeys.emplace(pubout, pubkeys);
718 }
719
720 if (!Assume(pubout.IsValid())) return std::nullopt;
721 return pubout;
722 }
723 bool IsRange() const override { return IsRangedDerivation() || m_ranged_participants; }
724 // musig() expressions can only be used in tr() contexts which have 32 byte xonly pubkeys
725 size_t GetSize() const override { return 32; }
726
727 std::string ToString(StringType type=StringType::PUBLIC) const override
728 {
729 std::string out = "musig(";
730 for (size_t i = 0; i < m_participants.size(); ++i) {
731 const auto& pubkey = m_participants.at(i);
732 if (i) out += ",";
733 out += pubkey->ToString(type);
734 }
735 out += ")";
737 if (IsRangedDerivation()) {
738 out += "/*";
739 }
740 return out;
741 }
742 bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
743 {
744 bool any_privkeys = false;
745 out = "musig(";
746 for (size_t i = 0; i < m_participants.size(); ++i) {
747 const auto& pubkey = m_participants.at(i);
748 if (i) out += ",";
749 std::string tmp;
750 if (pubkey->ToPrivateString(arg, tmp)) {
751 any_privkeys = true;
752 }
753 out += tmp;
754 }
755 out += ")";
757 if (IsRangedDerivation()) {
758 out += "/*";
759 }
760 return any_privkeys;
761 }
762 bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache = nullptr) const override
763 {
764 out = "musig(";
765 for (size_t i = 0; i < m_participants.size(); ++i) {
766 const auto& pubkey = m_participants.at(i);
767 if (i) out += ",";
768 std::string tmp;
769 if (!pubkey->ToNormalizedString(arg, tmp, cache)) {
770 return false;
771 }
772 out += tmp;
773 }
774 out += ")";
776 if (IsRangedDerivation()) {
777 out += "/*";
778 }
779 return true;
780 }
781
782 void GetPrivKey(int pos, const SigningProvider& arg, FlatSigningProvider& out) const override
783 {
784 // Get the private keys for any participants that we have
785 // If there is participant derivation, it will be done.
786 // If there is not, then the participant privkeys will be included directly
787 for (const auto& prov : m_participants) {
788 prov->GetPrivKey(pos, arg, out);
789 }
790 }
791
792 bool HavePrivateKeys(const SigningProvider& arg) const override
793 {
794 return std::ranges::all_of(m_participants, [&](const auto& prov) { return prov->HavePrivateKeys(arg); });
795 }
796
797 // Get RootPubKey and GetRootExtPubKey are used to return the single pubkey underlying the pubkey provider
798 // to be presented to the user in gethdkeys. As this is a multisig construction, there is no single underlying
799 // pubkey hence nothing should be returned.
800 // While the aggregate pubkey could be returned as the root (ext)pubkey, it is not a pubkey that anyone should
801 // be using by itself in a descriptor as it is unspendable without knowing its participants.
802 std::optional<CPubKey> GetRootPubKey() const override
803 {
804 return std::nullopt;
805 }
806 std::optional<CExtPubKey> GetRootExtPubKey() const override
807 {
808 return std::nullopt;
809 }
810
811 std::unique_ptr<PubkeyProvider> Clone() const override
812 {
813 std::vector<std::unique_ptr<PubkeyProvider>> providers;
814 providers.reserve(m_participants.size());
815 for (const std::unique_ptr<PubkeyProvider>& p : m_participants) {
816 providers.emplace_back(p->Clone());
817 }
818 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(providers), m_path, m_derive);
819 }
820 bool IsBIP32() const override
821 {
822 // musig() can only be a BIP 32 key if all participants are bip32 too
823 return std::all_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) { return pubkey->IsBIP32(); });
824 }
825 size_t GetKeyCount() const override
826 {
827 return 1 + m_participants.size();
828 }
829 bool CanSelfExpand() const override
830 {
831 // Participants must be self expandable for all MuSig expressions to be self expandable; the aggregate pubkey cannot be stored
832 // in the descriptor cache, so even aggregate-then-derive still requires the self expansion of participants prior to aggregation.
833 for (const auto& key : m_participants) {
834 if (!key->CanSelfExpand()) return false;
835 }
836 return true;
837 }
838};
839
841class DescriptorImpl : public Descriptor
842{
843protected:
845 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
847 const std::string m_name;
849 std::vector<std::string> m_warnings;
850
855 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
856
858 virtual std::string ToStringExtra() const { return ""; }
859
870 virtual std::vector<CScript> MakeScripts(const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts, FlatSigningProvider& out) const = 0;
871
872public:
873 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args() {}
874 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::unique_ptr<DescriptorImpl> script, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args(Vector(std::move(script))) {}
875 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::vector<std::unique_ptr<DescriptorImpl>> scripts, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args(std::move(scripts)) {}
876
877 enum class StringType
878 {
879 PUBLIC,
880 PRIVATE,
881 NORMALIZED,
882 COMPAT, // string calculation that mustn't change over time to stay compatible with previous software versions
883 };
884
885 // NOLINTNEXTLINE(misc-no-recursion)
886 bool IsSolvable() const override
887 {
888 for (const auto& arg : m_subdescriptor_args) {
889 if (!arg->IsSolvable()) return false;
890 }
891 return true;
892 }
893
894 // NOLINTNEXTLINE(misc-no-recursion)
895 bool HavePrivateKeys(const SigningProvider& arg) const override
896 {
897 if (m_pubkey_args.empty() && m_subdescriptor_args.empty()) return false;
898
899 for (const auto& sub: m_subdescriptor_args) {
900 if (!sub->HavePrivateKeys(arg)) return false;
901 }
902
903 for (const auto& pubkey : m_pubkey_args) {
904 if (!pubkey->HavePrivateKeys(arg)) return false;
905 }
906
907 return true;
908 }
909
910 // NOLINTNEXTLINE(misc-no-recursion)
911 bool IsRange() const final
912 {
913 for (const auto& pubkey : m_pubkey_args) {
914 if (pubkey->IsRange()) return true;
915 }
916 for (const auto& arg : m_subdescriptor_args) {
917 if (arg->IsRange()) return true;
918 }
919 return false;
920 }
921
922 // NOLINTNEXTLINE(misc-no-recursion)
923 virtual bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const
924 {
925 size_t pos = 0;
926 bool is_private{type == StringType::PRIVATE};
927 // For private string output, track if at least one key has a private key available.
928 // Initialize to true for non-private types.
929 bool any_success{!is_private};
930 for (const auto& scriptarg : m_subdescriptor_args) {
931 if (pos++) ret += ",";
932 std::string tmp;
933 bool subscript_res{scriptarg->ToStringHelper(arg, tmp, type, cache)};
934 if (!is_private && !subscript_res) return false;
935 any_success = any_success || subscript_res;
936 ret += tmp;
937 }
938 return any_success;
939 }
940
941 // NOLINTNEXTLINE(misc-no-recursion)
942 virtual bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type, const DescriptorCache* cache = nullptr) const
943 {
944 std::string extra = ToStringExtra();
945 size_t pos = extra.size() > 0 ? 1 : 0;
946 std::string ret = m_name + "(" + extra;
947 bool is_private{type == StringType::PRIVATE};
948 // For private string output, track if at least one key has a private key available.
949 // Initialize to true for non-private types.
950 bool any_success{!is_private};
951
952 for (const auto& pubkey : m_pubkey_args) {
953 if (pos++) ret += ",";
954 std::string tmp;
955 switch (type) {
956 case StringType::NORMALIZED:
957 if (!pubkey->ToNormalizedString(*arg, tmp, cache)) return false;
958 break;
959 case StringType::PRIVATE:
960 any_success = pubkey->ToPrivateString(*arg, tmp) || any_success;
961 break;
962 case StringType::PUBLIC:
963 tmp = pubkey->ToString();
964 break;
965 case StringType::COMPAT:
966 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
967 break;
968 }
969 ret += tmp;
970 }
971 std::string subscript;
972 bool subscript_res{ToStringSubScriptHelper(arg, subscript, type, cache)};
973 if (!is_private && !subscript_res) return false;
974 any_success = any_success || subscript_res;
975 if (pos && subscript.size()) ret += ',';
976 out = std::move(ret) + std::move(subscript) + ")";
977 return any_success;
978 }
979
980 std::string ToString(bool compat_format) const final
981 {
982 std::string ret;
983 ToStringHelper(nullptr, ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
984 return AddChecksum(ret);
985 }
986
987 bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
988 {
989 bool has_priv_key{ToStringHelper(&arg, out, StringType::PRIVATE)};
990 out = AddChecksum(out);
991 return has_priv_key;
992 }
993
994 bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override final
995 {
996 bool ret = ToStringHelper(&arg, out, StringType::NORMALIZED, cache);
997 out = AddChecksum(out);
998 return ret;
999 }
1000
1001 // NOLINTNEXTLINE(misc-no-recursion)
1002 bool ExpandHelper(int pos, const SigningProvider& arg, const DescriptorCache* read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache) const
1003 {
1004 FlatSigningProvider subprovider;
1005 std::vector<CPubKey> pubkeys;
1006 pubkeys.reserve(m_pubkey_args.size());
1007
1008 // Construct temporary data in `pubkeys`, `subscripts`, and `subprovider` to avoid producing output in case of failure.
1009 for (const auto& p : m_pubkey_args) {
1010 std::optional<CPubKey> pubkey = p->GetPubKey(pos, arg, subprovider, read_cache, write_cache);
1011 if (!pubkey) return false;
1012 pubkeys.push_back(pubkey.value());
1013 }
1014 std::vector<CScript> subscripts;
1015 for (const auto& subarg : m_subdescriptor_args) {
1016 std::vector<CScript> outscripts;
1017 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache)) return false;
1018 assert(outscripts.size() == 1);
1019 subscripts.emplace_back(std::move(outscripts[0]));
1020 }
1021 out.Merge(std::move(subprovider));
1022
1023 output_scripts = MakeScripts(pubkeys, std::span{subscripts}, out);
1024 return true;
1025 }
1026
1027 bool Expand(int pos, const SigningProvider& provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache = nullptr) const final
1028 {
1029 return ExpandHelper(pos, provider, nullptr, output_scripts, out, write_cache);
1030 }
1031
1032 bool ExpandFromCache(int pos, const DescriptorCache& read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const final
1033 {
1034 return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &read_cache, output_scripts, out, nullptr);
1035 }
1036
1037 // NOLINTNEXTLINE(misc-no-recursion)
1038 void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const final
1039 {
1040 for (const auto& p : m_pubkey_args) {
1041 p->GetPrivKey(pos, provider, out);
1042 }
1043 for (const auto& arg : m_subdescriptor_args) {
1044 arg->ExpandPrivate(pos, provider, out);
1045 }
1046 }
1047
1048 std::optional<OutputType> GetOutputType() const override { return std::nullopt; }
1049
1050 std::optional<int64_t> ScriptSize() const override { return {}; }
1051
1057 virtual std::optional<int64_t> MaxSatSize(bool use_max_sig) const { return {}; }
1058
1059 std::optional<int64_t> MaxSatisfactionWeight(bool) const override { return {}; }
1060
1061 std::optional<int64_t> MaxSatisfactionElems() const override { return {}; }
1062
1063 // NOLINTNEXTLINE(misc-no-recursion)
1064 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs) const override
1065 {
1066 for (const auto& p : m_pubkey_args) {
1067 std::optional<CPubKey> pub = p->GetRootPubKey();
1068 if (pub) pubkeys.insert(*pub);
1069 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
1070 if (ext_pub) ext_pubs.insert(*ext_pub);
1071 }
1072 for (const auto& arg : m_subdescriptor_args) {
1073 arg->GetPubKeys(pubkeys, ext_pubs);
1074 }
1075 }
1076
1077 virtual std::unique_ptr<DescriptorImpl> Clone() const = 0;
1078
1079 bool HasScripts() const override { return true; }
1080
1081 // NOLINTNEXTLINE(misc-no-recursion)
1082 std::vector<std::string> Warnings() const override {
1083 std::vector<std::string> all = m_warnings;
1084 for (const auto& sub : m_subdescriptor_args) {
1085 auto sub_w = sub->Warnings();
1086 all.insert(all.end(), sub_w.begin(), sub_w.end());
1087 }
1088 return all;
1089 }
1090
1091 uint32_t GetMaxKeyExpr() const final
1092 {
1093 uint32_t max_key_expr{0};
1094 std::vector<const DescriptorImpl*> todo = {this};
1095 while (!todo.empty()) {
1096 const DescriptorImpl* desc = todo.back();
1097 todo.pop_back();
1098 for (const auto& p : desc->m_pubkey_args) {
1099 max_key_expr = std::max(max_key_expr, p->m_expr_index);
1100 }
1101 for (const auto& s : desc->m_subdescriptor_args) {
1102 todo.push_back(s.get());
1103 }
1104 }
1105 return max_key_expr;
1106 }
1107
1108 size_t GetKeyCount() const final
1109 {
1110 size_t count{0};
1111 std::vector<const DescriptorImpl*> todo = {this};
1112 while (!todo.empty()) {
1113 const DescriptorImpl* desc = todo.back();
1114 todo.pop_back();
1115 for (const auto& p : desc->m_pubkey_args) {
1116 count += p->GetKeyCount();
1117 }
1118 for (const auto& s : desc->m_subdescriptor_args) {
1119 todo.push_back(s.get());
1120 }
1121 }
1122 return count;
1123 }
1124
1125 // NOLINTNEXTLINE(misc-no-recursion)
1126 bool CanSelfExpand() const override
1127 {
1128 for (const auto& key : m_pubkey_args) {
1129 if (!key->CanSelfExpand()) return false;
1130 }
1131 for (const auto& sub : m_subdescriptor_args) {
1132 if (!sub->CanSelfExpand()) return false;
1133 }
1134 return true;
1135 }
1136};
1137
1139class AddressDescriptor final : public DescriptorImpl
1140{
1141 const CTxDestination m_destination;
1142protected:
1143 std::string ToStringExtra() const override { return EncodeDestination(m_destination); }
1144 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript>, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(m_destination)); }
1145public:
1146 AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, "addr"), m_destination(std::move(destination)) {}
1147 bool IsSolvable() const final { return false; }
1148
1149 std::optional<OutputType> GetOutputType() const override
1150 {
1151 return OutputTypeFromDestination(m_destination);
1152 }
1153 bool IsSingleType() const final { return true; }
1154 bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; }
1155
1156 std::optional<int64_t> ScriptSize() const override { return GetScriptForDestination(m_destination).size(); }
1157 std::unique_ptr<DescriptorImpl> Clone() const override
1158 {
1159 return std::make_unique<AddressDescriptor>(m_destination);
1160 }
1161};
1162
1164class RawDescriptor final : public DescriptorImpl
1165{
1166 const CScript m_script;
1167protected:
1168 std::string ToStringExtra() const override { return HexStr(m_script); }
1169 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript>, FlatSigningProvider&) const override { return Vector(m_script); }
1170public:
1171 RawDescriptor(CScript script) : DescriptorImpl({}, "raw"), m_script(std::move(script)) {}
1172 bool IsSolvable() const final { return false; }
1173
1174 std::optional<OutputType> GetOutputType() const override
1175 {
1176 CTxDestination dest;
1177 ExtractDestination(m_script, dest);
1178 return OutputTypeFromDestination(dest);
1179 }
1180 bool IsSingleType() const final { return true; }
1181 bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; }
1182
1183 std::optional<int64_t> ScriptSize() const override { return m_script.size(); }
1184
1185 std::unique_ptr<DescriptorImpl> Clone() const override
1186 {
1187 return std::make_unique<RawDescriptor>(m_script);
1188 }
1189};
1190
1192class PKDescriptor final : public DescriptorImpl
1193{
1194private:
1195 const bool m_xonly;
1196protected:
1197 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override
1198 {
1199 if (m_xonly) {
1201 return Vector(std::move(script));
1202 } else {
1203 return Vector(GetScriptForRawPubKey(keys[0]));
1204 }
1205 }
1206public:
1207 PKDescriptor(std::unique_ptr<PubkeyProvider> prov, bool xonly = false) : DescriptorImpl(Vector(std::move(prov)), "pk"), m_xonly(xonly) {}
1208 bool IsSingleType() const final { return true; }
1209
1210 std::optional<int64_t> ScriptSize() const override {
1211 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1212 }
1213
1214 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1215 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1216 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1217 }
1218
1219 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1220 return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;
1221 }
1222
1223 std::optional<int64_t> MaxSatisfactionElems() const override { return 1; }
1224
1225 std::unique_ptr<DescriptorImpl> Clone() const override
1226 {
1227 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1228 }
1229};
1230
1232class PKHDescriptor final : public DescriptorImpl
1233{
1234protected:
1235 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override
1236 {
1237 CKeyID id = keys[0].GetID();
1239 }
1240public:
1241 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "pkh") {}
1242 std::optional<OutputType> GetOutputType() const override { return OutputType::LEGACY; }
1243 bool IsSingleType() const final { return true; }
1244
1245 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 1 + 20 + 1 + 1; }
1246
1247 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1248 const auto sig_size = use_max_sig ? 72 : 71;
1249 return 1 + sig_size + 1 + m_pubkey_args[0]->GetSize();
1250 }
1251
1252 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1253 return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;
1254 }
1255
1256 std::optional<int64_t> MaxSatisfactionElems() const override { return 2; }
1257
1258 std::unique_ptr<DescriptorImpl> Clone() const override
1259 {
1260 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1261 }
1262};
1263
1265class WPKHDescriptor final : public DescriptorImpl
1266{
1267protected:
1268 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override
1269 {
1270 CKeyID id = keys[0].GetID();
1272 }
1273public:
1274 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "wpkh") {}
1275 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
1276 bool IsSingleType() const final { return true; }
1277
1278 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 20; }
1279
1280 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1281 const auto sig_size = use_max_sig ? 72 : 71;
1282 return (1 + sig_size + 1 + 33);
1283 }
1284
1285 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1286 return MaxSatSize(use_max_sig);
1287 }
1288
1289 std::optional<int64_t> MaxSatisfactionElems() const override { return 2; }
1290
1291 std::unique_ptr<DescriptorImpl> Clone() const override
1292 {
1293 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1294 }
1295};
1296
1298class ComboDescriptor final : public DescriptorImpl
1299{
1300protected:
1301 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider& out) const override
1302 {
1303 std::vector<CScript> ret;
1304 CKeyID id = keys[0].GetID();
1305 ret.emplace_back(GetScriptForRawPubKey(keys[0])); // P2PK
1306 ret.emplace_back(GetScriptForDestination(PKHash(id))); // P2PKH
1307 if (keys[0].IsCompressed()) {
1309 out.scripts.emplace(CScriptID(p2wpkh), p2wpkh);
1310 ret.emplace_back(p2wpkh);
1311 ret.emplace_back(GetScriptForDestination(ScriptHash(p2wpkh))); // P2SH-P2WPKH
1312 }
1313 return ret;
1314 }
1315public:
1316 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "combo") {}
1317 bool IsSingleType() const final { return false; }
1318 std::unique_ptr<DescriptorImpl> Clone() const override
1319 {
1320 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1321 }
1322};
1323
1325class MultisigDescriptor final : public DescriptorImpl
1326{
1327 const int m_threshold;
1328 const bool m_sorted;
1329protected:
1330 std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
1331 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override {
1332 if (m_sorted) {
1333 std::vector<CPubKey> sorted_keys(keys);
1334 std::sort(sorted_keys.begin(), sorted_keys.end());
1335 return Vector(GetScriptForMultisig(m_threshold, sorted_keys));
1336 }
1337 return Vector(GetScriptForMultisig(m_threshold, keys));
1338 }
1339public:
1340 MultisigDescriptor(int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers, bool sorted = false) : DescriptorImpl(std::move(providers), sorted ? "sortedmulti" : "multi"), m_threshold(threshold), m_sorted(sorted) {}
1341 bool IsSingleType() const final { return true; }
1342
1343 std::optional<int64_t> ScriptSize() const override {
1344 const auto n_keys = m_pubkey_args.size();
1345 auto op = [](int64_t acc, const std::unique_ptr<PubkeyProvider>& pk) { return acc + 1 + pk->GetSize();};
1346 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1347 return 1 + BuildScript(n_keys).size() + BuildScript(m_threshold).size() + pubkeys_size;
1348 }
1349
1350 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1351 const auto sig_size = use_max_sig ? 72 : 71;
1352 return (1 + (1 + sig_size) * m_threshold);
1353 }
1354
1355 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1356 return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;
1357 }
1358
1359 std::optional<int64_t> MaxSatisfactionElems() const override { return 1 + m_threshold; }
1360
1361 std::unique_ptr<DescriptorImpl> Clone() const override
1362 {
1363 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1364 providers.reserve(m_pubkey_args.size());
1365 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), std::back_inserter(providers), [](const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1366 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1367 }
1368};
1369
1371class MultiADescriptor final : public DescriptorImpl
1372{
1373 const int m_threshold;
1374 const bool m_sorted;
1375protected:
1376 std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
1377 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override {
1378 CScript ret;
1379 std::vector<XOnlyPubKey> xkeys;
1380 xkeys.reserve(keys.size());
1381 for (const auto& key : keys) xkeys.emplace_back(key);
1382 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1383 ret << ToByteVector(xkeys[0]) << OP_CHECKSIG;
1384 for (size_t i = 1; i < keys.size(); ++i) {
1385 ret << ToByteVector(xkeys[i]) << OP_CHECKSIGADD;
1386 }
1387 ret << m_threshold << OP_NUMEQUAL;
1388 return Vector(std::move(ret));
1389 }
1390public:
1391 MultiADescriptor(int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers, bool sorted = false) : DescriptorImpl(std::move(providers), sorted ? "sortedmulti_a" : "multi_a"), m_threshold(threshold), m_sorted(sorted) {}
1392 bool IsSingleType() const final { return true; }
1393
1394 std::optional<int64_t> ScriptSize() const override {
1395 const auto n_keys = m_pubkey_args.size();
1396 return (1 + 32 + 1) * n_keys + BuildScript(m_threshold).size() + 1;
1397 }
1398
1399 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1400 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1401 }
1402
1403 std::optional<int64_t> MaxSatisfactionElems() const override { return m_pubkey_args.size(); }
1404
1405 std::unique_ptr<DescriptorImpl> Clone() const override
1406 {
1407 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1408 providers.reserve(m_pubkey_args.size());
1409 for (const auto& arg : m_pubkey_args) {
1410 providers.push_back(arg->Clone());
1411 }
1412 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1413 }
1414};
1415
1417class SHDescriptor final : public DescriptorImpl
1418{
1419protected:
1420 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript> scripts, FlatSigningProvider& out) const override
1421 {
1422 auto ret = Vector(GetScriptForDestination(ScriptHash(scripts[0])));
1423 if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
1424 return ret;
1425 }
1426
1427 bool IsSegwit() const { return m_subdescriptor_args[0]->GetOutputType() == OutputType::BECH32; }
1428
1429public:
1430 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "sh") {}
1431
1432 std::optional<OutputType> GetOutputType() const override
1433 {
1434 assert(m_subdescriptor_args.size() == 1);
1435 if (IsSegwit()) return OutputType::P2SH_SEGWIT;
1436 return OutputType::LEGACY;
1437 }
1438 bool IsSingleType() const final { return true; }
1439
1440 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 20 + 1; }
1441
1442 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1443 if (const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1444 if (const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1445 // The subscript is never witness data.
1446 const auto subscript_weight = (1 + *subscript_size) * WITNESS_SCALE_FACTOR;
1447 // The weight depends on whether the inner descriptor is satisfied using the witness stack.
1448 if (IsSegwit()) return subscript_weight + *sat_size;
1449 return subscript_weight + *sat_size * WITNESS_SCALE_FACTOR;
1450 }
1451 }
1452 return {};
1453 }
1454
1455 std::optional<int64_t> MaxSatisfactionElems() const override {
1456 if (const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems()) return 1 + *sub_elems;
1457 return {};
1458 }
1459
1460 std::unique_ptr<DescriptorImpl> Clone() const override
1461 {
1462 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1463 }
1464};
1465
1467class WSHDescriptor final : public DescriptorImpl
1468{
1469protected:
1470 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript> scripts, FlatSigningProvider& out) const override
1471 {
1473 if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
1474 return ret;
1475 }
1476public:
1477 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "wsh") {}
1478 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
1479 bool IsSingleType() const final { return true; }
1480
1481 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 32; }
1482
1483 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1484 if (const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1485 if (const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1486 return GetSizeOfCompactSize(*subscript_size) + *subscript_size + *sat_size;
1487 }
1488 }
1489 return {};
1490 }
1491
1492 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1493 return MaxSatSize(use_max_sig);
1494 }
1495
1496 std::optional<int64_t> MaxSatisfactionElems() const override {
1497 if (const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems()) return 1 + *sub_elems;
1498 return {};
1499 }
1500
1501 std::unique_ptr<DescriptorImpl> Clone() const override
1502 {
1503 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1504 }
1505};
1506
1508class TRDescriptor final : public DescriptorImpl
1509{
1510 std::vector<int> m_depths;
1511protected:
1512 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts, FlatSigningProvider& out) const override
1513 {
1514 TaprootBuilder builder;
1515 assert(m_depths.size() == scripts.size());
1516 for (size_t pos = 0; pos < m_depths.size(); ++pos) {
1517 builder.Add(m_depths[pos], scripts[pos], TAPROOT_LEAF_TAPSCRIPT);
1518 }
1519 if (!builder.IsComplete()) return {};
1520 assert(keys.size() == 1);
1521 XOnlyPubKey xpk(keys[0]);
1522 if (!xpk.IsFullyValid()) return {};
1523 builder.Finalize(xpk);
1524 WitnessV1Taproot output = builder.GetOutput();
1525 out.tr_trees[output] = builder;
1526 return Vector(GetScriptForDestination(output));
1527 }
1528 bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const override
1529 {
1530 if (m_depths.empty()) {
1531 // If there are no sub-descriptors and a PRIVATE string
1532 // is requested, return `false` to indicate that the presence
1533 // of a private key depends solely on the internal key (which is checked
1534 // in the caller), not on any sub-descriptor. This ensures correct behavior for
1535 // descriptors like tr(internal_key) when checking for private keys.
1536 return type != StringType::PRIVATE;
1537 }
1538 std::vector<bool> path;
1539 bool is_private{type == StringType::PRIVATE};
1540 // For private string output, track if at least one key has a private key available.
1541 // Initialize to true for non-private types.
1542 bool any_success{!is_private};
1543
1544 for (size_t pos = 0; pos < m_depths.size(); ++pos) {
1545 if (pos) ret += ',';
1546 while ((int)path.size() <= m_depths[pos]) {
1547 if (path.size()) ret += '{';
1548 path.push_back(false);
1549 }
1550 std::string tmp;
1551 bool subscript_res{m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)};
1552 if (!is_private && !subscript_res) return false;
1553 any_success = any_success || subscript_res;
1554 ret += tmp;
1555 while (!path.empty() && path.back()) {
1556 if (path.size() > 1) ret += '}';
1557 path.pop_back();
1558 }
1559 if (!path.empty()) path.back() = true;
1560 }
1561 return any_success;
1562 }
1563public:
1564 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1565 DescriptorImpl(Vector(std::move(internal_key)), std::move(descs), "tr"), m_depths(std::move(depths))
1566 {
1567 assert(m_subdescriptor_args.size() == m_depths.size());
1568 }
1569 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32M; }
1570 bool IsSingleType() const final { return true; }
1571
1572 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 32; }
1573
1574 std::optional<int64_t> MaxSatisfactionWeight(bool) const override {
1575 // FIXME: We assume keypath spend, which can lead to very large underestimations.
1576 return 1 + 65;
1577 }
1578
1579 std::optional<int64_t> MaxSatisfactionElems() const override {
1580 // FIXME: See above, we assume keypath spend.
1581 return 1;
1582 }
1583
1584 std::unique_ptr<DescriptorImpl> Clone() const override
1585 {
1586 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1587 subdescs.reserve(m_subdescriptor_args.size());
1588 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), std::back_inserter(subdescs), [](const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1589 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1590 }
1591};
1592
1593/* We instantiate Miniscript here with a simple integer as key type.
1594 * The value of these key integers are an index in the
1595 * DescriptorImpl::m_pubkey_args vector.
1596 */
1597
1601class ScriptMaker {
1603 const std::vector<CPubKey>& m_keys;
1605 const miniscript::MiniscriptContext m_script_ctx;
1606
1610 uint160 GetHash160(uint32_t key) const {
1611 if (miniscript::IsTapscript(m_script_ctx)) {
1612 return Hash160(XOnlyPubKey{m_keys[key]});
1613 }
1614 return m_keys[key].GetID();
1615 }
1616
1617public:
1618 ScriptMaker(const std::vector<CPubKey>& keys LIFETIMEBOUND, const miniscript::MiniscriptContext script_ctx) : m_keys(keys), m_script_ctx{script_ctx} {}
1619
1620 std::vector<unsigned char> ToPKBytes(uint32_t key) const {
1621 // In Tapscript keys always serialize as x-only, whether an x-only key was used in the descriptor or not.
1622 if (!miniscript::IsTapscript(m_script_ctx)) {
1623 return {m_keys[key].begin(), m_keys[key].end()};
1624 }
1625 const XOnlyPubKey xonly_pubkey{m_keys[key]};
1626 return {xonly_pubkey.begin(), xonly_pubkey.end()};
1627 }
1628
1629 std::vector<unsigned char> ToPKHBytes(uint32_t key) const {
1630 auto id = GetHash160(key);
1631 return {id.begin(), id.end()};
1632 }
1633};
1634
1638class StringMaker {
1640 const SigningProvider* m_arg;
1642 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1644 const DescriptorImpl::StringType m_type;
1645 const DescriptorCache* m_cache;
1646
1647public:
1648 StringMaker(const SigningProvider* arg LIFETIMEBOUND,
1649 const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys LIFETIMEBOUND,
1650 DescriptorImpl::StringType type,
1651 const DescriptorCache* cache LIFETIMEBOUND)
1652 : m_arg(arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {}
1653
1654 std::optional<std::string> ToString(uint32_t key, bool& has_priv_key) const
1655 {
1656 std::string ret;
1657 has_priv_key = false;
1658 switch (m_type) {
1659 case DescriptorImpl::StringType::PUBLIC:
1660 ret = m_pubkeys[key]->ToString();
1661 break;
1662 case DescriptorImpl::StringType::PRIVATE:
1663 has_priv_key = m_pubkeys[key]->ToPrivateString(*m_arg, ret);
1664 break;
1665 case DescriptorImpl::StringType::NORMALIZED:
1666 if (!m_pubkeys[key]->ToNormalizedString(*m_arg, ret, m_cache)) return {};
1667 break;
1668 case DescriptorImpl::StringType::COMPAT:
1669 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::COMPAT);
1670 break;
1671 }
1672 return ret;
1673 }
1674};
1675
1676class MiniscriptDescriptor final : public DescriptorImpl
1677{
1678private:
1680
1681protected:
1682 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
1683 FlatSigningProvider& provider) const override
1684 {
1685 const auto script_ctx{m_node.GetMsCtx()};
1686 for (const auto& key : keys) {
1687 if (miniscript::IsTapscript(script_ctx)) {
1688 provider.pubkeys.emplace(Hash160(XOnlyPubKey{key}), key);
1689 } else {
1690 provider.pubkeys.emplace(key.GetID(), key);
1691 }
1692 }
1693 return Vector(m_node.ToScript(ScriptMaker(keys, script_ctx)));
1694 }
1695
1696public:
1697 MiniscriptDescriptor(std::vector<std::unique_ptr<PubkeyProvider>> providers, miniscript::Node<uint32_t>&& node)
1698 : DescriptorImpl(std::move(providers), "?"), m_node(std::move(node))
1699 {
1700 // Traverse miniscript tree for unsafe use of older()
1702 if (node.Fragment() == miniscript::Fragment::OLDER) {
1703 const uint32_t raw = node.K();
1704 const uint32_t value_part = raw & ~CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
1705 if (value_part > CTxIn::SEQUENCE_LOCKTIME_MASK) {
1706 const bool is_time_based = (raw & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) != 0;
1707 if (is_time_based) {
1708 m_warnings.push_back(strprintf("time-based relative locktime: older(%u) > (65535 * 512) seconds is unsafe", raw));
1709 } else {
1710 m_warnings.push_back(strprintf("height-based relative locktime: older(%u) > 65535 blocks is unsafe", raw));
1711 }
1712 }
1713 }
1714 });
1715 }
1716
1717 bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type,
1718 const DescriptorCache* cache = nullptr) const override
1719 {
1720 bool has_priv_key{false};
1721 auto res = m_node.ToString(StringMaker(arg, m_pubkey_args, type, cache), has_priv_key);
1722 if (res) out = *res;
1723 if (type == StringType::PRIVATE) {
1724 Assume(res.has_value());
1725 return has_priv_key;
1726 } else {
1727 return res.has_value();
1728 }
1729 }
1730
1731 bool IsSolvable() const override { return true; }
1732 bool IsSingleType() const final { return true; }
1733
1734 std::optional<int64_t> ScriptSize() const override { return m_node.ScriptSize(); }
1735
1736 std::optional<int64_t> MaxSatSize(bool) const override
1737 {
1738 // For Miniscript we always assume high-R ECDSA signatures.
1739 return m_node.GetWitnessSize();
1740 }
1741
1742 std::optional<int64_t> MaxSatisfactionElems() const override
1743 {
1744 return m_node.GetStackSize();
1745 }
1746
1747 std::unique_ptr<DescriptorImpl> Clone() const override
1748 {
1749 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1750 providers.reserve(m_pubkey_args.size());
1751 for (const auto& arg : m_pubkey_args) {
1752 providers.push_back(arg->Clone());
1753 }
1754 return std::make_unique<MiniscriptDescriptor>(std::move(providers), m_node.Clone());
1755 }
1756};
1757
1759class RawTRDescriptor final : public DescriptorImpl
1760{
1761protected:
1762 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts, FlatSigningProvider& out) const override
1763 {
1764 assert(keys.size() == 1);
1765 XOnlyPubKey xpk(keys[0]);
1766 if (!xpk.IsFullyValid()) return {};
1767 WitnessV1Taproot output{xpk};
1768 return Vector(GetScriptForDestination(output));
1769 }
1770public:
1771 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(Vector(std::move(output_key)), "rawtr") {}
1772 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32M; }
1773 bool IsSingleType() const final { return true; }
1774
1775 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 32; }
1776
1777 std::optional<int64_t> MaxSatisfactionWeight(bool) const override {
1778 // We can't know whether there is a script path, so assume key path spend.
1779 return 1 + 65;
1780 }
1781
1782 std::optional<int64_t> MaxSatisfactionElems() const override {
1783 // See above, we assume keypath spend.
1784 return 1;
1785 }
1786
1787 std::unique_ptr<DescriptorImpl> Clone() const override
1788 {
1789 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1790 }
1791};
1792
1794class UnusedDescriptor final : public DescriptorImpl
1795{
1796protected:
1797 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts, FlatSigningProvider& out) const override { return {}; }
1798public:
1799 UnusedDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "unused") {}
1800 bool IsSingleType() const final { return true; }
1801 bool HasScripts() const override { return false; }
1802
1803 std::unique_ptr<DescriptorImpl> Clone() const override
1804 {
1805 return std::make_unique<UnusedDescriptor>(m_pubkey_args.at(0)->Clone());
1806 }
1807};
1808
1809
1811// Parser //
1813
1814enum class ParseScriptContext {
1815 TOP,
1816 P2SH,
1817 P2WPKH,
1818 P2WSH,
1819 P2TR,
1820 MUSIG,
1821};
1822
1823std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem, bool& apostrophe, std::string& error, bool& has_hardened)
1824{
1825 bool hardened = false;
1826 if (elem.size() > 0) {
1827 const char last = elem[elem.size() - 1];
1828 if (last == '\'' || last == 'h') {
1829 elem = elem.first(elem.size() - 1);
1830 hardened = true;
1831 apostrophe = last == '\'';
1832 }
1833 }
1834 const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
1835 if (!p) {
1836 error = strprintf("Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
1837 return std::nullopt;
1838 } else if (*p > 0x7FFFFFFFUL) {
1839 error = strprintf("Key path value %u is out of range", *p);
1840 return std::nullopt;
1841 }
1842 has_hardened = has_hardened || hardened;
1843
1844 return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
1845}
1846
1858[[nodiscard]] bool ParseKeyPath(const std::vector<std::span<const char>>& split, std::vector<KeyPath>& out, bool& apostrophe, std::string& error, bool allow_multipath, bool& has_hardened)
1859{
1860 KeyPath path;
1861 struct MultipathSubstitutes {
1862 size_t placeholder_index;
1863 std::vector<uint32_t> values;
1864 };
1865 std::optional<MultipathSubstitutes> substitutes;
1866 has_hardened = false;
1867
1868 for (size_t i = 1; i < split.size(); ++i) {
1869 const std::span<const char>& elem = split[i];
1870
1871 // Check if element contains multipath specifier
1872 if (!elem.empty() && elem.front() == '<' && elem.back() == '>') {
1873 if (!allow_multipath) {
1874 error = strprintf("Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1875 return false;
1876 }
1877 if (substitutes) {
1878 error = "Multiple multipath key path specifiers found";
1879 return false;
1880 }
1881
1882 // Parse each possible value
1883 std::vector<std::span<const char>> nums = Split(std::span(elem.begin()+1, elem.end()-1), ";");
1884 if (nums.size() < 2) {
1885 error = "Multipath key path specifiers must have at least two items";
1886 return false;
1887 }
1888
1889 substitutes.emplace();
1890 std::unordered_set<uint32_t> seen_substitutes;
1891 for (const auto& num : nums) {
1892 const auto& op_num = ParseKeyPathNum(num, apostrophe, error, has_hardened);
1893 if (!op_num) return false;
1894 auto [_, inserted] = seen_substitutes.insert(*op_num);
1895 if (!inserted) {
1896 error = strprintf("Duplicated key path value %u in multipath specifier", *op_num);
1897 return false;
1898 }
1899 substitutes->values.emplace_back(*op_num);
1900 }
1901
1902 path.emplace_back(); // Placeholder for multipath segment
1903 substitutes->placeholder_index = path.size() - 1;
1904 } else {
1905 const auto& op_num = ParseKeyPathNum(elem, apostrophe, error, has_hardened);
1906 if (!op_num) return false;
1907 path.emplace_back(*op_num);
1908 }
1909 }
1910
1911 if (!substitutes) {
1912 out.emplace_back(std::move(path));
1913 } else {
1914 // Replace the multipath placeholder with each value while generating paths
1915 for (uint32_t substitute : substitutes->values) {
1916 KeyPath branch_path = path;
1917 branch_path[substitutes->placeholder_index] = substitute;
1918 out.emplace_back(std::move(branch_path));
1919 }
1920 }
1921 return true;
1922}
1923
1924[[nodiscard]] bool ParseKeyPath(const std::vector<std::span<const char>>& split, std::vector<KeyPath>& out, bool& apostrophe, std::string& error, bool allow_multipath)
1925{
1926 bool dummy;
1927 return ParseKeyPath(split, out, apostrophe, error, allow_multipath, /*has_hardened=*/dummy);
1928}
1929
1930static DeriveType ParseDeriveType(std::vector<std::span<const char>>& split, bool& apostrophe)
1931{
1932 DeriveType type = DeriveType::NON_RANGED;
1933 if (std::ranges::equal(split.back(), std::span{"*"}.first(1))) {
1934 split.pop_back();
1935 type = DeriveType::UNHARDENED_RANGED;
1936 } else if (std::ranges::equal(split.back(), std::span{"*'"}.first(2)) || std::ranges::equal(split.back(), std::span{"*h"}.first(2))) {
1937 apostrophe = std::ranges::equal(split.back(), std::span{"*'"}.first(2));
1938 split.pop_back();
1939 type = DeriveType::HARDENED_RANGED;
1940 }
1941 return type;
1942}
1943
1945std::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)
1946{
1947 std::vector<std::unique_ptr<PubkeyProvider>> ret;
1948 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1949 auto split = Split(sp, '/');
1950 std::string str(split[0].begin(), split[0].end());
1951 if (str.size() == 0) {
1952 error = "No key provided";
1953 return {};
1954 }
1955 if (IsSpace(str.front()) || IsSpace(str.back())) {
1956 error = strprintf("Key '%s' is invalid due to whitespace", str);
1957 return {};
1958 }
1959 if (split.size() == 1) {
1960 if (IsHex(str)) {
1961 std::vector<unsigned char> data = ParseHex(str);
1962 CPubKey pubkey(data);
1963 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1964 error = "Hybrid public keys are not allowed";
1965 return {};
1966 }
1967 if (pubkey.IsFullyValid()) {
1968 if (permit_uncompressed || pubkey.IsCompressed()) {
1969 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, false));
1970 ++key_exp_index;
1971 return ret;
1972 } else {
1973 error = "Uncompressed keys are not allowed";
1974 return {};
1975 }
1976 } else if (data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1977 unsigned char fullkey[33] = {0x02};
1978 std::copy(data.begin(), data.end(), fullkey + 1);
1979 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1980 if (pubkey.IsFullyValid()) {
1981 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, true));
1982 ++key_exp_index;
1983 return ret;
1984 }
1985 }
1986 error = strprintf("Pubkey '%s' is invalid", str);
1987 return {};
1988 }
1989 CKey key = DecodeSecret(str);
1990 if (key.IsValid()) {
1991 if (permit_uncompressed || key.IsCompressed()) {
1992 CPubKey pubkey = key.GetPubKey();
1993 out.keys.emplace(pubkey.GetID(), key);
1994 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1995 ++key_exp_index;
1996 return ret;
1997 } else {
1998 error = "Uncompressed keys are not allowed";
1999 return {};
2000 }
2001 }
2002 }
2003 CExtKey extkey = DecodeExtKey(str);
2004 CExtPubKey extpubkey = DecodeExtPubKey(str);
2005 if (!extkey.key.IsValid() && !extpubkey.pubkey.IsValid()) {
2006 error = strprintf("key '%s' is not valid", str);
2007 return {};
2008 }
2009 std::vector<KeyPath> paths;
2010 DeriveType type = ParseDeriveType(split, apostrophe);
2011 if (!ParseKeyPath(split, paths, apostrophe, error, /*allow_multipath=*/true)) return {};
2012 if (extkey.key.IsValid()) {
2013 extpubkey = extkey.Neuter();
2014 out.keys.emplace(extpubkey.pubkey.GetID(), extkey.key);
2015 }
2016 for (auto& path : paths) {
2017 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
2018 }
2019 ++key_exp_index;
2020 return ret;
2021}
2022
2024// NOLINTNEXTLINE(misc-no-recursion)
2025std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index, const std::span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
2026{
2027 std::vector<std::unique_ptr<PubkeyProvider>> ret;
2028
2029 using namespace script;
2030
2031 // musig cannot be nested inside of an origin
2032 std::span<const char> span = sp;
2033 if (Const("musig(", span, /*skip=*/false)) {
2034 if (ctx != ParseScriptContext::P2TR) {
2035 error = "musig() is only allowed in tr() and rawtr()";
2036 return {};
2037 }
2038
2039 // Split the span on the end parentheses. The end parentheses must
2040 // be included in the resulting span so that Expr is happy.
2041 auto split = Split(sp, ')', /*include_sep=*/true);
2042 if (split.size() > 2) {
2043 error = "Too many ')' in musig() expression";
2044 return {};
2045 }
2046 std::span<const char> expr(split.at(0).begin(), split.at(0).end());
2047 if (!Func("musig", expr)) {
2048 error = "Invalid musig() expression";
2049 return {};
2050 }
2051
2052 // Parse the participant pubkeys
2053 bool any_ranged = false;
2054 bool all_bip32 = true;
2055 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2056 bool any_key_parsed = false;
2057 size_t max_multipath_len = 0;
2058 while (expr.size()) {
2059 if (any_key_parsed && !Const(",", expr)) {
2060 error = strprintf("musig(): expected ',', got '%c'", expr[0]);
2061 return {};
2062 }
2063 auto arg = Expr(expr);
2064 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG, out, error);
2065 if (pk.empty()) {
2066 error = strprintf("musig(): %s", error);
2067 return {};
2068 }
2069 any_key_parsed = true;
2070
2071 any_ranged = any_ranged || pk.at(0)->IsRange();
2072 all_bip32 = all_bip32 && pk.at(0)->IsBIP32();
2073
2074 max_multipath_len = std::max(max_multipath_len, pk.size());
2075
2076 providers.emplace_back(std::move(pk));
2077 }
2078 if (!any_key_parsed) {
2079 error = "musig(): Must contain key expressions";
2080 return {};
2081 }
2082
2083 // Parse any derivation
2084 DeriveType deriv_type = DeriveType::NON_RANGED;
2085 std::vector<KeyPath> derivation_multipaths;
2086 if (split.size() == 2 && Const("/", split.at(1), /*skip=*/false)) {
2087 if (!all_bip32) {
2088 error = "musig(): derivation requires all participants to be xpubs or xprvs";
2089 return {};
2090 }
2091 if (any_ranged) {
2092 error = "musig(): Cannot have ranged participant keys if musig() also has derivation";
2093 return {};
2094 }
2095 bool dummy = false;
2096 auto deriv_split = Split(split.at(1), '/');
2097 deriv_type = ParseDeriveType(deriv_split, dummy);
2098 if (deriv_type == DeriveType::HARDENED_RANGED) {
2099 error = "musig(): Cannot have hardened child derivation";
2100 return {};
2101 }
2102 bool has_hardened = false;
2103 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error, /*allow_multipath=*/true, has_hardened)) {
2104 error = "musig(): " + error;
2105 return {};
2106 }
2107 if (has_hardened) {
2108 error = "musig(): cannot have hardened derivation steps";
2109 return {};
2110 }
2111 } else {
2112 derivation_multipaths.emplace_back();
2113 }
2114
2115 // Makes sure that all providers vectors in providers are the given length, or exactly length 1
2116 // Length 1 vectors have the single provider cloned until it matches the given length.
2117 const auto& clone_providers = [&providers](size_t length) -> bool {
2118 for (auto& multipath_providers : providers) {
2119 if (multipath_providers.size() == 1) {
2120 for (size_t i = 1; i < length; ++i) {
2121 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
2122 }
2123 } else if (multipath_providers.size() != length) {
2124 return false;
2125 }
2126 }
2127 return true;
2128 };
2129
2130 // Emplace the final MuSigPubkeyProvider into ret with the pubkey providers from the specified provider vectors index
2131 // and the path from the specified path index
2132 const auto& emplace_final_provider = [&ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](size_t vec_idx, size_t path_idx) -> void {
2133 KeyPath& path = derivation_multipaths.at(path_idx);
2134 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2135 pubs.reserve(providers.size());
2136 for (auto& vec : providers) {
2137 pubs.emplace_back(std::move(vec.at(vec_idx)));
2138 }
2139 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
2140 };
2141
2142 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
2143 error = "musig(): Cannot have multipath participant keys if musig() is also multipath";
2144 return {};
2145 } else if (max_multipath_len > 1) {
2146 if (!clone_providers(max_multipath_len)) {
2147 error = strprintf("musig(): Multipath derivation paths have mismatched lengths");
2148 return {};
2149 }
2150 for (size_t i = 0; i < max_multipath_len; ++i) {
2151 // Final MuSigPubkeyProvider uses participant pubkey providers at each multipath position, and the first (and only) path
2152 emplace_final_provider(i, 0);
2153 }
2154 } else if (derivation_multipaths.size() > 1) {
2155 // All key provider vectors should be length 1. Clone them until they have the same length as paths
2156 if (!Assume(clone_providers(derivation_multipaths.size()))) {
2157 error = "musig(): Multipath derivation path with multipath participants is disallowed"; // This error is unreachable due to earlier check
2158 return {};
2159 }
2160 for (size_t i = 0; i < derivation_multipaths.size(); ++i) {
2161 // Final MuSigPubkeyProvider uses cloned participant pubkey providers, and the multipath derivation paths
2162 emplace_final_provider(i, i);
2163 }
2164 } else {
2165 // No multipath derivation, MuSigPubkeyProvider uses the first (and only) participant pubkey providers, and the first (and only) path
2166 emplace_final_provider(0, 0);
2167 }
2168 ++key_exp_index; // Increment key expression index for the MuSigPubkeyProvider too
2169 return ret;
2170 }
2171
2172 auto origin_split = Split(sp, ']');
2173 if (origin_split.size() > 2) {
2174 error = "Multiple ']' characters found for a single pubkey";
2175 return {};
2176 }
2177 // This is set if either the origin or path suffix contains a hardened derivation.
2178 bool apostrophe = false;
2179 if (origin_split.size() == 1) {
2180 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx, out, apostrophe, error);
2181 }
2182 if (origin_split[0].empty() || origin_split[0][0] != '[') {
2183 error = strprintf("Key origin start '[ character expected but not found, got '%c' instead",
2184 origin_split[0].empty() ? ']' : origin_split[0][0]);
2185 return {};
2186 }
2187 auto slash_split = Split(origin_split[0].subspan(1), '/');
2188 if (slash_split[0].size() != 8) {
2189 error = strprintf("Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
2190 return {};
2191 }
2192 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
2193 if (!IsHex(fpr_hex)) {
2194 error = strprintf("Fingerprint '%s' is not hex", fpr_hex);
2195 return {};
2196 }
2197 auto fpr_bytes = ParseHex(fpr_hex);
2198 KeyOriginInfo info;
2199 static_assert(sizeof(info.fingerprint) == 4, "Fingerprint must be 4 bytes");
2200 assert(fpr_bytes.size() == 4);
2201 std::copy_n(fpr_bytes.begin(), info.fingerprint.size(), info.fingerprint.begin());
2202 std::vector<KeyPath> path;
2203 if (!ParseKeyPath(slash_split, path, apostrophe, error, /*allow_multipath=*/false)) return {};
2204 info.path = path.at(0);
2205 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx, out, apostrophe, error);
2206 if (providers.empty()) return {};
2207 ret.reserve(providers.size());
2208 for (auto& prov : providers) {
2209 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(prov->m_expr_index, info, std::move(prov), apostrophe));
2210 }
2211 return ret;
2212}
2213
2214std::unique_ptr<PubkeyProvider> InferPubkey(const CPubKey& pubkey, ParseScriptContext ctx, const SigningProvider& provider)
2215{
2216 // Key cannot be hybrid
2217 if (!pubkey.IsValidNonHybrid()) {
2218 return nullptr;
2219 }
2220 // Uncompressed is only allowed in TOP and P2SH contexts
2221 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.IsCompressed()) {
2222 return nullptr;
2223 }
2224 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey, false);
2225 KeyOriginInfo info;
2226 if (provider.GetKeyOrigin(pubkey.GetID(), info)) {
2227 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider), /*apostrophe=*/false);
2228 }
2229 return key_provider;
2230}
2231
2232std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(const XOnlyPubKey& xkey, ParseScriptContext ctx, const SigningProvider& provider)
2233{
2234 CPubKey pubkey{xkey.GetEvenCorrespondingCPubKey()};
2235 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey, true);
2236 KeyOriginInfo info;
2237 if (provider.GetKeyOriginByXOnly(xkey, info)) {
2238 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider), /*apostrophe=*/false);
2239 }
2240 return key_provider;
2241}
2242
2246struct KeyParser {
2248 using Key = uint32_t;
2250 FlatSigningProvider* m_out;
2252 const SigningProvider* m_in;
2254 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2256 mutable std::string m_key_parsing_error;
2258 const miniscript::MiniscriptContext m_script_ctx;
2260 uint32_t& m_expr_index;
2261
2263 miniscript::MiniscriptContext ctx, uint32_t& key_exp_index LIFETIMEBOUND)
2264 : m_out(out), m_in(in), m_script_ctx(ctx), m_expr_index(key_exp_index) {}
2265
2266 bool KeyCompare(const Key& a, const Key& b) const {
2267 return *m_keys.at(a).at(0) < *m_keys.at(b).at(0);
2268 }
2269
2270 ParseScriptContext ParseContext() const {
2271 switch (m_script_ctx) {
2272 case miniscript::MiniscriptContext::P2WSH: return ParseScriptContext::P2WSH;
2273 case miniscript::MiniscriptContext::TAPSCRIPT: return ParseScriptContext::P2TR;
2274 }
2275 assert(false);
2276 }
2277
2278 std::optional<Key> FromString(std::span<const char>& in) const
2279 {
2280 assert(m_out);
2281 Key key = m_keys.size();
2282 auto pk = ParsePubkey(m_expr_index, in, ParseContext(), *m_out, m_key_parsing_error);
2283 if (pk.empty()) return {};
2284 m_keys.emplace_back(std::move(pk));
2285 return key;
2286 }
2287
2288 std::optional<std::string> ToString(const Key& key, bool&) const
2289 {
2290 return m_keys.at(key).at(0)->ToString();
2291 }
2292
2293 template<typename I> std::optional<Key> FromPKBytes(I begin, I end) const
2294 {
2295 assert(m_in);
2296 Key key = m_keys.size();
2297 if (miniscript::IsTapscript(m_script_ctx) && end - begin == 32) {
2298 XOnlyPubKey pubkey;
2299 std::copy(begin, end, pubkey.begin());
2300 if (auto pubkey_provider = InferXOnlyPubkey(pubkey, ParseContext(), *m_in)) {
2301 m_keys.emplace_back();
2302 m_keys.back().push_back(std::move(pubkey_provider));
2303 return key;
2304 }
2305 } else if (!miniscript::IsTapscript(m_script_ctx)) {
2306 CPubKey pubkey(begin, end);
2307 if (auto pubkey_provider = InferPubkey(pubkey, ParseContext(), *m_in)) {
2308 m_keys.emplace_back();
2309 m_keys.back().push_back(std::move(pubkey_provider));
2310 return key;
2311 }
2312 }
2313 return {};
2314 }
2315
2316 template<typename I> std::optional<Key> FromPKHBytes(I begin, I end) const
2317 {
2318 assert(end - begin == 20);
2319 assert(m_in);
2320 uint160 hash;
2321 std::copy(begin, end, hash.begin());
2322 CKeyID keyid(hash);
2323 CPubKey pubkey;
2324 if (m_in->GetPubKey(keyid, pubkey)) {
2325 if (auto pubkey_provider = InferPubkey(pubkey, ParseContext(), *m_in)) {
2326 Key key = m_keys.size();
2327 m_keys.emplace_back();
2328 m_keys.back().push_back(std::move(pubkey_provider));
2329 return key;
2330 }
2331 }
2332 return {};
2333 }
2334
2335 miniscript::MiniscriptContext MsContext() const {
2336 return m_script_ctx;
2337 }
2338};
2339
2341// NOLINTNEXTLINE(misc-no-recursion)
2342std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
2343{
2344 using namespace script;
2345 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2346 std::vector<std::unique_ptr<DescriptorImpl>> ret;
2347 auto expr = Expr(sp);
2348 if (Func("pk", expr)) {
2349 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2350 if (pubkeys.empty()) {
2351 error = strprintf("pk(): %s", error);
2352 return {};
2353 }
2354 for (auto& pubkey : pubkeys) {
2355 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2356 }
2357 return ret;
2358 }
2359 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && Func("pkh", expr)) {
2360 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2361 if (pubkeys.empty()) {
2362 error = strprintf("pkh(): %s", error);
2363 return {};
2364 }
2365 for (auto& pubkey : pubkeys) {
2366 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2367 }
2368 return ret;
2369 }
2370 if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
2371 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2372 if (pubkeys.empty()) {
2373 error = strprintf("combo(): %s", error);
2374 return {};
2375 }
2376 for (auto& pubkey : pubkeys) {
2377 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2378 }
2379 return ret;
2380 } else if (Func("combo", expr)) {
2381 error = "Can only have combo() at top level";
2382 return {};
2383 }
2384 const bool multi = Func("multi", expr);
2385 const bool sortedmulti = !multi && Func("sortedmulti", expr);
2386 const bool multi_a = !(multi || sortedmulti) && Func("multi_a", expr);
2387 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) && Func("sortedmulti_a", expr);
2388 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2389 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2390 auto threshold = Expr(expr);
2391 uint32_t thres;
2392 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers; // List of multipath expanded pubkeys
2393 if (const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2394 thres = *maybe_thres;
2395 } else {
2396 error = strprintf("Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2397 return {};
2398 }
2399 size_t script_size = 0;
2400 size_t max_providers_len = 0;
2401 while (expr.size()) {
2402 if (!Const(",", expr)) {
2403 error = strprintf("Multi: expected ',', got '%c'", expr[0]);
2404 return {};
2405 }
2406 auto arg = Expr(expr);
2407 auto pks = ParsePubkey(key_exp_index, arg, ctx, out, error);
2408 if (pks.empty()) {
2409 error = strprintf("Multi: %s", error);
2410 return {};
2411 }
2412 script_size += pks.at(0)->GetSize() + 1;
2413 max_providers_len = std::max(max_providers_len, pks.size());
2414 providers.emplace_back(std::move(pks));
2415 }
2416 if ((multi || sortedmulti) && (providers.empty() || providers.size() > MAX_PUBKEYS_PER_MULTISIG)) {
2417 error = strprintf("Cannot have %u keys in multisig; must have between 1 and %d keys, inclusive", providers.size(), MAX_PUBKEYS_PER_MULTISIG);
2418 return {};
2419 } else if ((multi_a || sortedmulti_a) && (providers.empty() || providers.size() > MAX_PUBKEYS_PER_MULTI_A)) {
2420 error = strprintf("Cannot have %u keys in multi_a; must have between 1 and %d keys, inclusive", providers.size(), MAX_PUBKEYS_PER_MULTI_A);
2421 return {};
2422 } else if (thres < 1) {
2423 error = strprintf("Multisig threshold cannot be %d, must be at least 1", thres);
2424 return {};
2425 } else if (thres > providers.size()) {
2426 error = strprintf("Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2427 return {};
2428 }
2429 if (ctx == ParseScriptContext::TOP) {
2430 if (providers.size() > 3) {
2431 error = strprintf("Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2432 return {};
2433 }
2434 }
2435 if (ctx == ParseScriptContext::P2SH) {
2436 // This limits the maximum number of compressed pubkeys to 15.
2437 if (script_size + 3 > MAX_SCRIPT_ELEMENT_SIZE) {
2438 error = strprintf("P2SH script is too large, %d bytes is larger than %d bytes", script_size + 3, MAX_SCRIPT_ELEMENT_SIZE);
2439 return {};
2440 }
2441 }
2442
2443 // Make sure all vecs are of the same length, or exactly length 1
2444 // For length 1 vectors, clone key providers until vector is the same length
2445 for (auto& vec : providers) {
2446 if (vec.size() == 1) {
2447 for (size_t i = 1; i < max_providers_len; ++i) {
2448 vec.emplace_back(vec.at(0)->Clone());
2449 }
2450 } else if (vec.size() != max_providers_len) {
2451 error = strprintf("multi(): Multipath derivation paths have mismatched lengths");
2452 return {};
2453 }
2454 }
2455
2456 // Build the final descriptors vector
2457 for (size_t i = 0; i < max_providers_len; ++i) {
2458 // Build final pubkeys vectors by retrieving the i'th subscript for each vector in subscripts
2459 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2460 pubs.reserve(providers.size());
2461 for (auto& pub : providers) {
2462 pubs.emplace_back(std::move(pub.at(i)));
2463 }
2464 if (multi || sortedmulti) {
2465 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2466 } else {
2467 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2468 }
2469 }
2470 return ret;
2471 } else if (multi || sortedmulti) {
2472 error = "Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2473 return {};
2474 } else if (multi_a || sortedmulti_a) {
2475 error = "Can only have multi_a/sortedmulti_a inside tr()";
2476 return {};
2477 }
2478 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wpkh", expr)) {
2479 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH, out, error);
2480 if (pubkeys.empty()) {
2481 error = strprintf("wpkh(): %s", error);
2482 return {};
2483 }
2484 for (auto& pubkey : pubkeys) {
2485 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2486 }
2487 return ret;
2488 } else if (Func("wpkh", expr)) {
2489 error = "Can only have wpkh() at top level or inside sh()";
2490 return {};
2491 }
2492 if (ctx == ParseScriptContext::TOP && Func("sh", expr)) {
2493 auto descs = ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out, error);
2494 if (descs.empty() || expr.size()) return {};
2495 std::vector<std::unique_ptr<DescriptorImpl>> ret;
2496 ret.reserve(descs.size());
2497 for (auto& desc : descs) {
2498 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2499 }
2500 return ret;
2501 } else if (Func("sh", expr)) {
2502 error = "Can only have sh() at top level";
2503 return {};
2504 }
2505 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wsh", expr)) {
2506 auto descs = ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH, out, error);
2507 if (descs.empty() || expr.size()) return {};
2508 for (auto& desc : descs) {
2509 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2510 }
2511 return ret;
2512 } else if (Func("wsh", expr)) {
2513 error = "Can only have wsh() at top level or inside sh()";
2514 return {};
2515 }
2516 if (ctx == ParseScriptContext::TOP && Func("addr", expr)) {
2517 CTxDestination dest = DecodeDestination(std::string(expr.begin(), expr.end()));
2518 if (!IsValidDestination(dest)) {
2519 error = "Address is not valid";
2520 return {};
2521 }
2522 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2523 return ret;
2524 } else if (Func("addr", expr)) {
2525 error = "Can only have addr() at top level";
2526 return {};
2527 }
2528 if (ctx == ParseScriptContext::TOP && Func("tr", expr)) {
2529 auto arg = Expr(expr);
2530 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error);
2531 if (internal_keys.empty()) {
2532 error = strprintf("tr(): %s", error);
2533 return {};
2534 }
2535 size_t max_providers_len = internal_keys.size();
2536 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2537 std::vector<int> depths;
2538 if (expr.size()) {
2539 if (!Const(",", expr)) {
2540 error = strprintf("tr: expected ',', got '%c'", expr[0]);
2541 return {};
2542 }
2546 std::vector<bool> branches;
2547 // Loop over all provided scripts. In every iteration exactly one script will be processed.
2548 // Use a do-loop because inside this if-branch we expect at least one script.
2549 do {
2550 // First process all open braces.
2551 while (Const("{", expr)) {
2552 branches.push_back(false); // new left branch
2553 if (branches.size() > TAPROOT_CONTROL_MAX_NODE_COUNT) {
2554 error = strprintf("tr() supports at most %i nesting levels", TAPROOT_CONTROL_MAX_NODE_COUNT);
2555 return {};
2556 }
2557 }
2558 // Process the actual script expression.
2559 auto sarg = Expr(expr);
2560 subscripts.emplace_back(ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR, out, error));
2561 if (subscripts.back().empty()) return {};
2562 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2563 depths.push_back(branches.size());
2564 // Process closing braces; one is expected for every right branch we were in.
2565 while (branches.size() && branches.back()) {
2566 if (!Const("}", expr)) {
2567 error = strprintf("tr(): expected '}' after script expression");
2568 return {};
2569 }
2570 branches.pop_back(); // move up one level after encountering '}'
2571 }
2572 // If after that, we're at the end of a left branch, expect a comma.
2573 if (branches.size() && !branches.back()) {
2574 if (!Const(",", expr)) {
2575 error = strprintf("tr(): expected ',' after script expression");
2576 return {};
2577 }
2578 branches.back() = true; // And now we're in a right branch.
2579 }
2580 } while (branches.size());
2581 // After we've explored a whole tree, we must be at the end of the expression.
2582 if (expr.size()) {
2583 error = strprintf("tr(): expected ')' after script expression");
2584 return {};
2585 }
2586 }
2588
2589 // Make sure all vecs are of the same length, or exactly length 1
2590 // For length 1 vectors, clone subdescs until vector is the same length
2591 for (auto& vec : subscripts) {
2592 if (vec.size() == 1) {
2593 for (size_t i = 1; i < max_providers_len; ++i) {
2594 vec.emplace_back(vec.at(0)->Clone());
2595 }
2596 } else if (vec.size() != max_providers_len) {
2597 error = strprintf("tr(): Multipath subscripts have mismatched lengths");
2598 return {};
2599 }
2600 }
2601
2602 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2603 error = strprintf("tr(): Multipath internal key mismatches multipath subscripts lengths");
2604 return {};
2605 }
2606
2607 while (internal_keys.size() < max_providers_len) {
2608 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2609 }
2610
2611 // Build the final descriptors vector
2612 for (size_t i = 0; i < max_providers_len; ++i) {
2613 // Build final subscripts vectors by retrieving the i'th subscript for each vector in subscripts
2614 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2615 this_subs.reserve(subscripts.size());
2616 for (auto& subs : subscripts) {
2617 this_subs.emplace_back(std::move(subs.at(i)));
2618 }
2619 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2620 }
2621 return ret;
2622
2623
2624 } else if (Func("tr", expr)) {
2625 error = "Can only have tr at top level";
2626 return {};
2627 }
2628 if (ctx == ParseScriptContext::TOP && Func("rawtr", expr)) {
2629 auto arg = Expr(expr);
2630 if (expr.size()) {
2631 error = strprintf("rawtr(): only one key expected.");
2632 return {};
2633 }
2634 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error);
2635 if (output_keys.empty()) {
2636 error = strprintf("rawtr(): %s", error);
2637 return {};
2638 }
2639 for (auto& pubkey : output_keys) {
2640 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2641 }
2642 return ret;
2643 } else if (Func("rawtr", expr)) {
2644 error = "Can only have rawtr at top level";
2645 return {};
2646 }
2647 if (ctx == ParseScriptContext::TOP && Func("unused", expr)) {
2648 // Check for only one expression, should not find commas, brackets, or parentheses
2649 auto arg = Expr(expr);
2650 if (expr.size()) {
2651 error = strprintf("unused(): only one key expected");
2652 return {};
2653 }
2654 auto keys = ParsePubkey(key_exp_index, arg, ctx, out, error);
2655 if (keys.empty()) return {};
2656 for (auto& pubkey : keys) {
2657 if (pubkey->IsRange()) {
2658 error = "unused(): key cannot be ranged";
2659 return {};
2660 }
2661 ret.emplace_back(std::make_unique<UnusedDescriptor>(std::move(pubkey)));
2662 }
2663 return ret;
2664 } else if (Func("unused", expr)) {
2665 error = "Can only have unused at top level";
2666 return {};
2667 }
2668 if (ctx == ParseScriptContext::TOP && Func("raw", expr)) {
2669 std::string str(expr.begin(), expr.end());
2670 if (!IsHex(str)) {
2671 error = "Raw script is not hex";
2672 return {};
2673 }
2674 auto bytes = ParseHex(str);
2675 ret.emplace_back(std::make_unique<RawDescriptor>(CScript(bytes.begin(), bytes.end())));
2676 return ret;
2677 } else if (Func("raw", expr)) {
2678 error = "Can only have raw() at top level";
2679 return {};
2680 }
2681 // Process miniscript expressions.
2682 {
2683 const auto script_ctx{ctx == ParseScriptContext::P2WSH ? miniscript::MiniscriptContext::P2WSH : miniscript::MiniscriptContext::TAPSCRIPT};
2684 KeyParser parser(/*out = */&out, /* in = */nullptr, /* ctx = */script_ctx, key_exp_index);
2685 auto node = miniscript::FromString(std::string(expr.begin(), expr.end()), parser);
2686 if (parser.m_key_parsing_error != "") {
2687 error = std::move(parser.m_key_parsing_error);
2688 return {};
2689 }
2690 if (node) {
2691 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2692 error = "Miniscript expressions can only be used in wsh or tr.";
2693 return {};
2694 }
2695 if (!node->IsSane() || node->IsNotSatisfiable()) {
2696 // Try to find the first insane sub for better error reporting.
2697 const auto* insane_node = &node.value();
2698 if (const auto sub = node->FindInsaneSub()) insane_node = sub;
2699 error = *insane_node->ToString(parser);
2700 if (!insane_node->IsValid()) {
2701 error += " is invalid";
2702 } else if (!node->IsSane()) {
2703 error += " is not sane";
2704 if (!insane_node->IsNonMalleable()) {
2705 error += ": malleable witnesses exist";
2706 } else if (insane_node == &node.value() && !insane_node->NeedsSignature()) {
2707 error += ": witnesses without signature exist";
2708 } else if (!insane_node->CheckTimeLocksMix()) {
2709 error += ": contains mixes of timelocks expressed in blocks and seconds";
2710 } else if (!insane_node->CheckDuplicateKey()) {
2711 error += ": contains duplicate public keys";
2712 } else if (!insane_node->ValidSatisfactions()) {
2713 error += ": needs witnesses that may exceed resource limits";
2714 }
2715 } else {
2716 error += " is not satisfiable";
2717 }
2718 return {};
2719 }
2720 // A signature check is required for a miniscript to be sane. Therefore no sane miniscript
2721 // may have an empty list of public keys.
2722 CHECK_NONFATAL(!parser.m_keys.empty());
2723 // Make sure all vecs are of the same length, or exactly length 1
2724 // For length 1 vectors, clone subdescs until vector is the same length
2725 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2726 [](const std::vector<std::unique_ptr<PubkeyProvider>>& a, const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2727 return a.size() < b.size();
2728 })->size();
2729
2730 for (auto& vec : parser.m_keys) {
2731 if (vec.size() == 1) {
2732 for (size_t i = 1; i < num_multipath; ++i) {
2733 vec.emplace_back(vec.at(0)->Clone());
2734 }
2735 } else if (vec.size() != num_multipath) {
2736 error = strprintf("Miniscript: Multipath derivation paths have mismatched lengths");
2737 return {};
2738 }
2739 }
2740
2741 // Build the final descriptors vector
2742 for (size_t i = 0; i < num_multipath; ++i) {
2743 // Build final pubkeys vectors by retrieving the i'th subscript for each vector in subscripts
2744 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2745 pubs.reserve(parser.m_keys.size());
2746 for (auto& pub : parser.m_keys) {
2747 pubs.emplace_back(std::move(pub.at(i)));
2748 }
2749 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs), node->Clone()));
2750 }
2751 return ret;
2752 }
2753 }
2754 if (ctx == ParseScriptContext::P2SH) {
2755 error = "A function is needed within P2SH";
2756 return {};
2757 } else if (ctx == ParseScriptContext::P2WSH) {
2758 error = "A function is needed within P2WSH";
2759 return {};
2760 }
2761 error = strprintf("'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2762 return {};
2763}
2764
2765std::unique_ptr<DescriptorImpl> InferMultiA(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
2766{
2767 auto match = MatchMultiA(script);
2768 if (!match) return {};
2769 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2770 keys.reserve(match->second.size());
2771 for (const auto keyspan : match->second) {
2772 if (keyspan.size() != 32) return {};
2773 auto key = InferXOnlyPubkey(XOnlyPubKey{keyspan}, ctx, provider);
2774 if (!key) return {};
2775 keys.push_back(std::move(key));
2776 }
2777 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
2778}
2779
2780// NOLINTNEXTLINE(misc-no-recursion)
2781std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
2782{
2783 if (ctx == ParseScriptContext::P2TR && script.size() == 34 && script[0] == 32 && script[33] == OP_CHECKSIG) {
2784 XOnlyPubKey key{std::span{script}.subspan(1, 32)};
2785 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider), true);
2786 }
2787
2788 if (ctx == ParseScriptContext::P2TR) {
2789 auto ret = InferMultiA(script, ctx, provider);
2790 if (ret) return ret;
2791 }
2792
2793 std::vector<std::vector<unsigned char>> data;
2794 TxoutType txntype = Solver(script, data);
2795
2796 if (txntype == TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2797 CPubKey pubkey(data[0]);
2798 if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2799 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2800 }
2801 }
2802 if (txntype == TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2803 uint160 hash(data[0]);
2804 CKeyID keyid(hash);
2805 CPubKey pubkey;
2806 if (provider.GetPubKey(keyid, pubkey)) {
2807 if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2808 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2809 }
2810 }
2811 }
2812 if (txntype == TxoutType::WITNESS_V0_KEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH)) {
2813 uint160 hash(data[0]);
2814 CKeyID keyid(hash);
2815 CPubKey pubkey;
2816 if (provider.GetPubKey(keyid, pubkey)) {
2817 if (auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
2818 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2819 }
2820 }
2821 }
2822 if (txntype == TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2823 bool ok = true;
2824 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2825 for (size_t i = 1; i + 1 < data.size(); ++i) {
2826 CPubKey pubkey(data[i]);
2827 if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2828 providers.push_back(std::move(pubkey_provider));
2829 } else {
2830 ok = false;
2831 break;
2832 }
2833 }
2834 if (ok) return std::make_unique<MultisigDescriptor>((int)data[0][0], std::move(providers));
2835 }
2836 if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) {
2837 uint160 hash(data[0]);
2838 CScriptID scriptid(hash);
2839 CScript subscript;
2840 if (provider.GetCScript(scriptid, subscript)) {
2841 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
2842 if (sub) return std::make_unique<SHDescriptor>(std::move(sub));
2843 }
2844 }
2845 if (txntype == TxoutType::WITNESS_V0_SCRIPTHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH)) {
2846 CScriptID scriptid{RIPEMD160(data[0])};
2847 CScript subscript;
2848 if (provider.GetCScript(scriptid, subscript)) {
2849 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
2850 if (sub) return std::make_unique<WSHDescriptor>(std::move(sub));
2851 }
2852 }
2853 if (txntype == TxoutType::WITNESS_V1_TAPROOT && ctx == ParseScriptContext::TOP) {
2854 // Extract x-only pubkey from output.
2855 XOnlyPubKey pubkey;
2856 std::copy(data[0].begin(), data[0].end(), pubkey.begin());
2857 // Request spending data.
2858 TaprootSpendData tap;
2859 if (provider.GetTaprootSpendData(pubkey, tap)) {
2860 // If found, convert it back to tree form.
2861 auto tree = InferTaprootTree(tap, pubkey);
2862 if (tree) {
2863 // If that works, try to infer subdescriptors for all leaves.
2864 bool ok = true;
2865 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2866 std::vector<int> depths;
2867 for (const auto& [depth, script, leaf_ver] : *tree) {
2868 std::unique_ptr<DescriptorImpl> subdesc;
2869 if (leaf_ver == TAPROOT_LEAF_TAPSCRIPT) {
2870 subdesc = InferScript(CScript(script.begin(), script.end()), ParseScriptContext::P2TR, provider);
2871 }
2872 if (!subdesc) {
2873 ok = false;
2874 break;
2875 } else {
2876 subscripts.push_back(std::move(subdesc));
2877 depths.push_back(depth);
2878 }
2879 }
2880 if (ok) {
2881 auto key = InferXOnlyPubkey(tap.internal_key, ParseScriptContext::P2TR, provider);
2882 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2883 }
2884 }
2885 }
2886 // If the above doesn't work, construct a rawtr() descriptor with just the encoded x-only pubkey.
2887 if (pubkey.IsFullyValid()) {
2888 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
2889 if (key) {
2890 return std::make_unique<RawTRDescriptor>(std::move(key));
2891 }
2892 }
2893 }
2894
2895 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2896 const auto script_ctx{ctx == ParseScriptContext::P2WSH ? miniscript::MiniscriptContext::P2WSH : miniscript::MiniscriptContext::TAPSCRIPT};
2897 uint32_t key_exp_index = 0;
2898 KeyParser parser(/* out = */nullptr, /* in = */&provider, /* ctx = */script_ctx, key_exp_index);
2899 auto node = miniscript::FromScript(script, parser);
2900 if (node && node->IsSane()) {
2901 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2902 keys.reserve(parser.m_keys.size());
2903 for (auto& key : parser.m_keys) {
2904 keys.emplace_back(std::move(key.at(0)));
2905 }
2906 return std::make_unique<MiniscriptDescriptor>(std::move(keys), std::move(*node));
2907 }
2908 }
2909
2910 // The following descriptors are all top-level only descriptors.
2911 // So if we are not at the top level, return early.
2912 if (ctx != ParseScriptContext::TOP) return nullptr;
2913
2914 CTxDestination dest;
2915 if (ExtractDestination(script, dest)) {
2916 if (GetScriptForDestination(dest) == script) {
2917 return std::make_unique<AddressDescriptor>(std::move(dest));
2918 }
2919 }
2920
2921 return std::make_unique<RawDescriptor>(script);
2922}
2923
2924
2925} // namespace
2926
2928bool CheckChecksum(std::span<const char>& sp, bool require_checksum, std::string& error, std::string* out_checksum = nullptr)
2929{
2930 auto check_split = Split(sp, '#');
2931 if (check_split.size() > 2) {
2932 error = "Multiple '#' symbols";
2933 return false;
2934 }
2935 if (check_split.size() == 1 && require_checksum){
2936 error = "Missing checksum";
2937 return false;
2938 }
2939 if (check_split.size() == 2) {
2940 if (check_split[1].size() != 8) {
2941 error = strprintf("Expected 8 character checksum, not %u characters", check_split[1].size());
2942 return false;
2943 }
2944 }
2945 auto checksum = DescriptorChecksum(check_split[0]);
2946 if (checksum.empty()) {
2947 error = "Invalid characters in payload";
2948 return false;
2949 }
2950 if (check_split.size() == 2) {
2951 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2952 error = strprintf("Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2953 return false;
2954 }
2955 }
2956 if (out_checksum) *out_checksum = std::move(checksum);
2957 sp = check_split[0];
2958 return true;
2959}
2960
2961std::vector<std::unique_ptr<Descriptor>> Parse(std::string_view descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
2962{
2963 std::span<const char> sp{descriptor};
2964 if (!CheckChecksum(sp, require_checksum, error)) return {};
2965 uint32_t key_exp_index = 0;
2966 auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
2967 if (sp.empty() && !ret.empty()) {
2968 std::vector<std::unique_ptr<Descriptor>> descs;
2969 descs.reserve(ret.size());
2970 for (auto& r : ret) {
2971 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2972 }
2973 return descs;
2974 }
2975 return {};
2976}
2977
2978std::string GetDescriptorChecksum(const std::string& descriptor)
2979{
2980 std::string ret;
2981 std::string error;
2982 std::span<const char> sp{descriptor};
2983 if (!CheckChecksum(sp, false, error, &ret)) return "";
2984 return ret;
2985}
2986
2987std::unique_ptr<Descriptor> InferDescriptor(const CScript& script, const SigningProvider& provider)
2988{
2989 return InferScript(script, ParseScriptContext::TOP, provider);
2990}
2991
2993{
2994 std::string desc_str = desc.ToString(/*compat_format=*/true);
2995 uint256 id;
2996 CSHA256().Write((unsigned char*)desc_str.data(), desc_str.size()).Finalize(id.begin());
2997 return id;
2998}
2999
3000void DescriptorCache::CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
3001{
3002 m_parent_xpubs[key_exp_pos] = xpub;
3003}
3004
3005void DescriptorCache::CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey& xpub)
3006{
3007 auto& xpubs = m_derived_xpubs[key_exp_pos];
3008 xpubs[der_index] = xpub;
3009}
3010
3011void DescriptorCache::CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
3012{
3013 m_last_hardened_xpubs[key_exp_pos] = xpub;
3014}
3015
3016bool DescriptorCache::GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const
3017{
3018 const auto& it = m_parent_xpubs.find(key_exp_pos);
3019 if (it == m_parent_xpubs.end()) return false;
3020 xpub = it->second;
3021 return true;
3022}
3023
3024bool DescriptorCache::GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey& xpub) const
3025{
3026 const auto& key_exp_it = m_derived_xpubs.find(key_exp_pos);
3027 if (key_exp_it == m_derived_xpubs.end()) return false;
3028 const auto& der_it = key_exp_it->second.find(der_index);
3029 if (der_it == key_exp_it->second.end()) return false;
3030 xpub = der_it->second;
3031 return true;
3032}
3033
3035{
3036 const auto& it = m_last_hardened_xpubs.find(key_exp_pos);
3037 if (it == m_last_hardened_xpubs.end()) return false;
3038 xpub = it->second;
3039 return true;
3040}
3041
3043{
3044 DescriptorCache diff;
3045 for (const auto& parent_xpub_pair : other.GetCachedParentExtPubKeys()) {
3046 CExtPubKey xpub;
3047 if (GetCachedParentExtPubKey(parent_xpub_pair.first, xpub)) {
3048 if (xpub != parent_xpub_pair.second) {
3049 throw std::runtime_error(std::string(__func__) + ": New cached parent xpub does not match already cached parent xpub");
3050 }
3051 continue;
3052 }
3053 CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
3054 diff.CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
3055 }
3056 for (const auto& derived_xpub_map_pair : other.GetCachedDerivedExtPubKeys()) {
3057 for (const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
3058 CExtPubKey xpub;
3059 if (GetCachedDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, xpub)) {
3060 if (xpub != derived_xpub_pair.second) {
3061 throw std::runtime_error(std::string(__func__) + ": New cached derived xpub does not match already cached derived xpub");
3062 }
3063 continue;
3064 }
3065 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3066 diff.CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3067 }
3068 }
3069 for (const auto& lh_xpub_pair : other.GetCachedLastHardenedExtPubKeys()) {
3070 CExtPubKey xpub;
3071 if (GetCachedLastHardenedExtPubKey(lh_xpub_pair.first, xpub)) {
3072 if (xpub != lh_xpub_pair.second) {
3073 throw std::runtime_error(std::string(__func__) + ": New cached last hardened xpub does not match already cached last hardened xpub");
3074 }
3075 continue;
3076 }
3077 CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
3078 diff.CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
3079 }
3080 return diff;
3081}
3082
3084{
3085 return m_parent_xpubs;
3086}
3087
3088std::unordered_map<uint32_t, ExtPubKeyMap> DescriptorCache::GetCachedDerivedExtPubKeys() const
3089{
3090 return m_derived_xpubs;
3091}
3092
3094{
3095 return m_last_hardened_xpubs;
3096}
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
Definition: addresstype.cpp:49
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
Definition: addresstype.h:143
#define LIFETIMEBOUND
Definition: attributes.h:16
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
Definition: bip32.cpp:53
int ret
node::NodeContext m_node
Definition: bitcoin-gui.cpp:47
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:112
#define Assert(val)
Identity function.
Definition: check.h:116
#define Assume(val)
Assume is the identity function.
Definition: check.h:128
An encapsulated private key.
Definition: key.h:37
unsigned int size() const
Simple read-only vector-like interface.
Definition: key.h:119
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:125
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
Definition: key.h:128
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:182
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:26
KeyFingerprint fingerprint() const
Definition: pubkey.h:30
An encapsulated public key.
Definition: pubkey.h:40
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:206
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:166
bool IsValid() const
Definition: pubkey.h:191
bool IsValidNonHybrid() const noexcept
Check if a public key is a syntactically valid compressed or uncompressed key.
Definition: pubkey.h:197
A hasher class for SHA-256.
Definition: sha256.h:14
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:725
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:699
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:406
A reference to a CScript: the Hash160 of its serialization.
Definition: script.h:597
Cache for single descriptor's derived extended pubkeys.
Definition: descriptor.h:29
bool GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached parent xpub.
std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
ExtPubKeyMap m_last_hardened_xpubs
Map key expression index -> last hardened xpub.
Definition: descriptor.h:36
void CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey &xpub)
Cache an xpub derived at an index.
DescriptorCache MergeAndDiff(const DescriptorCache &other)
Combine another DescriptorCache into this one.
ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const
Retrieve all cached last hardened xpubs.
void CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a parent xpub.
void CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a last hardened xpub.
bool GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey &xpub) const
Retrieve a cached xpub derived at an index.
std::unordered_map< uint32_t, ExtPubKeyMap > m_derived_xpubs
Map key expression index -> map of (key derivation index -> xpub)
Definition: descriptor.h:32
bool GetCachedLastHardenedExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached last hardened xpub.
ExtPubKeyMap m_parent_xpubs
Map key expression index -> parent xpub.
Definition: descriptor.h:34
An interface to be implemented by keystores that support signing.
bool GetKeyByXOnly(const XOnlyPubKey &pubkey, CKey &key) const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
Utility class to construct Taproot outputs from internal key and script tree.
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
bool IsComplete() const
Return whether there were either no leaves, or the leaves form a Huffman tree.
TaprootBuilder & Add(int depth, std::span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
const unsigned char * begin() const
Definition: pubkey.h:301
static constexpr size_t size()
Definition: pubkey.h:299
CPubKey GetEvenCorrespondingCPubKey() const
Definition: pubkey.cpp:223
bool IsFullyValid() const
Determine if this pubkey is fully valid.
Definition: pubkey.cpp:230
constexpr unsigned char * begin()
Definition: uint256.h:101
A node in a miniscript expression.
Definition: miniscript.h:535
size_type size() const
Definition: prevector.h:247
160-bit opaque blob.
Definition: uint256.h:184
256-bit opaque blob.
Definition: uint256.h:196
static const PrecomputedData data
Precomputed COutPoint and CCoins values.
static const int WITNESS_SCALE_FACTOR
Definition: consensus.h:21
CScript ParseScript(const std::string &s)
Definition: core_io.cpp:92
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:100
uint160 RIPEMD160(std::span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
Definition: hash.h:230
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: hex_base.cpp:30
static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
Definition: interpreter.h:243
static constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT
Definition: interpreter.h:246
std::string EncodeExtKey(const CExtKey &key)
Definition: key_io.cpp:284
CExtPubKey DecodeExtPubKey(const std::string &str)
Definition: key_io.cpp:245
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
Definition: key_io.cpp:300
std::string EncodeSecret(const CKey &key)
Definition: key_io.cpp:232
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:295
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:214
std::string EncodeExtPubKey(const CExtPubKey &key)
Definition: key_io.cpp:258
CExtKey DecodeExtKey(const std::string &str)
Definition: key_io.cpp:268
std::string m_path
CExtPubKey CreateMuSig2SyntheticXpub(const CPubKey &pubkey)
Construct the BIP 328 synthetic xpub for a pubkey.
Definition: musig.cpp:74
std::optional< CPubKey > MuSig2AggregatePubkeys(const std::vector< CPubKey > &pubkeys, secp256k1_musig_keyagg_cache &keyagg_cache, const std::optional< CPubKey > &expected_aggregate)
Compute the full aggregate pubkey from the given participant pubkeys in their current order.
Definition: musig.cpp:57
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
Definition: miniscript.h:259
std::optional< Node< typename Ctx::Key > > FromScript(const CScript &script, const Ctx &ctx)
Definition: miniscript.h:2693
void ForEachNode(const Node< Key > &root, Fn &&fn)
Unordered traversal of a miniscript node tree.
Definition: miniscript.h:199
std::optional< Node< typename Ctx::Key > > FromString(const std::string &str, const Ctx &ctx)
Definition: miniscript.h:2687
@ OLDER
[n] OP_CHECKSEQUENCEVERIFY
Definition: messages.h:22
std::span< const char > Expr(std::span< const char > &sp)
Extract the expression that sp begins with.
Definition: parsing.cpp:31
bool Func(const std::string &str, std::span< const char > &sp)
Parse a function call.
Definition: parsing.cpp:22
bool Const(const std::string &str, std::span< const char > &sp, bool skip)
Parse a constant.
Definition: parsing.cpp:13
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \t")
Definition: subprocess.h:308
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:249
std::vector< T > Split(const std::span< const char > &sp, std::string_view separators, bool include_sep=false)
Split a string on any char found in separators, returning a vector.
Definition: string.h:119
static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)
Definition: spend.cpp:246
static bool IsSegwit(const Descriptor &desc)
Whether the descriptor represents, directly or not, a witness program.
Definition: spend.cpp:49
bool operator<(const CNetAddr &a, const CNetAddr &b)
Definition: netaddress.cpp:608
std::optional< OutputType > OutputTypeFromDestination(const CTxDestination &dest)
Get the OutputType for a CTxDestination.
Definition: outputtype.cpp:80
const char * name
Definition: rest.cpp:56
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
bool CheckChecksum(std::span< const char > &sp, bool require_checksum, std::string &error, std::string *out_checksum=nullptr)
Check a descriptor checksum, and update desc to be the checksum-less part.
std::vector< std::unique_ptr< Descriptor > > Parse(std::string_view descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
Definition: descriptor.h:26
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
Definition: script.h:29
@ OP_CHECKSIG
Definition: script.h:191
@ OP_NUMEQUAL
Definition: script.h:172
@ OP_CHECKSIGADD
Definition: script.h:211
static constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
Definition: script.h:38
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
Definition: script.h:611
static const int MAX_PUBKEYS_PER_MULTISIG
Definition: script.h:35
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:68
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
constexpr unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
Definition: serialize.h:291
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
Definition: sign.cpp:238
std::optional< std::vector< std::tuple< int, std::vector< unsigned char >, int > > > InferTaprootTree(const TaprootSpendData &spenddata, const XOnlyPubKey &output)
Given a TaprootSpendData and the output key, reconstruct its script tree.
const SigningProvider & DUMMY_SIGNING_PROVIDER
void PolyMod(const std::vector< typename F::Elem > &mod, std::vector< typename F::Elem > &val, const F &field)
Compute the remainder of a polynomial division of val by mod, putting the result in mod.
Definition: sketch_impl.h:18
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: solver.cpp:141
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition: solver.cpp:218
std::optional< std::pair< int, std::vector< std::span< const unsigned char > > > > MatchMultiA(const CScript &script)
Definition: solver.cpp:107
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: solver.cpp:213
TxoutType
Definition: solver.h:22
@ WITNESS_V1_TAPROOT
@ WITNESS_V0_SCRIPTHASH
@ WITNESS_V0_KEYHASH
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
Definition: strencodings.h:69
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
Definition: strencodings.h:166
Definition: key.h:229
CExtPubKey Neuter() const
Definition: key.cpp:380
bool Derive(CExtKey &out, unsigned int nChild) const
Definition: key.cpp:359
CKey key
Definition: key.h:234
CPubKey pubkey
Definition: pubkey.h:348
bool Derive(CExtPubKey &out, unsigned int nChild, uint256 *bip32_tweak_out=nullptr) const
Definition: pubkey.cpp:415
Interface for parsed descriptor objects.
Definition: descriptor.h:108
virtual std::optional< int64_t > MaxSatisfactionElems() const =0
Get the maximum size number of stack elements for satisfying this descriptor.
virtual void GetPubKeys(std::set< CPubKey > &pubkeys, std::set< CExtPubKey > &ext_pubs) const =0
Return all (extended) public keys for this descriptor, including any from subdescriptors.
virtual bool ToNormalizedString(const SigningProvider &provider, std::string &out, const DescriptorCache *cache=nullptr) const =0
Convert the descriptor to a normalized string.
virtual std::optional< int64_t > MaxSatisfactionWeight(bool use_max_sig) const =0
Get the maximum size of a satisfaction for this descriptor, in weight units.
virtual std::vector< std::string > Warnings() const =0
Semantic/safety warnings (includes subdescriptors).
virtual std::string ToString(bool compat_format=false) const =0
Convert the descriptor back to a string, undoing parsing.
virtual std::optional< OutputType > GetOutputType() const =0
virtual bool HasScripts() const =0
Whether this descriptor produces any scripts with the Expand functions.
virtual bool Expand(int pos, const SigningProvider &provider, std::vector< CScript > &output_scripts, FlatSigningProvider &out, DescriptorCache *write_cache=nullptr) const =0
Expand a descriptor at a specified position.
virtual bool IsRange() const =0
Whether the expansion of this descriptor depends on the position.
virtual std::optional< int64_t > ScriptSize() const =0
Get the size of the scriptPubKey for this descriptor.
virtual bool IsSolvable() const =0
Whether this descriptor has all information about signing ignoring lack of private keys.
virtual void ExpandPrivate(int pos, const SigningProvider &provider, FlatSigningProvider &out) const =0
Expand the private key for a descriptor at a specified position, if possible.
virtual uint32_t GetMaxKeyExpr() const =0
Get the maximum key expression index.
virtual bool ToPrivateString(const SigningProvider &provider, std::string &out) const =0
Convert the descriptor to a private string.
virtual bool HavePrivateKeys(const SigningProvider &provider) const =0
Whether the given provider has all private keys required by this descriptor.
virtual bool ExpandFromCache(int pos, const DescriptorCache &read_cache, std::vector< CScript > &output_scripts, FlatSigningProvider &out) const =0
Expand a descriptor at a specified position using cached expansion data.
bool GetPubKey(const CKeyID &keyid, CPubKey &pubkey) const override
std::map< CKeyID, CKey > keys
KeyFingerprint fingerprint
First 32 bits of the Hash160 of the public key at the root of the path.
Definition: keyorigin.h:14
std::vector< uint32_t > path
Definition: keyorigin.h:15
XOnlyPubKey internal_key
The BIP341 internal key.
std::vector< uint16_t > keys
Definition: dbwrapper.cpp:376
FuzzedDataProvider provider
Definition: dbwrapper.cpp:366
static int count
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172
consteval auto _(util::TranslatedLiteral str)
Definition: translation.h:79
bool IsHex(std::string_view str)
assert(!tx.IsCoinBase())
std::vector< std::common_type_t< Args... > > Vector(Args &&... args)
Construct a vector with the specified elements.
Definition: vector.h:23