Bitcoin Core  26.1.0
P2P Digital Currency
scriptpubkeyman.h
Go to the documentation of this file.
1 // Copyright (c) 2019-2022 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 <addresstype.h>
9 #include <logging.h>
10 #include <psbt.h>
11 #include <script/descriptor.h>
12 #include <script/script.h>
13 #include <script/signingprovider.h>
14 #include <util/error.h>
15 #include <util/message.h>
16 #include <util/result.h>
17 #include <util/time.h>
18 #include <wallet/crypter.h>
19 #include <wallet/types.h>
20 #include <wallet/walletdb.h>
21 #include <wallet/walletutil.h>
22 
23 #include <boost/signals2/signal.hpp>
24 
25 #include <optional>
26 #include <unordered_map>
27 
28 enum class OutputType;
29 struct bilingual_str;
30 
31 namespace wallet {
32 struct MigrationData;
33 
34 // Wallet storage things that ScriptPubKeyMans need in order to be able to store things to the wallet database.
35 // It provides access to things that are part of the entire wallet and not specific to a ScriptPubKeyMan such as
36 // wallet flags, wallet version, encryption keys, encryption status, and the database itself. This allows a
37 // ScriptPubKeyMan to have callbacks into CWallet without causing a circular dependency.
38 // WalletStorage should be the same for all ScriptPubKeyMans of a wallet.
40 {
41 public:
42  virtual ~WalletStorage() = default;
43  virtual std::string GetDisplayName() const = 0;
44  virtual WalletDatabase& GetDatabase() const = 0;
45  virtual bool IsWalletFlagSet(uint64_t) const = 0;
46  virtual void UnsetBlankWalletFlag(WalletBatch&) = 0;
47  virtual bool CanSupportFeature(enum WalletFeature) const = 0;
48  virtual void SetMinVersion(enum WalletFeature, WalletBatch* = nullptr) = 0;
49  virtual const CKeyingMaterial& GetEncryptionKey() const = 0;
50  virtual bool HasEncryptionKeys() const = 0;
51  virtual bool IsLocked() const = 0;
52 };
53 
55 static constexpr int64_t UNKNOWN_TIME = std::numeric_limits<int64_t>::max();
56 
58 static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000;
59 
60 std::vector<CKeyID> GetAffectedKeys(const CScript& spk, const SigningProvider& provider);
61 
111 class CKeyPool
112 {
113 public:
115  int64_t nTime;
119  bool fInternal;
122 
123  CKeyPool();
124  CKeyPool(const CPubKey& vchPubKeyIn, bool internalIn);
125 
126  template<typename Stream>
127  void Serialize(Stream& s) const
128  {
129  s << int{259900}; // Unused field, writes the highest client version ever written
130  s << nTime << vchPubKey << fInternal << m_pre_split;
131  }
132 
133  template<typename Stream>
134  void Unserialize(Stream& s)
135  {
136  s >> int{}; // Discard unused field
137  s >> nTime >> vchPubKey;
138  try {
139  s >> fInternal;
140  } catch (std::ios_base::failure&) {
141  /* flag as external address if we can't read the internal boolean
142  (this will be the case for any wallet before the HD chain split version) */
143  fInternal = false;
144  }
145  try {
146  s >> m_pre_split;
147  } catch (std::ios_base::failure&) {
148  /* flag as postsplit address if we can't read the m_pre_split boolean
149  (this will be the case for any wallet that upgrades to HD chain split) */
150  m_pre_split = false;
151  }
152  }
153 };
154 
156 {
158  std::optional<bool> internal;
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  */
169 {
170 protected:
172 
173 public:
174  explicit ScriptPubKeyMan(WalletStorage& storage) : m_storage(storage) {}
175  virtual ~ScriptPubKeyMan() {};
176  virtual util::Result<CTxDestination> GetNewDestination(const OutputType type) { return util::Error{Untranslated("Not supported")}; }
177  virtual isminetype IsMine(const CScript& script) const { return ISMINE_NO; }
178 
180  virtual bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) { return false; }
181  virtual bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) { return false; }
182 
183  virtual util::Result<CTxDestination> GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool) { return util::Error{Untranslated("Not supported")}; }
184  virtual void KeepDestination(int64_t index, const OutputType& type) {}
185  virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) {}
186 
191  virtual bool TopUp(unsigned int size = 0) { return false; }
192 
200  virtual std::vector<WalletDestination> MarkUnusedAddresses(const CScript& script) { return {}; }
201 
206  virtual bool SetupGeneration(bool force = false) { return false; }
207 
208  /* Returns true if HD is enabled */
209  virtual bool IsHDEnabled() const { return false; }
210 
211  /* Returns true if the wallet can give out new addresses. This means it has keys in the keypool or can generate new keys */
212  virtual bool CanGetAddresses(bool internal = false) const { return false; }
213 
215  virtual bool Upgrade(int prev_version, int new_version, bilingual_str& error) { return true; }
216 
217  virtual bool HavePrivateKeys() const { return false; }
218 
220  virtual void RewriteDB() {}
221 
222  virtual std::optional<int64_t> GetOldestKeyPoolTime() const { return GetTime(); }
223 
224  virtual unsigned int GetKeyPoolSize() const { return 0; }
225 
226  virtual int64_t GetTimeFirstKey() const { return 0; }
227 
228  virtual std::unique_ptr<CKeyMetadata> GetMetadata(const CTxDestination& dest) const { return nullptr; }
229 
230  virtual std::unique_ptr<SigningProvider> GetSolvingProvider(const CScript& script) const { return nullptr; }
231 
235  virtual bool CanProvide(const CScript& script, SignatureData& sigdata) { return false; }
236 
238  virtual bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, bilingual_str>& input_errors) const { return false; }
240  virtual SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const { return SigningResult::SIGNING_FAILED; };
242  virtual TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = SIGHASH_DEFAULT, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const { return TransactionError::INVALID_PSBT; }
243 
244  virtual uint256 GetID() const { return uint256(); }
245 
247  virtual std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys() const { return {}; };
248 
250  template <typename... Params>
251  void WalletLogPrintf(const char* fmt, Params... parameters) const
252  {
253  LogPrintf(("%s " + std::string{fmt}).c_str(), m_storage.GetDisplayName(), parameters...);
254  };
255 
257  boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;
258 
260  boost::signals2::signal<void ()> NotifyCanGetAddressesChanged;
261 
263  boost::signals2::signal<void (const ScriptPubKeyMan* spkm, int64_t new_birth_time)> NotifyFirstKeyTimeChanged;
264 };
265 
267 static const std::unordered_set<OutputType> LEGACY_OUTPUT_TYPES {
271 };
272 
273 class DescriptorScriptPubKeyMan;
274 
276 {
277 private:
280 
281  using WatchOnlySet = std::set<CScript>;
282  using WatchKeyMap = std::map<CKeyID, CPubKey>;
283 
284  WalletBatch *encrypted_batch GUARDED_BY(cs_KeyStore) = nullptr;
285 
286  using CryptedKeyMap = std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>;
287 
288  CryptedKeyMap mapCryptedKeys GUARDED_BY(cs_KeyStore);
289  WatchOnlySet setWatchOnly GUARDED_BY(cs_KeyStore);
290  WatchKeyMap mapWatchKeys GUARDED_BY(cs_KeyStore);
291 
292  // By default, do not scan any block until keys/scripts are generated/imported
293  int64_t nTimeFirstKey GUARDED_BY(cs_KeyStore) = UNKNOWN_TIME;
294 
296  int64_t m_keypool_size GUARDED_BY(cs_KeyStore){DEFAULT_KEYPOOL_SIZE};
297 
298  bool AddKeyPubKeyInner(const CKey& key, const CPubKey &pubkey);
299  bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
300 
312  bool AddWatchOnlyInMem(const CScript &dest);
314  bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
315 
317  bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
318 
319  void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
320 
322  bool AddCScriptWithDB(WalletBatch& batch, const CScript& script);
323 
325  bool AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info);
326 
327  /* the HD chain data model (external chain counters) */
329  std::unordered_map<CKeyID, CHDChain, SaltedSipHasher> m_inactive_hd_chains;
330 
331  /* HD derive new child key (on internal or external chain) */
332  void DeriveNewChildKey(WalletBatch& batch, CKeyMetadata& metadata, CKey& secret, CHDChain& hd_chain, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
333 
334  std::set<int64_t> setInternalKeyPool GUARDED_BY(cs_KeyStore);
335  std::set<int64_t> setExternalKeyPool GUARDED_BY(cs_KeyStore);
336  std::set<int64_t> set_pre_split_keypool GUARDED_BY(cs_KeyStore);
337  int64_t m_max_keypool_index GUARDED_BY(cs_KeyStore) = 0;
339  // Tracks keypool indexes to CKeyIDs of keys that have been taken out of the keypool but may be returned to it
341 
343  bool GetKeyFromPool(CPubKey &key, const OutputType type);
344 
359  bool ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal);
360 
371  bool TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal);
372 
373  bool TopUpChain(CHDChain& chain, unsigned int size);
374 public:
375  LegacyScriptPubKeyMan(WalletStorage& storage, int64_t keypool_size) : ScriptPubKeyMan(storage), m_keypool_size(keypool_size) {}
376 
378  isminetype IsMine(const CScript& script) const override;
379 
380  bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override;
381  bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override;
382 
383  util::Result<CTxDestination> GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool) override;
384  void KeepDestination(int64_t index, const OutputType& type) override;
385  void ReturnDestination(int64_t index, bool internal, const CTxDestination&) override;
386 
387  bool TopUp(unsigned int size = 0) override;
388 
389  std::vector<WalletDestination> MarkUnusedAddresses(const CScript& script) override;
390 
392  void UpgradeKeyMetadata();
393 
394  bool IsHDEnabled() const override;
395 
396  bool SetupGeneration(bool force = false) override;
397 
398  bool Upgrade(int prev_version, int new_version, bilingual_str& error) override;
399 
400  bool HavePrivateKeys() const override;
401 
402  void RewriteDB() override;
403 
404  std::optional<int64_t> GetOldestKeyPoolTime() const override;
405  size_t KeypoolCountExternalKeys() const;
406  unsigned int GetKeyPoolSize() const override;
407 
408  int64_t GetTimeFirstKey() const override;
409 
410  std::unique_ptr<CKeyMetadata> GetMetadata(const CTxDestination& dest) const override;
411 
412  bool CanGetAddresses(bool internal = false) const override;
413 
414  std::unique_ptr<SigningProvider> GetSolvingProvider(const CScript& script) const override;
415 
416  bool CanProvide(const CScript& script, SignatureData& sigdata) override;
417 
418  bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, bilingual_str>& input_errors) const override;
419  SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const override;
420  TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = SIGHASH_DEFAULT, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const override;
421 
422  uint256 GetID() const override;
423 
424  // Map from Key ID to key metadata.
425  std::map<CKeyID, CKeyMetadata> mapKeyMetadata GUARDED_BY(cs_KeyStore);
426 
427  // Map from Script ID to key metadata (for watch-only keys).
428  std::map<CScriptID, CKeyMetadata> m_script_metadata GUARDED_BY(cs_KeyStore);
429 
431  bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override;
433  bool LoadKey(const CKey& key, const CPubKey &pubkey);
435  bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
437  bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret, bool checksum_valid);
438  void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
440  bool LoadCScript(const CScript& redeemScript);
442  void LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata &metadata);
443  void LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &metadata);
445  CPubKey GenerateNewKey(WalletBatch& batch, CHDChain& hd_chain, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
446 
447  /* Set the HD chain model (chain child index counters) and writes it to the database */
448  void AddHDChain(const CHDChain& chain);
450  void LoadHDChain(const CHDChain& chain);
451  const CHDChain& GetHDChain() const { return m_hd_chain; }
452  void AddInactiveHDChain(const CHDChain& chain);
453 
455  bool LoadWatchOnly(const CScript &dest);
457  bool HaveWatchOnly(const CScript &dest) const;
459  bool HaveWatchOnly() const;
461  bool RemoveWatchOnly(const CScript &dest);
462  bool AddWatchOnly(const CScript& dest, int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
463 
465  bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const;
466 
467  /* SigningProvider overrides */
468  bool HaveKey(const CKeyID &address) const override;
469  bool GetKey(const CKeyID &address, CKey& keyOut) const override;
470  bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const override;
471  bool AddCScript(const CScript& redeemScript) override;
472  bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override;
473 
475  void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool);
476  bool NewKeyPool();
478 
479  bool ImportScripts(const std::set<CScript> scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
480  bool ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
481  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);
482  bool ImportScriptPubKeys(const std::set<CScript>& script_pub_keys, const bool have_solving_data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
483 
484  /* Returns true if the wallet can generate new keys */
485  bool CanGenerateKeys() const;
486 
487  /* Generates a new HD seed (will not be activated) */
489 
490  /* Derives a new HD seed (will not be activated) */
491  CPubKey DeriveNewSeed(const CKey& key);
492 
493  /* Set the current HD seed (will reset the chain child index counters)
494  Sets the seed's version based on the current wallet version (so the
495  caller must ensure the current wallet version is correct before calling
496  this function). */
497  void SetHDSeed(const CPubKey& key);
498 
505  void LearnRelatedScripts(const CPubKey& key, OutputType);
506 
511  void LearnAllRelatedScripts(const CPubKey& key);
512 
521  const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; }
522 
523  std::set<CKeyID> GetKeys() const override;
524  std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys() const override;
525 
530  std::unordered_set<CScript, SaltedSipHasher> GetNotMineScriptPubKeys() const;
531 
534  std::optional<MigrationData> MigrateToDescriptor();
536  bool DeleteRecords();
537 };
538 
541 {
542 private:
544 public:
545  explicit LegacySigningProvider(const LegacyScriptPubKeyMan& spk_man) : m_spk_man(spk_man) {}
546 
547  bool GetCScript(const CScriptID &scriptid, CScript& script) const override { return m_spk_man.GetCScript(scriptid, script); }
548  bool HaveCScript(const CScriptID &scriptid) const override { return m_spk_man.HaveCScript(scriptid); }
549  bool GetPubKey(const CKeyID &address, CPubKey& pubkey) const override { return m_spk_man.GetPubKey(address, pubkey); }
550  bool GetKey(const CKeyID &address, CKey& key) const override { return false; }
551  bool HaveKey(const CKeyID &address) const override { return false; }
552  bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override { return m_spk_man.GetKeyOrigin(keyid, info); }
553 };
554 
556 {
557 private:
558  using ScriptPubKeyMap = std::map<CScript, int32_t>; // Map of scripts to descriptor range index
559  using PubKeyMap = std::map<CPubKey, int32_t>; // Map of pubkeys involved in scripts to descriptor range index
560  using CryptedKeyMap = std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>;
561  using KeyMap = std::map<CKeyID, CKey>;
562 
563  ScriptPubKeyMap m_map_script_pub_keys GUARDED_BY(cs_desc_man);
564  PubKeyMap m_map_pubkeys GUARDED_BY(cs_desc_man);
565  int32_t m_max_cached_index = -1;
566 
567  KeyMap m_map_keys GUARDED_BY(cs_desc_man);
568  CryptedKeyMap m_map_crypted_keys GUARDED_BY(cs_desc_man);
569 
572 
574  int64_t m_keypool_size GUARDED_BY(cs_desc_man){DEFAULT_KEYPOOL_SIZE};
575 
576  bool AddDescriptorKeyWithDB(WalletBatch& batch, const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man);
577 
579 
580  // Cached FlatSigningProviders to avoid regenerating them each time they are needed.
582  // Fetch the SigningProvider for the given script and optionally include private keys
583  std::unique_ptr<FlatSigningProvider> GetSigningProvider(const CScript& script, bool include_private = false) const;
584  // Fetch the SigningProvider for the given pubkey and always include private keys. This should only be called by signing code.
585  std::unique_ptr<FlatSigningProvider> GetSigningProvider(const CPubKey& pubkey) const;
586  // Fetch the SigningProvider for a given index and optionally include private keys. Called by the above functions.
587  std::unique_ptr<FlatSigningProvider> GetSigningProvider(int32_t index, bool include_private = false) const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man);
588 
589 protected:
590  WalletDescriptor m_wallet_descriptor GUARDED_BY(cs_desc_man);
591 
592 public:
593  DescriptorScriptPubKeyMan(WalletStorage& storage, WalletDescriptor& descriptor, int64_t keypool_size)
594  : ScriptPubKeyMan(storage),
595  m_keypool_size(keypool_size),
596  m_wallet_descriptor(descriptor)
597  {}
598  DescriptorScriptPubKeyMan(WalletStorage& storage, int64_t keypool_size)
599  : ScriptPubKeyMan(storage),
600  m_keypool_size(keypool_size)
601  {}
602 
604 
606  isminetype IsMine(const CScript& script) const override;
607 
608  bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override;
609  bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override;
610 
611  util::Result<CTxDestination> GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool) override;
612  void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) override;
613 
614  // Tops up the descriptor cache and m_map_script_pub_keys. The cache is stored in the wallet file
615  // and is used to expand the descriptor in GetNewDestination. DescriptorScriptPubKeyMan relies
616  // more on ephemeral data than LegacyScriptPubKeyMan. For wallets using unhardened derivation
617  // (with or without private keys), the "keypool" is a single xpub.
618  bool TopUp(unsigned int size = 0) override;
619 
620  std::vector<WalletDestination> MarkUnusedAddresses(const CScript& script) override;
621 
622  bool IsHDEnabled() const override;
623 
625  bool SetupDescriptorGeneration(const CExtKey& master_key, OutputType addr_type, bool internal);
626 
630  bool SetupDescriptor(std::unique_ptr<Descriptor>desc);
631 
632  bool HavePrivateKeys() const override;
633 
634  std::optional<int64_t> GetOldestKeyPoolTime() const override;
635  unsigned int GetKeyPoolSize() const override;
636 
637  int64_t GetTimeFirstKey() const override;
638 
639  std::unique_ptr<CKeyMetadata> GetMetadata(const CTxDestination& dest) const override;
640 
641  bool CanGetAddresses(bool internal = false) const override;
642 
643  std::unique_ptr<SigningProvider> GetSolvingProvider(const CScript& script) const override;
644 
645  bool CanProvide(const CScript& script, SignatureData& sigdata) override;
646 
647  bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, bilingual_str>& input_errors) const override;
648  SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const override;
649  TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = SIGHASH_DEFAULT, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const override;
650 
651  uint256 GetID() const override;
652 
653  void SetCache(const DescriptorCache& cache);
654 
655  bool AddKey(const CKeyID& key_id, const CKey& key);
656  bool AddCryptedKey(const CKeyID& key_id, const CPubKey& pubkey, const std::vector<unsigned char>& crypted_key);
657 
658  bool HasWalletDescriptor(const WalletDescriptor& desc) const;
659  void UpdateWalletDescriptor(WalletDescriptor& descriptor);
660  bool CanUpdateToWalletDescriptor(const WalletDescriptor& descriptor, std::string& error);
661  void AddDescriptorKey(const CKey& key, const CPubKey &pubkey);
662  void WriteDescriptor();
663 
665  std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys() const override;
666  std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys(int32_t minimum_index) const;
667  int32_t GetEndRange() const;
668 
669  bool GetDescriptorString(std::string& out, const bool priv) const;
670 
671  void UpgradeDescriptorCache();
672 };
673 
676 {
678  std::vector<std::pair<std::string, int64_t>> watch_descs;
679  std::vector<std::pair<std::string, int64_t>> solvable_descs;
680  std::vector<std::unique_ptr<DescriptorScriptPubKeyMan>> desc_spkms;
681  std::shared_ptr<CWallet> watchonly_wallet{nullptr};
682  std::shared_ptr<CWallet> solvable_wallet{nullptr};
683 };
684 
685 } // namespace wallet
686 
687 #endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H
int64_t GetTimeFirstKey() const override
virtual std::string GetDisplayName() const =0
bool GetCScript(const CScriptID &scriptid, CScript &script) const override
bool AddWatchOnlyInMem(const CScript &dest)
virtual SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const
Sign a message with the given script.
bool ImportPrivKeys(const std::map< CKeyID, CKey > &privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
static const std::string sighash
Definition: sighash.json.h:3
void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Update wallet first key creation time.
std::map< CKeyID, CPubKey > WatchKeyMap
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override
Adds a key to the store, and saves it to disk.
virtual uint256 GetID() const
bool RemoveWatchOnly(const CScript &dest)
Remove a watch only script from the keystore.
bool GetKey(const CKeyID &address, CKey &key) const override
std::vector< WalletDestination > MarkUnusedAddresses(const CScript &script) override
Mark unused addresses as being used Affects all keys up to and including the one determined by provid...
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
Adds an encrypted key to the store, and saves it to disk.
void UpgradeKeyMetadata()
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
std::vector< WalletDestination > MarkUnusedAddresses(const CScript &script) override
Mark unused addresses as being used Affects all keys up to and including the one determined by provid...
const CHDChain & GetHDChain() const
bool Upgrade(int prev_version, int new_version, bilingual_str &error) override
Upgrades the wallet to the specified version.
virtual bool IsWalletFlagSet(uint64_t) const =0
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
virtual TransactionError FillPSBT(PartiallySignedTransaction &psbt, const PrecomputedTransactionData &txdata, int sighash_type=SIGHASH_DEFAULT, bool sign=true, bool bip32derivs=false, int *n_signed=nullptr, bool finalize=true) const
Adds script and derivation path information to a PSBT, and optionally signs it.
virtual WalletDatabase & GetDatabase() const =0
util::Result< CTxDestination > GetNewDestination(const OutputType type) override
isminetype IsMine(const CScript &script) const override
void AddKeypoolPubkeyWithDB(const CPubKey &pubkey, const bool internal, WalletBatch &batch)
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) ...
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override
Bilingual messages:
Definition: translation.h:18
std::map< int64_t, CKeyID > m_index_to_reserved_key
bool NewKeyPool()
Mark old keypool keys as used, and generate all new keys.
void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
unsigned int GetKeyPoolSize() const override
virtual bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch)
RecursiveMutex cs_KeyStore
bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const override
bool TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal)
Like TopUp() but adds keys for inactive HD chains.
SigningResult
Definition: message.h:43
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:48
bool AddCScript(const CScript &redeemScript) override
std::optional< MigrationData > MigrateToDescriptor()
Get the DescriptorScriptPubKeyMans (with private keys) that have the same scriptPubKeys as this Legac...
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const override
Sign a message with the given script.
Definition: key.h:208
bool CanGetAddresses(bool internal=false) const override
struct containing information needed for migrating legacy wallets to descriptor wallets ...
std::vector< std::pair< std::string, int64_t > > solvable_descs
bool SetupDescriptorGeneration(const CExtKey &master_key, OutputType addr_type, bool internal)
Setup descriptors based on the given CExtkey.
std::map< CKeyID, CKey > KeyMap
bool CanUpdateToWalletDescriptor(const WalletDescriptor &descriptor, std::string &error)
DescriptorScriptPubKeyMan(WalletStorage &storage, int64_t keypool_size)
boost::signals2::signal< void()> NotifyCanGetAddressesChanged
Keypool has new keys.
std::map< CKeyID, std::pair< CPubKey, std::vector< unsigned char > >> CryptedKeyMap
static const unsigned int DEFAULT_KEYPOOL_SIZE
Default for -keypool.
bool AddWatchOnly(const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Private version of AddWatchOnly method which does not accept a timestamp, and which will reset the wa...
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
std::vector< std::pair< std::string, int64_t > > watch_descs
void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata)
bool AddKeyPubKeyWithDB(WalletBatch &batch, const CKey &key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Adds a key to the store, and saves it to disk.
bool m_pre_split
Whether this key was generated for a keypool before the wallet was upgraded to HD-split.
void UpdateWalletDescriptor(WalletDescriptor &descriptor)
bool ImportScriptPubKeys(const std::set< CScript > &script_pub_keys, const bool have_solving_data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
void SetHDSeed(const CPubKey &key)
bool DeleteRecords()
Delete all the records ofthis LegacyScriptPubKeyMan from disk.
A version of CTransaction with the PSBT format.
Definition: psbt.h:946
virtual void UnsetBlankWalletFlag(WalletBatch &)=0
Access to the wallet database.
Definition: walletdb.h:190
A key from a CWallet&#39;s keypool.
bool GetKey(const CKeyID &address, CKey &keyOut) const override
boost::signals2::signal< void(const ScriptPubKeyMan *spkm, int64_t new_birth_time)> NotifyFirstKeyTimeChanged
Birth time changed.
void Unserialize(Stream &s)
bool AddKey(const CKeyID &key_id, const CKey &key)
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
virtual bool SignTransaction(CMutableTransaction &tx, const std::map< COutPoint, Coin > &coins, int sighash, std::map< int, bilingual_str > &input_errors) const
Creates new signatures and adds them to the transaction.
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
virtual bool IsLocked() const =0
virtual bool CanProvide(const CScript &script, SignatureData &sigdata)
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that...
Taproot only; implied when sighash byte is missing, and equivalent to SIGHASH_ALL.
Definition: interpreter.h:33
unsigned int GetKeyPoolSize() const override
bool IsHDEnabled() const override
std::set< CScript > WatchOnlySet
std::map< CPubKey, int32_t > PubKeyMap
OutputType
Definition: outputtype.h:17
int64_t nTime
The time at which the key was generated. Set in AddKeypoolPubKeyWithDB.
virtual std::optional< int64_t > GetOldestKeyPoolTime() const
int64_t m_keypool_size GUARDED_BY(cs_KeyStore)
Number of pre-generated keys/scripts (part of the look-ahead process, used to detect payments) ...
bool CanGetAddresses(bool internal=false) const override
bool SetupDescriptor(std::unique_ptr< Descriptor >desc)
Provide a descriptor at setup time Returns false if already setup or setup fails, true if setup is su...
void SetCache(const DescriptorCache &cache)
virtual isminetype IsMine(const CScript &script) const
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that...
bool AddCryptedKey(const CKeyID &key_id, const CPubKey &pubkey, const std::vector< unsigned char > &crypted_key)
WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
bool HaveKey(const CKeyID &address) const override
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override
virtual std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const
ScriptPubKeyMan(WalletStorage &storage)
static constexpr int64_t UNKNOWN_TIME
Constant representing an unknown spkm creation time.
virtual const CKeyingMaterial & GetEncryptionKey() const =0
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that...
std::set< CKeyID > GetKeys() const override
bool HavePrivateKeys() const override
virtual bool CanSupportFeature(enum WalletFeature) const =0
CPubKey vchPubKey
The public key.
bool fInternal
Whether this keypool entry is in the internal keypool (for change outputs)
void ReturnDestination(int64_t index, bool internal, const CTxDestination &addr) override
std::vector< CKeyID > GetAffectedKeys(const CScript &spk, const SigningProvider &provider)
virtual void SetMinVersion(enum WalletFeature, WalletBatch *=nullptr)=0
void RewriteDB() override
The action to do when the DB needs rewrite.
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
virtual bool HasEncryptionKeys() const =0
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
std::optional< int64_t > GetOldestKeyPoolTime() const override
Wraps a LegacyScriptPubKeyMan so that it can be returned in a new unique_ptr.
bool HaveKey(const CKeyID &address) const override
void AddHDChain(const CHDChain &chain)
virtual std::vector< WalletDestination > MarkUnusedAddresses(const CScript &script)
Mark unused addresses as being used Affects all keys up to and including the one determined by provid...
An encapsulated public key.
Definition: pubkey.h:33
Fillable signing provider that keeps keys in an address->secret map.
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
Definition: types.h:40
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const override
Sign a message with the given script.
WalletFeature
(client) version numbers for particular wallet features
Definition: walletutil.h:15
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
isminetype IsMine(const CScript &script) const override
void ReturnDestination(int64_t index, bool internal, const CTxDestination &) override
WalletBatch *encrypted_batch GUARDED_BY(cs_KeyStore)
ScriptPubKeyMap m_map_script_pub_keys GUARDED_BY(cs_desc_man)
std::map< CScript, int32_t > ScriptPubKeyMap
bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
virtual bool IsHDEnabled() const
util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool) override
LegacySigningProvider(const LegacyScriptPubKeyMan &spk_man)
virtual std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const
static const std::unordered_set< OutputType > LEGACY_OUTPUT_TYPES
OutputTypes supported by the LegacyScriptPubKeyMan.
std::optional< int64_t > GetOldestKeyPoolTime() const override
std::unordered_set< CScript, SaltedSipHasher > GetNotMineScriptPubKeys() const
Retrieves scripts that were imported by bugs into the legacy spkm and are simply invalid, such as a sh(sh(pkh())) script, or not watched.
bool SignTransaction(CMutableTransaction &tx, const std::map< COutPoint, Coin > &coins, int sighash, std::map< int, bilingual_str > &input_errors) const override
Creates new signatures and adds them to the transaction.
uint256 GetID() const override
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, bool checksum_valid)
Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) ...
Descriptor with some wallet metadata.
Definition: walletutil.h:84
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)
virtual bool HavePrivateKeys() const
bool HaveCScript(const CScriptID &scriptid) const override
bool AddCScriptWithDB(WalletBatch &batch, const CScript &script)
Adds a script to the store and saves it to disk.
virtual void KeepDestination(int64_t index, const OutputType &type)
virtual unsigned int GetKeyPoolSize() const
bool CheckDecryptionKey(const CKeyingMaterial &master_key, bool accept_no_keys=false) override
Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the ke...
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
Definition: addresstype.h:129
virtual void RewriteDB()
The action to do when the DB needs rewrite.
bool TopUpChain(CHDChain &chain, unsigned int size)
virtual bool CanGetAddresses(bool internal=false) const
256-bit opaque blob.
Definition: uint256.h:106
CPubKey DeriveNewSeed(const CKey &key)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
void LearnRelatedScripts(const CPubKey &key, OutputType)
Explicitly make the wallet learn the related scripts for outputs to the given key.
void WalletLogPrintf(const char *fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
An interface to be implemented by keystores that support signing.
util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool) override
std::unordered_map< CKeyID, CHDChain, SaltedSipHasher > m_inactive_hd_chains
const LegacyScriptPubKeyMan & m_spk_man
bool ImportScripts(const std::set< CScript > scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
bool error(const char *fmt, const Args &... args)
Definition: logging.h:262
const CChainParams & Params()
Return the currently selected parameters.
Cache for single descriptor&#39;s derived extended pubkeys.
Definition: descriptor.h:19
bool GetDescriptorString(std::string &out, const bool priv) const
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:412
virtual util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool)
bool SetupGeneration(bool force=false) override
Sets up the key generation stuff, i.e.
void LearnAllRelatedScripts(const CPubKey &key)
Same as LearnRelatedScripts, but when the OutputType is not known (and could be anything).
std::map< CKeyID, std::pair< CPubKey, std::vector< unsigned char > >> CryptedKeyMap
virtual bool CheckDecryptionKey(const CKeyingMaterial &master_key, bool accept_no_keys=false)
Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the ke...
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:23
std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const override
std::map< int32_t, FlatSigningProvider > m_map_signing_providers
bool m_decryption_thoroughly_checked
keeps track of whether Unlock has run a thorough check before
bool AddKeyPubKeyInner(const CKey &key, const CPubKey &pubkey)
TransactionError
Definition: error.h:22
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
virtual bool HaveCScript(const CScriptID &hash) const override
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
void Serialize(Stream &s) const
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
Fetches a pubkey from mapWatchKeys if it exists there.
bool HaveWatchOnly() const
Returns whether there are any watch-only things in the wallet.
void AddDescriptorKey(const CKey &key, const CPubKey &pubkey)
void AddInactiveHDChain(const CHDChain &chain)
A reference to a CScript: the Hash160 of its serialization.
Definition: script.h:581
A mutable version of CTransaction.
Definition: transaction.h:379
CPubKey GenerateNewKey(WalletBatch &batch, CHDChain &hd_chain, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Generate a new key.
bool GetKeyFromPool(CPubKey &key, const OutputType type)
Fetches a key from the keypool.
int64_t m_keypool_size GUARDED_BY(cs_desc_man)
Number of pre-generated keys/scripts (part of the look-ahead process, used to detect payments) ...
bool fDecryptionThoroughlyChecked
keeps track of whether Unlock has run a thorough check before
bool AddDescriptorKeyWithDB(WalletBatch &batch, const CKey &key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
KeyMap GetKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
void KeepDestination(int64_t index, const OutputType &type) override
std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const override
bool TopUp(unsigned int size=0) override
Fills internal address pool.
std::vector< CKeyPool > MarkReserveKeysAsUsed(int64_t keypool_id) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Marks all keys in the keypool up to and including the provided key as used.
TransactionError FillPSBT(PartiallySignedTransaction &psbt, const PrecomputedTransactionData &txdata, int sighash_type=SIGHASH_DEFAULT, bool sign=true, bool bip32derivs=false, int *n_signed=nullptr, bool finalize=true) const override
Adds script and derivation path information to a PSBT, and optionally signs it.
virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination &addr)
An encapsulated private key.
Definition: key.h:32
std::map< CKeyID, int64_t > m_pool_key_to_index
bool ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, bool fRequestedInternal)
Reserves a key from the keypool and sets nIndex to its index.
TransactionError FillPSBT(PartiallySignedTransaction &psbt, const PrecomputedTransactionData &txdata, int sighash_type=SIGHASH_DEFAULT, bool sign=true, bool bip32derivs=false, int *n_signed=nullptr, bool finalize=true) const override
Adds script and derivation path information to a PSBT, and optionally signs it.
virtual int64_t GetTimeFirstKey() const
bool CheckDecryptionKey(const CKeyingMaterial &master_key, bool accept_no_keys=false) override
Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the ke...
void DeriveNewChildKey(WalletBatch &batch, CKeyMetadata &metadata, CKey &secret, CHDChain &hd_chain, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
virtual bool TopUp(unsigned int size=0)
Fills internal address pool.
virtual std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
#define LogPrintf(...)
Definition: logging.h:237
virtual util::Result< CTxDestination > GetNewDestination(const OutputType type)
int64_t GetTime()
DEPRECATED, see GetTime.
Definition: time.cpp:97
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
virtual ~WalletStorage()=default
virtual bool Upgrade(int prev_version, int new_version, bilingual_str &error)
Upgrades the wallet to the specified version.
virtual bool SetupGeneration(bool force=false)
Sets up the key generation stuff, i.e.
const std::map< CKeyID, int64_t > & GetAllReserveKeys() const
bool HasWalletDescriptor(const WalletDescriptor &desc) const
boost::signals2::signal< void(bool fHaveWatchOnly)> NotifyWatchonlyChanged
Watch-only address added.
An instance of this class represents one database.
Definition: db.h:124
int64_t GetTimeFirstKey() const override
bool TopUp(unsigned int size=0) override
Fills internal address pool.
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Load a keypool entry.
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
Definition: crypter.h:62
void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
std::vector< std::unique_ptr< DescriptorScriptPubKeyMan > > desc_spkms
util::Result< CTxDestination > GetNewDestination(const OutputType type) override
bool SignTransaction(CMutableTransaction &tx, const std::map< COutPoint, Coin > &coins, int sighash, std::map< int, bilingual_str > &input_errors) const override
Creates new signatures and adds them to the transaction.
std::unique_ptr< FlatSigningProvider > GetSigningProvider(const CScript &script, bool include_private=false) const
WalletStorage & m_storage
bool AddKeyOriginWithDB(WalletBatch &batch, const CPubKey &pubkey, const KeyOriginInfo &info)
Add a KeyOriginInfo to the wallet.