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