aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/scriptpubkeyman.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/scriptpubkeyman.h')
-rw-r--r--src/wallet/scriptpubkeyman.h118
1 files changed, 79 insertions, 39 deletions
diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h
index 8b50711280..7b1c023bc9 100644
--- a/src/wallet/scriptpubkeyman.h
+++ b/src/wallet/scriptpubkeyman.h
@@ -74,6 +74,11 @@ std::vector<CKeyID> GetAffectedKeys(const CScript& spk, const SigningProvider& p
* keys (by default 1000) ahead of the last used key and scans for the
* addresses of those keys. This avoids the risk of not seeing transactions
* involving the wallet's addresses, or of re-using the same address.
+ * In the unlikely case where none of the addresses in the `gap limit` are
+ * used on-chain, the look-ahead will not be incremented to keep
+ * a constant size and addresses beyond this range will not be detected by an
+ * old backup. For this reason, it is not recommended to decrease keypool size
+ * lower than default value.
*
* The HD-split wallet feature added a second keypool (commit: 02592f4c). There
* is an external keypool (for addresses to hand out) and an internal keypool
@@ -196,8 +201,28 @@ public:
virtual int64_t GetTimeFirstKey() const { return 0; }
- //! Return address metadata
virtual const CKeyMetadata* GetMetadata(const CTxDestination& dest) const { return nullptr; }
+
+ virtual std::unique_ptr<SigningProvider> GetSigningProvider(const CScript& script) const { return nullptr; }
+
+ /** Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSigningProvider) that, combined with
+ * sigdata, can produce a valid signature.
+ */
+ virtual bool CanProvide(const CScript& script, SignatureData& sigdata) { return false; }
+
+ virtual uint256 GetID() const { return uint256(); }
+
+ /** Prepends the wallet name in logging output to ease debugging in multi-wallet use cases */
+ template<typename... Params>
+ void WalletLogPrintf(std::string fmt, Params... parameters) const {
+ LogPrintf(("%s " + fmt).c_str(), m_storage.GetDisplayName(), parameters...);
+ };
+
+ /** Watch-only address added */
+ boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;
+
+ /** Keypool has new keys */
+ boost::signals2::signal<void ()> NotifyCanGetAddressesChanged;
};
class LegacyScriptPubKeyMan : public ScriptPubKeyMan, public FillableSigningProvider
@@ -209,7 +234,7 @@ private:
using WatchOnlySet = std::set<CScript>;
using WatchKeyMap = std::map<CKeyID, CPubKey>;
- WalletBatch *encrypted_batch GUARDED_BY(cs_wallet) = nullptr;
+ WalletBatch *encrypted_batch GUARDED_BY(cs_KeyStore) = nullptr;
using CryptedKeyMap = std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>;
@@ -217,7 +242,7 @@ private:
WatchOnlySet setWatchOnly GUARDED_BY(cs_KeyStore);
WatchKeyMap mapWatchKeys GUARDED_BY(cs_KeyStore);
- int64_t nTimeFirstKey GUARDED_BY(cs_wallet) = 0;
+ int64_t nTimeFirstKey GUARDED_BY(cs_KeyStore) = 0;
bool AddKeyPubKeyInner(const CKey& key, const CPubKey &pubkey);
bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
@@ -231,14 +256,14 @@ private:
* of the other AddWatchOnly which accepts a timestamp and sets
* nTimeFirstKey more intelligently for more efficient rescans.
*/
- bool AddWatchOnly(const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool AddWatchOnly(const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
+ bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
bool AddWatchOnlyInMem(const CScript &dest);
//! Adds a watch-only address to the store, and saves it to disk.
- bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
//! Adds a key to the store, and saves it to disk.
- bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
@@ -252,12 +277,12 @@ private:
CHDChain hdChain;
/* HD derive new child key (on internal or external chain) */
- void DeriveNewChildKey(WalletBatch& batch, CKeyMetadata& metadata, CKey& secret, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void DeriveNewChildKey(WalletBatch& batch, CKeyMetadata& metadata, CKey& secret, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
- std::set<int64_t> setInternalKeyPool GUARDED_BY(cs_wallet);
- std::set<int64_t> setExternalKeyPool GUARDED_BY(cs_wallet);
- std::set<int64_t> set_pre_split_keypool GUARDED_BY(cs_wallet);
- int64_t m_max_keypool_index GUARDED_BY(cs_wallet) = 0;
+ std::set<int64_t> setInternalKeyPool GUARDED_BY(cs_KeyStore);
+ std::set<int64_t> setExternalKeyPool GUARDED_BY(cs_KeyStore);
+ std::set<int64_t> set_pre_split_keypool GUARDED_BY(cs_KeyStore);
+ int64_t m_max_keypool_index GUARDED_BY(cs_KeyStore) = 0;
std::map<CKeyID, int64_t> m_pool_key_to_index;
// Tracks keypool indexes to CKeyIDs of keys that have been taken out of the keypool but may be returned to it
std::map<int64_t, CKeyID> m_index_to_reserved_key;
@@ -282,6 +307,8 @@ private:
bool ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal);
public:
+ using ScriptPubKeyMan::ScriptPubKeyMan;
+
bool GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error) override;
isminetype IsMine(const CScript& script) const override;
@@ -297,7 +324,7 @@ public:
void MarkUnusedAddresses(const CScript& script) override;
//! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo
- void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void UpgradeKeyMetadata();
bool IsHDEnabled() const override;
@@ -310,7 +337,7 @@ public:
void RewriteDB() override;
int64_t GetOldestKeyPoolTime() override;
- size_t KeypoolCountExternalKeys() override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ size_t KeypoolCountExternalKeys() override;
unsigned int GetKeyPoolSize() const override;
int64_t GetTimeFirstKey() const override;
@@ -319,28 +346,34 @@ public:
bool CanGetAddresses(bool internal = false) override;
+ std::unique_ptr<SigningProvider> GetSigningProvider(const CScript& script) const override;
+
+ bool CanProvide(const CScript& script, SignatureData& sigdata) override;
+
+ uint256 GetID() const override;
+
// Map from Key ID to key metadata.
- std::map<CKeyID, CKeyMetadata> mapKeyMetadata GUARDED_BY(cs_wallet);
+ std::map<CKeyID, CKeyMetadata> mapKeyMetadata GUARDED_BY(cs_KeyStore);
// Map from Script ID to key metadata (for watch-only keys).
- std::map<CScriptID, CKeyMetadata> m_script_metadata GUARDED_BY(cs_wallet);
+ std::map<CScriptID, CKeyMetadata> m_script_metadata GUARDED_BY(cs_KeyStore);
//! Adds a key to the store, and saves it to disk.
- bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override;
//! Adds a key to the store, without saving it to disk (used by LoadWallet)
bool LoadKey(const CKey& key, const CPubKey &pubkey);
//! Adds an encrypted key to the store, and saves it to disk.
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
//! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
- void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
//! Adds a CScript to the store
bool LoadCScript(const CScript& redeemScript);
//! Load metadata (used by LoadWallet)
- void LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata &metadata) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- void LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &metadata) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata &metadata);
+ void LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &metadata);
//! Generate a new key
- CPubKey GenerateNewKey(WalletBatch& batch, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ CPubKey GenerateNewKey(WalletBatch& batch, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
/* Set the HD chain model (chain child index counters) */
void SetHDChain(const CHDChain& chain, bool memonly);
@@ -353,8 +386,8 @@ public:
//! Returns whether there are any watch-only things in the wallet
bool HaveWatchOnly() const;
//! Remove a watch only script from the keystore
- bool RemoveWatchOnly(const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- bool AddWatchOnly(const CScript& dest, int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool RemoveWatchOnly(const CScript &dest);
+ bool AddWatchOnly(const CScript& dest, int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
//! Fetches a pubkey from mapWatchKeys if it exists there
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const;
@@ -367,14 +400,14 @@ public:
bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override;
//! Load a keypool entry
- void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool);
bool NewKeyPool();
- void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
- bool ImportScripts(const std::set<CScript> scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- bool ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- 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_wallet);
- bool ImportScriptPubKeys(const std::set<CScript>& script_pub_keys, const bool have_solving_data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool ImportScripts(const std::set<CScript> scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
+ bool ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
+ 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);
+ bool ImportScriptPubKeys(const std::set<CScript>& script_pub_keys, const bool have_solving_data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
/* Returns true if the wallet can generate new keys */
bool CanGenerateKeys();
@@ -408,19 +441,26 @@ public:
/**
* Marks all keys in the keypool up to and including reserve_key as used.
*/
- void MarkReserveKeysAsUsed(int64_t keypool_id) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ void MarkReserveKeysAsUsed(int64_t keypool_id) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; }
std::set<CKeyID> GetKeys() const override;
- // Temporary CWallet accessors and aliases.
- friend class CWallet;
- friend class ReserveDestination;
- LegacyScriptPubKeyMan(CWallet& wallet);
- void NotifyWatchonlyChanged(bool fHaveWatchOnly) const;
- void NotifyCanGetAddressesChanged() const;
- template<typename... Params> void WalletLogPrintf(const std::string& fmt, const Params&... parameters) const;
- CWallet& m_wallet;
- RecursiveMutex& cs_wallet;
+};
+
+/** Wraps a LegacyScriptPubKeyMan so that it can be returned in a new unique_ptr */
+class LegacySigningProvider : public SigningProvider
+{
+private:
+ const LegacyScriptPubKeyMan& m_spk_man;
+public:
+ LegacySigningProvider(const LegacyScriptPubKeyMan& spk_man) : m_spk_man(spk_man) {}
+
+ bool GetCScript(const CScriptID &scriptid, CScript& script) const override { return m_spk_man.GetCScript(scriptid, script); }
+ bool HaveCScript(const CScriptID &scriptid) const override { return m_spk_man.HaveCScript(scriptid); }
+ bool GetPubKey(const CKeyID &address, CPubKey& pubkey) const override { return m_spk_man.GetPubKey(address, pubkey); }
+ bool GetKey(const CKeyID &address, CKey& key) const override { return m_spk_man.GetKey(address, key); }
+ bool HaveKey(const CKeyID &address) const override { return m_spk_man.HaveKey(address); }
+ bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override { return m_spk_man.GetKeyOrigin(keyid, info); }
};
#endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H