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