/ src / test / fuzz / util / descriptor.h
descriptor.h
 1  // Copyright (c) 2023-present The Bitcoin Core developers
 2  // Distributed under the MIT software license, see the accompanying
 3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 4  
 5  #ifndef BITCOIN_TEST_FUZZ_UTIL_DESCRIPTOR_H
 6  #define BITCOIN_TEST_FUZZ_UTIL_DESCRIPTOR_H
 7  
 8  #include <key_io.h>
 9  #include <util/strencodings.h>
10  #include <script/descriptor.h>
11  #include <test/fuzz/fuzz.h>
12  
13  #include <functional>
14  
15  /**
16   * Converts a mocked descriptor string to a valid one. Every key in a mocked descriptor key is
17   * represented by 2 hex characters preceded by the '%' character. We parse the two hex characters
18   * as an index in a list of pre-generated keys. This list contains keys of the various types
19   * accepted in descriptor keys expressions.
20   */
21  class MockedDescriptorConverter {
22  private:
23      //! Types are raw (un)compressed pubkeys, raw xonly pubkeys, raw privkeys (WIF), xpubs, xprvs.
24      static constexpr uint8_t KEY_TYPES_COUNT{6};
25      //! How many keys we'll generate in total.
26      static constexpr size_t TOTAL_KEYS_GENERATED{std::numeric_limits<uint8_t>::max() + 1};
27      //! 256 keys of various types.
28      std::array<std::string, TOTAL_KEYS_GENERATED> keys_str;
29  
30  public:
31      // We derive the type of key to generate from the 1-byte id parsed from hex.
32      bool IdIsCompPubKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 0; }
33      bool IdIsUnCompPubKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 1; }
34      bool IdIsXOnlyPubKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 2; }
35      bool IdIsConstPrivKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 3; }
36      bool IdIsXpub(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 4; }
37      bool IdIsXprv(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 5; }
38  
39      //! When initializing the target, populate the list of keys.
40      void Init();
41  
42      //! Parse an id in the keys vectors from a 2-characters hex string.
43      std::optional<uint8_t> IdxFromHex(std::string_view hex_characters) const;
44  
45      //! Get an actual descriptor string from a descriptor string whose keys were mocked.
46      std::optional<std::string> GetDescriptor(std::string_view mocked_desc) const;
47  };
48  
49  //! Default maximum number of derivation indexes in a single derivation path when limiting its depth.
50  constexpr int MAX_DEPTH{2};
51  
52  /**
53   * Whether the buffer, if it represents a valid descriptor, contains a derivation path deeper than
54   * a given maximum depth. Note this may also be hit for deriv paths in origins.
55   */
56  bool HasDeepDerivPath(const FuzzBufferType& buff, const int max_depth = MAX_DEPTH);
57  
58  #endif // BITCOIN_TEST_FUZZ_UTIL_DESCRIPTOR_H