Branch data Line data Source code
# 1 : : // Copyright (c) 2018-2020 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 <key_io.h>
# 8 : : #include <pubkey.h>
# 9 : : #include <script/script.h>
# 10 : : #include <script/standard.h>
# 11 : :
# 12 : : #include <span.h>
# 13 : : #include <util/bip32.h>
# 14 : : #include <util/spanparsing.h>
# 15 : : #include <util/system.h>
# 16 : : #include <util/strencodings.h>
# 17 : : #include <util/vector.h>
# 18 : :
# 19 : : #include <memory>
# 20 : : #include <optional>
# 21 : : #include <string>
# 22 : : #include <vector>
# 23 : :
# 24 : : namespace {
# 25 : :
# 26 : : ////////////////////////////////////////////////////////////////////////////
# 27 : : // Checksum //
# 28 : : ////////////////////////////////////////////////////////////////////////////
# 29 : :
# 30 : : // This section implements a checksum algorithm for descriptors with the
# 31 : : // following properties:
# 32 : : // * Mistakes in a descriptor string are measured in "symbol errors". The higher
# 33 : : // the number of symbol errors, the harder it is to detect:
# 34 : : // * An error substituting a character from 0123456789()[],'/*abcdefgh@:$%{} for
# 35 : : // another in that set always counts as 1 symbol error.
# 36 : : // * Note that hex encoded keys are covered by these characters. Xprvs and
# 37 : : // xpubs use other characters too, but already have their own checksum
# 38 : : // mechanism.
# 39 : : // * Function names like "multi()" use other characters, but mistakes in
# 40 : : // these would generally result in an unparsable descriptor.
# 41 : : // * A case error always counts as 1 symbol error.
# 42 : : // * Any other 1 character substitution error counts as 1 or 2 symbol errors.
# 43 : : // * Any 1 symbol error is always detected.
# 44 : : // * Any 2 or 3 symbol error in a descriptor of up to 49154 characters is always detected.
# 45 : : // * Any 4 symbol error in a descriptor of up to 507 characters is always detected.
# 46 : : // * Any 5 symbol error in a descriptor of up to 77 characters is always detected.
# 47 : : // * Is optimized to minimize the chance a 5 symbol error in a descriptor up to 387 characters is undetected
# 48 : : // * Random errors have a chance of 1 in 2**40 of being undetected.
# 49 : : //
# 50 : : // These properties are achieved by expanding every group of 3 (non checksum) characters into
# 51 : : // 4 GF(32) symbols, over which a cyclic code is defined.
# 52 : :
# 53 : : /*
# 54 : : * Interprets c as 8 groups of 5 bits which are the coefficients of a degree 8 polynomial over GF(32),
# 55 : : * multiplies that polynomial by x, computes its remainder modulo a generator, and adds the constant term val.
# 56 : : *
# 57 : : * 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}.
# 58 : : * It is chosen to define an cyclic error detecting code which is selected by:
# 59 : : * - Starting from all BCH codes over GF(32) of degree 8 and below, which by construction guarantee detecting
# 60 : : * 3 errors in windows up to 19000 symbols.
# 61 : : * - Taking all those generators, and for degree 7 ones, extend them to degree 8 by adding all degree-1 factors.
# 62 : : * - Selecting just the set of generators that guarantee detecting 4 errors in a window of length 512.
# 63 : : * - Selecting one of those with best worst-case behavior for 5 errors in windows of length up to 512.
# 64 : : *
# 65 : : * The generator and the constants to implement it can be verified using this Sage code:
# 66 : : * B = GF(2) # Binary field
# 67 : : * BP.<b> = B[] # Polynomials over the binary field
# 68 : : * F_mod = b**5 + b**3 + 1
# 69 : : * F.<f> = GF(32, modulus=F_mod, repr='int') # GF(32) definition
# 70 : : * FP.<x> = F[] # Polynomials over GF(32)
# 71 : : * E_mod = x**3 + x + F.fetch_int(8)
# 72 : : * E.<e> = F.extension(E_mod) # Extension field definition
# 73 : : * alpha = e**2743 # Choice of an element in extension field
# 74 : : * for p in divisors(E.order() - 1): # Verify alpha has order 32767.
# 75 : : * assert((alpha**p == 1) == (p % 32767 == 0))
# 76 : : * G = lcm([(alpha**i).minpoly() for i in [1056,1057,1058]] + [x + 1])
# 77 : : * print(G) # Print out the generator
# 78 : : * for i in [1,2,4,8,16]: # Print out {1,2,4,8,16}*(G mod x^8), packed in hex integers.
# 79 : : * v = 0
# 80 : : * for coef in reversed((F.fetch_int(i)*(G % x**8)).coefficients(sparse=True)):
# 81 : : * v = v*32 + coef.integer_representation()
# 82 : : * print("0x%x" % v)
# 83 : : */
# 84 : : uint64_t PolyMod(uint64_t c, int val)
# 85 : 38500643 : {
# 86 : 38500643 : uint8_t c0 = c >> 35;
# 87 : 38500643 : c = ((c & 0x7ffffffff) << 5) ^ val;
# 88 [ + + ]: 38500643 : if (c0 & 1) c ^= 0xf5dee51989;
# 89 [ + + ]: 38500643 : if (c0 & 2) c ^= 0xa9fdca3312;
# 90 [ + + ]: 38500643 : if (c0 & 4) c ^= 0x1bab10e32d;
# 91 [ + + ]: 38500643 : if (c0 & 8) c ^= 0x3706b1677a;
# 92 [ + + ]: 38500643 : if (c0 & 16) c ^= 0x644d626ffd;
# 93 : 38500643 : return c;
# 94 : 38500643 : }
# 95 : :
# 96 : : std::string DescriptorChecksum(const Span<const char>& span)
# 97 : 250836 : {
# 98 : : /** A character set designed such that:
# 99 : : * - The most common 'unprotected' descriptor characters (hex, keypaths) are in the first group of 32.
# 100 : : * - Case errors cause an offset that's a multiple of 32.
# 101 : : * - As many alphabetic characters are in the same group (while following the above restrictions).
# 102 : : *
# 103 : : * If p(x) gives the position of a character c in this character set, every group of 3 characters
# 104 : : * (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).
# 105 : : * This means that changes that only affect the lower 5 bits of the position, or only the higher 2 bits, will just
# 106 : : * affect a single symbol.
# 107 : : *
# 108 : : * As a result, within-group-of-32 errors count as 1 symbol, as do cross-group errors that don't affect
# 109 : : * the position within the groups.
# 110 : : */
# 111 : 250836 : static std::string INPUT_CHARSET =
# 112 : 250836 : "0123456789()[],'/*abcdefgh@:$%{}"
# 113 : 250836 : "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
# 114 : 250836 : "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
# 115 : :
# 116 : : /** The character set for the checksum itself (same as bech32). */
# 117 : 250836 : static std::string CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
# 118 : :
# 119 : 250836 : uint64_t c = 1;
# 120 : 250836 : int cls = 0;
# 121 : 250836 : int clscount = 0;
# 122 [ + + ]: 27307272 : for (auto ch : span) {
# 123 : 27307272 : auto pos = INPUT_CHARSET.find(ch);
# 124 [ + + ]: 27307272 : if (pos == std::string::npos) return "";
# 125 : 27307270 : c = PolyMod(c, pos & 31); // Emit a symbol for the position inside the group, for every character.
# 126 : 27307270 : cls = cls * 3 + (pos >> 5); // Accumulate the group numbers
# 127 [ + + ]: 27307270 : if (++clscount == 3) {
# 128 : : // Emit an extra symbol representing the group numbers, for every 3 characters.
# 129 : 8996722 : c = PolyMod(c, cls);
# 130 : 8996722 : cls = 0;
# 131 : 8996722 : clscount = 0;
# 132 : 8996722 : }
# 133 : 27307270 : }
# 134 [ + + ]: 250836 : if (clscount > 0) c = PolyMod(c, cls);
# 135 [ + + ]: 2257506 : for (int j = 0; j < 8; ++j) c = PolyMod(c, 0); // Shift further to determine the checksum.
# 136 : 250834 : c ^= 1; // Prevent appending zeroes from not affecting the checksum.
# 137 : :
# 138 : 250834 : std::string ret(8, ' ');
# 139 [ + + ]: 2257506 : for (int j = 0; j < 8; ++j) ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
# 140 : 250834 : return ret;
# 141 : 250836 : }
# 142 : :
# 143 : 247686 : std::string AddChecksum(const std::string& str) { return str + "#" + DescriptorChecksum(str); }
# 144 : :
# 145 : : ////////////////////////////////////////////////////////////////////////////
# 146 : : // Internal representation //
# 147 : : ////////////////////////////////////////////////////////////////////////////
# 148 : :
# 149 : : typedef std::vector<uint32_t> KeyPath;
# 150 : :
# 151 : : /** Interface for public key objects in descriptors. */
# 152 : : struct PubkeyProvider
# 153 : : {
# 154 : : protected:
# 155 : : //! Index of this key expression in the descriptor
# 156 : : //! E.g. If this PubkeyProvider is key1 in multi(2, key1, key2, key3), then m_expr_index = 0
# 157 : : uint32_t m_expr_index;
# 158 : :
# 159 : : public:
# 160 : 408707 : explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
# 161 : :
# 162 : 408707 : virtual ~PubkeyProvider() = default;
# 163 : :
# 164 : : /** Derive a public key.
# 165 : : * read_cache is the cache to read keys from (if not nullptr)
# 166 : : * write_cache is the cache to write keys to (if not nullptr)
# 167 : : * Caches are not exclusive but this is not tested. Currently we use them exclusively
# 168 : : */
# 169 : : virtual bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) = 0;
# 170 : :
# 171 : : /** Whether this represent multiple public keys at different positions. */
# 172 : : virtual bool IsRange() const = 0;
# 173 : :
# 174 : : /** Get the size of the generated public key(s) in bytes (33 or 65). */
# 175 : : virtual size_t GetSize() const = 0;
# 176 : :
# 177 : : /** Get the descriptor string form. */
# 178 : : virtual std::string ToString() const = 0;
# 179 : :
# 180 : : /** Get the descriptor string form including private data (if available in arg). */
# 181 : : virtual bool ToPrivateString(const SigningProvider& arg, std::string& out) const = 0;
# 182 : :
# 183 : : /** Get the descriptor string form with the xpub at the last hardened derivation */
# 184 : : virtual bool ToNormalizedString(const SigningProvider& arg, std::string& out, bool priv) const = 0;
# 185 : :
# 186 : : /** Derive a private key, if private data is available in arg. */
# 187 : : virtual bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const = 0;
# 188 : : };
# 189 : :
# 190 : : class OriginPubkeyProvider final : public PubkeyProvider
# 191 : : {
# 192 : : KeyOriginInfo m_origin;
# 193 : : std::unique_ptr<PubkeyProvider> m_provider;
# 194 : :
# 195 : : std::string OriginString() const
# 196 : 119414 : {
# 197 : 119414 : return HexStr(m_origin.fingerprint) + FormatHDKeypath(m_origin.path);
# 198 : 119414 : }
# 199 : :
# 200 : : public:
# 201 : 202790 : OriginPubkeyProvider(uint32_t exp_index, KeyOriginInfo info, std::unique_ptr<PubkeyProvider> provider) : PubkeyProvider(exp_index), m_origin(std::move(info)), m_provider(std::move(provider)) {}
# 202 : : bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) override
# 203 : 107206 : {
# 204 [ + + ]: 107206 : if (!m_provider->GetPubKey(pos, arg, key, info, read_cache, write_cache)) return false;
# 205 : 107189 : std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), info.fingerprint);
# 206 : 107189 : info.path.insert(info.path.begin(), m_origin.path.begin(), m_origin.path.end());
# 207 : 107189 : return true;
# 208 : 107189 : }
# 209 : 1094 : bool IsRange() const override { return m_provider->IsRange(); }
# 210 : 324 : size_t GetSize() const override { return m_provider->GetSize(); }
# 211 : 119099 : std::string ToString() const override { return "[" + OriginString() + "]" + m_provider->ToString(); }
# 212 : : bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
# 213 : 200 : {
# 214 : 200 : std::string sub;
# 215 [ + + ]: 200 : if (!m_provider->ToPrivateString(arg, sub)) return false;
# 216 : 100 : ret = "[" + OriginString() + "]" + std::move(sub);
# 217 : 100 : return true;
# 218 : 100 : }
# 219 : : bool ToNormalizedString(const SigningProvider& arg, std::string& ret, bool priv) const override
# 220 : 215 : {
# 221 : 215 : std::string sub;
# 222 [ - + ]: 215 : if (!m_provider->ToNormalizedString(arg, sub, priv)) return false;
# 223 : : // If m_provider is a BIP32PubkeyProvider, we may get a string formatted like a OriginPubkeyProvider
# 224 : : // In that case, we need to strip out the leading square bracket and fingerprint from the substring,
# 225 : : // and append that to our own origin string.
# 226 [ + + ]: 215 : if (sub[0] == '[') {
# 227 : 32 : sub = sub.substr(9);
# 228 : 32 : ret = "[" + OriginString() + std::move(sub);
# 229 : 183 : } else {
# 230 : 183 : ret = "[" + OriginString() + "]" + std::move(sub);
# 231 : 183 : }
# 232 : 215 : return true;
# 233 : 215 : }
# 234 : : bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
# 235 : 78 : {
# 236 : 78 : return m_provider->GetPrivKey(pos, arg, key);
# 237 : 78 : }
# 238 : : };
# 239 : :
# 240 : : /** An object representing a parsed constant public key in a descriptor. */
# 241 : : class ConstPubkeyProvider final : public PubkeyProvider
# 242 : : {
# 243 : : CPubKey m_pubkey;
# 244 : :
# 245 : : public:
# 246 : 204079 : ConstPubkeyProvider(uint32_t exp_index, const CPubKey& pubkey) : PubkeyProvider(exp_index), m_pubkey(pubkey) {}
# 247 : : bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) override
# 248 : 159122 : {
# 249 : 159122 : key = m_pubkey;
# 250 : 159122 : info.path.clear();
# 251 : 159122 : CKeyID keyid = m_pubkey.GetID();
# 252 : 159122 : std::copy(keyid.begin(), keyid.begin() + sizeof(info.fingerprint), info.fingerprint);
# 253 : 159122 : return true;
# 254 : 159122 : }
# 255 : 9181 : bool IsRange() const override { return false; }
# 256 : 1087 : size_t GetSize() const override { return m_pubkey.size(); }
# 257 : 144940 : std::string ToString() const override { return HexStr(m_pubkey); }
# 258 : : bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
# 259 : 724 : {
# 260 : 724 : CKey key;
# 261 [ + + ]: 724 : if (!arg.GetKey(m_pubkey.GetID(), key)) return false;
# 262 : 632 : ret = EncodeSecret(key);
# 263 : 632 : return true;
# 264 : 632 : }
# 265 : : bool ToNormalizedString(const SigningProvider& arg, std::string& ret, bool priv) const override
# 266 : 639 : {
# 267 [ + + ]: 639 : if (priv) return ToPrivateString(arg, ret);
# 268 : 323 : ret = ToString();
# 269 : 323 : return true;
# 270 : 323 : }
# 271 : : bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
# 272 : 4787 : {
# 273 : 4787 : return arg.GetKey(m_pubkey.GetID(), key);
# 274 : 4787 : }
# 275 : : };
# 276 : :
# 277 : : enum class DeriveType {
# 278 : : NO,
# 279 : : UNHARDENED,
# 280 : : HARDENED,
# 281 : : };
# 282 : :
# 283 : : /** An object representing a parsed extended public key in a descriptor. */
# 284 : : class BIP32PubkeyProvider final : public PubkeyProvider
# 285 : : {
# 286 : : // Root xpub, path, and final derivation step type being used, if any
# 287 : : CExtPubKey m_root_extkey;
# 288 : : KeyPath m_path;
# 289 : : DeriveType m_derive;
# 290 : : // Cache of the parent of the final derived pubkeys.
# 291 : : // Primarily useful for situations when no read_cache is provided
# 292 : : CExtPubKey m_cached_xpub;
# 293 : :
# 294 : : bool GetExtKey(const SigningProvider& arg, CExtKey& ret) const
# 295 : 11608 : {
# 296 : 11608 : CKey key;
# 297 [ + + ]: 11608 : if (!arg.GetKey(m_root_extkey.pubkey.GetID(), key)) return false;
# 298 : 11082 : ret.nDepth = m_root_extkey.nDepth;
# 299 : 11082 : std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint + sizeof(ret.vchFingerprint), ret.vchFingerprint);
# 300 : 11082 : ret.nChild = m_root_extkey.nChild;
# 301 : 11082 : ret.chaincode = m_root_extkey.chaincode;
# 302 : 11082 : ret.key = key;
# 303 : 11082 : return true;
# 304 : 11082 : }
# 305 : :
# 306 : : // Derives the last xprv
# 307 : : bool GetDerivedExtKey(const SigningProvider& arg, CExtKey& xprv) const
# 308 : 10667 : {
# 309 [ + + ]: 10667 : if (!GetExtKey(arg, xprv)) return false;
# 310 [ + + ]: 25852 : for (auto entry : m_path) {
# 311 : 25852 : xprv.Derive(xprv, entry);
# 312 : 25852 : }
# 313 : 10285 : return true;
# 314 : 10285 : }
# 315 : :
# 316 : : bool IsHardened() const
# 317 : 8209 : {
# 318 [ + + ]: 8209 : if (m_derive == DeriveType::HARDENED) return true;
# 319 [ + + ]: 1116 : for (auto entry : m_path) {
# 320 [ + + ]: 1093 : if (entry >> 31) return true;
# 321 : 1093 : }
# 322 : 1116 : return false;
# 323 : 1116 : }
# 324 : :
# 325 : : public:
# 326 : 1838 : BIP32PubkeyProvider(uint32_t exp_index, const CExtPubKey& extkey, KeyPath path, DeriveType derive) : PubkeyProvider(exp_index), m_root_extkey(extkey), m_path(std::move(path)), m_derive(derive) {}
# 327 : 148277 : bool IsRange() const override { return m_derive != DeriveType::NO; }
# 328 : 260 : size_t GetSize() const override { return 33; }
# 329 : : bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key_out, KeyOriginInfo& final_info_out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) override
# 330 : 353568 : {
# 331 : : // Info of parent of the to be derived pubkey
# 332 : 353568 : KeyOriginInfo parent_info;
# 333 : 353568 : CKeyID keyid = m_root_extkey.pubkey.GetID();
# 334 : 353568 : std::copy(keyid.begin(), keyid.begin() + sizeof(parent_info.fingerprint), parent_info.fingerprint);
# 335 : 353568 : parent_info.path = m_path;
# 336 : :
# 337 : : // Info of the derived key itself which is copied out upon successful completion
# 338 : 353568 : KeyOriginInfo final_info_out_tmp = parent_info;
# 339 [ + + ]: 353568 : if (m_derive == DeriveType::UNHARDENED) final_info_out_tmp.path.push_back((uint32_t)pos);
# 340 [ + + ]: 353568 : if (m_derive == DeriveType::HARDENED) final_info_out_tmp.path.push_back(((uint32_t)pos) | 0x80000000L);
# 341 : :
# 342 : : // Derive keys or fetch them from cache
# 343 : 353568 : CExtPubKey final_extkey = m_root_extkey;
# 344 : 353568 : CExtPubKey parent_extkey = m_root_extkey;
# 345 : 353568 : bool der = true;
# 346 [ + + ]: 353568 : if (read_cache) {
# 347 [ + + ]: 332237 : if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
# 348 [ + + ]: 331509 : if (m_derive == DeriveType::HARDENED) return false;
# 349 : : // Try to get the derivation parent
# 350 [ + + ]: 330517 : if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey)) return false;
# 351 : 329730 : final_extkey = parent_extkey;
# 352 [ + + ]: 329730 : if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
# 353 : 329730 : }
# 354 [ + + ][ + + ]: 332237 : } else if (m_cached_xpub.pubkey.IsValid() && m_derive != DeriveType::HARDENED) {
# 355 : 13122 : parent_extkey = final_extkey = m_cached_xpub;
# 356 [ + + ]: 13122 : if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
# 357 [ + + ]: 13122 : } else if (IsHardened()) {
# 358 : 7922 : CExtKey xprv;
# 359 [ + + ]: 7922 : if (!GetDerivedExtKey(arg, xprv)) return false;
# 360 : 7704 : parent_extkey = xprv.Neuter();
# 361 [ + + ]: 7704 : if (m_derive == DeriveType::UNHARDENED) der = xprv.Derive(xprv, pos);
# 362 [ + + ]: 7704 : if (m_derive == DeriveType::HARDENED) der = xprv.Derive(xprv, pos | 0x80000000UL);
# 363 : 7704 : final_extkey = xprv.Neuter();
# 364 : 7704 : } else {
# 365 [ + + ]: 287 : for (auto entry : m_path) {
# 366 : 258 : der = parent_extkey.Derive(parent_extkey, entry);
# 367 : 258 : assert(der);
# 368 : 258 : }
# 369 : 287 : final_extkey = parent_extkey;
# 370 [ + + ]: 287 : if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
# 371 : 287 : assert(m_derive != DeriveType::HARDENED);
# 372 : 287 : }
# 373 : 353568 : assert(der);
# 374 : :
# 375 : 351571 : final_info_out = final_info_out_tmp;
# 376 : 351571 : key_out = final_extkey.pubkey;
# 377 : :
# 378 : : // We rely on the consumer to check that m_derive isn't HARDENED as above
# 379 : : // But we can't have already cached something in case we read something from the cache
# 380 : : // and parent_extkey isn't actually the parent.
# 381 [ + + ]: 351571 : if (!m_cached_xpub.pubkey.IsValid()) m_cached_xpub = parent_extkey;
# 382 : :
# 383 [ + + ]: 351571 : if (write_cache) {
# 384 : : // Only cache parent if there is any unhardened derivation
# 385 [ + + ]: 2319 : if (m_derive != DeriveType::HARDENED) {
# 386 : 1453 : write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
# 387 [ + - ]: 1453 : } else if (final_info_out.path.size() > 0) {
# 388 : 866 : write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
# 389 : 866 : }
# 390 : 2319 : }
# 391 : :
# 392 : 351571 : return true;
# 393 : 353568 : }
# 394 : : std::string ToString() const override
# 395 : 107848 : {
# 396 : 107848 : std::string ret = EncodeExtPubKey(m_root_extkey) + FormatHDKeypath(m_path);
# 397 [ + + ]: 107848 : if (IsRange()) {
# 398 : 107588 : ret += "/*";
# 399 [ + + ]: 107588 : if (m_derive == DeriveType::HARDENED) ret += '\'';
# 400 : 107588 : }
# 401 : 107848 : return ret;
# 402 : 107848 : }
# 403 : : bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
# 404 : 552 : {
# 405 : 552 : CExtKey key;
# 406 [ + + ]: 552 : if (!GetExtKey(arg, key)) return false;
# 407 : 408 : out = EncodeExtKey(key) + FormatHDKeypath(m_path);
# 408 [ + + ]: 408 : if (IsRange()) {
# 409 : 152 : out += "/*";
# 410 [ + + ]: 152 : if (m_derive == DeriveType::HARDENED) out += '\'';
# 411 : 152 : }
# 412 : 408 : return true;
# 413 : 408 : }
# 414 : : bool ToNormalizedString(const SigningProvider& arg, std::string& out, bool priv) const override
# 415 : 765 : {
# 416 : : // For hardened derivation type, just return the typical string, nothing to normalize
# 417 [ + + ]: 765 : if (m_derive == DeriveType::HARDENED) {
# 418 [ + + ]: 65 : if (priv) return ToPrivateString(arg, out);
# 419 : 33 : out = ToString();
# 420 : 33 : return true;
# 421 : 33 : }
# 422 : : // Step backwards to find the last hardened step in the path
# 423 : 700 : int i = (int)m_path.size() - 1;
# 424 [ + + ]: 1337 : for (; i >= 0; --i) {
# 425 [ + + ]: 1026 : if (m_path.at(i) >> 31) {
# 426 : 389 : break;
# 427 : 389 : }
# 428 : 1026 : }
# 429 : : // Either no derivation or all unhardened derivation
# 430 [ + + ]: 700 : if (i == -1) {
# 431 [ + + ]: 311 : if (priv) return ToPrivateString(arg, out);
# 432 : 163 : out = ToString();
# 433 : 163 : return true;
# 434 : 163 : }
# 435 : : // Derive the xpub at the last hardened step
# 436 : 389 : CExtKey xprv;
# 437 [ - + ]: 389 : if (!GetExtKey(arg, xprv)) return false;
# 438 : 389 : KeyOriginInfo origin;
# 439 : 389 : int k = 0;
# 440 [ + + ]: 1364 : for (; k <= i; ++k) {
# 441 : : // Derive
# 442 : 975 : xprv.Derive(xprv, m_path.at(k));
# 443 : : // Add to the path
# 444 : 975 : origin.path.push_back(m_path.at(k));
# 445 : : // First derivation element, get the fingerprint for origin
# 446 [ + + ]: 975 : if (k == 0) {
# 447 : 389 : std::copy(xprv.vchFingerprint, xprv.vchFingerprint + 4, origin.fingerprint);
# 448 : 389 : }
# 449 : 975 : }
# 450 : : // Build the remaining path
# 451 : 389 : KeyPath end_path;
# 452 [ + + ]: 778 : for (; k < (int)m_path.size(); ++k) {
# 453 : 389 : end_path.push_back(m_path.at(k));
# 454 : 389 : }
# 455 : : // Build the string
# 456 : 389 : std::string origin_str = HexStr(origin.fingerprint) + FormatHDKeypath(origin.path);
# 457 [ + + ]: 389 : out = "[" + origin_str + "]" + (priv ? EncodeExtKey(xprv) : EncodeExtPubKey(xprv.Neuter())) + FormatHDKeypath(end_path);
# 458 [ + + ]: 389 : if (IsRange()) {
# 459 : 293 : out += "/*";
# 460 : 293 : assert(m_derive == DeriveType::UNHARDENED);
# 461 : 293 : }
# 462 : 389 : return true;
# 463 : 389 : }
# 464 : : bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
# 465 : 2745 : {
# 466 : 2745 : CExtKey extkey;
# 467 [ + + ]: 2745 : if (!GetDerivedExtKey(arg, extkey)) return false;
# 468 [ + + ]: 2581 : if (m_derive == DeriveType::UNHARDENED) extkey.Derive(extkey, pos);
# 469 [ + + ]: 2581 : if (m_derive == DeriveType::HARDENED) extkey.Derive(extkey, pos | 0x80000000UL);
# 470 : 2581 : key = extkey.key;
# 471 : 2581 : return true;
# 472 : 2581 : }
# 473 : : };
# 474 : :
# 475 : : /** Base class for all Descriptor implementations. */
# 476 : : class DescriptorImpl : public Descriptor
# 477 : : {
# 478 : : //! Public key arguments for this descriptor (size 1 for PK, PKH, WPKH; any size for Multisig).
# 479 : : const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
# 480 : : //! The string name of the descriptor function.
# 481 : : const std::string m_name;
# 482 : :
# 483 : : protected:
# 484 : : //! The sub-descriptor arguments (empty for everything but SH and WSH).
# 485 : : //! In doc/descriptors.m this is referred to as SCRIPT expressions sh(SCRIPT)
# 486 : : //! and wsh(SCRIPT), and distinct from KEY expressions and ADDR expressions.
# 487 : : //! Subdescriptors can only ever generate a single script.
# 488 : : const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
# 489 : :
# 490 : : //! Return a serialization of anything except pubkey and script arguments, to be prepended to those.
# 491 : 274147 : virtual std::string ToStringExtra() const { return ""; }
# 492 : :
# 493 : : /** A helper function to construct the scripts for this descriptor.
# 494 : : *
# 495 : : * This function is invoked once by ExpandHelper.
# 496 : : *
# 497 : : * @param pubkeys The evaluations of the m_pubkey_args field.
# 498 : : * @param scripts The evaluations of m_subdescriptor_args (one for each m_subdescriptor_args element).
# 499 : : * @param out A FlatSigningProvider to put scripts or public keys in that are necessary to the solver.
# 500 : : * The origin info of the provided pubkeys is automatically added.
# 501 : : * @return A vector with scriptPubKeys for this descriptor.
# 502 : : */
# 503 : : virtual std::vector<CScript> MakeScripts(const std::vector<CPubKey>& pubkeys, Span<const CScript> scripts, FlatSigningProvider& out) const = 0;
# 504 : :
# 505 : : public:
# 506 : 308699 : DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args() {}
# 507 : 27510 : 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))) {}
# 508 : :
# 509 : : bool IsSolvable() const override
# 510 : 2040 : {
# 511 [ + + ]: 2040 : for (const auto& arg : m_subdescriptor_args) {
# 512 [ - + ]: 778 : if (!arg->IsSolvable()) return false;
# 513 : 778 : }
# 514 : 2040 : return true;
# 515 : 2040 : }
# 516 : :
# 517 : : bool IsRange() const final
# 518 : 50214 : {
# 519 [ + + ]: 50214 : for (const auto& pubkey : m_pubkey_args) {
# 520 [ + + ]: 48813 : if (pubkey->IsRange()) return true;
# 521 : 48813 : }
# 522 [ + + ]: 50214 : for (const auto& arg : m_subdescriptor_args) {
# 523 [ + + ]: 2413 : if (arg->IsRange()) return true;
# 524 : 2413 : }
# 525 : 10781 : return false;
# 526 : 10781 : }
# 527 : :
# 528 : : virtual bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, bool priv, bool normalized) const
# 529 : 277073 : {
# 530 : 277073 : size_t pos = 0;
# 531 [ + + ]: 277073 : for (const auto& scriptarg : m_subdescriptor_args) {
# 532 [ - + ]: 29623 : if (pos++) ret += ",";
# 533 : 29623 : std::string tmp;
# 534 [ + + ]: 29623 : if (!scriptarg->ToStringHelper(arg, tmp, priv, normalized)) return false;
# 535 : 29487 : ret += std::move(tmp);
# 536 : 29487 : }
# 537 : 277073 : return true;
# 538 : 277073 : }
# 539 : :
# 540 : : bool ToStringHelper(const SigningProvider* arg, std::string& out, bool priv, bool normalized) const
# 541 : 277309 : {
# 542 : 277309 : std::string extra = ToStringExtra();
# 543 [ + + ]: 277309 : size_t pos = extra.size() > 0 ? 1 : 0;
# 544 : 277309 : std::string ret = m_name + "(" + extra;
# 545 [ + + ]: 277309 : for (const auto& pubkey : m_pubkey_args) {
# 546 [ + + ]: 254453 : if (pos++) ret += ",";
# 547 : 254453 : std::string tmp;
# 548 [ + + ]: 254453 : if (normalized) {
# 549 [ - + ]: 1404 : if (!pubkey->ToNormalizedString(*arg, tmp, priv)) return false;
# 550 [ + + ]: 253049 : } else if (priv) {
# 551 [ + + ]: 780 : if (!pubkey->ToPrivateString(*arg, tmp)) return false;
# 552 : 252269 : } else {
# 553 : 252269 : tmp = pubkey->ToString();
# 554 : 252269 : }
# 555 : 254453 : ret += std::move(tmp);
# 556 : 254217 : }
# 557 : 277309 : std::string subscript;
# 558 [ + + ]: 277073 : if (!ToStringSubScriptHelper(arg, subscript, priv, normalized)) return false;
# 559 [ + + ][ - + ]: 276937 : if (pos && subscript.size()) ret += ',';
# 560 : 276937 : out = std::move(ret) + std::move(subscript) + ")";
# 561 : 276937 : return true;
# 562 : 276937 : }
# 563 : :
# 564 : : std::string ToString() const final
# 565 : 246425 : {
# 566 : 246425 : std::string ret;
# 567 : 246425 : ToStringHelper(nullptr, ret, false, false);
# 568 : 246425 : return AddChecksum(ret);
# 569 : 246425 : }
# 570 : :
# 571 : : bool ToPrivateString(const SigningProvider& arg, std::string& out) const final
# 572 : 472 : {
# 573 : 472 : bool ret = ToStringHelper(&arg, out, true, false);
# 574 : 472 : out = AddChecksum(out);
# 575 : 472 : return ret;
# 576 : 472 : }
# 577 : :
# 578 : : bool ToNormalizedString(const SigningProvider& arg, std::string& out, bool priv) const override final
# 579 : 789 : {
# 580 : 789 : bool ret = ToStringHelper(&arg, out, priv, true);
# 581 : 789 : out = AddChecksum(out);
# 582 : 789 : return ret;
# 583 : 789 : }
# 584 : :
# 585 : : bool ExpandHelper(int pos, const SigningProvider& arg, const DescriptorCache* read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache) const
# 586 : 558008 : {
# 587 : 558008 : std::vector<std::pair<CPubKey, KeyOriginInfo>> entries;
# 588 : 558008 : entries.reserve(m_pubkey_args.size());
# 589 : :
# 590 : : // Construct temporary data in `entries`, `subscripts`, and `subprovider` to avoid producing output in case of failure.
# 591 [ + + ]: 558008 : for (const auto& p : m_pubkey_args) {
# 592 : 512690 : entries.emplace_back();
# 593 [ + + ]: 512690 : if (!p->GetPubKey(pos, arg, entries.back().first, entries.back().second, read_cache, write_cache)) return false;
# 594 : 512690 : }
# 595 : 558008 : std::vector<CScript> subscripts;
# 596 : 556011 : FlatSigningProvider subprovider;
# 597 [ + + ]: 556011 : for (const auto& subarg : m_subdescriptor_args) {
# 598 : 30861 : std::vector<CScript> outscripts;
# 599 [ + + ]: 30861 : if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache)) return false;
# 600 : 30395 : assert(outscripts.size() == 1);
# 601 : 30395 : subscripts.emplace_back(std::move(outscripts[0]));
# 602 : 30395 : }
# 603 : 556011 : out = Merge(std::move(out), std::move(subprovider));
# 604 : :
# 605 : 555545 : std::vector<CPubKey> pubkeys;
# 606 : 555545 : pubkeys.reserve(entries.size());
# 607 [ + + ]: 555545 : for (auto& entry : entries) {
# 608 : 510693 : pubkeys.push_back(entry.first);
# 609 : 510693 : out.origins.emplace(entry.first.GetID(), std::make_pair<CPubKey, KeyOriginInfo>(CPubKey(entry.first), std::move(entry.second)));
# 610 : 510693 : }
# 611 : :
# 612 : 555545 : output_scripts = MakeScripts(pubkeys, MakeSpan(subscripts), out);
# 613 : 555545 : return true;
# 614 : 556011 : }
# 615 : :
# 616 : : bool Expand(int pos, const SigningProvider& provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache = nullptr) const final
# 617 : 211365 : {
# 618 : 211365 : return ExpandHelper(pos, provider, nullptr, output_scripts, out, write_cache);
# 619 : 211365 : }
# 620 : :
# 621 : : bool ExpandFromCache(int pos, const DescriptorCache& read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const final
# 622 : 315782 : {
# 623 : 315782 : return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &read_cache, output_scripts, out, nullptr);
# 624 : 315782 : }
# 625 : :
# 626 : : void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const final
# 627 : 7402 : {
# 628 [ + + ]: 7532 : for (const auto& p : m_pubkey_args) {
# 629 : 7532 : CKey key;
# 630 [ + + ]: 7532 : if (!p->GetPrivKey(pos, provider, key)) continue;
# 631 : 7223 : out.keys.emplace(key.GetPubKey().GetID(), key);
# 632 : 7223 : }
# 633 [ + + ]: 7402 : for (const auto& arg : m_subdescriptor_args) {
# 634 : 104 : arg->ExpandPrivate(pos, provider, out);
# 635 : 104 : }
# 636 : 7402 : }
# 637 : :
# 638 : 104 : std::optional<OutputType> GetOutputType() const override { return std::nullopt; }
# 639 : : };
# 640 : :
# 641 : : /** A parsed addr(A) descriptor. */
# 642 : : class AddressDescriptor final : public DescriptorImpl
# 643 : : {
# 644 : : const CTxDestination m_destination;
# 645 : : protected:
# 646 : 63 : std::string ToStringExtra() const override { return EncodeDestination(m_destination); }
# 647 : 32307 : std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript>, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(m_destination)); }
# 648 : : public:
# 649 : 32305 : AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, "addr"), m_destination(std::move(destination)) {}
# 650 : 0 : bool IsSolvable() const final { return false; }
# 651 : :
# 652 : : std::optional<OutputType> GetOutputType() const override
# 653 : 0 : {
# 654 : 0 : switch (m_destination.index()) {
# 655 [ # # ]: 0 : case 1 /* PKHash */:
# 656 [ # # ]: 0 : case 2 /* ScriptHash */: return OutputType::LEGACY;
# 657 [ # # ]: 0 : case 3 /* WitnessV0ScriptHash */:
# 658 [ # # ]: 0 : case 4 /* WitnessV0KeyHash */:
# 659 [ # # ]: 0 : case 5 /* WitnessUnknown */: return OutputType::BECH32;
# 660 [ # # ]: 0 : case 0 /* CNoDestination */:
# 661 [ # # ]: 0 : default: return std::nullopt;
# 662 : 0 : }
# 663 : 0 : }
# 664 : 0 : bool IsSingleType() const final { return true; }
# 665 : : };
# 666 : :
# 667 : : /** A parsed raw(H) descriptor. */
# 668 : : class RawDescriptor final : public DescriptorImpl
# 669 : : {
# 670 : : const CScript m_script;
# 671 : : protected:
# 672 : 4 : std::string ToStringExtra() const override { return HexStr(m_script); }
# 673 : 74791 : std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript>, FlatSigningProvider&) const override { return Vector(m_script); }
# 674 : : public:
# 675 : 74795 : RawDescriptor(CScript script) : DescriptorImpl({}, "raw"), m_script(std::move(script)) {}
# 676 : 0 : bool IsSolvable() const final { return false; }
# 677 : :
# 678 : : std::optional<OutputType> GetOutputType() const override
# 679 : 0 : {
# 680 : 0 : CTxDestination dest;
# 681 : 0 : ExtractDestination(m_script, dest);
# 682 : 0 : switch (dest.index()) {
# 683 [ # # ]: 0 : case 1 /* PKHash */:
# 684 [ # # ]: 0 : case 2 /* ScriptHash */: return OutputType::LEGACY;
# 685 [ # # ]: 0 : case 3 /* WitnessV0ScriptHash */:
# 686 [ # # ]: 0 : case 4 /* WitnessV0KeyHash */:
# 687 [ # # ]: 0 : case 5 /* WitnessUnknown */: return OutputType::BECH32;
# 688 [ # # ]: 0 : case 0 /* CNoDestination */:
# 689 [ # # ]: 0 : default: return std::nullopt;
# 690 : 0 : }
# 691 : 0 : }
# 692 : 0 : bool IsSingleType() const final { return true; }
# 693 : : };
# 694 : :
# 695 : : /** A parsed pk(P) descriptor. */
# 696 : : class PKDescriptor final : public DescriptorImpl
# 697 : : {
# 698 : : protected:
# 699 : 2683 : std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider&) const override { return Vector(GetScriptForRawPubKey(keys[0])); }
# 700 : : public:
# 701 : 22177 : PKDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "pk") {}
# 702 : 1 : bool IsSingleType() const final { return true; }
# 703 : : };
# 704 : :
# 705 : : /** A parsed pkh(P) descriptor. */
# 706 : : class PKHDescriptor final : public DescriptorImpl
# 707 : : {
# 708 : : protected:
# 709 : : std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider& out) const override
# 710 : 42482 : {
# 711 : 42482 : CKeyID id = keys[0].GetID();
# 712 : 42482 : out.pubkeys.emplace(id, keys[0]);
# 713 : 42482 : return Vector(GetScriptForDestination(PKHash(id)));
# 714 : 42482 : }
# 715 : : public:
# 716 : 77785 : PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "pkh") {}
# 717 : 584 : std::optional<OutputType> GetOutputType() const override { return OutputType::LEGACY; }
# 718 : 4189 : bool IsSingleType() const final { return true; }
# 719 : : };
# 720 : :
# 721 : : /** A parsed wpkh(P) descriptor. */
# 722 : : class WPKHDescriptor final : public DescriptorImpl
# 723 : : {
# 724 : : protected:
# 725 : : std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider& out) const override
# 726 : 267918 : {
# 727 : 267918 : CKeyID id = keys[0].GetID();
# 728 : 267918 : out.pubkeys.emplace(id, keys[0]);
# 729 : 267918 : return Vector(GetScriptForDestination(WitnessV0KeyHash(id)));
# 730 : 267918 : }
# 731 : : public:
# 732 : 98093 : WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "wpkh") {}
# 733 : 10385 : std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
# 734 : 9906 : bool IsSingleType() const final { return true; }
# 735 : : };
# 736 : :
# 737 : : /** A parsed combo(P) descriptor. */
# 738 : : class ComboDescriptor final : public DescriptorImpl
# 739 : : {
# 740 : : protected:
# 741 : : std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider& out) const override
# 742 : 87903 : {
# 743 : 87903 : std::vector<CScript> ret;
# 744 : 87903 : CKeyID id = keys[0].GetID();
# 745 : 87903 : out.pubkeys.emplace(id, keys[0]);
# 746 : 87903 : ret.emplace_back(GetScriptForRawPubKey(keys[0])); // P2PK
# 747 : 87903 : ret.emplace_back(GetScriptForDestination(PKHash(id))); // P2PKH
# 748 [ + + ]: 87903 : if (keys[0].IsCompressed()) {
# 749 : 87854 : CScript p2wpkh = GetScriptForDestination(WitnessV0KeyHash(id));
# 750 : 87854 : out.scripts.emplace(CScriptID(p2wpkh), p2wpkh);
# 751 : 87854 : ret.emplace_back(p2wpkh);
# 752 : 87854 : ret.emplace_back(GetScriptForDestination(ScriptHash(p2wpkh))); // P2SH-P2WPKH
# 753 : 87854 : }
# 754 : 87903 : return ret;
# 755 : 87903 : }
# 756 : : public:
# 757 : 209 : ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "combo") {}
# 758 : 1 : bool IsSingleType() const final { return false; }
# 759 : : };
# 760 : :
# 761 : : /** A parsed multi(...) or sortedmulti(...) descriptor */
# 762 : : class MultisigDescriptor final : public DescriptorImpl
# 763 : : {
# 764 : : const int m_threshold;
# 765 : : const bool m_sorted;
# 766 : : protected:
# 767 : 3095 : std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
# 768 : 17066 : std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider&) const override {
# 769 [ + + ]: 17066 : if (m_sorted) {
# 770 : 2169 : std::vector<CPubKey> sorted_keys(keys);
# 771 : 2169 : std::sort(sorted_keys.begin(), sorted_keys.end());
# 772 : 2169 : return Vector(GetScriptForMultisig(m_threshold, sorted_keys));
# 773 : 2169 : }
# 774 : 14897 : return Vector(GetScriptForMultisig(m_threshold, keys));
# 775 : 14897 : }
# 776 : : public:
# 777 : 3335 : 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) {}
# 778 : 0 : bool IsSingleType() const final { return true; }
# 779 : : };
# 780 : :
# 781 : : /** A parsed sh(...) descriptor. */
# 782 : : class SHDescriptor final : public DescriptorImpl
# 783 : : {
# 784 : : protected:
# 785 : : std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript> scripts, FlatSigningProvider& out) const override
# 786 : 15992 : {
# 787 : 15992 : auto ret = Vector(GetScriptForDestination(ScriptHash(scripts[0])));
# 788 [ + - ]: 15992 : if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
# 789 : 15992 : return ret;
# 790 : 15992 : }
# 791 : : public:
# 792 : 24529 : SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "sh") {}
# 793 : :
# 794 : : std::optional<OutputType> GetOutputType() const override
# 795 : 532 : {
# 796 : 532 : assert(m_subdescriptor_args.size() == 1);
# 797 [ + + ]: 532 : if (m_subdescriptor_args[0]->GetOutputType() == OutputType::BECH32) return OutputType::P2SH_SEGWIT;
# 798 : 62 : return OutputType::LEGACY;
# 799 : 62 : }
# 800 : 432 : bool IsSingleType() const final { return true; }
# 801 : : };
# 802 : :
# 803 : : /** A parsed wsh(...) descriptor. */
# 804 : : class WSHDescriptor final : public DescriptorImpl
# 805 : : {
# 806 : : protected:
# 807 : : std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript> scripts, FlatSigningProvider& out) const override
# 808 : 14403 : {
# 809 : 14403 : auto ret = Vector(GetScriptForDestination(WitnessV0ScriptHash(scripts[0])));
# 810 [ + - ]: 14403 : if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
# 811 : 14403 : return ret;
# 812 : 14403 : }
# 813 : : public:
# 814 : 2981 : WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "wsh") {}
# 815 : 82 : std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
# 816 : 33 : bool IsSingleType() const final { return true; }
# 817 : : };
# 818 : :
# 819 : : ////////////////////////////////////////////////////////////////////////////
# 820 : : // Parser //
# 821 : : ////////////////////////////////////////////////////////////////////////////
# 822 : :
# 823 : : enum class ParseScriptContext {
# 824 : : TOP, //!< Top-level context (script goes directly in scriptPubKey)
# 825 : : P2SH, //!< Inside sh() (script becomes P2SH redeemScript)
# 826 : : P2WPKH, //!< Inside wpkh() (no script, pubkey only)
# 827 : : P2WSH, //!< Inside wsh() (script becomes v0 witness script)
# 828 : : };
# 829 : :
# 830 : : /** Parse a key path, being passed a split list of elements (the first element is ignored). */
# 831 : : [[nodiscard]] bool ParseKeyPath(const std::vector<Span<const char>>& split, KeyPath& out, std::string& error)
# 832 : 2527 : {
# 833 [ + + ]: 10904 : for (size_t i = 1; i < split.size(); ++i) {
# 834 : 8385 : Span<const char> elem = split[i];
# 835 : 8385 : bool hardened = false;
# 836 [ + - ][ + + ]: 8385 : if (elem.size() > 0 && (elem[elem.size() - 1] == '\'' || elem[elem.size() - 1] == 'h')) {
# [ + + ]
# 837 : 6132 : elem = elem.first(elem.size() - 1);
# 838 : 6132 : hardened = true;
# 839 : 6132 : }
# 840 : 8385 : uint32_t p;
# 841 [ + + ]: 8385 : if (!ParseUInt32(std::string(elem.begin(), elem.end()), &p)) {
# 842 : 4 : error = strprintf("Key path value '%s' is not a valid uint32", std::string(elem.begin(), elem.end()));
# 843 : 4 : return false;
# 844 [ + + ]: 8381 : } else if (p > 0x7FFFFFFFUL) {
# 845 : 4 : error = strprintf("Key path value %u is out of range", p);
# 846 : 4 : return false;
# 847 : 4 : }
# 848 : 8377 : out.push_back(p | (((uint32_t)hardened) << 31));
# 849 : 8377 : }
# 850 : 2527 : return true;
# 851 : 2527 : }
# 852 : :
# 853 : : /** Parse a public key that excludes origin information. */
# 854 : : std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
# 855 : 3494 : {
# 856 : 3494 : using namespace spanparsing;
# 857 : :
# 858 [ + + ][ + + ]: 3494 : bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
# 859 : 3494 : auto split = Split(sp, '/');
# 860 : 3494 : std::string str(split[0].begin(), split[0].end());
# 861 [ + + ]: 3494 : if (str.size() == 0) {
# 862 : 4 : error = "No key provided";
# 863 : 4 : return nullptr;
# 864 : 4 : }
# 865 [ + + ]: 3490 : if (split.size() == 1) {
# 866 [ + + ]: 1698 : if (IsHex(str)) {
# 867 : 1297 : std::vector<unsigned char> data = ParseHex(str);
# 868 : 1297 : CPubKey pubkey(data);
# 869 [ + + ]: 1297 : if (pubkey.IsFullyValid()) {
# 870 [ + + ][ + + ]: 1295 : if (permit_uncompressed || pubkey.IsCompressed()) {
# 871 : 1289 : return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey);
# 872 : 1289 : } else {
# 873 : 6 : error = "Uncompressed keys are not allowed";
# 874 : 6 : return nullptr;
# 875 : 6 : }
# 876 : 2 : }
# 877 : 2 : error = strprintf("Pubkey '%s' is invalid", str);
# 878 : 2 : return nullptr;
# 879 : 2 : }
# 880 : 401 : CKey key = DecodeSecret(str);
# 881 [ + + ]: 401 : if (key.IsValid()) {
# 882 [ + + ][ + + ]: 345 : if (permit_uncompressed || key.IsCompressed()) {
# 883 : 339 : CPubKey pubkey = key.GetPubKey();
# 884 : 339 : out.keys.emplace(pubkey.GetID(), key);
# 885 : 339 : return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey);
# 886 : 339 : } else {
# 887 : 6 : error = "Uncompressed keys are not allowed";
# 888 : 6 : return nullptr;
# 889 : 6 : }
# 890 : 1848 : }
# 891 : 401 : }
# 892 : 1848 : CExtKey extkey = DecodeExtKey(str);
# 893 : 1848 : CExtPubKey extpubkey = DecodeExtPubKey(str);
# 894 [ + + ][ + + ]: 1848 : if (!extkey.key.IsValid() && !extpubkey.pubkey.IsValid()) {
# 895 : 2 : error = strprintf("key '%s' is not valid", str);
# 896 : 2 : return nullptr;
# 897 : 2 : }
# 898 : 1846 : KeyPath path;
# 899 : 1846 : DeriveType type = DeriveType::NO;
# 900 [ + + ]: 1846 : if (split.back() == MakeSpan("*").first(1)) {
# 901 : 1593 : split.pop_back();
# 902 : 1593 : type = DeriveType::UNHARDENED;
# 903 [ + + ][ + + ]: 1593 : } else if (split.back() == MakeSpan("*'").first(2) || split.back() == MakeSpan("*h").first(2)) {
# [ + + ]
# 904 : 58 : split.pop_back();
# 905 : 58 : type = DeriveType::HARDENED;
# 906 : 58 : }
# 907 [ + + ]: 1846 : if (!ParseKeyPath(split, path, error)) return nullptr;
# 908 [ + + ]: 1838 : if (extkey.key.IsValid()) {
# 909 : 265 : extpubkey = extkey.Neuter();
# 910 : 265 : out.keys.emplace(extpubkey.pubkey.GetID(), extkey.key);
# 911 : 265 : }
# 912 : 1838 : return std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type);
# 913 : 1838 : }
# 914 : :
# 915 : : /** Parse a public key including origin information (if enabled). */
# 916 : : std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
# 917 : 3522 : {
# 918 : 3522 : using namespace spanparsing;
# 919 : :
# 920 : 3522 : auto origin_split = Split(sp, ']');
# 921 [ + + ]: 3522 : if (origin_split.size() > 2) {
# 922 : 8 : error = "Multiple ']' characters found for a single pubkey";
# 923 : 8 : return nullptr;
# 924 : 8 : }
# 925 [ + + ]: 3514 : if (origin_split.size() == 1) return ParsePubkeyInner(key_exp_index, origin_split[0], ctx, out, error);
# 926 [ - + ][ + + ]: 701 : if (origin_split[0].empty() || origin_split[0][0] != '[') {
# 927 : 4 : error = strprintf("Key origin start '[ character expected but not found, got '%c' instead",
# 928 [ - + ]: 4 : origin_split[0].empty() ? /** empty, implies split char */ ']' : origin_split[0][0]);
# 929 : 4 : return nullptr;
# 930 : 4 : }
# 931 : 697 : auto slash_split = Split(origin_split[0].subspan(1), '/');
# 932 [ + + ]: 697 : if (slash_split[0].size() != 8) {
# 933 : 12 : error = strprintf("Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
# 934 : 12 : return nullptr;
# 935 : 12 : }
# 936 : 685 : std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
# 937 [ + + ]: 685 : if (!IsHex(fpr_hex)) {
# 938 : 4 : error = strprintf("Fingerprint '%s' is not hex", fpr_hex);
# 939 : 4 : return nullptr;
# 940 : 4 : }
# 941 : 681 : auto fpr_bytes = ParseHex(fpr_hex);
# 942 : 681 : KeyOriginInfo info;
# 943 : 681 : static_assert(sizeof(info.fingerprint) == 4, "Fingerprint must be 4 bytes");
# 944 : 681 : assert(fpr_bytes.size() == 4);
# 945 : 681 : std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint);
# 946 [ - + ]: 681 : if (!ParseKeyPath(slash_split, info.path, error)) return nullptr;
# 947 : 681 : auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], ctx, out, error);
# 948 [ + + ]: 681 : if (!provider) return nullptr;
# 949 : 677 : return std::make_unique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider));
# 950 : 677 : }
# 951 : :
# 952 : : /** Parse a script in a particular context. */
# 953 : : std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
# 954 : 3836 : {
# 955 : 3836 : using namespace spanparsing;
# 956 : :
# 957 : 3836 : auto expr = Expr(sp);
# 958 : 3836 : bool sorted_multi = false;
# 959 [ + + ]: 3836 : if (Func("pk", expr)) {
# 960 : 33 : auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
# 961 [ + + ]: 33 : if (!pubkey) return nullptr;
# 962 : 29 : ++key_exp_index;
# 963 : 29 : return std::make_unique<PKDescriptor>(std::move(pubkey));
# 964 : 29 : }
# 965 [ + + ]: 3803 : if (Func("pkh", expr)) {
# 966 : 633 : auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
# 967 [ + + ]: 633 : if (!pubkey) return nullptr;
# 968 : 617 : ++key_exp_index;
# 969 : 617 : return std::make_unique<PKHDescriptor>(std::move(pubkey));
# 970 : 617 : }
# 971 [ + + ][ + + ]: 3170 : if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
# [ + + ]
# 972 : 213 : auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
# 973 [ + + ]: 213 : if (!pubkey) return nullptr;
# 974 : 209 : ++key_exp_index;
# 975 : 209 : return std::make_unique<ComboDescriptor>(std::move(pubkey));
# 976 [ + + ]: 2957 : } else if (Func("combo", expr)) {
# 977 : 4 : error = "Can only have combo() at top level";
# 978 : 4 : return nullptr;
# 979 : 4 : }
# 980 [ + + ][ + + ]: 2953 : if ((sorted_multi = Func("sortedmulti", expr)) || Func("multi", expr)) {
# [ + + ]
# 981 : 413 : auto threshold = Expr(expr);
# 982 : 413 : uint32_t thres;
# 983 : 413 : std::vector<std::unique_ptr<PubkeyProvider>> providers;
# 984 [ + + ]: 413 : if (!ParseUInt32(std::string(threshold.begin(), threshold.end()), &thres)) {
# 985 : 4 : error = strprintf("Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
# 986 : 4 : return nullptr;
# 987 : 4 : }
# 988 : 409 : size_t script_size = 0;
# 989 [ + + ]: 1756 : while (expr.size()) {
# 990 [ - + ]: 1367 : if (!Const(",", expr)) {
# 991 : 0 : error = strprintf("Multi: expected ',', got '%c'", expr[0]);
# 992 : 0 : return nullptr;
# 993 : 0 : }
# 994 : 1367 : auto arg = Expr(expr);
# 995 : 1367 : auto pk = ParsePubkey(key_exp_index, arg, ctx, out, error);
# 996 [ + + ]: 1367 : if (!pk) return nullptr;
# 997 : 1347 : script_size += pk->GetSize() + 1;
# 998 : 1347 : providers.emplace_back(std::move(pk));
# 999 : 1347 : key_exp_index++;
# 1000 : 1347 : }
# 1001 [ - + ][ - + ]: 409 : if (providers.empty() || providers.size() > MAX_PUBKEYS_PER_MULTISIG) {
# 1002 : 0 : error = strprintf("Cannot have %u keys in multisig; must have between 1 and %d keys, inclusive", providers.size(), MAX_PUBKEYS_PER_MULTISIG);
# 1003 : 0 : return nullptr;
# 1004 [ + + ]: 389 : } else if (thres < 1) {
# 1005 : 4 : error = strprintf("Multisig threshold cannot be %d, must be at least 1", thres);
# 1006 : 4 : return nullptr;
# 1007 [ + + ]: 385 : } else if (thres > providers.size()) {
# 1008 : 4 : error = strprintf("Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
# 1009 : 4 : return nullptr;
# 1010 : 4 : }
# 1011 [ + + ]: 381 : if (ctx == ParseScriptContext::TOP) {
# 1012 [ + + ]: 26 : if (providers.size() > 3) {
# 1013 : 4 : error = strprintf("Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
# 1014 : 4 : return nullptr;
# 1015 : 4 : }
# 1016 : 377 : }
# 1017 [ + + ]: 377 : if (ctx == ParseScriptContext::P2SH) {
# 1018 : : // This limits the maximum number of compressed pubkeys to 15.
# 1019 [ + + ]: 151 : if (script_size + 3 > MAX_SCRIPT_ELEMENT_SIZE) {
# 1020 : 8 : error = strprintf("P2SH script is too large, %d bytes is larger than %d bytes", script_size + 3, MAX_SCRIPT_ELEMENT_SIZE);
# 1021 : 8 : return nullptr;
# 1022 : 8 : }
# 1023 : 369 : }
# 1024 : 369 : return std::make_unique<MultisigDescriptor>(thres, std::move(providers), sorted_multi);
# 1025 : 369 : }
# 1026 [ + + ][ + + ]: 2540 : if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wpkh", expr)) {
# [ + + ][ + + ]
# 1027 : 1276 : auto pubkey = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH, out, error);
# 1028 [ + + ]: 1276 : if (!pubkey) return nullptr;
# 1029 : 1264 : key_exp_index++;
# 1030 : 1264 : return std::make_unique<WPKHDescriptor>(std::move(pubkey));
# 1031 [ + + ]: 1264 : } else if (Func("wpkh", expr)) {
# 1032 : 4 : error = "Can only have wpkh() at top level or inside sh()";
# 1033 : 4 : return nullptr;
# 1034 : 4 : }
# 1035 [ + + ][ + + ]: 1260 : if (ctx == ParseScriptContext::TOP && Func("sh", expr)) {
# [ + + ]
# 1036 : 930 : auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out, error);
# 1037 [ + + ][ - + ]: 930 : if (!desc || expr.size()) return nullptr;
# 1038 : 902 : return std::make_unique<SHDescriptor>(std::move(desc));
# 1039 [ + + ]: 902 : } else if (Func("sh", expr)) {
# 1040 : 8 : error = "Can only have sh() at top level";
# 1041 : 8 : return nullptr;
# 1042 : 8 : }
# 1043 [ + + ][ + + ]: 322 : if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wsh", expr)) {
# [ + + ][ + + ]
# 1044 : 262 : auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH, out, error);
# 1045 [ + + ][ - + ]: 262 : if (!desc || expr.size()) return nullptr;
# 1046 : 222 : return std::make_unique<WSHDescriptor>(std::move(desc));
# 1047 [ + + ]: 222 : } else if (Func("wsh", expr)) {
# 1048 : 4 : error = "Can only have wsh() at top level or inside sh()";
# 1049 : 4 : return nullptr;
# 1050 : 4 : }
# 1051 [ + + ][ + + ]: 56 : if (ctx == ParseScriptContext::TOP && Func("addr", expr)) {
# [ + + ]
# 1052 : 16 : CTxDestination dest = DecodeDestination(std::string(expr.begin(), expr.end()));
# 1053 [ + + ]: 16 : if (!IsValidDestination(dest)) {
# 1054 : 4 : error = "Address is not valid";
# 1055 : 4 : return nullptr;
# 1056 : 4 : }
# 1057 : 12 : return std::make_unique<AddressDescriptor>(std::move(dest));
# 1058 [ - + ]: 40 : } else if (Func("addr", expr)) {
# 1059 : 0 : error = "Can only have addr() at top level";
# 1060 : 0 : return nullptr;
# 1061 : 0 : }
# 1062 [ + + ][ + + ]: 40 : if (ctx == ParseScriptContext::TOP && Func("raw", expr)) {
# [ + + ]
# 1063 : 16 : std::string str(expr.begin(), expr.end());
# 1064 [ + + ]: 16 : if (!IsHex(str)) {
# 1065 : 2 : error = "Raw script is not hex";
# 1066 : 2 : return nullptr;
# 1067 : 2 : }
# 1068 : 14 : auto bytes = ParseHex(str);
# 1069 : 14 : return std::make_unique<RawDescriptor>(CScript(bytes.begin(), bytes.end()));
# 1070 [ - + ]: 24 : } else if (Func("raw", expr)) {
# 1071 : 0 : error = "Can only have raw() at top level";
# 1072 : 0 : return nullptr;
# 1073 : 0 : }
# 1074 [ + + ]: 24 : if (ctx == ParseScriptContext::P2SH) {
# 1075 : 4 : error = "A function is needed within P2SH";
# 1076 : 4 : return nullptr;
# 1077 [ + + ]: 20 : } else if (ctx == ParseScriptContext::P2WSH) {
# 1078 : 4 : error = "A function is needed within P2WSH";
# 1079 : 4 : return nullptr;
# 1080 : 4 : }
# 1081 : 16 : error = strprintf("%s is not a valid descriptor function", std::string(expr.begin(), expr.end()));
# 1082 : 16 : return nullptr;
# 1083 : 16 : }
# 1084 : :
# 1085 : : std::unique_ptr<PubkeyProvider> InferPubkey(const CPubKey& pubkey, ParseScriptContext, const SigningProvider& provider)
# 1086 : 202451 : {
# 1087 : 202451 : std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey);
# 1088 : 202451 : KeyOriginInfo info;
# 1089 [ + + ]: 202451 : if (provider.GetKeyOrigin(pubkey.GetID(), info)) {
# 1090 : 202113 : return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider));
# 1091 : 202113 : }
# 1092 : 338 : return key_provider;
# 1093 : 338 : }
# 1094 : :
# 1095 : : std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
# 1096 : 332571 : {
# 1097 : 332571 : std::vector<std::vector<unsigned char>> data;
# 1098 : 332571 : TxoutType txntype = Solver(script, data);
# 1099 : :
# 1100 [ + + ]: 332571 : if (txntype == TxoutType::PUBKEY) {
# 1101 : 22148 : CPubKey pubkey(data[0]);
# 1102 [ + - ]: 22148 : if (pubkey.IsValid()) {
# 1103 : 22148 : return std::make_unique<PKDescriptor>(InferPubkey(pubkey, ctx, provider));
# 1104 : 22148 : }
# 1105 : 310423 : }
# 1106 [ + + ]: 310423 : if (txntype == TxoutType::PUBKEYHASH) {
# 1107 : 77647 : uint160 hash(data[0]);
# 1108 : 77647 : CKeyID keyid(hash);
# 1109 : 77647 : CPubKey pubkey;
# 1110 [ + + ]: 77647 : if (provider.GetPubKey(keyid, pubkey)) {
# 1111 : 77168 : return std::make_unique<PKHDescriptor>(InferPubkey(pubkey, ctx, provider));
# 1112 : 77168 : }
# 1113 : 233255 : }
# 1114 [ + + ][ + - ]: 233255 : if (txntype == TxoutType::WITNESS_V0_KEYHASH && ctx != ParseScriptContext::P2WSH) {
# 1115 : 124393 : uint160 hash(data[0]);
# 1116 : 124393 : CKeyID keyid(hash);
# 1117 : 124393 : CPubKey pubkey;
# 1118 [ + + ]: 124393 : if (provider.GetPubKey(keyid, pubkey)) {
# 1119 : 96829 : return std::make_unique<WPKHDescriptor>(InferPubkey(pubkey, ctx, provider));
# 1120 : 96829 : }
# 1121 : 136426 : }
# 1122 [ + + ]: 136426 : if (txntype == TxoutType::MULTISIG) {
# 1123 : 2966 : std::vector<std::unique_ptr<PubkeyProvider>> providers;
# 1124 [ + + ]: 9272 : for (size_t i = 1; i + 1 < data.size(); ++i) {
# 1125 : 6306 : CPubKey pubkey(data[i]);
# 1126 : 6306 : providers.push_back(InferPubkey(pubkey, ctx, provider));
# 1127 : 6306 : }
# 1128 : 2966 : return std::make_unique<MultisigDescriptor>((int)data[0][0], std::move(providers));
# 1129 : 2966 : }
# 1130 [ + + ][ + - ]: 133460 : if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) {
# 1131 : 24962 : uint160 hash(data[0]);
# 1132 : 24962 : CScriptID scriptid(hash);
# 1133 : 24962 : CScript subscript;
# 1134 [ + + ]: 24962 : if (provider.GetCScript(scriptid, subscript)) {
# 1135 : 23627 : auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
# 1136 [ + - ]: 23627 : if (sub) return std::make_unique<SHDescriptor>(std::move(sub));
# 1137 : 109833 : }
# 1138 : 24962 : }
# 1139 [ + + ][ + - ]: 109833 : if (txntype == TxoutType::WITNESS_V0_SCRIPTHASH && ctx != ParseScriptContext::P2WSH) {
# 1140 : 3199 : CScriptID scriptid;
# 1141 : 3199 : CRIPEMD160().Write(data[0].data(), data[0].size()).Finalize(scriptid.begin());
# 1142 : 3199 : CScript subscript;
# 1143 [ + + ]: 3199 : if (provider.GetCScript(scriptid, subscript)) {
# 1144 : 2759 : auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
# 1145 [ + - ]: 2759 : if (sub) return std::make_unique<WSHDescriptor>(std::move(sub));
# 1146 : 107074 : }
# 1147 : 3199 : }
# 1148 : :
# 1149 : 107074 : CTxDestination dest;
# 1150 [ + + ]: 107074 : if (ExtractDestination(script, dest)) {
# 1151 [ + - ]: 32293 : if (GetScriptForDestination(dest) == script) {
# 1152 : 32293 : return std::make_unique<AddressDescriptor>(std::move(dest));
# 1153 : 32293 : }
# 1154 : 74781 : }
# 1155 : :
# 1156 : 74781 : return std::make_unique<RawDescriptor>(script);
# 1157 : 74781 : }
# 1158 : :
# 1159 : :
# 1160 : : } // namespace
# 1161 : :
# 1162 : : /** Check a descriptor checksum, and update desc to be the checksum-less part. */
# 1163 : : bool CheckChecksum(Span<const char>& sp, bool require_checksum, std::string& error, std::string* out_checksum = nullptr)
# 1164 : 3173 : {
# 1165 : 3173 : using namespace spanparsing;
# 1166 : :
# 1167 : 3173 : auto check_split = Split(sp, '#');
# 1168 [ + + ]: 3173 : if (check_split.size() > 2) {
# 1169 : 4 : error = "Multiple '#' symbols";
# 1170 : 4 : return false;
# 1171 : 4 : }
# 1172 [ + + ][ + + ]: 3169 : if (check_split.size() == 1 && require_checksum){
# 1173 : 7 : error = "Missing checksum";
# 1174 : 7 : return false;
# 1175 : 7 : }
# 1176 [ + + ]: 3162 : if (check_split.size() == 2) {
# 1177 [ + + ]: 1514 : if (check_split[1].size() != 8) {
# 1178 : 12 : error = strprintf("Expected 8 character checksum, not %u characters", check_split[1].size());
# 1179 : 12 : return false;
# 1180 : 12 : }
# 1181 : 3150 : }
# 1182 : 3150 : auto checksum = DescriptorChecksum(check_split[0]);
# 1183 [ + + ]: 3150 : if (checksum.empty()) {
# 1184 : 2 : error = "Invalid characters in payload";
# 1185 : 2 : return false;
# 1186 : 2 : }
# 1187 [ + + ]: 3148 : if (check_split.size() == 2) {
# 1188 [ + + ]: 1500 : if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
# 1189 : 16 : error = strprintf("Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
# 1190 : 16 : return false;
# 1191 : 16 : }
# 1192 : 3132 : }
# 1193 [ + + ]: 3132 : if (out_checksum) *out_checksum = std::move(checksum);
# 1194 : 3132 : sp = check_split[0];
# 1195 : 3132 : return true;
# 1196 : 3132 : }
# 1197 : :
# 1198 : : std::unique_ptr<Descriptor> Parse(const std::string& descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
# 1199 : 2677 : {
# 1200 : 2677 : Span<const char> sp{descriptor};
# 1201 [ + + ]: 2677 : if (!CheckChecksum(sp, require_checksum, error)) return nullptr;
# 1202 : 2644 : uint32_t key_exp_index = 0;
# 1203 : 2644 : auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
# 1204 [ + - ][ + + ]: 2644 : if (sp.size() == 0 && ret) return std::unique_ptr<Descriptor>(std::move(ret));
# 1205 : 130 : return nullptr;
# 1206 : 130 : }
# 1207 : :
# 1208 : : std::string GetDescriptorChecksum(const std::string& descriptor)
# 1209 : 496 : {
# 1210 : 496 : std::string ret;
# 1211 : 496 : std::string error;
# 1212 : 496 : Span<const char> sp{descriptor};
# 1213 [ + + ]: 496 : if (!CheckChecksum(sp, false, error, &ret)) return "";
# 1214 : 488 : return ret;
# 1215 : 488 : }
# 1216 : :
# 1217 : : std::unique_ptr<Descriptor> InferDescriptor(const CScript& script, const SigningProvider& provider)
# 1218 : 306185 : {
# 1219 : 306185 : return InferScript(script, ParseScriptContext::TOP, provider);
# 1220 : 306185 : }
# 1221 : :
# 1222 : : void DescriptorCache::CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
# 1223 : 2965 : {
# 1224 : 2965 : m_parent_xpubs[key_exp_pos] = xpub;
# 1225 : 2965 : }
# 1226 : :
# 1227 : : void DescriptorCache::CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey& xpub)
# 1228 : 1636 : {
# 1229 : 1636 : auto& xpubs = m_derived_xpubs[key_exp_pos];
# 1230 : 1636 : xpubs[der_index] = xpub;
# 1231 : 1636 : }
# 1232 : :
# 1233 : : bool DescriptorCache::GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const
# 1234 : 331386 : {
# 1235 : 331386 : const auto& it = m_parent_xpubs.find(key_exp_pos);
# 1236 [ + + ]: 331386 : if (it == m_parent_xpubs.end()) return false;
# 1237 : 329730 : xpub = it->second;
# 1238 : 329730 : return true;
# 1239 : 329730 : }
# 1240 : :
# 1241 : : bool DescriptorCache::GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey& xpub) const
# 1242 : 333007 : {
# 1243 : 333007 : const auto& key_exp_it = m_derived_xpubs.find(key_exp_pos);
# 1244 [ + + ]: 333007 : if (key_exp_it == m_derived_xpubs.end()) return false;
# 1245 : 2472 : const auto& der_it = key_exp_it->second.find(der_index);
# 1246 [ + + ]: 2472 : if (der_it == key_exp_it->second.end()) return false;
# 1247 : 728 : xpub = der_it->second;
# 1248 : 728 : return true;
# 1249 : 728 : }
# 1250 : :
# 1251 : : const ExtPubKeyMap DescriptorCache::GetCachedParentExtPubKeys() const
# 1252 : 33447 : {
# 1253 : 33447 : return m_parent_xpubs;
# 1254 : 33447 : }
# 1255 : :
# 1256 : : const std::unordered_map<uint32_t, ExtPubKeyMap> DescriptorCache::GetCachedDerivedExtPubKeys() const
# 1257 : 33447 : {
# 1258 : 33447 : return m_derived_xpubs;
# 1259 : 33447 : }
|