mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
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:
parent
a5a44d10e9
commit
f60f437a6f
@ -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...); }
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user