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