Coverage Report

Created: 2024-10-21 15:10

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