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