Bitcoin Core 28.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
descriptor.cpp
Go to the documentation of this file.
1// Copyright (c) 2018-2022 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 <script/miniscript.h>
11#include <script/parsing.h>
12#include <script/script.h>
14#include <script/solver.h>
15#include <uint256.h>
16
17#include <common/args.h>
18#include <span.h>
19#include <util/bip32.h>
20#include <util/check.h>
21#include <util/strencodings.h>
22#include <util/vector.h>
23
24#include <memory>
25#include <numeric>
26#include <optional>
27#include <string>
28#include <vector>
29
30using util::Split;
31
32namespace {
33
35// Checksum //
37
38// This section implements a checksum algorithm for descriptors with the
39// following properties:
40// * Mistakes in a descriptor string are measured in "symbol errors". The higher
41// the number of symbol errors, the harder it is to detect:
42// * An error substituting a character from 0123456789()[],'/*abcdefgh@:$%{} for
43// another in that set always counts as 1 symbol error.
44// * Note that hex encoded keys are covered by these characters. Xprvs and
45// xpubs use other characters too, but already have their own checksum
46// mechanism.
47// * Function names like "multi()" use other characters, but mistakes in
48// these would generally result in an unparsable descriptor.
49// * A case error always counts as 1 symbol error.
50// * Any other 1 character substitution error counts as 1 or 2 symbol errors.
51// * Any 1 symbol error is always detected.
52// * Any 2 or 3 symbol error in a descriptor of up to 49154 characters is always detected.
53// * Any 4 symbol error in a descriptor of up to 507 characters is always detected.
54// * Any 5 symbol error in a descriptor of up to 77 characters is always detected.
55// * Is optimized to minimize the chance a 5 symbol error in a descriptor up to 387 characters is undetected
56// * Random errors have a chance of 1 in 2**40 of being undetected.
57//
58// These properties are achieved by expanding every group of 3 (non checksum) characters into
59// 4 GF(32) symbols, over which a cyclic code is defined.
60
61/*
62 * Interprets c as 8 groups of 5 bits which are the coefficients of a degree 8 polynomial over GF(32),
63 * multiplies that polynomial by x, computes its remainder modulo a generator, and adds the constant term val.
64 *
65 * 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}.
66 * It is chosen to define an cyclic error detecting code which is selected by:
67 * - Starting from all BCH codes over GF(32) of degree 8 and below, which by construction guarantee detecting
68 * 3 errors in windows up to 19000 symbols.
69 * - Taking all those generators, and for degree 7 ones, extend them to degree 8 by adding all degree-1 factors.
70 * - Selecting just the set of generators that guarantee detecting 4 errors in a window of length 512.
71 * - Selecting one of those with best worst-case behavior for 5 errors in windows of length up to 512.
72 *
73 * The generator and the constants to implement it can be verified using this Sage code:
74 * B = GF(2) # Binary field
75 * BP.<b> = B[] # Polynomials over the binary field
76 * F_mod = b**5 + b**3 + 1
77 * F.<f> = GF(32, modulus=F_mod, repr='int') # GF(32) definition
78 * FP.<x> = F[] # Polynomials over GF(32)
79 * E_mod = x**3 + x + F.fetch_int(8)
80 * E.<e> = F.extension(E_mod) # Extension field definition
81 * alpha = e**2743 # Choice of an element in extension field
82 * for p in divisors(E.order() - 1): # Verify alpha has order 32767.
83 * assert((alpha**p == 1) == (p % 32767 == 0))
84 * G = lcm([(alpha**i).minpoly() for i in [1056,1057,1058]] + [x + 1])
85 * print(G) # Print out the generator
86 * for i in [1,2,4,8,16]: # Print out {1,2,4,8,16}*(G mod x^8), packed in hex integers.
87 * v = 0
88 * for coef in reversed((F.fetch_int(i)*(G % x**8)).coefficients(sparse=True)):
89 * v = v*32 + coef.integer_representation()
90 * print("0x%x" % v)
91 */
92uint64_t PolyMod(uint64_t c, int val)
93{
94 uint8_t c0 = c >> 35;
95 c = ((c & 0x7ffffffff) << 5) ^ val;
96 if (c0 & 1) c ^= 0xf5dee51989;
97 if (c0 & 2) c ^= 0xa9fdca3312;
98 if (c0 & 4) c ^= 0x1bab10e32d;
99 if (c0 & 8) c ^= 0x3706b1677a;
100 if (c0 & 16) c ^= 0x644d626ffd;
101 return c;
102}
103
104std::string DescriptorChecksum(const Span<const char>& span)
105{
119 static const std::string INPUT_CHARSET =
120 "0123456789()[],'/*abcdefgh@:$%{}"
121 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
122 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
123
125 static const std::string CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
126
127 uint64_t c = 1;
128 int cls = 0;
129 int clscount = 0;
130 for (auto ch : span) {
131 auto pos = INPUT_CHARSET.find(ch);
132 if (pos == std::string::npos) return "";
133 c = PolyMod(c, pos & 31); // Emit a symbol for the position inside the group, for every character.
134 cls = cls * 3 + (pos >> 5); // Accumulate the group numbers
135 if (++clscount == 3) {
136 // Emit an extra symbol representing the group numbers, for every 3 characters.
137 c = PolyMod(c, cls);
138 cls = 0;
139 clscount = 0;
140 }
141 }
142 if (clscount > 0) c = PolyMod(c, cls);
143 for (int j = 0; j < 8; ++j) c = PolyMod(c, 0); // Shift further to determine the checksum.
144 c ^= 1; // Prevent appending zeroes from not affecting the checksum.
145
146 std::string ret(8, ' ');
147 for (int j = 0; j < 8; ++j) ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
148 return ret;
149}
150
151std::string AddChecksum(const std::string& str) { return str + "#" + DescriptorChecksum(str); }
152
154// Internal representation //
156
157typedef std::vector<uint32_t> KeyPath;
158
160struct PubkeyProvider
161{
162protected:
165 uint32_t m_expr_index;
166
167public:
168 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
169
170 virtual ~PubkeyProvider() = default;
171
175 bool operator<(PubkeyProvider& other) const {
176 CPubKey a, b;
177 SigningProvider dummy;
178 KeyOriginInfo dummy_info;
179
180 GetPubKey(0, dummy, a, dummy_info);
181 other.GetPubKey(0, dummy, b, dummy_info);
182
183 return a < b;
184 }
185
191 virtual bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const = 0;
192
194 virtual bool IsRange() const = 0;
195
197 virtual size_t GetSize() const = 0;
198
199 enum class StringType {
200 PUBLIC,
201 COMPAT // string calculation that mustn't change over time to stay compatible with previous software versions
202 };
203
205 virtual std::string ToString(StringType type=StringType::PUBLIC) const = 0;
206
208 virtual bool ToPrivateString(const SigningProvider& arg, std::string& out) const = 0;
209
213 virtual bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache = nullptr) const = 0;
214
216 virtual bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const = 0;
217
219 virtual std::optional<CPubKey> GetRootPubKey() const = 0;
221 virtual std::optional<CExtPubKey> GetRootExtPubKey() const = 0;
222};
223
224class OriginPubkeyProvider final : public PubkeyProvider
225{
226 KeyOriginInfo m_origin;
227 std::unique_ptr<PubkeyProvider> m_provider;
228 bool m_apostrophe;
229
230 std::string OriginString(StringType type, bool normalized=false) const
231 {
232 // If StringType==COMPAT, always use the apostrophe to stay compatible with previous versions
233 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
234 return HexStr(m_origin.fingerprint) + FormatHDKeypath(m_origin.path, use_apostrophe);
235 }
236
237public:
238 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) {}
239 bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
240 {
241 if (!m_provider->GetPubKey(pos, arg, key, info, read_cache, write_cache)) return false;
242 std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), info.fingerprint);
243 info.path.insert(info.path.begin(), m_origin.path.begin(), m_origin.path.end());
244 return true;
245 }
246 bool IsRange() const override { return m_provider->IsRange(); }
247 size_t GetSize() const override { return m_provider->GetSize(); }
248 std::string ToString(StringType type) const override { return "[" + OriginString(type) + "]" + m_provider->ToString(type); }
249 bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
250 {
251 std::string sub;
252 if (!m_provider->ToPrivateString(arg, sub)) return false;
253 ret = "[" + OriginString(StringType::PUBLIC) + "]" + std::move(sub);
254 return true;
255 }
256 bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
257 {
258 std::string sub;
259 if (!m_provider->ToNormalizedString(arg, sub, cache)) return false;
260 // If m_provider is a BIP32PubkeyProvider, we may get a string formatted like a OriginPubkeyProvider
261 // In that case, we need to strip out the leading square bracket and fingerprint from the substring,
262 // and append that to our own origin string.
263 if (sub[0] == '[') {
264 sub = sub.substr(9);
265 ret = "[" + OriginString(StringType::PUBLIC, /*normalized=*/true) + std::move(sub);
266 } else {
267 ret = "[" + OriginString(StringType::PUBLIC, /*normalized=*/true) + "]" + std::move(sub);
268 }
269 return true;
270 }
271 bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
272 {
273 return m_provider->GetPrivKey(pos, arg, key);
274 }
275 std::optional<CPubKey> GetRootPubKey() const override
276 {
277 return m_provider->GetRootPubKey();
278 }
279 std::optional<CExtPubKey> GetRootExtPubKey() const override
280 {
281 return m_provider->GetRootExtPubKey();
282 }
283};
284
286class ConstPubkeyProvider final : public PubkeyProvider
287{
288 CPubKey m_pubkey;
289 bool m_xonly;
290
291public:
292 ConstPubkeyProvider(uint32_t exp_index, const CPubKey& pubkey, bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
293 bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
294 {
295 key = m_pubkey;
296 info.path.clear();
297 CKeyID keyid = m_pubkey.GetID();
298 std::copy(keyid.begin(), keyid.begin() + sizeof(info.fingerprint), info.fingerprint);
299 return true;
300 }
301 bool IsRange() const override { return false; }
302 size_t GetSize() const override { return m_pubkey.size(); }
303 std::string ToString(StringType type) const override { return m_xonly ? HexStr(m_pubkey).substr(2) : HexStr(m_pubkey); }
304 bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
305 {
306 CKey key;
307 if (m_xonly) {
308 for (const auto& keyid : XOnlyPubKey(m_pubkey).GetKeyIDs()) {
309 arg.GetKey(keyid, key);
310 if (key.IsValid()) break;
311 }
312 } else {
313 arg.GetKey(m_pubkey.GetID(), key);
314 }
315 if (!key.IsValid()) return false;
316 ret = EncodeSecret(key);
317 return true;
318 }
319 bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
320 {
321 ret = ToString(StringType::PUBLIC);
322 return true;
323 }
324 bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
325 {
326 return arg.GetKey(m_pubkey.GetID(), key);
327 }
328 std::optional<CPubKey> GetRootPubKey() const override
329 {
330 return m_pubkey;
331 }
332 std::optional<CExtPubKey> GetRootExtPubKey() const override
333 {
334 return std::nullopt;
335 }
336};
337
338enum class DeriveType {
339 NO,
340 UNHARDENED,
341 HARDENED,
342};
343
345class BIP32PubkeyProvider final : public PubkeyProvider
346{
347 // Root xpub, path, and final derivation step type being used, if any
348 CExtPubKey m_root_extkey;
349 KeyPath m_path;
350 DeriveType m_derive;
351 // Whether ' or h is used in harded derivation
352 bool m_apostrophe;
353
354 bool GetExtKey(const SigningProvider& arg, CExtKey& ret) const
355 {
356 CKey key;
357 if (!arg.GetKey(m_root_extkey.pubkey.GetID(), key)) return false;
358 ret.nDepth = m_root_extkey.nDepth;
359 std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint + sizeof(ret.vchFingerprint), ret.vchFingerprint);
360 ret.nChild = m_root_extkey.nChild;
361 ret.chaincode = m_root_extkey.chaincode;
362 ret.key = key;
363 return true;
364 }
365
366 // Derives the last xprv
367 bool GetDerivedExtKey(const SigningProvider& arg, CExtKey& xprv, CExtKey& last_hardened) const
368 {
369 if (!GetExtKey(arg, xprv)) return false;
370 for (auto entry : m_path) {
371 if (!xprv.Derive(xprv, entry)) return false;
372 if (entry >> 31) {
373 last_hardened = xprv;
374 }
375 }
376 return true;
377 }
378
379 bool IsHardened() const
380 {
381 if (m_derive == DeriveType::HARDENED) return true;
382 for (auto entry : m_path) {
383 if (entry >> 31) return true;
384 }
385 return false;
386 }
387
388public:
389 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) {}
390 bool IsRange() const override { return m_derive != DeriveType::NO; }
391 size_t GetSize() const override { return 33; }
392 bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key_out, KeyOriginInfo& final_info_out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
393 {
394 // Info of parent of the to be derived pubkey
395 KeyOriginInfo parent_info;
396 CKeyID keyid = m_root_extkey.pubkey.GetID();
397 std::copy(keyid.begin(), keyid.begin() + sizeof(parent_info.fingerprint), parent_info.fingerprint);
398 parent_info.path = m_path;
399
400 // Info of the derived key itself which is copied out upon successful completion
401 KeyOriginInfo final_info_out_tmp = parent_info;
402 if (m_derive == DeriveType::UNHARDENED) final_info_out_tmp.path.push_back((uint32_t)pos);
403 if (m_derive == DeriveType::HARDENED) final_info_out_tmp.path.push_back(((uint32_t)pos) | 0x80000000L);
404
405 // Derive keys or fetch them from cache
406 CExtPubKey final_extkey = m_root_extkey;
407 CExtPubKey parent_extkey = m_root_extkey;
408 CExtPubKey last_hardened_extkey;
409 bool der = true;
410 if (read_cache) {
411 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
412 if (m_derive == DeriveType::HARDENED) return false;
413 // Try to get the derivation parent
414 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey)) return false;
415 final_extkey = parent_extkey;
416 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
417 }
418 } else if (IsHardened()) {
419 CExtKey xprv;
420 CExtKey lh_xprv;
421 if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return false;
422 parent_extkey = xprv.Neuter();
423 if (m_derive == DeriveType::UNHARDENED) der = xprv.Derive(xprv, pos);
424 if (m_derive == DeriveType::HARDENED) der = xprv.Derive(xprv, pos | 0x80000000UL);
425 final_extkey = xprv.Neuter();
426 if (lh_xprv.key.IsValid()) {
427 last_hardened_extkey = lh_xprv.Neuter();
428 }
429 } else {
430 for (auto entry : m_path) {
431 if (!parent_extkey.Derive(parent_extkey, entry)) return false;
432 }
433 final_extkey = parent_extkey;
434 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
435 assert(m_derive != DeriveType::HARDENED);
436 }
437 if (!der) return false;
438
439 final_info_out = final_info_out_tmp;
440 key_out = final_extkey.pubkey;
441
442 if (write_cache) {
443 // Only cache parent if there is any unhardened derivation
444 if (m_derive != DeriveType::HARDENED) {
445 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
446 // Cache last hardened xpub if we have it
447 if (last_hardened_extkey.pubkey.IsValid()) {
448 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
449 }
450 } else if (final_info_out.path.size() > 0) {
451 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
452 }
453 }
454
455 return true;
456 }
457 std::string ToString(StringType type, bool normalized) const
458 {
459 // If StringType==COMPAT, always use the apostrophe to stay compatible with previous versions
460 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
461 std::string ret = EncodeExtPubKey(m_root_extkey) + FormatHDKeypath(m_path, /*apostrophe=*/use_apostrophe);
462 if (IsRange()) {
463 ret += "/*";
464 if (m_derive == DeriveType::HARDENED) ret += use_apostrophe ? '\'' : 'h';
465 }
466 return ret;
467 }
468 std::string ToString(StringType type=StringType::PUBLIC) const override
469 {
470 return ToString(type, /*normalized=*/false);
471 }
472 bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
473 {
474 CExtKey key;
475 if (!GetExtKey(arg, key)) return false;
476 out = EncodeExtKey(key) + FormatHDKeypath(m_path, /*apostrophe=*/m_apostrophe);
477 if (IsRange()) {
478 out += "/*";
479 if (m_derive == DeriveType::HARDENED) out += m_apostrophe ? '\'' : 'h';
480 }
481 return true;
482 }
483 bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override
484 {
485 if (m_derive == DeriveType::HARDENED) {
486 out = ToString(StringType::PUBLIC, /*normalized=*/true);
487
488 return true;
489 }
490 // Step backwards to find the last hardened step in the path
491 int i = (int)m_path.size() - 1;
492 for (; i >= 0; --i) {
493 if (m_path.at(i) >> 31) {
494 break;
495 }
496 }
497 // Either no derivation or all unhardened derivation
498 if (i == -1) {
499 out = ToString();
500 return true;
501 }
502 // Get the path to the last hardened stup
503 KeyOriginInfo origin;
504 int k = 0;
505 for (; k <= i; ++k) {
506 // Add to the path
507 origin.path.push_back(m_path.at(k));
508 }
509 // Build the remaining path
510 KeyPath end_path;
511 for (; k < (int)m_path.size(); ++k) {
512 end_path.push_back(m_path.at(k));
513 }
514 // Get the fingerprint
515 CKeyID id = m_root_extkey.pubkey.GetID();
516 std::copy(id.begin(), id.begin() + 4, origin.fingerprint);
517
518 CExtPubKey xpub;
519 CExtKey lh_xprv;
520 // If we have the cache, just get the parent xpub
521 if (cache != nullptr) {
522 cache->GetCachedLastHardenedExtPubKey(m_expr_index, xpub);
523 }
524 if (!xpub.pubkey.IsValid()) {
525 // Cache miss, or nor cache, or need privkey
526 CExtKey xprv;
527 if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return false;
528 xpub = lh_xprv.Neuter();
529 }
530 assert(xpub.pubkey.IsValid());
531
532 // Build the string
533 std::string origin_str = HexStr(origin.fingerprint) + FormatHDKeypath(origin.path);
534 out = "[" + origin_str + "]" + EncodeExtPubKey(xpub) + FormatHDKeypath(end_path);
535 if (IsRange()) {
536 out += "/*";
537 assert(m_derive == DeriveType::UNHARDENED);
538 }
539 return true;
540 }
541 bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
542 {
543 CExtKey extkey;
544 CExtKey dummy;
545 if (!GetDerivedExtKey(arg, extkey, dummy)) return false;
546 if (m_derive == DeriveType::UNHARDENED && !extkey.Derive(extkey, pos)) return false;
547 if (m_derive == DeriveType::HARDENED && !extkey.Derive(extkey, pos | 0x80000000UL)) return false;
548 key = extkey.key;
549 return true;
550 }
551 std::optional<CPubKey> GetRootPubKey() const override
552 {
553 return std::nullopt;
554 }
555 std::optional<CExtPubKey> GetRootExtPubKey() const override
556 {
557 return m_root_extkey;
558 }
559};
560
562class DescriptorImpl : public Descriptor
563{
564protected:
566 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
568 const std::string m_name;
569
574 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
575
577 virtual std::string ToStringExtra() const { return ""; }
578
589 virtual std::vector<CScript> MakeScripts(const std::vector<CPubKey>& pubkeys, Span<const CScript> scripts, FlatSigningProvider& out) const = 0;
590
591public:
592 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args() {}
593 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))) {}
594 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)) {}
595
596 enum class StringType
597 {
598 PUBLIC,
599 PRIVATE,
600 NORMALIZED,
601 COMPAT, // string calculation that mustn't change over time to stay compatible with previous software versions
602 };
603
604 // NOLINTNEXTLINE(misc-no-recursion)
605 bool IsSolvable() const override
606 {
607 for (const auto& arg : m_subdescriptor_args) {
608 if (!arg->IsSolvable()) return false;
609 }
610 return true;
611 }
612
613 // NOLINTNEXTLINE(misc-no-recursion)
614 bool IsRange() const final
615 {
616 for (const auto& pubkey : m_pubkey_args) {
617 if (pubkey->IsRange()) return true;
618 }
619 for (const auto& arg : m_subdescriptor_args) {
620 if (arg->IsRange()) return true;
621 }
622 return false;
623 }
624
625 // NOLINTNEXTLINE(misc-no-recursion)
626 virtual bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const
627 {
628 size_t pos = 0;
629 for (const auto& scriptarg : m_subdescriptor_args) {
630 if (pos++) ret += ",";
631 std::string tmp;
632 if (!scriptarg->ToStringHelper(arg, tmp, type, cache)) return false;
633 ret += tmp;
634 }
635 return true;
636 }
637
638 // NOLINTNEXTLINE(misc-no-recursion)
639 virtual bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type, const DescriptorCache* cache = nullptr) const
640 {
641 std::string extra = ToStringExtra();
642 size_t pos = extra.size() > 0 ? 1 : 0;
643 std::string ret = m_name + "(" + extra;
644 for (const auto& pubkey : m_pubkey_args) {
645 if (pos++) ret += ",";
646 std::string tmp;
647 switch (type) {
648 case StringType::NORMALIZED:
649 if (!pubkey->ToNormalizedString(*arg, tmp, cache)) return false;
650 break;
651 case StringType::PRIVATE:
652 if (!pubkey->ToPrivateString(*arg, tmp)) return false;
653 break;
654 case StringType::PUBLIC:
655 tmp = pubkey->ToString();
656 break;
657 case StringType::COMPAT:
658 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
659 break;
660 }
661 ret += tmp;
662 }
663 std::string subscript;
664 if (!ToStringSubScriptHelper(arg, subscript, type, cache)) return false;
665 if (pos && subscript.size()) ret += ',';
666 out = std::move(ret) + std::move(subscript) + ")";
667 return true;
668 }
669
670 std::string ToString(bool compat_format) const final
671 {
672 std::string ret;
673 ToStringHelper(nullptr, ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
674 return AddChecksum(ret);
675 }
676
677 bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
678 {
679 bool ret = ToStringHelper(&arg, out, StringType::PRIVATE);
680 out = AddChecksum(out);
681 return ret;
682 }
683
684 bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override final
685 {
686 bool ret = ToStringHelper(&arg, out, StringType::NORMALIZED, cache);
687 out = AddChecksum(out);
688 return ret;
689 }
690
691 // NOLINTNEXTLINE(misc-no-recursion)
692 bool ExpandHelper(int pos, const SigningProvider& arg, const DescriptorCache* read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache) const
693 {
694 std::vector<std::pair<CPubKey, KeyOriginInfo>> entries;
695 entries.reserve(m_pubkey_args.size());
696
697 // Construct temporary data in `entries`, `subscripts`, and `subprovider` to avoid producing output in case of failure.
698 for (const auto& p : m_pubkey_args) {
699 entries.emplace_back();
700 if (!p->GetPubKey(pos, arg, entries.back().first, entries.back().second, read_cache, write_cache)) return false;
701 }
702 std::vector<CScript> subscripts;
703 FlatSigningProvider subprovider;
704 for (const auto& subarg : m_subdescriptor_args) {
705 std::vector<CScript> outscripts;
706 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache)) return false;
707 assert(outscripts.size() == 1);
708 subscripts.emplace_back(std::move(outscripts[0]));
709 }
710 out.Merge(std::move(subprovider));
711
712 std::vector<CPubKey> pubkeys;
713 pubkeys.reserve(entries.size());
714 for (auto& entry : entries) {
715 pubkeys.push_back(entry.first);
716 out.origins.emplace(entry.first.GetID(), std::make_pair<CPubKey, KeyOriginInfo>(CPubKey(entry.first), std::move(entry.second)));
717 }
718
719 output_scripts = MakeScripts(pubkeys, Span{subscripts}, out);
720 return true;
721 }
722
723 bool Expand(int pos, const SigningProvider& provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache = nullptr) const final
724 {
725 return ExpandHelper(pos, provider, nullptr, output_scripts, out, write_cache);
726 }
727
728 bool ExpandFromCache(int pos, const DescriptorCache& read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const final
729 {
730 return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &read_cache, output_scripts, out, nullptr);
731 }
732
733 // NOLINTNEXTLINE(misc-no-recursion)
734 void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const final
735 {
736 for (const auto& p : m_pubkey_args) {
737 CKey key;
738 if (!p->GetPrivKey(pos, provider, key)) continue;
739 out.keys.emplace(key.GetPubKey().GetID(), key);
740 }
741 for (const auto& arg : m_subdescriptor_args) {
742 arg->ExpandPrivate(pos, provider, out);
743 }
744 }
745
746 std::optional<OutputType> GetOutputType() const override { return std::nullopt; }
747
748 std::optional<int64_t> ScriptSize() const override { return {}; }
749
755 virtual std::optional<int64_t> MaxSatSize(bool use_max_sig) const { return {}; }
756
757 std::optional<int64_t> MaxSatisfactionWeight(bool) const override { return {}; }
758
759 std::optional<int64_t> MaxSatisfactionElems() const override { return {}; }
760
761 // NOLINTNEXTLINE(misc-no-recursion)
762 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs) const override
763 {
764 for (const auto& p : m_pubkey_args) {
765 std::optional<CPubKey> pub = p->GetRootPubKey();
766 if (pub) pubkeys.insert(*pub);
767 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
768 if (ext_pub) ext_pubs.insert(*ext_pub);
769 }
770 for (const auto& arg : m_subdescriptor_args) {
771 arg->GetPubKeys(pubkeys, ext_pubs);
772 }
773 }
774};
775
777class AddressDescriptor final : public DescriptorImpl
778{
779 const CTxDestination m_destination;
780protected:
781 std::string ToStringExtra() const override { return EncodeDestination(m_destination); }
782 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript>, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(m_destination)); }
783public:
784 AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, "addr"), m_destination(std::move(destination)) {}
785 bool IsSolvable() const final { return false; }
786
787 std::optional<OutputType> GetOutputType() const override
788 {
789 return OutputTypeFromDestination(m_destination);
790 }
791 bool IsSingleType() const final { return true; }
792 bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; }
793
794 std::optional<int64_t> ScriptSize() const override { return GetScriptForDestination(m_destination).size(); }
795};
796
798class RawDescriptor final : public DescriptorImpl
799{
800 const CScript m_script;
801protected:
802 std::string ToStringExtra() const override { return HexStr(m_script); }
803 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript>, FlatSigningProvider&) const override { return Vector(m_script); }
804public:
805 RawDescriptor(CScript script) : DescriptorImpl({}, "raw"), m_script(std::move(script)) {}
806 bool IsSolvable() const final { return false; }
807
808 std::optional<OutputType> GetOutputType() const override
809 {
810 CTxDestination dest;
811 ExtractDestination(m_script, dest);
812 return OutputTypeFromDestination(dest);
813 }
814 bool IsSingleType() const final { return true; }
815 bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; }
816
817 std::optional<int64_t> ScriptSize() const override { return m_script.size(); }
818};
819
821class PKDescriptor final : public DescriptorImpl
822{
823private:
824 const bool m_xonly;
825protected:
826 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider&) const override
827 {
828 if (m_xonly) {
830 return Vector(std::move(script));
831 } else {
832 return Vector(GetScriptForRawPubKey(keys[0]));
833 }
834 }
835public:
836 PKDescriptor(std::unique_ptr<PubkeyProvider> prov, bool xonly = false) : DescriptorImpl(Vector(std::move(prov)), "pk"), m_xonly(xonly) {}
837 bool IsSingleType() const final { return true; }
838
839 std::optional<int64_t> ScriptSize() const override {
840 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
841 }
842
843 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
844 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
845 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
846 }
847
848 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
849 return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;
850 }
851
852 std::optional<int64_t> MaxSatisfactionElems() const override { return 1; }
853};
854
856class PKHDescriptor final : public DescriptorImpl
857{
858protected:
859 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider& out) const override
860 {
861 CKeyID id = keys[0].GetID();
862 out.pubkeys.emplace(id, keys[0]);
864 }
865public:
866 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "pkh") {}
867 std::optional<OutputType> GetOutputType() const override { return OutputType::LEGACY; }
868 bool IsSingleType() const final { return true; }
869
870 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 1 + 20 + 1 + 1; }
871
872 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
873 const auto sig_size = use_max_sig ? 72 : 71;
874 return 1 + sig_size + 1 + m_pubkey_args[0]->GetSize();
875 }
876
877 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
878 return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;
879 }
880
881 std::optional<int64_t> MaxSatisfactionElems() const override { return 2; }
882};
883
885class WPKHDescriptor final : public DescriptorImpl
886{
887protected:
888 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider& out) const override
889 {
890 CKeyID id = keys[0].GetID();
891 out.pubkeys.emplace(id, keys[0]);
893 }
894public:
895 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "wpkh") {}
896 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
897 bool IsSingleType() const final { return true; }
898
899 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 20; }
900
901 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
902 const auto sig_size = use_max_sig ? 72 : 71;
903 return (1 + sig_size + 1 + 33);
904 }
905
906 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
907 return MaxSatSize(use_max_sig);
908 }
909
910 std::optional<int64_t> MaxSatisfactionElems() const override { return 2; }
911};
912
914class ComboDescriptor final : public DescriptorImpl
915{
916protected:
917 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider& out) const override
918 {
919 std::vector<CScript> ret;
920 CKeyID id = keys[0].GetID();
921 out.pubkeys.emplace(id, keys[0]);
922 ret.emplace_back(GetScriptForRawPubKey(keys[0])); // P2PK
923 ret.emplace_back(GetScriptForDestination(PKHash(id))); // P2PKH
924 if (keys[0].IsCompressed()) {
926 out.scripts.emplace(CScriptID(p2wpkh), p2wpkh);
927 ret.emplace_back(p2wpkh);
928 ret.emplace_back(GetScriptForDestination(ScriptHash(p2wpkh))); // P2SH-P2WPKH
929 }
930 return ret;
931 }
932public:
933 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "combo") {}
934 bool IsSingleType() const final { return false; }
935};
936
938class MultisigDescriptor final : public DescriptorImpl
939{
940 const int m_threshold;
941 const bool m_sorted;
942protected:
943 std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
944 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider&) const override {
945 if (m_sorted) {
946 std::vector<CPubKey> sorted_keys(keys);
947 std::sort(sorted_keys.begin(), sorted_keys.end());
948 return Vector(GetScriptForMultisig(m_threshold, sorted_keys));
949 }
950 return Vector(GetScriptForMultisig(m_threshold, keys));
951 }
952public:
953 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) {}
954 bool IsSingleType() const final { return true; }
955
956 std::optional<int64_t> ScriptSize() const override {
957 const auto n_keys = m_pubkey_args.size();
958 auto op = [](int64_t acc, const std::unique_ptr<PubkeyProvider>& pk) { return acc + 1 + pk->GetSize();};
959 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
960 return 1 + BuildScript(n_keys).size() + BuildScript(m_threshold).size() + pubkeys_size;
961 }
962
963 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
964 const auto sig_size = use_max_sig ? 72 : 71;
965 return (1 + (1 + sig_size) * m_threshold);
966 }
967
968 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
969 return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;
970 }
971
972 std::optional<int64_t> MaxSatisfactionElems() const override { return 1 + m_threshold; }
973};
974
976class MultiADescriptor final : public DescriptorImpl
977{
978 const int m_threshold;
979 const bool m_sorted;
980protected:
981 std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
982 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider&) const override {
983 CScript ret;
984 std::vector<XOnlyPubKey> xkeys;
985 xkeys.reserve(keys.size());
986 for (const auto& key : keys) xkeys.emplace_back(key);
987 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
988 ret << ToByteVector(xkeys[0]) << OP_CHECKSIG;
989 for (size_t i = 1; i < keys.size(); ++i) {
990 ret << ToByteVector(xkeys[i]) << OP_CHECKSIGADD;
991 }
992 ret << m_threshold << OP_NUMEQUAL;
993 return Vector(std::move(ret));
994 }
995public:
996 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) {}
997 bool IsSingleType() const final { return true; }
998
999 std::optional<int64_t> ScriptSize() const override {
1000 const auto n_keys = m_pubkey_args.size();
1001 return (1 + 32 + 1) * n_keys + BuildScript(m_threshold).size() + 1;
1002 }
1003
1004 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1005 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1006 }
1007
1008 std::optional<int64_t> MaxSatisfactionElems() const override { return m_pubkey_args.size(); }
1009};
1010
1012class SHDescriptor final : public DescriptorImpl
1013{
1014protected:
1015 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript> scripts, FlatSigningProvider& out) const override
1016 {
1017 auto ret = Vector(GetScriptForDestination(ScriptHash(scripts[0])));
1018 if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
1019 return ret;
1020 }
1021
1022 bool IsSegwit() const { return m_subdescriptor_args[0]->GetOutputType() == OutputType::BECH32; }
1023
1024public:
1025 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "sh") {}
1026
1027 std::optional<OutputType> GetOutputType() const override
1028 {
1029 assert(m_subdescriptor_args.size() == 1);
1030 if (IsSegwit()) return OutputType::P2SH_SEGWIT;
1031 return OutputType::LEGACY;
1032 }
1033 bool IsSingleType() const final { return true; }
1034
1035 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 20 + 1; }
1036
1037 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1038 if (const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1039 if (const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1040 // The subscript is never witness data.
1041 const auto subscript_weight = (1 + *subscript_size) * WITNESS_SCALE_FACTOR;
1042 // The weight depends on whether the inner descriptor is satisfied using the witness stack.
1043 if (IsSegwit()) return subscript_weight + *sat_size;
1044 return subscript_weight + *sat_size * WITNESS_SCALE_FACTOR;
1045 }
1046 }
1047 return {};
1048 }
1049
1050 std::optional<int64_t> MaxSatisfactionElems() const override {
1051 if (const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems()) return 1 + *sub_elems;
1052 return {};
1053 }
1054};
1055
1057class WSHDescriptor final : public DescriptorImpl
1058{
1059protected:
1060 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript> scripts, FlatSigningProvider& out) const override
1061 {
1063 if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
1064 return ret;
1065 }
1066public:
1067 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "wsh") {}
1068 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
1069 bool IsSingleType() const final { return true; }
1070
1071 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 32; }
1072
1073 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1074 if (const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1075 if (const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1076 return GetSizeOfCompactSize(*subscript_size) + *subscript_size + *sat_size;
1077 }
1078 }
1079 return {};
1080 }
1081
1082 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1083 return MaxSatSize(use_max_sig);
1084 }
1085
1086 std::optional<int64_t> MaxSatisfactionElems() const override {
1087 if (const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems()) return 1 + *sub_elems;
1088 return {};
1089 }
1090};
1091
1093class TRDescriptor final : public DescriptorImpl
1094{
1095 std::vector<int> m_depths;
1096protected:
1097 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript> scripts, FlatSigningProvider& out) const override
1098 {
1099 TaprootBuilder builder;
1100 assert(m_depths.size() == scripts.size());
1101 for (size_t pos = 0; pos < m_depths.size(); ++pos) {
1102 builder.Add(m_depths[pos], scripts[pos], TAPROOT_LEAF_TAPSCRIPT);
1103 }
1104 if (!builder.IsComplete()) return {};
1105 assert(keys.size() == 1);
1106 XOnlyPubKey xpk(keys[0]);
1107 if (!xpk.IsFullyValid()) return {};
1108 builder.Finalize(xpk);
1109 WitnessV1Taproot output = builder.GetOutput();
1110 out.tr_trees[output] = builder;
1111 out.pubkeys.emplace(keys[0].GetID(), keys[0]);
1112 return Vector(GetScriptForDestination(output));
1113 }
1114 bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const override
1115 {
1116 if (m_depths.empty()) return true;
1117 std::vector<bool> path;
1118 for (size_t pos = 0; pos < m_depths.size(); ++pos) {
1119 if (pos) ret += ',';
1120 while ((int)path.size() <= m_depths[pos]) {
1121 if (path.size()) ret += '{';
1122 path.push_back(false);
1123 }
1124 std::string tmp;
1125 if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)) return false;
1126 ret += tmp;
1127 while (!path.empty() && path.back()) {
1128 if (path.size() > 1) ret += '}';
1129 path.pop_back();
1130 }
1131 if (!path.empty()) path.back() = true;
1132 }
1133 return true;
1134 }
1135public:
1136 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1137 DescriptorImpl(Vector(std::move(internal_key)), std::move(descs), "tr"), m_depths(std::move(depths))
1138 {
1139 assert(m_subdescriptor_args.size() == m_depths.size());
1140 }
1141 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32M; }
1142 bool IsSingleType() const final { return true; }
1143
1144 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 32; }
1145
1146 std::optional<int64_t> MaxSatisfactionWeight(bool) const override {
1147 // FIXME: We assume keypath spend, which can lead to very large underestimations.
1148 return 1 + 65;
1149 }
1150
1151 std::optional<int64_t> MaxSatisfactionElems() const override {
1152 // FIXME: See above, we assume keypath spend.
1153 return 1;
1154 }
1155};
1156
1157/* We instantiate Miniscript here with a simple integer as key type.
1158 * The value of these key integers are an index in the
1159 * DescriptorImpl::m_pubkey_args vector.
1160 */
1161
1165class ScriptMaker {
1167 const std::vector<CPubKey>& m_keys;
1169 const miniscript::MiniscriptContext m_script_ctx;
1170
1174 uint160 GetHash160(uint32_t key) const {
1175 if (miniscript::IsTapscript(m_script_ctx)) {
1176 return Hash160(XOnlyPubKey{m_keys[key]});
1177 }
1178 return m_keys[key].GetID();
1179 }
1180
1181public:
1182 ScriptMaker(const std::vector<CPubKey>& keys LIFETIMEBOUND, const miniscript::MiniscriptContext script_ctx) : m_keys(keys), m_script_ctx{script_ctx} {}
1183
1184 std::vector<unsigned char> ToPKBytes(uint32_t key) const {
1185 // In Tapscript keys always serialize as x-only, whether an x-only key was used in the descriptor or not.
1186 if (!miniscript::IsTapscript(m_script_ctx)) {
1187 return {m_keys[key].begin(), m_keys[key].end()};
1188 }
1189 const XOnlyPubKey xonly_pubkey{m_keys[key]};
1190 return {xonly_pubkey.begin(), xonly_pubkey.end()};
1191 }
1192
1193 std::vector<unsigned char> ToPKHBytes(uint32_t key) const {
1194 auto id = GetHash160(key);
1195 return {id.begin(), id.end()};
1196 }
1197};
1198
1202class StringMaker {
1204 const SigningProvider* m_arg;
1206 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1208 bool m_private;
1209
1210public:
1211 StringMaker(const SigningProvider* arg LIFETIMEBOUND, const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys LIFETIMEBOUND, bool priv)
1212 : m_arg(arg), m_pubkeys(pubkeys), m_private(priv) {}
1213
1214 std::optional<std::string> ToString(uint32_t key) const
1215 {
1216 std::string ret;
1217 if (m_private) {
1218 if (!m_pubkeys[key]->ToPrivateString(*m_arg, ret)) return {};
1219 } else {
1220 ret = m_pubkeys[key]->ToString();
1221 }
1222 return ret;
1223 }
1224};
1225
1226class MiniscriptDescriptor final : public DescriptorImpl
1227{
1228private:
1230
1231protected:
1232 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript> scripts,
1233 FlatSigningProvider& provider) const override
1234 {
1235 const auto script_ctx{m_node->GetMsCtx()};
1236 for (const auto& key : keys) {
1237 if (miniscript::IsTapscript(script_ctx)) {
1238 provider.pubkeys.emplace(Hash160(XOnlyPubKey{key}), key);
1239 } else {
1240 provider.pubkeys.emplace(key.GetID(), key);
1241 }
1242 }
1243 return Vector(m_node->ToScript(ScriptMaker(keys, script_ctx)));
1244 }
1245
1246public:
1247 MiniscriptDescriptor(std::vector<std::unique_ptr<PubkeyProvider>> providers, miniscript::NodeRef<uint32_t> node)
1248 : DescriptorImpl(std::move(providers), "?"), m_node(std::move(node)) {}
1249
1250 bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type,
1251 const DescriptorCache* cache = nullptr) const override
1252 {
1253 if (const auto res = m_node->ToString(StringMaker(arg, m_pubkey_args, type == StringType::PRIVATE))) {
1254 out = *res;
1255 return true;
1256 }
1257 return false;
1258 }
1259
1260 bool IsSolvable() const override { return true; }
1261 bool IsSingleType() const final { return true; }
1262
1263 std::optional<int64_t> ScriptSize() const override { return m_node->ScriptSize(); }
1264
1265 std::optional<int64_t> MaxSatSize(bool) const override {
1266 // For Miniscript we always assume high-R ECDSA signatures.
1267 return m_node->GetWitnessSize();
1268 }
1269
1270 std::optional<int64_t> MaxSatisfactionElems() const override {
1271 return m_node->GetStackSize();
1272 }
1273};
1274
1276class RawTRDescriptor final : public DescriptorImpl
1277{
1278protected:
1279 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript> scripts, FlatSigningProvider& out) const override
1280 {
1281 assert(keys.size() == 1);
1282 XOnlyPubKey xpk(keys[0]);
1283 if (!xpk.IsFullyValid()) return {};
1284 WitnessV1Taproot output{xpk};
1285 return Vector(GetScriptForDestination(output));
1286 }
1287public:
1288 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(Vector(std::move(output_key)), "rawtr") {}
1289 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32M; }
1290 bool IsSingleType() const final { return true; }
1291
1292 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 32; }
1293
1294 std::optional<int64_t> MaxSatisfactionWeight(bool) const override {
1295 // We can't know whether there is a script path, so assume key path spend.
1296 return 1 + 65;
1297 }
1298
1299 std::optional<int64_t> MaxSatisfactionElems() const override {
1300 // See above, we assume keypath spend.
1301 return 1;
1302 }
1303};
1304
1306// Parser //
1308
1309enum class ParseScriptContext {
1310 TOP,
1311 P2SH,
1312 P2WPKH,
1313 P2WSH,
1314 P2TR,
1315};
1316
1326[[nodiscard]] bool ParseKeyPath(const std::vector<Span<const char>>& split, KeyPath& out, bool& apostrophe, std::string& error)
1327{
1328 for (size_t i = 1; i < split.size(); ++i) {
1329 Span<const char> elem = split[i];
1330 bool hardened = false;
1331 if (elem.size() > 0) {
1332 const char last = elem[elem.size() - 1];
1333 if (last == '\'' || last == 'h') {
1334 elem = elem.first(elem.size() - 1);
1335 hardened = true;
1336 apostrophe = last == '\'';
1337 }
1338 }
1339 uint32_t p;
1340 if (!ParseUInt32(std::string(elem.begin(), elem.end()), &p)) {
1341 error = strprintf("Key path value '%s' is not a valid uint32", std::string(elem.begin(), elem.end()));
1342 return false;
1343 } else if (p > 0x7FFFFFFFUL) {
1344 error = strprintf("Key path value %u is out of range", p);
1345 return false;
1346 }
1347 out.push_back(p | (((uint32_t)hardened) << 31));
1348 }
1349 return true;
1350}
1351
1353std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, bool& apostrophe, std::string& error)
1354{
1355 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1356 auto split = Split(sp, '/');
1357 std::string str(split[0].begin(), split[0].end());
1358 if (str.size() == 0) {
1359 error = "No key provided";
1360 return nullptr;
1361 }
1362 if (split.size() == 1) {
1363 if (IsHex(str)) {
1364 std::vector<unsigned char> data = ParseHex(str);
1365 CPubKey pubkey(data);
1366 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1367 error = "Hybrid public keys are not allowed";
1368 return nullptr;
1369 }
1370 if (pubkey.IsFullyValid()) {
1371 if (permit_uncompressed || pubkey.IsCompressed()) {
1372 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, false);
1373 } else {
1374 error = "Uncompressed keys are not allowed";
1375 return nullptr;
1376 }
1377 } else if (data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1378 unsigned char fullkey[33] = {0x02};
1379 std::copy(data.begin(), data.end(), fullkey + 1);
1380 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1381 if (pubkey.IsFullyValid()) {
1382 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, true);
1383 }
1384 }
1385 error = strprintf("Pubkey '%s' is invalid", str);
1386 return nullptr;
1387 }
1388 CKey key = DecodeSecret(str);
1389 if (key.IsValid()) {
1390 if (permit_uncompressed || key.IsCompressed()) {
1391 CPubKey pubkey = key.GetPubKey();
1392 out.keys.emplace(pubkey.GetID(), key);
1393 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR);
1394 } else {
1395 error = "Uncompressed keys are not allowed";
1396 return nullptr;
1397 }
1398 }
1399 }
1400 CExtKey extkey = DecodeExtKey(str);
1401 CExtPubKey extpubkey = DecodeExtPubKey(str);
1402 if (!extkey.key.IsValid() && !extpubkey.pubkey.IsValid()) {
1403 error = strprintf("key '%s' is not valid", str);
1404 return nullptr;
1405 }
1406 KeyPath path;
1407 DeriveType type = DeriveType::NO;
1408 if (split.back() == Span{"*"}.first(1)) {
1409 split.pop_back();
1410 type = DeriveType::UNHARDENED;
1411 } else if (split.back() == Span{"*'"}.first(2) || split.back() == Span{"*h"}.first(2)) {
1412 apostrophe = split.back() == Span{"*'"}.first(2);
1413 split.pop_back();
1414 type = DeriveType::HARDENED;
1415 }
1416 if (!ParseKeyPath(split, path, apostrophe, error)) return nullptr;
1417 if (extkey.key.IsValid()) {
1418 extpubkey = extkey.Neuter();
1419 out.keys.emplace(extpubkey.pubkey.GetID(), extkey.key);
1420 }
1421 return std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe);
1422}
1423
1425std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
1426{
1427 auto origin_split = Split(sp, ']');
1428 if (origin_split.size() > 2) {
1429 error = "Multiple ']' characters found for a single pubkey";
1430 return nullptr;
1431 }
1432 // This is set if either the origin or path suffix contains a hardened derivation.
1433 bool apostrophe = false;
1434 if (origin_split.size() == 1) {
1435 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx, out, apostrophe, error);
1436 }
1437 if (origin_split[0].empty() || origin_split[0][0] != '[') {
1438 error = strprintf("Key origin start '[ character expected but not found, got '%c' instead",
1439 origin_split[0].empty() ? ']' : origin_split[0][0]);
1440 return nullptr;
1441 }
1442 auto slash_split = Split(origin_split[0].subspan(1), '/');
1443 if (slash_split[0].size() != 8) {
1444 error = strprintf("Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
1445 return nullptr;
1446 }
1447 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
1448 if (!IsHex(fpr_hex)) {
1449 error = strprintf("Fingerprint '%s' is not hex", fpr_hex);
1450 return nullptr;
1451 }
1452 auto fpr_bytes = ParseHex(fpr_hex);
1453 KeyOriginInfo info;
1454 static_assert(sizeof(info.fingerprint) == 4, "Fingerprint must be 4 bytes");
1455 assert(fpr_bytes.size() == 4);
1456 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint);
1457 if (!ParseKeyPath(slash_split, info.path, apostrophe, error)) return nullptr;
1458 auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], ctx, out, apostrophe, error);
1459 if (!provider) return nullptr;
1460 return std::make_unique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider), apostrophe);
1461}
1462
1463std::unique_ptr<PubkeyProvider> InferPubkey(const CPubKey& pubkey, ParseScriptContext ctx, const SigningProvider& provider)
1464{
1465 // Key cannot be hybrid
1466 if (!pubkey.IsValidNonHybrid()) {
1467 return nullptr;
1468 }
1469 // Uncompressed is only allowed in TOP and P2SH contexts
1470 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.IsCompressed()) {
1471 return nullptr;
1472 }
1473 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey, false);
1474 KeyOriginInfo info;
1475 if (provider.GetKeyOrigin(pubkey.GetID(), info)) {
1476 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider), /*apostrophe=*/false);
1477 }
1478 return key_provider;
1479}
1480
1481std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(const XOnlyPubKey& xkey, ParseScriptContext ctx, const SigningProvider& provider)
1482{
1483 CPubKey pubkey{xkey.GetEvenCorrespondingCPubKey()};
1484 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey, true);
1485 KeyOriginInfo info;
1486 if (provider.GetKeyOriginByXOnly(xkey, info)) {
1487 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider), /*apostrophe=*/false);
1488 }
1489 return key_provider;
1490}
1491
1495struct KeyParser {
1497 using Key = uint32_t;
1499 FlatSigningProvider* m_out;
1501 const SigningProvider* m_in;
1503 mutable std::vector<std::unique_ptr<PubkeyProvider>> m_keys;
1505 mutable std::string m_key_parsing_error;
1507 const miniscript::MiniscriptContext m_script_ctx;
1509 uint32_t m_offset;
1510
1512 miniscript::MiniscriptContext ctx, uint32_t offset = 0)
1513 : m_out(out), m_in(in), m_script_ctx(ctx), m_offset(offset) {}
1514
1515 bool KeyCompare(const Key& a, const Key& b) const {
1516 return *m_keys.at(a) < *m_keys.at(b);
1517 }
1518
1519 ParseScriptContext ParseContext() const {
1520 switch (m_script_ctx) {
1521 case miniscript::MiniscriptContext::P2WSH: return ParseScriptContext::P2WSH;
1522 case miniscript::MiniscriptContext::TAPSCRIPT: return ParseScriptContext::P2TR;
1523 }
1524 assert(false);
1525 }
1526
1527 template<typename I> std::optional<Key> FromString(I begin, I end) const
1528 {
1529 assert(m_out);
1530 Key key = m_keys.size();
1531 auto pk = ParsePubkey(m_offset + key, {&*begin, &*end}, ParseContext(), *m_out, m_key_parsing_error);
1532 if (!pk) return {};
1533 m_keys.push_back(std::move(pk));
1534 return key;
1535 }
1536
1537 std::optional<std::string> ToString(const Key& key) const
1538 {
1539 return m_keys.at(key)->ToString();
1540 }
1541
1542 template<typename I> std::optional<Key> FromPKBytes(I begin, I end) const
1543 {
1544 assert(m_in);
1545 Key key = m_keys.size();
1546 if (miniscript::IsTapscript(m_script_ctx) && end - begin == 32) {
1547 XOnlyPubKey pubkey;
1548 std::copy(begin, end, pubkey.begin());
1549 if (auto pubkey_provider = InferPubkey(pubkey.GetEvenCorrespondingCPubKey(), ParseContext(), *m_in)) {
1550 m_keys.push_back(std::move(pubkey_provider));
1551 return key;
1552 }
1553 } else if (!miniscript::IsTapscript(m_script_ctx)) {
1554 CPubKey pubkey(begin, end);
1555 if (auto pubkey_provider = InferPubkey(pubkey, ParseContext(), *m_in)) {
1556 m_keys.push_back(std::move(pubkey_provider));
1557 return key;
1558 }
1559 }
1560 return {};
1561 }
1562
1563 template<typename I> std::optional<Key> FromPKHBytes(I begin, I end) const
1564 {
1565 assert(end - begin == 20);
1566 assert(m_in);
1567 uint160 hash;
1568 std::copy(begin, end, hash.begin());
1569 CKeyID keyid(hash);
1570 CPubKey pubkey;
1571 if (m_in->GetPubKey(keyid, pubkey)) {
1572 if (auto pubkey_provider = InferPubkey(pubkey, ParseContext(), *m_in)) {
1573 Key key = m_keys.size();
1574 m_keys.push_back(std::move(pubkey_provider));
1575 return key;
1576 }
1577 }
1578 return {};
1579 }
1580
1581 miniscript::MiniscriptContext MsContext() const {
1582 return m_script_ctx;
1583 }
1584};
1585
1587// NOLINTNEXTLINE(misc-no-recursion)
1588std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
1589{
1590 using namespace script;
1591
1592 auto expr = Expr(sp);
1593 if (Func("pk", expr)) {
1594 auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
1595 if (!pubkey) {
1596 error = strprintf("pk(): %s", error);
1597 return nullptr;
1598 }
1599 ++key_exp_index;
1600 return std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR);
1601 }
1602 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && Func("pkh", expr)) {
1603 auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
1604 if (!pubkey) {
1605 error = strprintf("pkh(): %s", error);
1606 return nullptr;
1607 }
1608 ++key_exp_index;
1609 return std::make_unique<PKHDescriptor>(std::move(pubkey));
1610 } else if (ctx != ParseScriptContext::P2TR && Func("pkh", expr)) {
1611 // Under Taproot, always the Miniscript parser deal with it.
1612 error = "Can only have pkh at top level, in sh(), wsh(), or in tr()";
1613 return nullptr;
1614 }
1615 if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
1616 auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
1617 if (!pubkey) {
1618 error = strprintf("combo(): %s", error);
1619 return nullptr;
1620 }
1621 ++key_exp_index;
1622 return std::make_unique<ComboDescriptor>(std::move(pubkey));
1623 } else if (Func("combo", expr)) {
1624 error = "Can only have combo() at top level";
1625 return nullptr;
1626 }
1627 const bool multi = Func("multi", expr);
1628 const bool sortedmulti = !multi && Func("sortedmulti", expr);
1629 const bool multi_a = !(multi || sortedmulti) && Func("multi_a", expr);
1630 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) && Func("sortedmulti_a", expr);
1631 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
1632 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
1633 auto threshold = Expr(expr);
1634 uint32_t thres;
1635 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1636 if (!ParseUInt32(std::string(threshold.begin(), threshold.end()), &thres)) {
1637 error = strprintf("Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
1638 return nullptr;
1639 }
1640 size_t script_size = 0;
1641 while (expr.size()) {
1642 if (!Const(",", expr)) {
1643 error = strprintf("Multi: expected ',', got '%c'", expr[0]);
1644 return nullptr;
1645 }
1646 auto arg = Expr(expr);
1647 auto pk = ParsePubkey(key_exp_index, arg, ctx, out, error);
1648 if (!pk) {
1649 error = strprintf("Multi: %s", error);
1650 return nullptr;
1651 }
1652 script_size += pk->GetSize() + 1;
1653 providers.emplace_back(std::move(pk));
1654 key_exp_index++;
1655 }
1656 if ((multi || sortedmulti) && (providers.empty() || providers.size() > MAX_PUBKEYS_PER_MULTISIG)) {
1657 error = strprintf("Cannot have %u keys in multisig; must have between 1 and %d keys, inclusive", providers.size(), MAX_PUBKEYS_PER_MULTISIG);
1658 return nullptr;
1659 } else if ((multi_a || sortedmulti_a) && (providers.empty() || providers.size() > MAX_PUBKEYS_PER_MULTI_A)) {
1660 error = strprintf("Cannot have %u keys in multi_a; must have between 1 and %d keys, inclusive", providers.size(), MAX_PUBKEYS_PER_MULTI_A);
1661 return nullptr;
1662 } else if (thres < 1) {
1663 error = strprintf("Multisig threshold cannot be %d, must be at least 1", thres);
1664 return nullptr;
1665 } else if (thres > providers.size()) {
1666 error = strprintf("Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
1667 return nullptr;
1668 }
1669 if (ctx == ParseScriptContext::TOP) {
1670 if (providers.size() > 3) {
1671 error = strprintf("Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
1672 return nullptr;
1673 }
1674 }
1675 if (ctx == ParseScriptContext::P2SH) {
1676 // This limits the maximum number of compressed pubkeys to 15.
1677 if (script_size + 3 > MAX_SCRIPT_ELEMENT_SIZE) {
1678 error = strprintf("P2SH script is too large, %d bytes is larger than %d bytes", script_size + 3, MAX_SCRIPT_ELEMENT_SIZE);
1679 return nullptr;
1680 }
1681 }
1682 if (multi || sortedmulti) {
1683 return std::make_unique<MultisigDescriptor>(thres, std::move(providers), sortedmulti);
1684 } else {
1685 return std::make_unique<MultiADescriptor>(thres, std::move(providers), sortedmulti_a);
1686 }
1687 } else if (multi || sortedmulti) {
1688 error = "Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
1689 return nullptr;
1690 } else if (multi_a || sortedmulti_a) {
1691 error = "Can only have multi_a/sortedmulti_a inside tr()";
1692 return nullptr;
1693 }
1694 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wpkh", expr)) {
1695 auto pubkey = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH, out, error);
1696 if (!pubkey) {
1697 error = strprintf("wpkh(): %s", error);
1698 return nullptr;
1699 }
1700 key_exp_index++;
1701 return std::make_unique<WPKHDescriptor>(std::move(pubkey));
1702 } else if (Func("wpkh", expr)) {
1703 error = "Can only have wpkh() at top level or inside sh()";
1704 return nullptr;
1705 }
1706 if (ctx == ParseScriptContext::TOP && Func("sh", expr)) {
1707 auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out, error);
1708 if (!desc || expr.size()) return nullptr;
1709 return std::make_unique<SHDescriptor>(std::move(desc));
1710 } else if (Func("sh", expr)) {
1711 error = "Can only have sh() at top level";
1712 return nullptr;
1713 }
1714 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wsh", expr)) {
1715 auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH, out, error);
1716 if (!desc || expr.size()) return nullptr;
1717 return std::make_unique<WSHDescriptor>(std::move(desc));
1718 } else if (Func("wsh", expr)) {
1719 error = "Can only have wsh() at top level or inside sh()";
1720 return nullptr;
1721 }
1722 if (ctx == ParseScriptContext::TOP && Func("addr", expr)) {
1723 CTxDestination dest = DecodeDestination(std::string(expr.begin(), expr.end()));
1724 if (!IsValidDestination(dest)) {
1725 error = "Address is not valid";
1726 return nullptr;
1727 }
1728 return std::make_unique<AddressDescriptor>(std::move(dest));
1729 } else if (Func("addr", expr)) {
1730 error = "Can only have addr() at top level";
1731 return nullptr;
1732 }
1733 if (ctx == ParseScriptContext::TOP && Func("tr", expr)) {
1734 auto arg = Expr(expr);
1735 auto internal_key = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error);
1736 if (!internal_key) {
1737 error = strprintf("tr(): %s", error);
1738 return nullptr;
1739 }
1740 ++key_exp_index;
1741 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
1742 std::vector<int> depths;
1743 if (expr.size()) {
1744 if (!Const(",", expr)) {
1745 error = strprintf("tr: expected ',', got '%c'", expr[0]);
1746 return nullptr;
1747 }
1751 std::vector<bool> branches;
1752 // Loop over all provided scripts. In every iteration exactly one script will be processed.
1753 // Use a do-loop because inside this if-branch we expect at least one script.
1754 do {
1755 // First process all open braces.
1756 while (Const("{", expr)) {
1757 branches.push_back(false); // new left branch
1758 if (branches.size() > TAPROOT_CONTROL_MAX_NODE_COUNT) {
1759 error = strprintf("tr() supports at most %i nesting levels", TAPROOT_CONTROL_MAX_NODE_COUNT);
1760 return nullptr;
1761 }
1762 }
1763 // Process the actual script expression.
1764 auto sarg = Expr(expr);
1765 subscripts.emplace_back(ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR, out, error));
1766 if (!subscripts.back()) return nullptr;
1767 depths.push_back(branches.size());
1768 // Process closing braces; one is expected for every right branch we were in.
1769 while (branches.size() && branches.back()) {
1770 if (!Const("}", expr)) {
1771 error = strprintf("tr(): expected '}' after script expression");
1772 return nullptr;
1773 }
1774 branches.pop_back(); // move up one level after encountering '}'
1775 }
1776 // If after that, we're at the end of a left branch, expect a comma.
1777 if (branches.size() && !branches.back()) {
1778 if (!Const(",", expr)) {
1779 error = strprintf("tr(): expected ',' after script expression");
1780 return nullptr;
1781 }
1782 branches.back() = true; // And now we're in a right branch.
1783 }
1784 } while (branches.size());
1785 // After we've explored a whole tree, we must be at the end of the expression.
1786 if (expr.size()) {
1787 error = strprintf("tr(): expected ')' after script expression");
1788 return nullptr;
1789 }
1790 }
1792 return std::make_unique<TRDescriptor>(std::move(internal_key), std::move(subscripts), std::move(depths));
1793 } else if (Func("tr", expr)) {
1794 error = "Can only have tr at top level";
1795 return nullptr;
1796 }
1797 if (ctx == ParseScriptContext::TOP && Func("rawtr", expr)) {
1798 auto arg = Expr(expr);
1799 if (expr.size()) {
1800 error = strprintf("rawtr(): only one key expected.");
1801 return nullptr;
1802 }
1803 auto output_key = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error);
1804 if (!output_key) return nullptr;
1805 ++key_exp_index;
1806 return std::make_unique<RawTRDescriptor>(std::move(output_key));
1807 } else if (Func("rawtr", expr)) {
1808 error = "Can only have rawtr at top level";
1809 return nullptr;
1810 }
1811 if (ctx == ParseScriptContext::TOP && Func("raw", expr)) {
1812 std::string str(expr.begin(), expr.end());
1813 if (!IsHex(str)) {
1814 error = "Raw script is not hex";
1815 return nullptr;
1816 }
1817 auto bytes = ParseHex(str);
1818 return std::make_unique<RawDescriptor>(CScript(bytes.begin(), bytes.end()));
1819 } else if (Func("raw", expr)) {
1820 error = "Can only have raw() at top level";
1821 return nullptr;
1822 }
1823 // Process miniscript expressions.
1824 {
1825 const auto script_ctx{ctx == ParseScriptContext::P2WSH ? miniscript::MiniscriptContext::P2WSH : miniscript::MiniscriptContext::TAPSCRIPT};
1826 KeyParser parser(/*out = */&out, /* in = */nullptr, /* ctx = */script_ctx, key_exp_index);
1827 auto node = miniscript::FromString(std::string(expr.begin(), expr.end()), parser);
1828 if (parser.m_key_parsing_error != "") {
1829 error = std::move(parser.m_key_parsing_error);
1830 return nullptr;
1831 }
1832 if (node) {
1833 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
1834 error = "Miniscript expressions can only be used in wsh or tr.";
1835 return nullptr;
1836 }
1837 if (!node->IsSane() || node->IsNotSatisfiable()) {
1838 // Try to find the first insane sub for better error reporting.
1839 auto insane_node = node.get();
1840 if (const auto sub = node->FindInsaneSub()) insane_node = sub;
1841 if (const auto str = insane_node->ToString(parser)) error = *str;
1842 if (!insane_node->IsValid()) {
1843 error += " is invalid";
1844 } else if (!node->IsSane()) {
1845 error += " is not sane";
1846 if (!insane_node->IsNonMalleable()) {
1847 error += ": malleable witnesses exist";
1848 } else if (insane_node == node.get() && !insane_node->NeedsSignature()) {
1849 error += ": witnesses without signature exist";
1850 } else if (!insane_node->CheckTimeLocksMix()) {
1851 error += ": contains mixes of timelocks expressed in blocks and seconds";
1852 } else if (!insane_node->CheckDuplicateKey()) {
1853 error += ": contains duplicate public keys";
1854 } else if (!insane_node->ValidSatisfactions()) {
1855 error += ": needs witnesses that may exceed resource limits";
1856 }
1857 } else {
1858 error += " is not satisfiable";
1859 }
1860 return nullptr;
1861 }
1862 // A signature check is required for a miniscript to be sane. Therefore no sane miniscript
1863 // may have an empty list of public keys.
1864 CHECK_NONFATAL(!parser.m_keys.empty());
1865 key_exp_index += parser.m_keys.size();
1866 return std::make_unique<MiniscriptDescriptor>(std::move(parser.m_keys), std::move(node));
1867 }
1868 }
1869 if (ctx == ParseScriptContext::P2SH) {
1870 error = "A function is needed within P2SH";
1871 return nullptr;
1872 } else if (ctx == ParseScriptContext::P2WSH) {
1873 error = "A function is needed within P2WSH";
1874 return nullptr;
1875 }
1876 error = strprintf("'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
1877 return nullptr;
1878}
1879
1880std::unique_ptr<DescriptorImpl> InferMultiA(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
1881{
1882 auto match = MatchMultiA(script);
1883 if (!match) return {};
1884 std::vector<std::unique_ptr<PubkeyProvider>> keys;
1885 keys.reserve(match->second.size());
1886 for (const auto keyspan : match->second) {
1887 if (keyspan.size() != 32) return {};
1888 auto key = InferXOnlyPubkey(XOnlyPubKey{keyspan}, ctx, provider);
1889 if (!key) return {};
1890 keys.push_back(std::move(key));
1891 }
1892 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
1893}
1894
1895// NOLINTNEXTLINE(misc-no-recursion)
1896std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
1897{
1898 if (ctx == ParseScriptContext::P2TR && script.size() == 34 && script[0] == 32 && script[33] == OP_CHECKSIG) {
1899 XOnlyPubKey key{Span{script}.subspan(1, 32)};
1900 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider), true);
1901 }
1902
1903 if (ctx == ParseScriptContext::P2TR) {
1904 auto ret = InferMultiA(script, ctx, provider);
1905 if (ret) return ret;
1906 }
1907
1908 std::vector<std::vector<unsigned char>> data;
1909 TxoutType txntype = Solver(script, data);
1910
1911 if (txntype == TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
1912 CPubKey pubkey(data[0]);
1913 if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
1914 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
1915 }
1916 }
1917 if (txntype == TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
1918 uint160 hash(data[0]);
1919 CKeyID keyid(hash);
1920 CPubKey pubkey;
1921 if (provider.GetPubKey(keyid, pubkey)) {
1922 if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
1923 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
1924 }
1925 }
1926 }
1927 if (txntype == TxoutType::WITNESS_V0_KEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH)) {
1928 uint160 hash(data[0]);
1929 CKeyID keyid(hash);
1930 CPubKey pubkey;
1931 if (provider.GetPubKey(keyid, pubkey)) {
1932 if (auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
1933 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
1934 }
1935 }
1936 }
1937 if (txntype == TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
1938 bool ok = true;
1939 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1940 for (size_t i = 1; i + 1 < data.size(); ++i) {
1941 CPubKey pubkey(data[i]);
1942 if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
1943 providers.push_back(std::move(pubkey_provider));
1944 } else {
1945 ok = false;
1946 break;
1947 }
1948 }
1949 if (ok) return std::make_unique<MultisigDescriptor>((int)data[0][0], std::move(providers));
1950 }
1951 if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) {
1952 uint160 hash(data[0]);
1953 CScriptID scriptid(hash);
1954 CScript subscript;
1955 if (provider.GetCScript(scriptid, subscript)) {
1956 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
1957 if (sub) return std::make_unique<SHDescriptor>(std::move(sub));
1958 }
1959 }
1960 if (txntype == TxoutType::WITNESS_V0_SCRIPTHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH)) {
1961 CScriptID scriptid{RIPEMD160(data[0])};
1962 CScript subscript;
1963 if (provider.GetCScript(scriptid, subscript)) {
1964 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
1965 if (sub) return std::make_unique<WSHDescriptor>(std::move(sub));
1966 }
1967 }
1968 if (txntype == TxoutType::WITNESS_V1_TAPROOT && ctx == ParseScriptContext::TOP) {
1969 // Extract x-only pubkey from output.
1970 XOnlyPubKey pubkey;
1971 std::copy(data[0].begin(), data[0].end(), pubkey.begin());
1972 // Request spending data.
1973 TaprootSpendData tap;
1974 if (provider.GetTaprootSpendData(pubkey, tap)) {
1975 // If found, convert it back to tree form.
1976 auto tree = InferTaprootTree(tap, pubkey);
1977 if (tree) {
1978 // If that works, try to infer subdescriptors for all leaves.
1979 bool ok = true;
1980 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
1981 std::vector<int> depths;
1982 for (const auto& [depth, script, leaf_ver] : *tree) {
1983 std::unique_ptr<DescriptorImpl> subdesc;
1984 if (leaf_ver == TAPROOT_LEAF_TAPSCRIPT) {
1985 subdesc = InferScript(CScript(script.begin(), script.end()), ParseScriptContext::P2TR, provider);
1986 }
1987 if (!subdesc) {
1988 ok = false;
1989 break;
1990 } else {
1991 subscripts.push_back(std::move(subdesc));
1992 depths.push_back(depth);
1993 }
1994 }
1995 if (ok) {
1996 auto key = InferXOnlyPubkey(tap.internal_key, ParseScriptContext::P2TR, provider);
1997 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
1998 }
1999 }
2000 }
2001 // If the above doesn't work, construct a rawtr() descriptor with just the encoded x-only pubkey.
2002 if (pubkey.IsFullyValid()) {
2003 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
2004 if (key) {
2005 return std::make_unique<RawTRDescriptor>(std::move(key));
2006 }
2007 }
2008 }
2009
2010 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2011 const auto script_ctx{ctx == ParseScriptContext::P2WSH ? miniscript::MiniscriptContext::P2WSH : miniscript::MiniscriptContext::TAPSCRIPT};
2012 KeyParser parser(/* out = */nullptr, /* in = */&provider, /* ctx = */script_ctx);
2013 auto node = miniscript::FromScript(script, parser);
2014 if (node && node->IsSane()) {
2015 return std::make_unique<MiniscriptDescriptor>(std::move(parser.m_keys), std::move(node));
2016 }
2017 }
2018
2019 // The following descriptors are all top-level only descriptors.
2020 // So if we are not at the top level, return early.
2021 if (ctx != ParseScriptContext::TOP) return nullptr;
2022
2023 CTxDestination dest;
2024 if (ExtractDestination(script, dest)) {
2025 if (GetScriptForDestination(dest) == script) {
2026 return std::make_unique<AddressDescriptor>(std::move(dest));
2027 }
2028 }
2029
2030 return std::make_unique<RawDescriptor>(script);
2031}
2032
2033
2034} // namespace
2035
2037bool CheckChecksum(Span<const char>& sp, bool require_checksum, std::string& error, std::string* out_checksum = nullptr)
2038{
2039 auto check_split = Split(sp, '#');
2040 if (check_split.size() > 2) {
2041 error = "Multiple '#' symbols";
2042 return false;
2043 }
2044 if (check_split.size() == 1 && require_checksum){
2045 error = "Missing checksum";
2046 return false;
2047 }
2048 if (check_split.size() == 2) {
2049 if (check_split[1].size() != 8) {
2050 error = strprintf("Expected 8 character checksum, not %u characters", check_split[1].size());
2051 return false;
2052 }
2053 }
2054 auto checksum = DescriptorChecksum(check_split[0]);
2055 if (checksum.empty()) {
2056 error = "Invalid characters in payload";
2057 return false;
2058 }
2059 if (check_split.size() == 2) {
2060 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2061 error = strprintf("Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2062 return false;
2063 }
2064 }
2065 if (out_checksum) *out_checksum = std::move(checksum);
2066 sp = check_split[0];
2067 return true;
2068}
2069
2070std::unique_ptr<Descriptor> Parse(const std::string& descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
2071{
2072 Span<const char> sp{descriptor};
2073 if (!CheckChecksum(sp, require_checksum, error)) return nullptr;
2074 uint32_t key_exp_index = 0;
2075 auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
2076 if (sp.size() == 0 && ret) return std::unique_ptr<Descriptor>(std::move(ret));
2077 return nullptr;
2078}
2079
2080std::string GetDescriptorChecksum(const std::string& descriptor)
2081{
2082 std::string ret;
2083 std::string error;
2084 Span<const char> sp{descriptor};
2085 if (!CheckChecksum(sp, false, error, &ret)) return "";
2086 return ret;
2087}
2088
2089std::unique_ptr<Descriptor> InferDescriptor(const CScript& script, const SigningProvider& provider)
2090{
2091 return InferScript(script, ParseScriptContext::TOP, provider);
2092}
2093
2095{
2096 std::string desc_str = desc.ToString(/*compat_format=*/true);
2097 uint256 id;
2098 CSHA256().Write((unsigned char*)desc_str.data(), desc_str.size()).Finalize(id.begin());
2099 return id;
2100}
2101
2102void DescriptorCache::CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
2103{
2104 m_parent_xpubs[key_exp_pos] = xpub;
2105}
2106
2107void DescriptorCache::CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey& xpub)
2108{
2109 auto& xpubs = m_derived_xpubs[key_exp_pos];
2110 xpubs[der_index] = xpub;
2111}
2112
2113void DescriptorCache::CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
2114{
2115 m_last_hardened_xpubs[key_exp_pos] = xpub;
2116}
2117
2118bool DescriptorCache::GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const
2119{
2120 const auto& it = m_parent_xpubs.find(key_exp_pos);
2121 if (it == m_parent_xpubs.end()) return false;
2122 xpub = it->second;
2123 return true;
2124}
2125
2126bool DescriptorCache::GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey& xpub) const
2127{
2128 const auto& key_exp_it = m_derived_xpubs.find(key_exp_pos);
2129 if (key_exp_it == m_derived_xpubs.end()) return false;
2130 const auto& der_it = key_exp_it->second.find(der_index);
2131 if (der_it == key_exp_it->second.end()) return false;
2132 xpub = der_it->second;
2133 return true;
2134}
2135
2137{
2138 const auto& it = m_last_hardened_xpubs.find(key_exp_pos);
2139 if (it == m_last_hardened_xpubs.end()) return false;
2140 xpub = it->second;
2141 return true;
2142}
2143
2145{
2146 DescriptorCache diff;
2147 for (const auto& parent_xpub_pair : other.GetCachedParentExtPubKeys()) {
2148 CExtPubKey xpub;
2149 if (GetCachedParentExtPubKey(parent_xpub_pair.first, xpub)) {
2150 if (xpub != parent_xpub_pair.second) {
2151 throw std::runtime_error(std::string(__func__) + ": New cached parent xpub does not match already cached parent xpub");
2152 }
2153 continue;
2154 }
2155 CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
2156 diff.CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
2157 }
2158 for (const auto& derived_xpub_map_pair : other.GetCachedDerivedExtPubKeys()) {
2159 for (const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
2160 CExtPubKey xpub;
2161 if (GetCachedDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, xpub)) {
2162 if (xpub != derived_xpub_pair.second) {
2163 throw std::runtime_error(std::string(__func__) + ": New cached derived xpub does not match already cached derived xpub");
2164 }
2165 continue;
2166 }
2167 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2168 diff.CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2169 }
2170 }
2171 for (const auto& lh_xpub_pair : other.GetCachedLastHardenedExtPubKeys()) {
2172 CExtPubKey xpub;
2173 if (GetCachedLastHardenedExtPubKey(lh_xpub_pair.first, xpub)) {
2174 if (xpub != lh_xpub_pair.second) {
2175 throw std::runtime_error(std::string(__func__) + ": New cached last hardened xpub does not match already cached last hardened xpub");
2176 }
2177 continue;
2178 }
2179 CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
2180 diff.CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
2181 }
2182 return diff;
2183}
2184
2189
2190std::unordered_map<uint32_t, ExtPubKeyMap> DescriptorCache::GetCachedDerivedExtPubKeys() const
2191{
2192 return m_derived_xpubs;
2193}
2194
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
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.
#define LIFETIMEBOUND
Definition attributes.h:16
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
Definition bip32.cpp:54
int ret
node::NodeContext m_node
#define CHECK_NONFATAL(condition)
Identity function.
Definition check.h:73
An encapsulated private key.
Definition key.h:35
unsigned int size() const
Simple read-only vector-like interface.
Definition key.h:117
bool IsValid() const
Check whether this private key is valid.
Definition key.h:123
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
Definition key.h:126
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition key.cpp:182
A reference to a CKey: the Hash160 of its serialized public key.
Definition pubkey.h:24
An encapsulated public key.
Definition pubkey.h:34
bool IsCompressed() const
Check whether this is a compressed public key.
Definition pubkey.h:204
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition pubkey.h:164
bool IsValid() const
Definition pubkey.h:189
bool IsValidNonHybrid() const noexcept
Check if a public key is a syntactically valid compressed or uncompressed key.
Definition pubkey.h:195
A hasher class for SHA-256.
Definition sha256.h:14
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition sha256.cpp:727
CSHA256 & Write(const unsigned char *data, size_t len)
Definition sha256.cpp:701
Serialized script, used inside transaction inputs and outputs.
Definition script.h:414
A reference to a CScript: the Hash160 of its serialization.
Definition script.h:591
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
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
A Span is an object that can refer to a contiguous sequence of objects.
Definition span.h:98
constexpr std::size_t size() const noexcept
Definition span.h:187
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
Definition span.h:195
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
Definition span.h:205
constexpr C * begin() const noexcept
Definition span.h:175
constexpr C * end() const noexcept
Definition span.h:176
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.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
TaprootBuilder & Add(int depth, Span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
const unsigned char * begin() const
Definition pubkey.h:295
CPubKey GetEvenCorrespondingCPubKey() const
Definition pubkey.cpp:219
bool IsFullyValid() const
Determine if this pubkey is fully valid.
Definition pubkey.cpp:226
constexpr unsigned char * begin()
Definition uint256.h:102
size_type size() const
Definition prevector.h:296
void reserve(size_type new_capacity)
Definition prevector.h:347
160-bit opaque blob.
Definition uint256.h:166
256-bit opaque blob.
Definition uint256.h:178
static const int WITNESS_SCALE_FACTOR
Definition consensus.h:21
CScript ParseScript(const std::string &s)
Definition core_read.cpp:63
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition hash.h:92
uint160 RIPEMD160(Span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
Definition hash.h:222
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition hex_base.cpp:29
static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
static constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT
std::string EncodeExtKey(const CExtKey &key)
Definition key_io.cpp:280
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:296
std::string EncodeSecret(const CKey &key)
Definition key_io.cpp:231
std::string EncodeDestination(const CTxDestination &dest)
Definition key_io.cpp:291
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
NodeRef< typename Ctx::Key > FromString(const std::string &str, const Ctx &ctx)
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
Definition miniscript.h:240
std::shared_ptr< const Node< Key > > NodeRef
Definition miniscript.h:187
NodeRef< typename Ctx::Key > FromScript(const CScript &script, const Ctx &ctx)
bool Const(const std::string &str, Span< const char > &sp)
Parse a constant.
Definition parsing.cpp:15
Span< const char > Expr(Span< const char > &sp)
Extract the expression that sp begins with.
Definition parsing.cpp:33
bool Func(const std::string &str, Span< const char > &sp)
Parse a function call.
Definition parsing.cpp:24
std::vector< T > Split(const Span< const char > &sp, std::string_view separators)
Split a string on any char found in separators, returning a vector.
Definition string.h:30
bool operator<(const CNetAddr &a, const CNetAddr &b)
std::optional< OutputType > OutputTypeFromDestination(const CTxDestination &dest)
Get the OutputType for a CTxDestination.
const char * name
Definition rest.cpp:49
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
bool CheckChecksum(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.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
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:27
@ OP_CHECKSIG
Definition script.h:189
@ OP_NUMEQUAL
Definition script.h:170
@ OP_CHECKSIGADD
Definition script.h:209
static constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
Definition script.h:36
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
Definition script.h:605
static const int MAX_PUBKEYS_PER_MULTISIG
Definition script.h:33
std::vector< unsigned char > ToByteVector(const T &in)
Definition script.h:66
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:295
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
Definition sign.cpp:109
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
std::optional< std::pair< int, std::vector< Span< const unsigned char > > > > MatchMultiA(const CScript &script)
Definition solver.cpp:107
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition solver.cpp:218
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 key.h:227
CExtPubKey Neuter() const
Definition key.cpp:380
bool Derive(CExtKey &out, unsigned int nChild) const
Definition key.cpp:359
CKey key
Definition key.h:232
bool Derive(CExtPubKey &out, unsigned int nChild) const
Definition pubkey.cpp:408
CPubKey pubkey
Definition pubkey.h:348
Interface for parsed descriptor objects.
Definition descriptor.h:98
virtual std::string ToString(bool compat_format=false) const =0
Convert the descriptor back to a string, undoing parsing.
std::map< CKeyID, CPubKey > pubkeys
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.
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
bool IsHex(std::string_view str)
bool ParseUInt32(std::string_view str, uint32_t *out)
Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
assert(!tx.IsCoinBase())
std::vector< typename std::common_type< Args... >::type > Vector(Args &&... args)
Construct a vector with the specified elements.
Definition vector.h:23