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