From f60f437a6f29e66b47151b805102d85ecb602356 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Thu, 5 Dec 2019 18:01:30 -0500 Subject: [PATCH] Merge #17369: Refactor: Move encryption code between KeyMan and Wallet 7cecf10ac32af0fca206ac5f24f482bdec88cb7d Replace LegacyScriptPubKeyMan::IsCrypted with LegacyScriptPubKeyMan::HasEncryptionKeys (Andrew Chow) bf6417142f36a2f75b3a11368bd73fe788ae1ccb Remove SetCrypted() and fUseCrypto; Change IsCrypted()'s implementation (Andrew Chow) 77a777118eaf78f10a439810d1c08d510a539aa0 Rename EncryptKeys to Encrypt and pass in the encrypted batch to use (Andrew Chow) 35f962fcf0d5107ae6a3a9348e249a9b18ff7106 Clear mapKeys before encrypting (Andrew Chow) 14b5efd66ff0afbf3bf9158a724534a9090fc7fc Move fDecryptionThoroughlyChecked from CWallet to LegacyScriptPubKeyMan (Andrew Chow) 97c0374a46943b2ed38ea24eeeff1f1568dd55b3 Move Unlock implementation to LegacyScriptPubKeyMan (Andrew Chow) e576b135d6451101d6a8219f55d80aefa216dc38 Replace LegacyScriptPubKeyMan::vMasterKey with GetDecryptionKey() (Andrew Chow) fd9d6eebc1eabb4675a118d19d38283da2dead39 Add GetEncryptionKey() and HasEncryptionKeys() to WalletStorage (Andrew Chow) Pull request description: Let wallet class handle locked/unlocked status and master key, and let keyman handle encrypting its data and determining whether there is encrypted data. There should be no change in behavior, but state is tracked differently. The fUseCrypto atomic bool is eliminated and replaced with equivalent HasEncryptionKeys checks. Split from #17261 ACKs for top commit: laanwj: ACK 7cecf10 Tree-SHA512: 95a997c366ca539abba0c0a7a0015f39d27b55220683d8d86344ff2d926db4724da67700d2c8ec2d82ed75d07404318c6cb81544af8aadeefab312167257e673 --- src/wallet/scriptpubkeyman.cpp | 121 +++++++++++++++------------------ src/wallet/scriptpubkeyman.h | 19 ++++-- src/wallet/wallet.cpp | 50 ++++++++++---- src/wallet/wallet.h | 23 ++----- 4 files changed, 111 insertions(+), 102 deletions(-) diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index d46676d39d..1eef41f4b2 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -173,12 +173,11 @@ isminetype LegacyScriptPubKeyMan::IsMine(const CTxDestination& dest) const return IsMine(script); } -bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixingOnly, bool accept_no_keys) +bool LegacyScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys) { { LOCK(cs_KeyStore); - if (!SetCrypted()) - return false; + assert(mapKeys.empty()); bool keyPass = mapCryptedKeys.empty(); // Always pass when there are no encrypted keys bool keyFail = false; @@ -188,7 +187,7 @@ bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixingOnly, b const CPubKey &vchPubKey = (*mi).second.first; const std::vector &vchCryptedSecret = (*mi).second.second; CKey key; - if (!DecryptKey(vMasterKeyIn, vchCryptedSecret, vchPubKey, key)) + if (!DecryptKey(master_key, vchCryptedSecret, vchPubKey, key)) { keyFail = true; break; @@ -205,61 +204,60 @@ bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixingOnly, b if (keyFail) { return false; } - if (!keyPass && !accept_no_keys) { - if (m_spk_man == nullptr) { - return false; - } else { - AssertLockHeld(m_spk_man->cs_KeyStore); - if (m_spk_man->cryptedHDChain.IsNull()) { - return false; - } - } + if (!keyPass && !accept_no_keys && cryptedHDChain.IsNull()) { + return false; } - vMasterKey = vMasterKeyIn; - - if (m_spk_man != nullptr) { - AssertLockHeld(m_spk_man->cs_KeyStore); - if(!m_spk_man->cryptedHDChain.IsNull()) { - bool chainPass = false; - // try to decrypt seed and make sure it matches - CHDChain hdChainTmp; - if (m_spk_man->DecryptHDChain(hdChainTmp)) { - // make sure seed matches this chain - chainPass = m_spk_man->cryptedHDChain.GetID() == hdChainTmp.GetSeedHash(); - } - if (!chainPass) { - vMasterKey.clear(); - return false; - } + // This implementation is sligthly different with bitcoin's + // because function `DecryptHDChain` uses vMasterKey + m_wallet.GetEncryptionKeyMutable() = master_key; + AssertLockHeld(cs_KeyStore); + if(!cryptedHDChain.IsNull()) { + bool chainPass = false; + // try to decrypt seed and make sure it matches + CHDChain hdChainTmp; + if (DecryptHDChain(hdChainTmp)) { + // make sure seed matches this chain + chainPass = cryptedHDChain.GetID() == hdChainTmp.GetSeedHash(); + } + if (!chainPass) { + m_wallet.GetEncryptionKeyMutable().clear(); + return false; } } fDecryptionThoroughlyChecked = true; } - fOnlyMixingAllowed = fForMixingOnly; - NotifyStatusChanged(this); return true; } -bool LegacyScriptPubKeyMan::EncryptKeys(CKeyingMaterial& vMasterKeyIn) +bool LegacyScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) { + AssertLockHeld(cs_wallet); LOCK(cs_KeyStore); - if (!mapCryptedKeys.empty() || IsCrypted()) + encrypted_batch = batch; + if (!mapCryptedKeys.empty()) { + encrypted_batch = nullptr; return false; + } - fUseCrypto = true; - for (const KeyMap::value_type& mKey : mapKeys) + KeyMap keys_to_encrypt; + keys_to_encrypt.swap(mapKeys); // Clear mapKeys so AddCryptedKeyInner will succeed. + for (const KeyMap::value_type& mKey : keys_to_encrypt) { const CKey &key = mKey.second; CPubKey vchPubKey = key.GetPubKey(); CKeyingMaterial vchSecret(key.begin(), key.end()); std::vector vchCryptedSecret; - if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(), vchCryptedSecret)) + if (!EncryptSecret(master_key, vchSecret, vchPubKey.GetHash(), vchCryptedSecret)) { + encrypted_batch = nullptr; return false; - if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) + } + if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) { + encrypted_batch = nullptr; return false; + } } - mapKeys.clear(); + encrypted_batch = nullptr; return true; } @@ -386,7 +384,7 @@ bool LegacyScriptPubKeyMan::GenerateNewHDChainEncrypted(const SecureString& secu assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)); LOCK(cs_wallet); - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { return false; } @@ -524,7 +522,7 @@ bool LegacyScriptPubKeyMan::EncryptHDChain(const CKeyingMaterial& vMasterKeyIn, { LOCK(cs_KeyStore); // should call EncryptKeys first - if (!IsCrypted()) + if (!m_storage.HasEncryptionKeys()) return false; if (!cryptedHDChain.IsNull()) @@ -582,7 +580,7 @@ bool LegacyScriptPubKeyMan::EncryptHDChain(const CKeyingMaterial& vMasterKeyIn, bool LegacyScriptPubKeyMan::DecryptHDChain(CHDChain& hdChainRet) const { LOCK(cs_KeyStore); - if (!IsCrypted()) + if (!m_storage.HasEncryptionKeys()) return true; if (cryptedHDChain.IsNull()) @@ -594,7 +592,7 @@ bool LegacyScriptPubKeyMan::DecryptHDChain(CHDChain& hdChainRet) const SecureVector vchSecureSeed; SecureVector vchSecureCryptedSeed = cryptedHDChain.GetSeed(); std::vector vchCryptedSeed(vchSecureCryptedSeed.begin(), vchSecureCryptedSeed.end()); - if (!DecryptSecret(vMasterKey, vchCryptedSeed, cryptedHDChain.GetID(), vchSecureSeed)) + if (!DecryptSecret(m_storage.GetEncryptionKey(), vchCryptedSeed, cryptedHDChain.GetID(), vchSecureSeed)) return false; hdChainRet = cryptedHDChain; @@ -616,9 +614,9 @@ bool LegacyScriptPubKeyMan::DecryptHDChain(CHDChain& hdChainRet) const std::vector vchCryptedMnemonic(vchSecureCryptedMnemonic.begin(), vchSecureCryptedMnemonic.end()); std::vector vchCryptedMnemonicPassphrase(vchSecureCryptedMnemonicPassphrase.begin(), vchSecureCryptedMnemonicPassphrase.end()); - if (!vchCryptedMnemonic.empty() && !DecryptSecret(vMasterKey, vchCryptedMnemonic, cryptedHDChain.GetID(), vchSecureMnemonic)) + if (!vchCryptedMnemonic.empty() && !DecryptSecret(m_storage.GetEncryptionKey(), vchCryptedMnemonic, cryptedHDChain.GetID(), vchSecureMnemonic)) return false; - if (!vchCryptedMnemonicPassphrase.empty() && !DecryptSecret(vMasterKey, vchCryptedMnemonicPassphrase, cryptedHDChain.GetID(), vchSecureMnemonicPassphrase)) + if (!vchCryptedMnemonicPassphrase.empty() && !DecryptSecret(m_storage.GetEncryptionKey(), vchCryptedMnemonicPassphrase, cryptedHDChain.GetID(), vchSecureMnemonicPassphrase)) return false; if (!hdChainRet.SetMnemonic(vchSecureMnemonic, vchSecureMnemonicPassphrase, false)) @@ -802,7 +800,7 @@ bool LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(WalletBatch& batch, const CKey& s RemoveWatchOnly(script); } - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { return batch.WriteKey(pubkey, secret.GetPrivKey(), mapKeyMetadata[pubkey.GetID()]); @@ -843,7 +841,7 @@ void LegacyScriptPubKeyMan::LoadScriptMetadata(const CScriptID& script_id, const bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey& key, const CPubKey &pubkey) { LOCK(cs_KeyStore); - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { return FillableSigningProvider::AddKeyPubKey(key, pubkey); } @@ -853,7 +851,7 @@ bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey& key, const CPubKey &pu std::vector vchCryptedSecret; CKeyingMaterial vchSecret(key.begin(), key.end()); - if (!EncryptSecret(vMasterKey, vchSecret, pubkey.GetHash(), vchCryptedSecret)) { + if (!EncryptSecret(m_storage.GetEncryptionKey(), vchSecret, pubkey.GetHash(), vchCryptedSecret)) { return false; } @@ -866,7 +864,7 @@ bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey& key, const CPubKey &pu bool LegacyScriptPubKeyMan::GetKeyInner(const CKeyID &address, CKey& keyOut) const { LOCK(cs_KeyStore); - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { return FillableSigningProvider::GetKey(address, keyOut); } @@ -875,7 +873,7 @@ bool LegacyScriptPubKeyMan::GetKeyInner(const CKeyID &address, CKey& keyOut) con { const CPubKey &vchPubKey = (*mi).second.first; const std::vector &vchCryptedSecret = (*mi).second.second; - return DecryptKey(vMasterKey, vchCryptedSecret, vchPubKey, keyOut); + return DecryptKey(m_storage.GetEncryptionKey(), vchCryptedSecret, vchPubKey, keyOut); } return false; } @@ -883,7 +881,7 @@ bool LegacyScriptPubKeyMan::GetKeyInner(const CKeyID &address, CKey& keyOut) con bool LegacyScriptPubKeyMan::GetPubKeyInner(const CKeyID &address, CPubKey& vchPubKeyOut) const { LOCK(cs_KeyStore); - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { if (!FillableSigningProvider::GetPubKey(address, vchPubKeyOut)) { return GetWatchPubKey(address, vchPubKeyOut); } @@ -908,7 +906,7 @@ bool LegacyScriptPubKeyMan::LoadCryptedKey(const CPubKey &vchPubKey, const std:: bool LegacyScriptPubKeyMan::HaveKeyInner(const CKeyID &address) const { LOCK(cs_KeyStore); - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { return FillableSigningProvider::HaveKey(address); } return mapCryptedKeys.count(address) > 0; @@ -917,9 +915,7 @@ bool LegacyScriptPubKeyMan::HaveKeyInner(const CKeyID &address) const bool LegacyScriptPubKeyMan::AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret) { LOCK(cs_KeyStore); - if (!SetCrypted()) { - return false; - } + assert(mapKeys.empty()); mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret); return true; @@ -1044,7 +1040,7 @@ bool LegacyScriptPubKeyMan::AddWatchOnly(const CScript& dest, int64_t nCreateTim bool LegacyScriptPubKeyMan::SetHDChain(const CHDChain& chain) { LOCK(cs_KeyStore); - if (IsCrypted()) + if (m_storage.HasEncryptionKeys()) return false; if (chain.IsCrypted()) @@ -1057,7 +1053,7 @@ bool LegacyScriptPubKeyMan::SetHDChain(const CHDChain& chain) bool LegacyScriptPubKeyMan::SetCryptedHDChain(const CHDChain& chain) { LOCK(cs_KeyStore); - if (!SetCrypted()) + if (!m_storage.HasEncryptionKeys()) return false; if (!chain.IsCrypted()) @@ -1281,7 +1277,7 @@ void LegacyScriptPubKeyMan::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata& if (!hdChainCurrent.SetAccount(nAccountIndex, acc)) throw std::runtime_error(std::string(__func__) + ": SetAccount failed"); - if (IsCrypted()) { + if (m_storage.HasEncryptionKeys()) { if (!SetCryptedHDChain(batch, hdChainCurrent, false)) throw std::runtime_error(std::string(__func__) + ": SetCryptedHDChain failed"); } @@ -1693,7 +1689,7 @@ bool LegacyScriptPubKeyMan::ImportScriptPubKeys(const std::set& script_ std::set LegacyScriptPubKeyMan::GetKeys() const { LOCK(cs_KeyStore); - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { return FillableSigningProvider::GetKeys(); } std::set set_address; @@ -1707,7 +1703,7 @@ std::set LegacyScriptPubKeyMan::GetKeys() const bool LegacyScriptPubKeyMan::GetHDChain(CHDChain& hdChainRet) const { LOCK(cs_KeyStore); - if (IsCrypted() && !cryptedHDChain.IsNull()) { + if (m_storage.HasEncryptionKeys() && !cryptedHDChain.IsNull()) { hdChainRet = cryptedHDChain; return true; } @@ -1720,13 +1716,8 @@ bool LegacyScriptPubKeyMan::GetHDChain(CHDChain& hdChainRet) const LegacyScriptPubKeyMan::LegacyScriptPubKeyMan(CWallet& wallet) : ScriptPubKeyMan(wallet), m_wallet(wallet), - cs_wallet(wallet.cs_wallet), - vMasterKey(wallet.vMasterKey), - fUseCrypto(wallet.fUseCrypto), - fDecryptionThoroughlyChecked(wallet.fDecryptionThoroughlyChecked) {} + cs_wallet(wallet.cs_wallet) {} -bool LegacyScriptPubKeyMan::SetCrypted() { return m_wallet.SetCrypted(); } -bool LegacyScriptPubKeyMan::IsCrypted() const { return m_wallet.IsCrypted(); } void LegacyScriptPubKeyMan::NotifyWatchonlyChanged(bool fHaveWatchOnly) const { return m_wallet.NotifyWatchonlyChanged(fHaveWatchOnly); } void LegacyScriptPubKeyMan::NotifyCanGetAddressesChanged() const { return m_wallet.NotifyCanGetAddressesChanged(); } template void LegacyScriptPubKeyMan::WalletLogPrintf(const std::string& fmt, const Params&... parameters) const { return m_wallet.WalletLogPrintf(fmt, parameters...); } diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h index 2f2eeab3e2..54eb2241fb 100644 --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -29,6 +29,9 @@ public: virtual void UnsetBlankWalletFlag(WalletBatch&) = 0; virtual bool CanSupportFeature(enum WalletFeature) const = 0; virtual void SetMinVersion(enum WalletFeature, WalletBatch* = nullptr, bool = false) = 0; + virtual const CKeyingMaterial& GetEncryptionKey() const = 0; + virtual CKeyingMaterial& GetEncryptionKeyMutable() = 0; + virtual bool HasEncryptionKeys() const = 0; virtual bool IsLocked(bool fForMixing = false) const = 0; }; @@ -145,6 +148,10 @@ public: virtual isminetype IsMine(const CScript& script) const { return ISMINE_NO; } virtual isminetype IsMine(const CTxDestination& dest) const { return ISMINE_NO; } + //! Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the keys handled by it. + virtual bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) { return false; } + virtual bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) { return false; } + virtual bool GetReservedDestination(bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) { return false; } virtual void KeepDestination(int64_t index) {} virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) {} @@ -180,6 +187,9 @@ public: class LegacyScriptPubKeyMan : public ScriptPubKeyMan, public FillableSigningProvider { private: + //! keeps track of whether Unlock has run a thorough check before + bool fDecryptionThoroughlyChecked = false; + using WatchOnlySet = std::set; using WatchKeyMap = std::map; using HDPubKeyMap = std::map; @@ -259,8 +269,8 @@ public: isminetype IsMine(const CScript& script) const override; isminetype IsMine(const CTxDestination& dest) const override; - //! will encrypt previously unencrypted keys - bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); + bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override; + bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override; bool GetReservedDestination(bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) override; void KeepDestination(int64_t index) override; @@ -421,16 +431,11 @@ public: friend class CWallet; friend class ReserveDestination; LegacyScriptPubKeyMan(CWallet& wallet); - bool SetCrypted(); - bool IsCrypted() const; void NotifyWatchonlyChanged(bool fHaveWatchOnly) const; void NotifyCanGetAddressesChanged() const; template void WalletLogPrintf(const std::string& fmt, const Params&... parameters) const; CWallet& m_wallet; CCriticalSection& cs_wallet; - CKeyingMaterial& vMasterKey GUARDED_BY(cs_KeyStore); - std::atomic& fUseCrypto; - bool& fDecryptionThoroughlyChecked; }; #endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 05688461f0..d7a2648d45 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -610,8 +610,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) { LOCK(cs_wallet); mapMasterKeys[++nMasterKeyMaxID] = kMasterKey; - assert(!encrypted_batch); - encrypted_batch = new WalletBatch(*database); + WalletBatch* encrypted_batch = new WalletBatch(*database); if (!encrypted_batch->TxnBegin()) { delete encrypted_batch; encrypted_batch = nullptr; @@ -624,8 +623,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) if (auto spk_man = m_spk_man.get()) { spk_man->GetHDChain(hdChainCurrent); - if (!spk_man->EncryptKeys(_vMasterKey)) - { + if (!spk_man->Encrypt(_vMasterKey, encrypted_batch)) { encrypted_batch->TxnAbort(); delete encrypted_batch; encrypted_batch = nullptr; @@ -4889,15 +4887,9 @@ std::vector CWallet::GroupOutputs(const std::vector& outpu return groups; } -bool CWallet::SetCrypted() +bool CWallet::IsCrypted() const { - LOCK(cs_KeyStore); - if (fUseCrypto) - return true; - if (!mapKeys.empty()) - return false; - fUseCrypto = true; - return true; + return HasEncryptionKeys(); } // This function should be used in a different combinations to determine @@ -4931,7 +4923,7 @@ bool CWallet::IsLocked(bool fForMixing) const bool CWallet::Lock(bool fAllowMixing) { - if (!SetCrypted()) + if (!IsCrypted()) return false; if(!fAllowMixing) { @@ -4975,6 +4967,23 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool fForMixingOnl return false; } +bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixingOnly, bool accept_no_keys) +{ + { + LOCK(cs_KeyStore); + if (m_spk_man) { + if (!m_spk_man->CheckDecryptionKey(vMasterKeyIn, accept_no_keys)) { + return false; + } + } else { + vMasterKey = vMasterKeyIn; + } + fOnlyMixingAllowed = fForMixingOnly; + } + NotifyStatusChanged(this); + return true; +} + ScriptPubKeyMan* CWallet::GetScriptPubKeyMan(const CScript& script) const { return m_spk_man.get(); @@ -4994,3 +5003,18 @@ LegacyScriptPubKeyMan* CWallet::GetLegacyScriptPubKeyMan() const { return m_spk_man.get(); } + +const CKeyingMaterial& CWallet::GetEncryptionKey() const +{ + return vMasterKey; +} + +CKeyingMaterial& CWallet::GetEncryptionKeyMutable() +{ + return vMasterKey; +} + +bool CWallet::HasEncryptionKeys() const +{ + return !mapMasterKeys.empty(); +} diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 922ad18c08..48dbae10b2 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -650,18 +650,9 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati private: CKeyingMaterial vMasterKey GUARDED_BY(cs_KeyStore); - //! if fUseCrypto is true, mapKeys must be empty - //! if fUseCrypto is false, vMasterKey must be empty - std::atomic fUseCrypto; - - //! keeps track of whether Unlock has run a thorough check before - bool fDecryptionThoroughlyChecked; - //! if fOnlyMixingAllowed is true, only mixing should be allowed in unlocked wallet bool fOnlyMixingAllowed; - bool SetCrypted(); - bool Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixingOnly = false, bool accept_no_keys = false); std::atomic fAbortRescan{false}; @@ -813,9 +804,7 @@ public: /** Construct wallet with specified name and database implementation. */ CWallet(interfaces::Chain* chain, const std::string& name, std::unique_ptr database) - : fUseCrypto(false), - fDecryptionThoroughlyChecked(false), - fOnlyMixingAllowed(false), + : fOnlyMixingAllowed(false), m_chain(chain), m_name(name), database(std::move(database)) @@ -826,13 +815,11 @@ public: { // Should not have slots connected at this point. assert(NotifyUnload.empty()); - delete encrypted_batch; - encrypted_batch = nullptr; } /** Interface to assert chain access */ bool HaveChain() const { return m_chain ? true : false; } - bool IsCrypted() const { return fUseCrypto; } + bool IsCrypted() const; bool IsLocked(bool fForMixing = false) const override; bool Lock(bool fForMixing = false); @@ -1280,6 +1267,10 @@ public: LegacyScriptPubKeyMan* GetLegacyScriptPubKeyMan() const; + const CKeyingMaterial& GetEncryptionKey() const override; + CKeyingMaterial& GetEncryptionKeyMutable() override; + bool HasEncryptionKeys() const override; + // Temporary LegacyScriptPubKeyMan accessors and aliases. friend class LegacyScriptPubKeyMan; std::unique_ptr m_spk_man = std::make_unique(*this); @@ -1290,8 +1281,6 @@ public: LegacyScriptPubKeyMan::WatchOnlySet& setWatchOnly GUARDED_BY(cs_KeyStore) = m_spk_man->setWatchOnly; LegacyScriptPubKeyMan::WatchKeyMap& mapWatchKeys GUARDED_BY(cs_KeyStore) = m_spk_man->mapWatchKeys; LegacyScriptPubKeyMan::HDPubKeyMap& mapHdPubKeys GUARDED_BY(cs_KeyStore) = m_spk_man->mapHdPubKeys; - WalletBatch*& encrypted_batch GUARDED_BY(cs_wallet) = m_spk_man->encrypted_batch; - using CryptedKeyMap = LegacyScriptPubKeyMan::CryptedKeyMap; }; /**