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