Line data Source code
1 : // Copyright (c) 2017-2021 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_WALLET_WALLETUTIL_H 6 : #define BITCOIN_WALLET_WALLETUTIL_H 7 : 8 : #include <fs.h> 9 : #include <script/descriptor.h> 10 : #include <support/allocators/secure.h> 11 : 12 : #include <vector> 13 : 14 : namespace wallet { 15 : /** (client) version numbers for particular wallet features */ 16 : enum WalletFeature 17 : { 18 : FEATURE_BASE = 10500, // the earliest version new wallets supports (only useful for getwalletinfo's clientversion output) 19 : 20 : FEATURE_WALLETCRYPT = 40000, // wallet encryption 21 : FEATURE_COMPRPUBKEY = 60000, // compressed public keys 22 : FEATURE_HD = 120200, // Hierarchical key derivation after BIP32 (HD Wallet), BIP44 (multi-coin), BIP39 (mnemonic) 23 : // which uses on-the-fly private key derivation 24 : 25 : FEATURE_LATEST = FEATURE_HD 26 : }; 27 : 28 : bool IsFeatureSupported(int wallet_version, int feature_version); 29 : WalletFeature GetClosestWalletFeature(int version); 30 : 31 : enum WalletFlags : uint64_t { 32 : // wallet flags in the upper section (> 1 << 31) will lead to not opening the wallet if flag is unknown 33 : // unknown wallet flags in the lower section <= (1 << 31) will be tolerated 34 : 35 : // will categorize coins as clean (not reused) and dirty (reused), and handle 36 : // them with privacy considerations in mind 37 : WALLET_FLAG_AVOID_REUSE = (1ULL << 0), 38 : 39 : // Indicates that the metadata has already been upgraded to contain key origins 40 : WALLET_FLAG_KEY_ORIGIN_METADATA = (1ULL << 1), 41 : 42 : // Indicates that the descriptor cache has been upgraded to cache last hardened xpubs 43 : WALLET_FLAG_LAST_HARDENED_XPUB_CACHED = (1ULL << 2), 44 : 45 : // will enforce the rule that the wallet can't contain any private keys (only watch-only/pubkeys) 46 : WALLET_FLAG_DISABLE_PRIVATE_KEYS = (1ULL << 32), 47 : 48 : //! Flag set when a wallet contains no HD seed and no private keys, scripts, 49 : //! addresses, and other watch only things, and is therefore "blank." 50 : //! 51 : //! The only function this flag serves is to distinguish a blank wallet from 52 : //! a newly created wallet when the wallet database is loaded, to avoid 53 : //! initialization that should only happen on first run. 54 : //! 55 : //! This flag is also a mandatory flag to prevent previous versions of 56 : //! bitcoin from opening the wallet, thinking it was newly created, and 57 : //! then improperly reinitializing it. 58 : WALLET_FLAG_BLANK_WALLET = (1ULL << 33), 59 : 60 : //! Indicate that this wallet supports DescriptorScriptPubKeyMan 61 : WALLET_FLAG_DESCRIPTORS = (1ULL << 34), 62 : 63 : //! Indicates that the wallet needs an external signer 64 : WALLET_FLAG_EXTERNAL_SIGNER = (1ULL << 35), 65 : }; 66 : 67 : //! Get the path of the wallet directory. 68 : fs::path GetWalletDir(); 69 : 70 : /** Descriptor with some wallet metadata */ 71 22 : class WalletDescriptor 72 : { 73 : public: 74 : std::shared_ptr<Descriptor> descriptor; 75 : uint256 id; // Descriptor ID (calculated once at descriptor initialization/deserialization) 76 75 : uint64_t creation_time = 0; 77 75 : int32_t range_start = 0; // First item in range; start of range, inclusive, i.e. [range_start, range_end). This never changes. 78 75 : int32_t range_end = 0; // Item after the last; end of range, exclusive, i.e. [range_start, range_end). This will increment with each TopUp() 79 75 : int32_t next_index = 0; // Position of the next item to generate 80 : DescriptorCache cache; 81 : 82 9 : void DeserializeDescriptor(const std::string& str) 83 : { 84 9 : std::string error; 85 9 : FlatSigningProvider keys; 86 9 : descriptor = Parse(str, keys, error, true); 87 9 : if (!descriptor) { 88 1 : throw std::ios_base::failure("Invalid descriptor: " + error); 89 : } 90 8 : id = DescriptorID(*descriptor); 91 10 : } 92 : 93 35085 : SERIALIZE_METHODS(WalletDescriptor, obj) 94 : { 95 11695 : std::string descriptor_str; 96 23381 : SER_WRITE(obj, descriptor_str = obj.descriptor->ToString()); 97 11695 : READWRITE(descriptor_str, obj.creation_time, obj.next_index, obj.range_start, obj.range_end); 98 11704 : SER_READ(obj, obj.DeserializeDescriptor(descriptor_str)); 99 11695 : } 100 : 101 150 : WalletDescriptor() {} 102 160 : WalletDescriptor(std::shared_ptr<Descriptor> descriptor, uint64_t creation_time, int32_t range_start, int32_t range_end, int32_t next_index) : descriptor(descriptor), id(DescriptorID(*descriptor)), creation_time(creation_time), range_start(range_start), range_end(range_end), next_index(next_index) { } 103 : }; 104 : 105 : class CWallet; 106 : class DescriptorScriptPubKeyMan; 107 : 108 : /** struct containing information needed for migrating legacy wallets to descriptor wallets */ 109 0 : struct MigrationData 110 : { 111 : CExtKey master_key; 112 : SecureString mnemonic; 113 : SecureString mnemonic_passphrase; 114 : // Highest BIP44 index the legacy wallet ever derived per chain (external/0, 115 : // internal/1). The active pkh() descriptors created during migration must 116 : // start handing out the next address from this index, otherwise post- 117 : // migration getnewaddress would re-derive addresses the legacy wallet had 118 : // already given out. Carried via MigrationData purely to advance the active 119 : // descriptors' next_index — the inactive combo descriptors built in 120 : // MigrateToDescriptor already cover the history themselves. 121 0 : uint32_t external_chain_counter{0}; 122 0 : uint32_t internal_chain_counter{0}; 123 : std::vector<std::pair<std::string, int64_t>> watch_descs; 124 : std::vector<std::pair<std::string, int64_t>> solvable_descs; 125 : std::vector<std::unique_ptr<DescriptorScriptPubKeyMan>> desc_spkms; 126 0 : std::shared_ptr<CWallet> watchonly_wallet{nullptr}; 127 0 : std::shared_ptr<CWallet> solvable_wallet{nullptr}; 128 : }; 129 : } // namespace wallet 130 : 131 : #endif // BITCOIN_WALLET_WALLETUTIL_H