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