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 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> Serialize(Stream & s)117 void Serialize(Stream& s) const 118 { 119 int nVersion = s.GetVersion(); 120 if (!(s.GetType() & SER_GETHASH)) { 121 s << nVersion; 122 } 123 s << nTime << vchPubKey << fInternal << m_pre_split; 124 } 125 126 template<typename Stream> Unserialize(Stream & s)127 void Unserialize(Stream& s) 128 { 129 int nVersion = s.GetVersion(); 130 if (!(s.GetType() & SER_GETHASH)) { 131 s >> nVersion; 132 } 133 s >> nTime >> vchPubKey; 134 try { 135 s >> fInternal; 136 } 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 fInternal = false; 140 } 141 try { 142 s >> m_pre_split; 143 } 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 m_pre_split = false; 147 } 148 } 149 }; 150 151 class KeyIDHasher 152 { 153 public: KeyIDHasher()154 KeyIDHasher() {} 155 operator()156 size_t operator()(const CKeyID& id) const 157 { 158 return id.GetUint64(0); 159 } 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: ScriptPubKeyMan(WalletStorage & storage)175 explicit ScriptPubKeyMan(WalletStorage& storage) : m_storage(storage) {} ~ScriptPubKeyMan()176 virtual ~ScriptPubKeyMan() {}; GetNewDestination(const OutputType type,CTxDestination & dest,std::string & error)177 virtual bool GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error) { return false; } IsMine(const CScript & script)178 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 virtual bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) { return false; } Encrypt(const CKeyingMaterial & master_key,WalletBatch * batch)182 virtual bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) { return false; } 183 GetReservedDestination(const OutputType type,bool internal,CTxDestination & address,int64_t & index,CKeyPool & keypool,std::string & error)184 virtual bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error) { return false; } KeepDestination(int64_t index,const OutputType & type)185 virtual void KeepDestination(int64_t index, const OutputType& type) {} ReturnDestination(int64_t index,bool internal,const CTxDestination & addr)186 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 virtual bool TopUp(unsigned int size = 0) { return false; } 193 194 //! Mark unused addresses as being used MarkUnusedAddresses(const CScript & script)195 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 virtual bool SetupGeneration(bool force = false) { return false; } 202 203 /* Returns true if HD is enabled */ IsHDEnabled()204 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 virtual bool CanGetAddresses(bool internal = false) const { return false; } 208 209 /** Upgrades the wallet to the specified version */ Upgrade(int prev_version,int new_version,bilingual_str & error)210 virtual bool Upgrade(int prev_version, int new_version, bilingual_str& error) { return true; } 211 HavePrivateKeys()212 virtual bool HavePrivateKeys() const { return false; } 213 214 //! The action to do when the DB needs rewrite RewriteDB()215 virtual void RewriteDB() {} 216 GetOldestKeyPoolTime()217 virtual int64_t GetOldestKeyPoolTime() const { return GetTime(); } 218 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, const PrecomputedTransactionData& txdata, 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 241 /** Prepends the wallet name in logging output to ease debugging in multi-wallet use cases */ 242 template<typename... Params> WalletLogPrintf(std::string fmt,Params...parameters)243 void WalletLogPrintf(std::string fmt, Params... parameters) const { 244 LogPrintf(("%s " + fmt).c_str(), m_storage.GetDisplayName(), parameters...); 245 }; 246 247 /** Watch-only address added */ 248 boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged; 249 250 /** Keypool has new keys */ 251 boost::signals2::signal<void ()> NotifyCanGetAddressesChanged; 252 }; 253 254 /** OutputTypes supported by the LegacyScriptPubKeyMan */ 255 static const std::unordered_set<OutputType> LEGACY_OUTPUT_TYPES { 256 OutputType::LEGACY, 257 OutputType::P2SH_SEGWIT, 258 OutputType::BECH32, 259 }; 260 261 class LegacyScriptPubKeyMan : public ScriptPubKeyMan, public FillableSigningProvider 262 { 263 private: 264 //! keeps track of whether Unlock has run a thorough check before 265 bool fDecryptionThoroughlyChecked = true; 266 267 using WatchOnlySet = std::set<CScript>; 268 using WatchKeyMap = std::map<CKeyID, CPubKey>; 269 270 WalletBatch *encrypted_batch GUARDED_BY(cs_KeyStore) = nullptr; 271 272 using CryptedKeyMap = std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>; 273 274 CryptedKeyMap mapCryptedKeys GUARDED_BY(cs_KeyStore); 275 WatchOnlySet setWatchOnly GUARDED_BY(cs_KeyStore); 276 WatchKeyMap mapWatchKeys GUARDED_BY(cs_KeyStore); 277 278 int64_t nTimeFirstKey GUARDED_BY(cs_KeyStore) = 0; 279 280 bool AddKeyPubKeyInner(const CKey& key, const CPubKey &pubkey); 281 bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); 282 283 /** 284 * Private version of AddWatchOnly method which does not accept a 285 * timestamp, and which will reset the wallet's nTimeFirstKey value to 1 if 286 * the watch key did not previously have a timestamp associated with it. 287 * Because this is an inherited virtual method, it is accessible despite 288 * being marked private, but it is marked private anyway to encourage use 289 * of the other AddWatchOnly which accepts a timestamp and sets 290 * nTimeFirstKey more intelligently for more efficient rescans. 291 */ 292 bool AddWatchOnly(const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 293 bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 294 bool AddWatchOnlyInMem(const CScript &dest); 295 //! Adds a watch-only address to the store, and saves it to disk. 296 bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 297 298 //! Adds a key to the store, and saves it to disk. 299 bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 300 301 void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch); 302 303 //! Adds a script to the store and saves it to disk 304 bool AddCScriptWithDB(WalletBatch& batch, const CScript& script); 305 306 /** Add a KeyOriginInfo to the wallet */ 307 bool AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info); 308 309 /* the HD chain data model (external chain counters) */ 310 CHDChain m_hd_chain; 311 std::unordered_map<CKeyID, CHDChain, SaltedSipHasher> m_inactive_hd_chains; 312 313 /* HD derive new child key (on internal or external chain) */ 314 void DeriveNewChildKey(WalletBatch& batch, CKeyMetadata& metadata, CKey& secret, CHDChain& hd_chain, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 315 316 std::set<int64_t> setInternalKeyPool GUARDED_BY(cs_KeyStore); 317 std::set<int64_t> setExternalKeyPool GUARDED_BY(cs_KeyStore); 318 std::set<int64_t> set_pre_split_keypool GUARDED_BY(cs_KeyStore); 319 int64_t m_max_keypool_index GUARDED_BY(cs_KeyStore) = 0; 320 std::map<CKeyID, int64_t> m_pool_key_to_index; 321 // Tracks keypool indexes to CKeyIDs of keys that have been taken out of the keypool but may be returned to it 322 std::map<int64_t, CKeyID> m_index_to_reserved_key; 323 324 //! Fetches a key from the keypool 325 bool GetKeyFromPool(CPubKey &key, const OutputType type, bool internal = false); 326 327 /** 328 * Reserves a key from the keypool and sets nIndex to its index 329 * 330 * @param[out] nIndex the index of the key in keypool 331 * @param[out] keypool the keypool the key was drawn from, which could be the 332 * the pre-split pool if present, or the internal or external pool 333 * @param fRequestedInternal true if the caller would like the key drawn 334 * from the internal keypool, false if external is preferred 335 * 336 * @return true if succeeded, false if failed due to empty keypool 337 * @throws std::runtime_error if keypool read failed, key was invalid, 338 * was not found in the wallet, or was misclassified in the internal 339 * or external keypool 340 */ 341 bool ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal); 342 343 /** 344 * Like TopUp() but adds keys for inactive HD chains. 345 * Ensures that there are at least -keypool number of keys derived after the given index. 346 * 347 * @param seed_id the CKeyID for the HD seed. 348 * @param index the index to start generating keys from 349 * @param internal whether the internal chain should be used. true for internal chain, false for external chain. 350 * 351 * @return true if seed was found and keys were derived. false if unable to derive seeds 352 */ 353 bool TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal); 354 355 public: 356 using ScriptPubKeyMan::ScriptPubKeyMan; 357 358 bool GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error) override; 359 isminetype IsMine(const CScript& script) const override; 360 361 bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override; 362 bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override; 363 364 bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error) override; 365 void KeepDestination(int64_t index, const OutputType& type) override; 366 void ReturnDestination(int64_t index, bool internal, const CTxDestination&) override; 367 368 bool TopUp(unsigned int size = 0) override; 369 370 void MarkUnusedAddresses(const CScript& script) override; 371 372 //! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo 373 void UpgradeKeyMetadata(); 374 375 bool IsHDEnabled() const override; 376 377 bool SetupGeneration(bool force = false) override; 378 379 bool Upgrade(int prev_version, int new_version, bilingual_str& error) override; 380 381 bool HavePrivateKeys() const override; 382 383 void RewriteDB() override; 384 385 int64_t GetOldestKeyPoolTime() const override; 386 size_t KeypoolCountExternalKeys() const; 387 unsigned int GetKeyPoolSize() const override; 388 389 int64_t GetTimeFirstKey() const override; 390 391 std::unique_ptr<CKeyMetadata> GetMetadata(const CTxDestination& dest) const override; 392 393 bool CanGetAddresses(bool internal = false) const override; 394 395 std::unique_ptr<SigningProvider> GetSolvingProvider(const CScript& script) const override; 396 397 bool CanProvide(const CScript& script, SignatureData& sigdata) override; 398 399 bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const override; 400 SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const override; 401 TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr) const override; 402 403 uint256 GetID() const override; 404 405 // Map from Key ID to key metadata. 406 std::map<CKeyID, CKeyMetadata> mapKeyMetadata GUARDED_BY(cs_KeyStore); 407 408 // Map from Script ID to key metadata (for watch-only keys). 409 std::map<CScriptID, CKeyMetadata> m_script_metadata GUARDED_BY(cs_KeyStore); 410 411 //! Adds a key to the store, and saves it to disk. 412 bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override; 413 //! Adds a key to the store, without saving it to disk (used by LoadWallet) 414 bool LoadKey(const CKey& key, const CPubKey &pubkey); 415 //! Adds an encrypted key to the store, and saves it to disk. 416 bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); 417 //! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) 418 bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret, bool checksum_valid); 419 void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 420 //! Adds a CScript to the store 421 bool LoadCScript(const CScript& redeemScript); 422 //! Load metadata (used by LoadWallet) 423 void LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata &metadata); 424 void LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &metadata); 425 //! Generate a new key 426 CPubKey GenerateNewKey(WalletBatch& batch, CHDChain& hd_chain, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 427 428 /* Set the HD chain model (chain child index counters) and writes it to the database */ 429 void AddHDChain(const CHDChain& chain); 430 //! Load a HD chain model (used by LoadWallet) 431 void LoadHDChain(const CHDChain& chain); GetHDChain()432 const CHDChain& GetHDChain() const { return m_hd_chain; } 433 void AddInactiveHDChain(const CHDChain& chain); 434 435 //! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) 436 bool LoadWatchOnly(const CScript &dest); 437 //! Returns whether the watch-only script is in the wallet 438 bool HaveWatchOnly(const CScript &dest) const; 439 //! Returns whether there are any watch-only things in the wallet 440 bool HaveWatchOnly() const; 441 //! Remove a watch only script from the keystore 442 bool RemoveWatchOnly(const CScript &dest); 443 bool AddWatchOnly(const CScript& dest, int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 444 445 //! Fetches a pubkey from mapWatchKeys if it exists there 446 bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const; 447 448 /* SigningProvider overrides */ 449 bool HaveKey(const CKeyID &address) const override; 450 bool GetKey(const CKeyID &address, CKey& keyOut) const override; 451 bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const override; 452 bool AddCScript(const CScript& redeemScript) override; 453 bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override; 454 455 //! Load a keypool entry 456 void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool); 457 bool NewKeyPool(); 458 void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 459 460 bool ImportScripts(const std::set<CScript> scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 461 bool ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 462 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); 463 bool ImportScriptPubKeys(const std::set<CScript>& script_pub_keys, const bool have_solving_data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 464 465 /* Returns true if the wallet can generate new keys */ 466 bool CanGenerateKeys() const; 467 468 /* Generates a new HD seed (will not be activated) */ 469 CPubKey GenerateNewSeed(); 470 471 /* Derives a new HD seed (will not be activated) */ 472 CPubKey DeriveNewSeed(const CKey& key); 473 474 /* Set the current HD seed (will reset the chain child index counters) 475 Sets the seed's version based on the current wallet version (so the 476 caller must ensure the current wallet version is correct before calling 477 this function). */ 478 void SetHDSeed(const CPubKey& key); 479 480 /** 481 * Explicitly make the wallet learn the related scripts for outputs to the 482 * given key. This is purely to make the wallet file compatible with older 483 * software, as FillableSigningProvider automatically does this implicitly for all 484 * keys now. 485 */ 486 void LearnRelatedScripts(const CPubKey& key, OutputType); 487 488 /** 489 * Same as LearnRelatedScripts, but when the OutputType is not known (and could 490 * be anything). 491 */ 492 void LearnAllRelatedScripts(const CPubKey& key); 493 494 /** 495 * Marks all keys in the keypool up to and including reserve_key as used. 496 */ 497 void MarkReserveKeysAsUsed(int64_t keypool_id) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); GetAllReserveKeys()498 const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; } 499 500 std::set<CKeyID> GetKeys() const override; 501 }; 502 503 /** Wraps a LegacyScriptPubKeyMan so that it can be returned in a new unique_ptr. Does not provide privkeys */ 504 class LegacySigningProvider : public SigningProvider 505 { 506 private: 507 const LegacyScriptPubKeyMan& m_spk_man; 508 public: LegacySigningProvider(const LegacyScriptPubKeyMan & spk_man)509 explicit LegacySigningProvider(const LegacyScriptPubKeyMan& spk_man) : m_spk_man(spk_man) {} 510 GetCScript(const CScriptID & scriptid,CScript & script)511 bool GetCScript(const CScriptID &scriptid, CScript& script) const override { return m_spk_man.GetCScript(scriptid, script); } HaveCScript(const CScriptID & scriptid)512 bool HaveCScript(const CScriptID &scriptid) const override { return m_spk_man.HaveCScript(scriptid); } GetPubKey(const CKeyID & address,CPubKey & pubkey)513 bool GetPubKey(const CKeyID &address, CPubKey& pubkey) const override { return m_spk_man.GetPubKey(address, pubkey); } GetKey(const CKeyID & address,CKey & key)514 bool GetKey(const CKeyID &address, CKey& key) const override { return false; } HaveKey(const CKeyID & address)515 bool HaveKey(const CKeyID &address) const override { return false; } GetKeyOrigin(const CKeyID & keyid,KeyOriginInfo & info)516 bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override { return m_spk_man.GetKeyOrigin(keyid, info); } 517 }; 518 519 class DescriptorScriptPubKeyMan : public ScriptPubKeyMan 520 { 521 private: 522 using ScriptPubKeyMap = std::map<CScript, int32_t>; // Map of scripts to descriptor range index 523 using PubKeyMap = std::map<CPubKey, int32_t>; // Map of pubkeys involved in scripts to descriptor range index 524 using CryptedKeyMap = std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>; 525 using KeyMap = std::map<CKeyID, CKey>; 526 527 ScriptPubKeyMap m_map_script_pub_keys GUARDED_BY(cs_desc_man); 528 PubKeyMap m_map_pubkeys GUARDED_BY(cs_desc_man); 529 int32_t m_max_cached_index = -1; 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: DescriptorScriptPubKeyMan(WalletStorage & storage,WalletDescriptor & descriptor)552 DescriptorScriptPubKeyMan(WalletStorage& storage, WalletDescriptor& descriptor) 553 : ScriptPubKeyMan(storage), 554 m_wallet_descriptor(descriptor) 555 {} DescriptorScriptPubKeyMan(WalletStorage & storage)556 DescriptorScriptPubKeyMan(WalletStorage& storage) 557 : ScriptPubKeyMan(storage) 558 {} 559 560 mutable RecursiveMutex cs_desc_man; 561 562 bool GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error) override; 563 isminetype IsMine(const CScript& script) const override; 564 565 bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override; 566 bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override; 567 568 bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error) override; 569 void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) override; 570 571 // Tops up the descriptor cache and m_map_script_pub_keys. The cache is stored in the wallet file 572 // and is used to expand the descriptor in GetNewDestination. DescriptorScriptPubKeyMan relies 573 // more on ephemeral data than LegacyScriptPubKeyMan. For wallets using unhardened derivation 574 // (with or without private keys), the "keypool" is a single xpub. 575 bool TopUp(unsigned int size = 0) override; 576 577 void MarkUnusedAddresses(const CScript& script) override; 578 579 bool IsHDEnabled() const override; 580 581 //! Setup descriptors based on the given CExtkey 582 bool SetupDescriptorGeneration(const CExtKey& master_key, OutputType addr_type, bool internal); 583 584 /** Provide a descriptor at setup time 585 * Returns false if already setup or setup fails, true if setup is successful 586 */ 587 bool SetupDescriptor(std::unique_ptr<Descriptor>desc); 588 589 bool HavePrivateKeys() const override; 590 591 int64_t GetOldestKeyPoolTime() const override; 592 unsigned int GetKeyPoolSize() const override; 593 594 int64_t GetTimeFirstKey() const override; 595 596 std::unique_ptr<CKeyMetadata> GetMetadata(const CTxDestination& dest) const override; 597 598 bool CanGetAddresses(bool internal = false) const override; 599 600 std::unique_ptr<SigningProvider> GetSolvingProvider(const CScript& script) const override; 601 602 bool CanProvide(const CScript& script, SignatureData& sigdata) override; 603 604 bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const override; 605 SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const override; 606 TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr) const override; 607 608 uint256 GetID() const override; 609 610 void SetCache(const DescriptorCache& cache); 611 612 bool AddKey(const CKeyID& key_id, const CKey& key); 613 bool AddCryptedKey(const CKeyID& key_id, const CPubKey& pubkey, const std::vector<unsigned char>& crypted_key); 614 615 bool HasWalletDescriptor(const WalletDescriptor& desc) const; 616 void UpdateWalletDescriptor(WalletDescriptor& descriptor); 617 bool CanUpdateToWalletDescriptor(const WalletDescriptor& descriptor, std::string& error); 618 void AddDescriptorKey(const CKey& key, const CPubKey &pubkey); 619 void WriteDescriptor(); 620 621 const WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man); 622 const std::vector<CScript> GetScriptPubKeys() const; 623 624 bool GetDescriptorString(std::string& out) const; 625 626 void UpgradeDescriptorCache(); 627 }; 628 629 #endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H 630