Branch data Line data Source code
# 1 : : // Copyright (c) 2019-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_SCRIPTPUBKEYMAN_H
# 6 : : #define BITCOIN_WALLET_SCRIPTPUBKEYMAN_H
# 7 : :
# 8 : : #include <psbt.h>
# 9 : : #include <script/descriptor.h>
# 10 : : #include <script/signingprovider.h>
# 11 : : #include <script/standard.h>
# 12 : : #include <util/error.h>
# 13 : : #include <util/message.h>
# 14 : : #include <util/time.h>
# 15 : : #include <wallet/crypter.h>
# 16 : : #include <wallet/ismine.h>
# 17 : : #include <wallet/walletdb.h>
# 18 : : #include <wallet/walletutil.h>
# 19 : :
# 20 : : #include <boost/signals2/signal.hpp>
# 21 : :
# 22 : : #include <optional>
# 23 : : #include <unordered_map>
# 24 : :
# 25 : : enum class OutputType;
# 26 : : struct bilingual_str;
# 27 : :
# 28 : : namespace wallet {
# 29 : : // Wallet storage things that ScriptPubKeyMans need in order to be able to store things to the wallet database.
# 30 : : // It provides access to things that are part of the entire wallet and not specific to a ScriptPubKeyMan such as
# 31 : : // wallet flags, wallet version, encryption keys, encryption status, and the database itself. This allows a
# 32 : : // ScriptPubKeyMan to have callbacks into CWallet without causing a circular dependency.
# 33 : : // WalletStorage should be the same for all ScriptPubKeyMans of a wallet.
# 34 : : class WalletStorage
# 35 : : {
# 36 : : public:
# 37 : 876 : virtual ~WalletStorage() = default;
# 38 : : virtual const std::string GetDisplayName() const = 0;
# 39 : : virtual WalletDatabase& GetDatabase() const = 0;
# 40 : : virtual bool IsWalletFlagSet(uint64_t) const = 0;
# 41 : : virtual void UnsetBlankWalletFlag(WalletBatch&) = 0;
# 42 : : virtual bool CanSupportFeature(enum WalletFeature) const = 0;
# 43 : : virtual void SetMinVersion(enum WalletFeature, WalletBatch* = nullptr) = 0;
# 44 : : virtual const CKeyingMaterial& GetEncryptionKey() const = 0;
# 45 : : virtual bool HasEncryptionKeys() const = 0;
# 46 : : virtual bool IsLocked() const = 0;
# 47 : : };
# 48 : :
# 49 : : //! Default for -keypool
# 50 : : static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000;
# 51 : :
# 52 : : std::vector<CKeyID> GetAffectedKeys(const CScript& spk, const SigningProvider& provider);
# 53 : :
# 54 : : /** A key from a CWallet's keypool
# 55 : : *
# 56 : : * The wallet holds one (for pre HD-split wallets) or several keypools. These
# 57 : : * are sets of keys that have not yet been used to provide addresses or receive
# 58 : : * change.
# 59 : : *
# 60 : : * The Bitcoin Core wallet was originally a collection of unrelated private
# 61 : : * keys with their associated addresses. If a non-HD wallet generated a
# 62 : : * key/address, gave that address out and then restored a backup from before
# 63 : : * that key's generation, then any funds sent to that address would be
# 64 : : * lost definitively.
# 65 : : *
# 66 : : * The keypool was implemented to avoid this scenario (commit: 10384941). The
# 67 : : * wallet would generate a set of keys (100 by default). When a new public key
# 68 : : * was required, either to give out as an address or to use in a change output,
# 69 : : * it would be drawn from the keypool. The keypool would then be topped up to
# 70 : : * maintain 100 keys. This ensured that as long as the wallet hadn't used more
# 71 : : * than 100 keys since the previous backup, all funds would be safe, since a
# 72 : : * restored wallet would be able to scan for all owned addresses.
# 73 : : *
# 74 : : * A keypool also allowed encrypted wallets to give out addresses without
# 75 : : * having to be decrypted to generate a new private key.
# 76 : : *
# 77 : : * With the introduction of HD wallets (commit: f1902510), the keypool
# 78 : : * essentially became an address look-ahead pool. Restoring old backups can no
# 79 : : * longer definitively lose funds as long as the addresses used were from the
# 80 : : * wallet's HD seed (since all private keys can be rederived from the seed).
# 81 : : * However, if many addresses were used since the backup, then the wallet may
# 82 : : * not know how far ahead in the HD chain to look for its addresses. The
# 83 : : * keypool is used to implement a 'gap limit'. The keypool maintains a set of
# 84 : : * keys (by default 1000) ahead of the last used key and scans for the
# 85 : : * addresses of those keys. This avoids the risk of not seeing transactions
# 86 : : * involving the wallet's addresses, or of re-using the same address.
# 87 : : * In the unlikely case where none of the addresses in the `gap limit` are
# 88 : : * used on-chain, the look-ahead will not be incremented to keep
# 89 : : * a constant size and addresses beyond this range will not be detected by an
# 90 : : * old backup. For this reason, it is not recommended to decrease keypool size
# 91 : : * lower than default value.
# 92 : : *
# 93 : : * The HD-split wallet feature added a second keypool (commit: 02592f4c). There
# 94 : : * is an external keypool (for addresses to hand out) and an internal keypool
# 95 : : * (for change addresses).
# 96 : : *
# 97 : : * Keypool keys are stored in the wallet/keystore's keymap. The keypool data is
# 98 : : * stored as sets of indexes in the wallet (setInternalKeyPool,
# 99 : : * setExternalKeyPool and set_pre_split_keypool), and a map from the key to the
# 100 : : * index (m_pool_key_to_index). The CKeyPool object is used to
# 101 : : * serialize/deserialize the pool data to/from the database.
# 102 : : */
# 103 : : class CKeyPool
# 104 : : {
# 105 : : public:
# 106 : : //! The time at which the key was generated. Set in AddKeypoolPubKeyWithDB
# 107 : : int64_t nTime;
# 108 : : //! The public key
# 109 : : CPubKey vchPubKey;
# 110 : : //! Whether this keypool entry is in the internal keypool (for change outputs)
# 111 : : bool fInternal;
# 112 : : //! Whether this key was generated for a keypool before the wallet was upgraded to HD-split
# 113 : : bool m_pre_split;
# 114 : :
# 115 : : CKeyPool();
# 116 : : CKeyPool(const CPubKey& vchPubKeyIn, bool internalIn);
# 117 : :
# 118 : : template<typename Stream>
# 119 : : void Serialize(Stream& s) const
# 120 : 19752 : {
# 121 : 19752 : int nVersion = s.GetVersion();
# 122 [ + - ]: 19752 : if (!(s.GetType() & SER_GETHASH)) {
# 123 : 19752 : s << nVersion;
# 124 : 19752 : }
# 125 : 19752 : s << nTime << vchPubKey << fInternal << m_pre_split;
# 126 : 19752 : }
# 127 : :
# 128 : : template<typename Stream>
# 129 : : void Unserialize(Stream& s)
# 130 : 21209 : {
# 131 : 21209 : int nVersion = s.GetVersion();
# 132 [ + - ]: 21209 : if (!(s.GetType() & SER_GETHASH)) {
# 133 : 21209 : s >> nVersion;
# 134 : 21209 : }
# 135 : 21209 : s >> nTime >> vchPubKey;
# 136 : 21209 : try {
# 137 : 21209 : s >> fInternal;
# 138 : 21209 : } catch (std::ios_base::failure&) {
# 139 : : /* flag as external address if we can't read the internal boolean
# 140 : : (this will be the case for any wallet before the HD chain split version) */
# 141 : 0 : fInternal = false;
# 142 : 0 : }
# 143 : 21209 : try {
# 144 : 21209 : s >> m_pre_split;
# 145 : 21209 : } catch (std::ios_base::failure&) {
# 146 : : /* flag as postsplit address if we can't read the m_pre_split boolean
# 147 : : (this will be the case for any wallet that upgrades to HD chain split) */
# 148 : 0 : m_pre_split = false;
# 149 : 0 : }
# 150 : 21209 : }
# 151 : : };
# 152 : :
# 153 : : struct WalletDestination
# 154 : : {
# 155 : : CTxDestination dest;
# 156 : : std::optional<bool> internal;
# 157 : : };
# 158 : :
# 159 : : /*
# 160 : : * A class implementing ScriptPubKeyMan manages some (or all) scriptPubKeys used in a wallet.
# 161 : : * It contains the scripts and keys related to the scriptPubKeys it manages.
# 162 : : * A ScriptPubKeyMan will be able to give out scriptPubKeys to be used, as well as marking
# 163 : : * when a scriptPubKey has been used. It also handles when and how to store a scriptPubKey
# 164 : : * and its related scripts and keys, including encryption.
# 165 : : */
# 166 : : class ScriptPubKeyMan
# 167 : : {
# 168 : : protected:
# 169 : : WalletStorage& m_storage;
# 170 : :
# 171 : : public:
# 172 : 3335 : explicit ScriptPubKeyMan(WalletStorage& storage) : m_storage(storage) {}
# 173 : 3335 : virtual ~ScriptPubKeyMan() {};
# 174 : 0 : virtual bool GetNewDestination(const OutputType type, CTxDestination& dest, bilingual_str& error) { return false; }
# 175 : 0 : virtual isminetype IsMine(const CScript& script) const { return ISMINE_NO; }
# 176 : :
# 177 : : //! Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the keys handled by it.
# 178 : 0 : virtual bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) { return false; }
# 179 : 0 : virtual bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) { return false; }
# 180 : :
# 181 : 0 : virtual bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error) { return false; }
# 182 : 2265 : virtual void KeepDestination(int64_t index, const OutputType& type) {}
# 183 : 0 : virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) {}
# 184 : :
# 185 : : /** Fills internal address pool. Use within ScriptPubKeyMan implementations should be used sparingly and only
# 186 : : * when something from the address pool is removed, excluding GetNewDestination and GetReservedDestination.
# 187 : : * External wallet code is primarily responsible for topping up prior to fetching new addresses
# 188 : : */
# 189 : 0 : virtual bool TopUp(unsigned int size = 0) { return false; }
# 190 : :
# 191 : : /** Mark unused addresses as being used
# 192 : : * Affects all keys up to and including the one determined by provided script.
# 193 : : *
# 194 : : * @param script determines the last key to mark as used
# 195 : : *
# 196 : : * @return All of the addresses affected
# 197 : : */
# 198 : 0 : virtual std::vector<WalletDestination> MarkUnusedAddresses(const CScript& script) { return {}; }
# 199 : :
# 200 : : /** Sets up the key generation stuff, i.e. generates new HD seeds and sets them as active.
# 201 : : * Returns false if already setup or setup fails, true if setup is successful
# 202 : : * Set force=true to make it re-setup if already setup, used for upgrades
# 203 : : */
# 204 : 0 : virtual bool SetupGeneration(bool force = false) { return false; }
# 205 : :
# 206 : : /* Returns true if HD is enabled */
# 207 : 0 : virtual bool IsHDEnabled() const { return false; }
# 208 : :
# 209 : : /* Returns true if the wallet can give out new addresses. This means it has keys in the keypool or can generate new keys */
# 210 : 0 : virtual bool CanGetAddresses(bool internal = false) const { return false; }
# 211 : :
# 212 : : /** Upgrades the wallet to the specified version */
# 213 : 0 : virtual bool Upgrade(int prev_version, int new_version, bilingual_str& error) { return true; }
# 214 : :
# 215 : 0 : virtual bool HavePrivateKeys() const { return false; }
# 216 : :
# 217 : : //! The action to do when the DB needs rewrite
# 218 : 0 : virtual void RewriteDB() {}
# 219 : :
# 220 : 0 : virtual std::optional<int64_t> GetOldestKeyPoolTime() const { return GetTime(); }
# 221 : :
# 222 : 0 : virtual unsigned int GetKeyPoolSize() const { return 0; }
# 223 : :
# 224 : 0 : virtual int64_t GetTimeFirstKey() const { return 0; }
# 225 : :
# 226 : 0 : virtual std::unique_ptr<CKeyMetadata> GetMetadata(const CTxDestination& dest) const { return nullptr; }
# 227 : :
# 228 : 0 : virtual std::unique_ptr<SigningProvider> GetSolvingProvider(const CScript& script) const { return nullptr; }
# 229 : :
# 230 : : /** Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that, combined with
# 231 : : * sigdata, can produce solving data.
# 232 : : */
# 233 : 0 : virtual bool CanProvide(const CScript& script, SignatureData& sigdata) { return false; }
# 234 : :
# 235 : : /** Creates new signatures and adds them to the transaction. Returns whether all inputs were signed */
# 236 : 0 : virtual bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, bilingual_str>& input_errors) const { return false; }
# 237 : : /** Sign a message with the given script */
# 238 : 0 : virtual SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const { return SigningResult::SIGNING_FAILED; };
# 239 : : /** Adds script and derivation path information to a PSBT, and optionally signs it. */
# 240 : 0 : virtual TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = SIGHASH_DEFAULT, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const { return TransactionError::INVALID_PSBT; }
# 241 : :
# 242 : 0 : virtual uint256 GetID() const { return uint256(); }
# 243 : :
# 244 : : /** Prepends the wallet name in logging output to ease debugging in multi-wallet use cases */
# 245 : : template<typename... Params>
# 246 : 38169 : void WalletLogPrintf(std::string fmt, Params... parameters) const {
# 247 : 38169 : LogPrintf(("%s " + fmt).c_str(), m_storage.GetDisplayName(), parameters...);
# 248 : 38169 : };
# 249 : :
# 250 : : /** Watch-only address added */
# 251 : : boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;
# 252 : :
# 253 : : /** Keypool has new keys */
# 254 : : boost::signals2::signal<void ()> NotifyCanGetAddressesChanged;
# 255 : : };
# 256 : :
# 257 : : /** OutputTypes supported by the LegacyScriptPubKeyMan */
# 258 : : static const std::unordered_set<OutputType> LEGACY_OUTPUT_TYPES {
# 259 : : OutputType::LEGACY,
# 260 : : OutputType::P2SH_SEGWIT,
# 261 : : OutputType::BECH32,
# 262 : : };
# 263 : :
# 264 : : class LegacyScriptPubKeyMan : public ScriptPubKeyMan, public FillableSigningProvider
# 265 : : {
# 266 : : private:
# 267 : : //! keeps track of whether Unlock has run a thorough check before
# 268 : : bool fDecryptionThoroughlyChecked = true;
# 269 : :
# 270 : : using WatchOnlySet = std::set<CScript>;
# 271 : : using WatchKeyMap = std::map<CKeyID, CPubKey>;
# 272 : :
# 273 : : WalletBatch *encrypted_batch GUARDED_BY(cs_KeyStore) = nullptr;
# 274 : :
# 275 : : using CryptedKeyMap = std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>;
# 276 : :
# 277 : : CryptedKeyMap mapCryptedKeys GUARDED_BY(cs_KeyStore);
# 278 : : WatchOnlySet setWatchOnly GUARDED_BY(cs_KeyStore);
# 279 : : WatchKeyMap mapWatchKeys GUARDED_BY(cs_KeyStore);
# 280 : :
# 281 : : int64_t nTimeFirstKey GUARDED_BY(cs_KeyStore) = 0;
# 282 : :
# 283 : : bool AddKeyPubKeyInner(const CKey& key, const CPubKey &pubkey);
# 284 : : bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
# 285 : :
# 286 : : /**
# 287 : : * Private version of AddWatchOnly method which does not accept a
# 288 : : * timestamp, and which will reset the wallet's nTimeFirstKey value to 1 if
# 289 : : * the watch key did not previously have a timestamp associated with it.
# 290 : : * Because this is an inherited virtual method, it is accessible despite
# 291 : : * being marked private, but it is marked private anyway to encourage use
# 292 : : * of the other AddWatchOnly which accepts a timestamp and sets
# 293 : : * nTimeFirstKey more intelligently for more efficient rescans.
# 294 : : */
# 295 : : bool AddWatchOnly(const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 296 : : bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 297 : : bool AddWatchOnlyInMem(const CScript &dest);
# 298 : : //! Adds a watch-only address to the store, and saves it to disk.
# 299 : : bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 300 : :
# 301 : : //! Adds a key to the store, and saves it to disk.
# 302 : : bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 303 : :
# 304 : : void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
# 305 : :
# 306 : : //! Adds a script to the store and saves it to disk
# 307 : : bool AddCScriptWithDB(WalletBatch& batch, const CScript& script);
# 308 : :
# 309 : : /** Add a KeyOriginInfo to the wallet */
# 310 : : bool AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info);
# 311 : :
# 312 : : /* the HD chain data model (external chain counters) */
# 313 : : CHDChain m_hd_chain;
# 314 : : std::unordered_map<CKeyID, CHDChain, SaltedSipHasher> m_inactive_hd_chains;
# 315 : :
# 316 : : /* HD derive new child key (on internal or external chain) */
# 317 : : void DeriveNewChildKey(WalletBatch& batch, CKeyMetadata& metadata, CKey& secret, CHDChain& hd_chain, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 318 : :
# 319 : : std::set<int64_t> setInternalKeyPool GUARDED_BY(cs_KeyStore);
# 320 : : std::set<int64_t> setExternalKeyPool GUARDED_BY(cs_KeyStore);
# 321 : : std::set<int64_t> set_pre_split_keypool GUARDED_BY(cs_KeyStore);
# 322 : : int64_t m_max_keypool_index GUARDED_BY(cs_KeyStore) = 0;
# 323 : : std::map<CKeyID, int64_t> m_pool_key_to_index;
# 324 : : // Tracks keypool indexes to CKeyIDs of keys that have been taken out of the keypool but may be returned to it
# 325 : : std::map<int64_t, CKeyID> m_index_to_reserved_key;
# 326 : :
# 327 : : //! Fetches a key from the keypool
# 328 : : bool GetKeyFromPool(CPubKey &key, const OutputType type, bool internal = false);
# 329 : :
# 330 : : /**
# 331 : : * Reserves a key from the keypool and sets nIndex to its index
# 332 : : *
# 333 : : * @param[out] nIndex the index of the key in keypool
# 334 : : * @param[out] keypool the keypool the key was drawn from, which could be the
# 335 : : * the pre-split pool if present, or the internal or external pool
# 336 : : * @param fRequestedInternal true if the caller would like the key drawn
# 337 : : * from the internal keypool, false if external is preferred
# 338 : : *
# 339 : : * @return true if succeeded, false if failed due to empty keypool
# 340 : : * @throws std::runtime_error if keypool read failed, key was invalid,
# 341 : : * was not found in the wallet, or was misclassified in the internal
# 342 : : * or external keypool
# 343 : : */
# 344 : : bool ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal);
# 345 : :
# 346 : : /**
# 347 : : * Like TopUp() but adds keys for inactive HD chains.
# 348 : : * Ensures that there are at least -keypool number of keys derived after the given index.
# 349 : : *
# 350 : : * @param seed_id the CKeyID for the HD seed.
# 351 : : * @param index the index to start generating keys from
# 352 : : * @param internal whether the internal chain should be used. true for internal chain, false for external chain.
# 353 : : *
# 354 : : * @return true if seed was found and keys were derived. false if unable to derive seeds
# 355 : : */
# 356 : : bool TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal);
# 357 : :
# 358 : : bool TopUpChain(CHDChain& chain, unsigned int size);
# 359 : : public:
# 360 : : using ScriptPubKeyMan::ScriptPubKeyMan;
# 361 : :
# 362 : : bool GetNewDestination(const OutputType type, CTxDestination& dest, bilingual_str& error) override;
# 363 : : isminetype IsMine(const CScript& script) const override;
# 364 : :
# 365 : : bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override;
# 366 : : bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override;
# 367 : :
# 368 : : bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error) override;
# 369 : : void KeepDestination(int64_t index, const OutputType& type) override;
# 370 : : void ReturnDestination(int64_t index, bool internal, const CTxDestination&) override;
# 371 : :
# 372 : : bool TopUp(unsigned int size = 0) override;
# 373 : :
# 374 : : std::vector<WalletDestination> MarkUnusedAddresses(const CScript& script) override;
# 375 : :
# 376 : : //! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo
# 377 : : void UpgradeKeyMetadata();
# 378 : :
# 379 : : bool IsHDEnabled() const override;
# 380 : :
# 381 : : bool SetupGeneration(bool force = false) override;
# 382 : :
# 383 : : bool Upgrade(int prev_version, int new_version, bilingual_str& error) override;
# 384 : :
# 385 : : bool HavePrivateKeys() const override;
# 386 : :
# 387 : : void RewriteDB() override;
# 388 : :
# 389 : : std::optional<int64_t> GetOldestKeyPoolTime() const override;
# 390 : : size_t KeypoolCountExternalKeys() const;
# 391 : : unsigned int GetKeyPoolSize() const override;
# 392 : :
# 393 : : int64_t GetTimeFirstKey() const override;
# 394 : :
# 395 : : std::unique_ptr<CKeyMetadata> GetMetadata(const CTxDestination& dest) const override;
# 396 : :
# 397 : : bool CanGetAddresses(bool internal = false) const override;
# 398 : :
# 399 : : std::unique_ptr<SigningProvider> GetSolvingProvider(const CScript& script) const override;
# 400 : :
# 401 : : bool CanProvide(const CScript& script, SignatureData& sigdata) override;
# 402 : :
# 403 : : bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, bilingual_str>& input_errors) const override;
# 404 : : SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const override;
# 405 : : TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = SIGHASH_DEFAULT, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const override;
# 406 : :
# 407 : : uint256 GetID() const override;
# 408 : :
# 409 : : // Map from Key ID to key metadata.
# 410 : : std::map<CKeyID, CKeyMetadata> mapKeyMetadata GUARDED_BY(cs_KeyStore);
# 411 : :
# 412 : : // Map from Script ID to key metadata (for watch-only keys).
# 413 : : std::map<CScriptID, CKeyMetadata> m_script_metadata GUARDED_BY(cs_KeyStore);
# 414 : :
# 415 : : //! Adds a key to the store, and saves it to disk.
# 416 : : bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override;
# 417 : : //! Adds a key to the store, without saving it to disk (used by LoadWallet)
# 418 : : bool LoadKey(const CKey& key, const CPubKey &pubkey);
# 419 : : //! Adds an encrypted key to the store, and saves it to disk.
# 420 : : bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
# 421 : : //! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
# 422 : : bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret, bool checksum_valid);
# 423 : : void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 424 : : //! Adds a CScript to the store
# 425 : : bool LoadCScript(const CScript& redeemScript);
# 426 : : //! Load metadata (used by LoadWallet)
# 427 : : void LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata &metadata);
# 428 : : void LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &metadata);
# 429 : : //! Generate a new key
# 430 : : CPubKey GenerateNewKey(WalletBatch& batch, CHDChain& hd_chain, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 431 : :
# 432 : : /* Set the HD chain model (chain child index counters) and writes it to the database */
# 433 : : void AddHDChain(const CHDChain& chain);
# 434 : : //! Load a HD chain model (used by LoadWallet)
# 435 : : void LoadHDChain(const CHDChain& chain);
# 436 : 880 : const CHDChain& GetHDChain() const { return m_hd_chain; }
# 437 : : void AddInactiveHDChain(const CHDChain& chain);
# 438 : :
# 439 : : //! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
# 440 : : bool LoadWatchOnly(const CScript &dest);
# 441 : : //! Returns whether the watch-only script is in the wallet
# 442 : : bool HaveWatchOnly(const CScript &dest) const;
# 443 : : //! Returns whether there are any watch-only things in the wallet
# 444 : : bool HaveWatchOnly() const;
# 445 : : //! Remove a watch only script from the keystore
# 446 : : bool RemoveWatchOnly(const CScript &dest);
# 447 : : bool AddWatchOnly(const CScript& dest, int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 448 : :
# 449 : : //! Fetches a pubkey from mapWatchKeys if it exists there
# 450 : : bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const;
# 451 : :
# 452 : : /* SigningProvider overrides */
# 453 : : bool HaveKey(const CKeyID &address) const override;
# 454 : : bool GetKey(const CKeyID &address, CKey& keyOut) const override;
# 455 : : bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const override;
# 456 : : bool AddCScript(const CScript& redeemScript) override;
# 457 : : bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override;
# 458 : :
# 459 : : //! Load a keypool entry
# 460 : : void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool);
# 461 : : bool NewKeyPool();
# 462 : : void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 463 : :
# 464 : : bool ImportScripts(const std::set<CScript> scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 465 : : bool ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 466 : : bool ImportPubKeys(const std::vector<CKeyID>& ordered_pubkeys, const std::map<CKeyID, CPubKey>& pubkey_map, const std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins, const bool add_keypool, const bool internal, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 467 : : bool ImportScriptPubKeys(const std::set<CScript>& script_pub_keys, const bool have_solving_data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 468 : :
# 469 : : /* Returns true if the wallet can generate new keys */
# 470 : : bool CanGenerateKeys() const;
# 471 : :
# 472 : : /* Generates a new HD seed (will not be activated) */
# 473 : : CPubKey GenerateNewSeed();
# 474 : :
# 475 : : /* Derives a new HD seed (will not be activated) */
# 476 : : CPubKey DeriveNewSeed(const CKey& key);
# 477 : :
# 478 : : /* Set the current HD seed (will reset the chain child index counters)
# 479 : : Sets the seed's version based on the current wallet version (so the
# 480 : : caller must ensure the current wallet version is correct before calling
# 481 : : this function). */
# 482 : : void SetHDSeed(const CPubKey& key);
# 483 : :
# 484 : : /**
# 485 : : * Explicitly make the wallet learn the related scripts for outputs to the
# 486 : : * given key. This is purely to make the wallet file compatible with older
# 487 : : * software, as FillableSigningProvider automatically does this implicitly for all
# 488 : : * keys now.
# 489 : : */
# 490 : : void LearnRelatedScripts(const CPubKey& key, OutputType);
# 491 : :
# 492 : : /**
# 493 : : * Same as LearnRelatedScripts, but when the OutputType is not known (and could
# 494 : : * be anything).
# 495 : : */
# 496 : : void LearnAllRelatedScripts(const CPubKey& key);
# 497 : :
# 498 : : /**
# 499 : : * Marks all keys in the keypool up to and including the provided key as used.
# 500 : : *
# 501 : : * @param keypool_id determines the last key to mark as used
# 502 : : *
# 503 : : * @return All affected keys
# 504 : : */
# 505 : : std::vector<CKeyPool> MarkReserveKeysAsUsed(int64_t keypool_id) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
# 506 : 7 : const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; }
# 507 : :
# 508 : : std::set<CKeyID> GetKeys() const override;
# 509 : : };
# 510 : :
# 511 : : /** Wraps a LegacyScriptPubKeyMan so that it can be returned in a new unique_ptr. Does not provide privkeys */
# 512 : : class LegacySigningProvider : public SigningProvider
# 513 : : {
# 514 : : private:
# 515 : : const LegacyScriptPubKeyMan& m_spk_man;
# 516 : : public:
# 517 : 516347 : explicit LegacySigningProvider(const LegacyScriptPubKeyMan& spk_man) : m_spk_man(spk_man) {}
# 518 : :
# 519 : 17945 : bool GetCScript(const CScriptID &scriptid, CScript& script) const override { return m_spk_man.GetCScript(scriptid, script); }
# 520 : 0 : bool HaveCScript(const CScriptID &scriptid) const override { return m_spk_man.HaveCScript(scriptid); }
# 521 : 486323 : bool GetPubKey(const CKeyID &address, CPubKey& pubkey) const override { return m_spk_man.GetPubKey(address, pubkey); }
# 522 : 0 : bool GetKey(const CKeyID &address, CKey& key) const override { return false; }
# 523 : 0 : bool HaveKey(const CKeyID &address) const override { return false; }
# 524 : 495733 : bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override { return m_spk_man.GetKeyOrigin(keyid, info); }
# 525 : : };
# 526 : :
# 527 : : class DescriptorScriptPubKeyMan : public ScriptPubKeyMan
# 528 : : {
# 529 : : private:
# 530 : : using ScriptPubKeyMap = std::map<CScript, int32_t>; // Map of scripts to descriptor range index
# 531 : : using PubKeyMap = std::map<CPubKey, int32_t>; // Map of pubkeys involved in scripts to descriptor range index
# 532 : : using CryptedKeyMap = std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>;
# 533 : : using KeyMap = std::map<CKeyID, CKey>;
# 534 : :
# 535 : : ScriptPubKeyMap m_map_script_pub_keys GUARDED_BY(cs_desc_man);
# 536 : : PubKeyMap m_map_pubkeys GUARDED_BY(cs_desc_man);
# 537 : : int32_t m_max_cached_index = -1;
# 538 : :
# 539 : : KeyMap m_map_keys GUARDED_BY(cs_desc_man);
# 540 : : CryptedKeyMap m_map_crypted_keys GUARDED_BY(cs_desc_man);
# 541 : :
# 542 : : //! keeps track of whether Unlock has run a thorough check before
# 543 : : bool m_decryption_thoroughly_checked = false;
# 544 : :
# 545 : : bool AddDescriptorKeyWithDB(WalletBatch& batch, const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man);
# 546 : :
# 547 : : KeyMap GetKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man);
# 548 : :
# 549 : : // Fetch the SigningProvider for the given script and optionally include private keys
# 550 : : std::unique_ptr<FlatSigningProvider> GetSigningProvider(const CScript& script, bool include_private = false) const;
# 551 : : // Fetch the SigningProvider for the given pubkey and always include private keys. This should only be called by signing code.
# 552 : : std::unique_ptr<FlatSigningProvider> GetSigningProvider(const CPubKey& pubkey) const;
# 553 : : // Fetch the SigningProvider for a given index and optionally include private keys. Called by the above functions.
# 554 : : std::unique_ptr<FlatSigningProvider> GetSigningProvider(int32_t index, bool include_private = false) const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man);
# 555 : :
# 556 : : protected:
# 557 : : WalletDescriptor m_wallet_descriptor GUARDED_BY(cs_desc_man);
# 558 : :
# 559 : : public:
# 560 : : DescriptorScriptPubKeyMan(WalletStorage& storage, WalletDescriptor& descriptor)
# 561 : : : ScriptPubKeyMan(storage),
# 562 : : m_wallet_descriptor(descriptor)
# 563 : 1472 : {}
# 564 : : DescriptorScriptPubKeyMan(WalletStorage& storage)
# 565 : : : ScriptPubKeyMan(storage)
# 566 : 1350 : {}
# 567 : :
# 568 : : mutable RecursiveMutex cs_desc_man;
# 569 : :
# 570 : : bool GetNewDestination(const OutputType type, CTxDestination& dest, bilingual_str& error) override;
# 571 : : isminetype IsMine(const CScript& script) const override;
# 572 : :
# 573 : : bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override;
# 574 : : bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override;
# 575 : :
# 576 : : bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error) override;
# 577 : : void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) override;
# 578 : :
# 579 : : // Tops up the descriptor cache and m_map_script_pub_keys. The cache is stored in the wallet file
# 580 : : // and is used to expand the descriptor in GetNewDestination. DescriptorScriptPubKeyMan relies
# 581 : : // more on ephemeral data than LegacyScriptPubKeyMan. For wallets using unhardened derivation
# 582 : : // (with or without private keys), the "keypool" is a single xpub.
# 583 : : bool TopUp(unsigned int size = 0) override;
# 584 : :
# 585 : : std::vector<WalletDestination> MarkUnusedAddresses(const CScript& script) override;
# 586 : :
# 587 : : bool IsHDEnabled() const override;
# 588 : :
# 589 : : //! Setup descriptors based on the given CExtkey
# 590 : : bool SetupDescriptorGeneration(const CExtKey& master_key, OutputType addr_type, bool internal);
# 591 : :
# 592 : : /** Provide a descriptor at setup time
# 593 : : * Returns false if already setup or setup fails, true if setup is successful
# 594 : : */
# 595 : : bool SetupDescriptor(std::unique_ptr<Descriptor>desc);
# 596 : :
# 597 : : bool HavePrivateKeys() const override;
# 598 : :
# 599 : : std::optional<int64_t> GetOldestKeyPoolTime() const override;
# 600 : : unsigned int GetKeyPoolSize() const override;
# 601 : :
# 602 : : int64_t GetTimeFirstKey() const override;
# 603 : :
# 604 : : std::unique_ptr<CKeyMetadata> GetMetadata(const CTxDestination& dest) const override;
# 605 : :
# 606 : : bool CanGetAddresses(bool internal = false) const override;
# 607 : :
# 608 : : std::unique_ptr<SigningProvider> GetSolvingProvider(const CScript& script) const override;
# 609 : :
# 610 : : bool CanProvide(const CScript& script, SignatureData& sigdata) override;
# 611 : :
# 612 : : bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, bilingual_str>& input_errors) const override;
# 613 : : SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const override;
# 614 : : TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = SIGHASH_DEFAULT, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const override;
# 615 : :
# 616 : : uint256 GetID() const override;
# 617 : :
# 618 : : void SetCache(const DescriptorCache& cache);
# 619 : :
# 620 : : bool AddKey(const CKeyID& key_id, const CKey& key);
# 621 : : bool AddCryptedKey(const CKeyID& key_id, const CPubKey& pubkey, const std::vector<unsigned char>& crypted_key);
# 622 : :
# 623 : : bool HasWalletDescriptor(const WalletDescriptor& desc) const;
# 624 : : void UpdateWalletDescriptor(WalletDescriptor& descriptor);
# 625 : : bool CanUpdateToWalletDescriptor(const WalletDescriptor& descriptor, std::string& error);
# 626 : : void AddDescriptorKey(const CKey& key, const CPubKey &pubkey);
# 627 : : void WriteDescriptor();
# 628 : :
# 629 : : const WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man);
# 630 : : const std::vector<CScript> GetScriptPubKeys() const;
# 631 : :
# 632 : : bool GetDescriptorString(std::string& out, const bool priv) const;
# 633 : :
# 634 : : void UpgradeDescriptorCache();
# 635 : : };
# 636 : : } // namespace wallet
# 637 : :
# 638 : : #endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H
|