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
This commit is contained in:
Andrew Chow 2019-12-05 18:01:30 -05:00 committed by PastaPastaPasta
parent a5a44d10e9
commit f60f437a6f
4 changed files with 111 additions and 102 deletions

View File

@ -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<unsigned char> &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<unsigned char> 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<unsigned char> 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<unsigned char> vchCryptedMnemonic(vchSecureCryptedMnemonic.begin(), vchSecureCryptedMnemonic.end());
std::vector<unsigned char> 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<unsigned char> 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<unsigned char> &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<unsigned char> &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<CScript>& script_
std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const
{
LOCK(cs_KeyStore);
if (!IsCrypted()) {
if (!m_storage.HasEncryptionKeys()) {
return FillableSigningProvider::GetKeys();
}
std::set<CKeyID> set_address;
@ -1707,7 +1703,7 @@ std::set<CKeyID> 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<typename... Params> void LegacyScriptPubKeyMan::WalletLogPrintf(const std::string& fmt, const Params&... parameters) const { return m_wallet.WalletLogPrintf(fmt, parameters...); }

View File

@ -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<CScript>;
using WatchKeyMap = std::map<CKeyID, CPubKey>;
using HDPubKeyMap = std::map<CKeyID, CHDPubKey>;
@ -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<typename... Params> void WalletLogPrintf(const std::string& fmt, const Params&... parameters) const;
CWallet& m_wallet;
CCriticalSection& cs_wallet;
CKeyingMaterial& vMasterKey GUARDED_BY(cs_KeyStore);
std::atomic<bool>& fUseCrypto;
bool& fDecryptionThoroughlyChecked;
};
#endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H

View File

@ -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<OutputGroup> CWallet::GroupOutputs(const std::vector<COutput>& 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();
}

View File

@ -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<bool> 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<bool> 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<WalletDatabase> 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<LegacyScriptPubKeyMan> m_spk_man = std::make_unique<LegacyScriptPubKeyMan>(*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;
};
/**