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