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