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