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