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