0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-05 14:06:27 -05:00

Locking: Lock cs_KeyStore instead of cs_wallet in legacy keyman

This commit only affects locking behavior and doesn't have other changes.
This commit is contained in:
Andrew Chow 2019-10-07 14:11:34 -04:00
parent f5be479694
commit fadc08ad94
13 changed files with 112 additions and 116 deletions

View file

@ -145,8 +145,7 @@ void TestGUI(interfaces::Node& node)
{ {
auto spk_man = wallet->GetLegacyScriptPubKeyMan(); auto spk_man = wallet->GetLegacyScriptPubKeyMan();
auto locked_chain = wallet->chain().lock(); auto locked_chain = wallet->chain().lock();
LOCK(wallet->cs_wallet); LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore);
AssertLockHeld(spk_man->cs_wallet);
wallet->SetAddressBook(GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type), "", "receive"); wallet->SetAddressBook(GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type), "", "receive");
spk_man->AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey()); spk_man->AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey());
wallet->SetLastBlockProcessed(105, ::ChainActive().Tip()->GetBlockHash()); wallet->SetLastBlockProcessed(105, ::ChainActive().Tip()->GetBlockHash());

View file

@ -27,8 +27,7 @@ std::string getnewaddress(CWallet& w)
void importaddress(CWallet& wallet, const std::string& address) void importaddress(CWallet& wallet, const std::string& address)
{ {
auto spk_man = wallet.GetLegacyScriptPubKeyMan(); auto spk_man = wallet.GetLegacyScriptPubKeyMan();
LOCK(wallet.cs_wallet); LOCK2(wallet.cs_wallet, spk_man->cs_KeyStore);
AssertLockHeld(spk_man->cs_wallet);
const auto dest = DecodeDestination(address); const auto dest = DecodeDestination(address);
assert(IsValidDestination(dest)); assert(IsValidDestination(dest));
const auto script = GetScriptForDestination(dest); const auto script = GetScriptForDestination(dest);

View file

@ -700,7 +700,7 @@ UniValue dumpprivkey(const JSONRPCRequest& request)
LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*wallet); LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*wallet);
auto locked_chain = pwallet->chain().lock(); auto locked_chain = pwallet->chain().lock();
LOCK(pwallet->cs_wallet); LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore);
EnsureWalletIsUnlocked(pwallet); EnsureWalletIsUnlocked(pwallet);
@ -751,8 +751,7 @@ UniValue dumpwallet(const JSONRPCRequest& request)
LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*wallet); LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*wallet);
auto locked_chain = pwallet->chain().lock(); auto locked_chain = pwallet->chain().lock();
LOCK(pwallet->cs_wallet); LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore);
AssertLockHeld(spk_man.cs_wallet);
EnsureWalletIsUnlocked(pwallet); EnsureWalletIsUnlocked(pwallet);

View file

@ -983,7 +983,7 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request)
LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*pwallet); LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*pwallet);
auto locked_chain = pwallet->chain().lock(); auto locked_chain = pwallet->chain().lock();
LOCK(pwallet->cs_wallet); LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore);
std::string label; std::string label;
if (!request.params[2].isNull()) if (!request.params[2].isNull())
@ -4014,7 +4014,7 @@ UniValue sethdseed(const JSONRPCRequest& request)
} }
auto locked_chain = pwallet->chain().lock(); auto locked_chain = pwallet->chain().lock();
LOCK(pwallet->cs_wallet); LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore);
// Do not do anything to non-HD wallets // Do not do anything to non-HD wallets
if (!pwallet->CanSupportFeature(FEATURE_HD)) { if (!pwallet->CanSupportFeature(FEATURE_HD)) {

View file

@ -13,6 +13,7 @@
bool LegacyScriptPubKeyMan::GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error) bool LegacyScriptPubKeyMan::GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error)
{ {
LOCK(cs_KeyStore);
error.clear(); error.clear();
// Generate a new key that is added to wallet // Generate a new key that is added to wallet
@ -238,7 +239,6 @@ bool LegacyScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key
bool LegacyScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) bool LegacyScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch)
{ {
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore); LOCK(cs_KeyStore);
encrypted_batch = batch; encrypted_batch = batch;
if (!mapCryptedKeys.empty()) { if (!mapCryptedKeys.empty()) {
@ -269,6 +269,7 @@ bool LegacyScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, WalletBat
bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool)
{ {
LOCK(cs_KeyStore);
if (!CanGetAddresses(internal)) { if (!CanGetAddresses(internal)) {
return false; return false;
} }
@ -282,7 +283,7 @@ bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool i
void LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script) void LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script)
{ {
AssertLockHeld(cs_wallet); LOCK(cs_KeyStore);
// extract addresses and check if they match with an unused keypool key // extract addresses and check if they match with an unused keypool key
for (const auto& keyid : GetAffectedKeys(script, *this)) { for (const auto& keyid : GetAffectedKeys(script, *this)) {
std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid); std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid);
@ -299,7 +300,7 @@ void LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script)
void LegacyScriptPubKeyMan::UpgradeKeyMetadata() void LegacyScriptPubKeyMan::UpgradeKeyMetadata()
{ {
AssertLockHeld(cs_wallet); LOCK(cs_KeyStore);
if (m_storage.IsLocked() || m_storage.IsWalletFlagSet(WALLET_FLAG_KEY_ORIGIN_METADATA)) { if (m_storage.IsLocked() || m_storage.IsWalletFlagSet(WALLET_FLAG_KEY_ORIGIN_METADATA)) {
return; return;
} }
@ -352,7 +353,7 @@ bool LegacyScriptPubKeyMan::IsHDEnabled() const
bool LegacyScriptPubKeyMan::CanGetAddresses(bool internal) bool LegacyScriptPubKeyMan::CanGetAddresses(bool internal)
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
// Check if the keypool has keys // Check if the keypool has keys
bool keypool_has_keys; bool keypool_has_keys;
if (internal && m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) { if (internal && m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) {
@ -369,7 +370,7 @@ bool LegacyScriptPubKeyMan::CanGetAddresses(bool internal)
bool LegacyScriptPubKeyMan::Upgrade(int prev_version, std::string& error) bool LegacyScriptPubKeyMan::Upgrade(int prev_version, std::string& error)
{ {
AssertLockHeld(cs_wallet); LOCK(cs_KeyStore);
error = ""; error = "";
bool hd_upgrade = false; bool hd_upgrade = false;
bool split_upgrade = false; bool split_upgrade = false;
@ -410,7 +411,7 @@ bool LegacyScriptPubKeyMan::HavePrivateKeys() const
void LegacyScriptPubKeyMan::RewriteDB() void LegacyScriptPubKeyMan::RewriteDB()
{ {
AssertLockHeld(cs_wallet); LOCK(cs_KeyStore);
setInternalKeyPool.clear(); setInternalKeyPool.clear();
setExternalKeyPool.clear(); setExternalKeyPool.clear();
m_pool_key_to_index.clear(); m_pool_key_to_index.clear();
@ -435,7 +436,7 @@ static int64_t GetOldestKeyTimeInPool(const std::set<int64_t>& setKeyPool, Walle
int64_t LegacyScriptPubKeyMan::GetOldestKeyPoolTime() int64_t LegacyScriptPubKeyMan::GetOldestKeyPoolTime()
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
WalletBatch batch(m_storage.GetDatabase()); WalletBatch batch(m_storage.GetDatabase());
@ -453,25 +454,25 @@ int64_t LegacyScriptPubKeyMan::GetOldestKeyPoolTime()
size_t LegacyScriptPubKeyMan::KeypoolCountExternalKeys() size_t LegacyScriptPubKeyMan::KeypoolCountExternalKeys()
{ {
AssertLockHeld(cs_wallet); LOCK(cs_KeyStore);
return setExternalKeyPool.size() + set_pre_split_keypool.size(); return setExternalKeyPool.size() + set_pre_split_keypool.size();
} }
unsigned int LegacyScriptPubKeyMan::GetKeyPoolSize() const unsigned int LegacyScriptPubKeyMan::GetKeyPoolSize() const
{ {
AssertLockHeld(cs_wallet); LOCK(cs_KeyStore);
return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size(); return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size();
} }
int64_t LegacyScriptPubKeyMan::GetTimeFirstKey() const int64_t LegacyScriptPubKeyMan::GetTimeFirstKey() const
{ {
AssertLockHeld(cs_wallet); LOCK(cs_KeyStore);
return nTimeFirstKey; return nTimeFirstKey;
} }
const CKeyMetadata* LegacyScriptPubKeyMan::GetMetadata(const CTxDestination& dest) const const CKeyMetadata* LegacyScriptPubKeyMan::GetMetadata(const CTxDestination& dest) const
{ {
AssertLockHeld(cs_wallet); LOCK(cs_KeyStore);
CKeyID key_id = GetKeyForDestination(*this, dest); CKeyID key_id = GetKeyForDestination(*this, dest);
if (!key_id.IsNull()) { if (!key_id.IsNull()) {
@ -496,7 +497,7 @@ const CKeyMetadata* LegacyScriptPubKeyMan::GetMetadata(const CTxDestination& des
*/ */
void LegacyScriptPubKeyMan::UpdateTimeFirstKey(int64_t nCreateTime) void LegacyScriptPubKeyMan::UpdateTimeFirstKey(int64_t nCreateTime)
{ {
AssertLockHeld(cs_wallet); AssertLockHeld(cs_KeyStore);
if (nCreateTime <= 1) { if (nCreateTime <= 1) {
// Cannot determine birthday information, so set the wallet birthday to // Cannot determine birthday information, so set the wallet birthday to
// the beginning of time. // the beginning of time.
@ -513,13 +514,14 @@ bool LegacyScriptPubKeyMan::LoadKey(const CKey& key, const CPubKey &pubkey)
bool LegacyScriptPubKeyMan::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey) bool LegacyScriptPubKeyMan::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
{ {
LOCK(cs_KeyStore);
WalletBatch batch(m_storage.GetDatabase()); WalletBatch batch(m_storage.GetDatabase());
return LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(batch, secret, pubkey); return LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(batch, secret, pubkey);
} }
bool LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(WalletBatch& batch, const CKey& secret, const CPubKey& pubkey) bool LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(WalletBatch& batch, const CKey& secret, const CPubKey& pubkey)
{ {
AssertLockHeld(cs_wallet); AssertLockHeld(cs_KeyStore);
// Make sure we aren't adding private keys to private key disabled wallets // Make sure we aren't adding private keys to private key disabled wallets
assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)); assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
@ -574,14 +576,14 @@ bool LegacyScriptPubKeyMan::LoadCScript(const CScript& redeemScript)
void LegacyScriptPubKeyMan::LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata& meta) void LegacyScriptPubKeyMan::LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata& meta)
{ {
AssertLockHeld(cs_wallet); LOCK(cs_KeyStore);
UpdateTimeFirstKey(meta.nCreateTime); UpdateTimeFirstKey(meta.nCreateTime);
mapKeyMetadata[keyID] = meta; mapKeyMetadata[keyID] = meta;
} }
void LegacyScriptPubKeyMan::LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata& meta) void LegacyScriptPubKeyMan::LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata& meta)
{ {
AssertLockHeld(cs_wallet); LOCK(cs_KeyStore);
UpdateTimeFirstKey(meta.nCreateTime); UpdateTimeFirstKey(meta.nCreateTime);
m_script_metadata[script_id] = meta; m_script_metadata[script_id] = meta;
} }
@ -630,7 +632,7 @@ bool LegacyScriptPubKeyMan::AddCryptedKey(const CPubKey &vchPubKey,
if (!AddCryptedKeyInner(vchPubKey, vchCryptedSecret)) if (!AddCryptedKeyInner(vchPubKey, vchCryptedSecret))
return false; return false;
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
if (encrypted_batch) if (encrypted_batch)
return encrypted_batch->WriteCryptedKey(vchPubKey, return encrypted_batch->WriteCryptedKey(vchPubKey,
vchCryptedSecret, vchCryptedSecret,
@ -663,7 +665,6 @@ static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)
bool LegacyScriptPubKeyMan::RemoveWatchOnly(const CScript &dest) bool LegacyScriptPubKeyMan::RemoveWatchOnly(const CScript &dest)
{ {
AssertLockHeld(cs_wallet);
{ {
LOCK(cs_KeyStore); LOCK(cs_KeyStore);
setWatchOnly.erase(dest); setWatchOnly.erase(dest);
@ -734,7 +735,7 @@ bool LegacyScriptPubKeyMan::AddWatchOnly(const CScript& dest, int64_t nCreateTim
void LegacyScriptPubKeyMan::SetHDChain(const CHDChain& chain, bool memonly) void LegacyScriptPubKeyMan::SetHDChain(const CHDChain& chain, bool memonly)
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
if (!memonly && !WalletBatch(m_storage.GetDatabase()).WriteHDChain(chain)) if (!memonly && !WalletBatch(m_storage.GetDatabase()).WriteHDChain(chain))
throw std::runtime_error(std::string(__func__) + ": writing chain failed"); throw std::runtime_error(std::string(__func__) + ": writing chain failed");
@ -771,7 +772,7 @@ bool LegacyScriptPubKeyMan::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& inf
{ {
CKeyMetadata meta; CKeyMetadata meta;
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
auto it = mapKeyMetadata.find(keyID); auto it = mapKeyMetadata.find(keyID);
if (it != mapKeyMetadata.end()) { if (it != mapKeyMetadata.end()) {
meta = it->second; meta = it->second;
@ -821,7 +822,7 @@ CPubKey LegacyScriptPubKeyMan::GenerateNewKey(WalletBatch &batch, bool internal)
{ {
assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)); assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET)); assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET));
AssertLockHeld(cs_wallet); AssertLockHeld(cs_KeyStore);
bool fCompressed = m_storage.CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets bool fCompressed = m_storage.CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
CKey secret; CKey secret;
@ -913,7 +914,7 @@ void LegacyScriptPubKeyMan::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata&
void LegacyScriptPubKeyMan::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool) void LegacyScriptPubKeyMan::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
{ {
AssertLockHeld(cs_wallet); LOCK(cs_KeyStore);
if (keypool.m_pre_split) { if (keypool.m_pre_split) {
set_pre_split_keypool.insert(nIndex); set_pre_split_keypool.insert(nIndex);
} else if (keypool.fInternal) { } else if (keypool.fInternal) {
@ -935,7 +936,7 @@ void LegacyScriptPubKeyMan::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
bool LegacyScriptPubKeyMan::CanGenerateKeys() bool LegacyScriptPubKeyMan::CanGenerateKeys()
{ {
// A wallet can generate keys if it has an HD seed (IsHDEnabled) or it is a non-HD wallet (pre FEATURE_HD) // A wallet can generate keys if it has an HD seed (IsHDEnabled) or it is a non-HD wallet (pre FEATURE_HD)
LOCK(cs_wallet); LOCK(cs_KeyStore);
return IsHDEnabled() || !m_storage.CanSupportFeature(FEATURE_HD); return IsHDEnabled() || !m_storage.CanSupportFeature(FEATURE_HD);
} }
@ -962,7 +963,7 @@ CPubKey LegacyScriptPubKeyMan::DeriveNewSeed(const CKey& key)
metadata.hd_seed_id = seed.GetID(); metadata.hd_seed_id = seed.GetID();
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
// mem store the metadata // mem store the metadata
mapKeyMetadata[seed.GetID()] = metadata; mapKeyMetadata[seed.GetID()] = metadata;
@ -977,7 +978,7 @@ CPubKey LegacyScriptPubKeyMan::DeriveNewSeed(const CKey& key)
void LegacyScriptPubKeyMan::SetHDSeed(const CPubKey& seed) void LegacyScriptPubKeyMan::SetHDSeed(const CPubKey& seed)
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
// store the keyid (hash160) together with // store the keyid (hash160) together with
// the child index counter in the database // the child index counter in the database
// as a hdchain object // as a hdchain object
@ -1000,7 +1001,7 @@ bool LegacyScriptPubKeyMan::NewKeyPool()
return false; return false;
} }
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
WalletBatch batch(m_storage.GetDatabase()); WalletBatch batch(m_storage.GetDatabase());
for (const int64_t nIndex : setInternalKeyPool) { for (const int64_t nIndex : setInternalKeyPool) {
@ -1034,7 +1035,7 @@ bool LegacyScriptPubKeyMan::TopUp(unsigned int kpSize)
return false; return false;
} }
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
if (m_storage.IsLocked()) return false; if (m_storage.IsLocked()) return false;
@ -1076,7 +1077,7 @@ bool LegacyScriptPubKeyMan::TopUp(unsigned int kpSize)
void LegacyScriptPubKeyMan::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch) void LegacyScriptPubKeyMan::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch)
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys? assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
int64_t index = ++m_max_keypool_index; int64_t index = ++m_max_keypool_index;
if (!batch.WritePool(index, CKeyPool(pubkey, internal))) { if (!batch.WritePool(index, CKeyPool(pubkey, internal))) {
@ -1107,7 +1108,7 @@ void LegacyScriptPubKeyMan::ReturnDestination(int64_t nIndex, bool fInternal, co
{ {
// Return to key pool // Return to key pool
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
if (fInternal) { if (fInternal) {
setInternalKeyPool.insert(nIndex); setInternalKeyPool.insert(nIndex);
} else if (!set_pre_split_keypool.empty()) { } else if (!set_pre_split_keypool.empty()) {
@ -1131,7 +1132,7 @@ bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, const OutputType typ
CKeyPool keypool; CKeyPool keypool;
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
int64_t nIndex; int64_t nIndex;
if (!ReserveKeyFromKeyPool(nIndex, keypool, internal) && !m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { if (!ReserveKeyFromKeyPool(nIndex, keypool, internal) && !m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
if (m_storage.IsLocked()) return false; if (m_storage.IsLocked()) return false;
@ -1150,7 +1151,7 @@ bool LegacyScriptPubKeyMan::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& key
nIndex = -1; nIndex = -1;
keypool.vchPubKey = CPubKey(); keypool.vchPubKey = CPubKey();
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
bool fReturningInternal = fRequestedInternal; bool fReturningInternal = fRequestedInternal;
fReturningInternal &= (IsHDEnabled() && m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) || m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS); fReturningInternal &= (IsHDEnabled() && m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) || m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
@ -1210,7 +1211,7 @@ void LegacyScriptPubKeyMan::LearnAllRelatedScripts(const CPubKey& key)
void LegacyScriptPubKeyMan::MarkReserveKeysAsUsed(int64_t keypool_id) void LegacyScriptPubKeyMan::MarkReserveKeysAsUsed(int64_t keypool_id)
{ {
AssertLockHeld(cs_wallet); AssertLockHeld(cs_KeyStore);
bool internal = setInternalKeyPool.count(keypool_id); bool internal = setInternalKeyPool.count(keypool_id);
if (!internal) assert(setExternalKeyPool.count(keypool_id) || set_pre_split_keypool.count(keypool_id)); if (!internal) assert(setExternalKeyPool.count(keypool_id) || set_pre_split_keypool.count(keypool_id));
std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool); std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool);
@ -1281,7 +1282,7 @@ bool LegacyScriptPubKeyMan::AddCScriptWithDB(WalletBatch& batch, const CScript&
bool LegacyScriptPubKeyMan::AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info) bool LegacyScriptPubKeyMan::AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info)
{ {
LOCK(cs_wallet); LOCK(cs_KeyStore);
std::copy(info.fingerprint, info.fingerprint + 4, mapKeyMetadata[pubkey.GetID()].key_origin.fingerprint); std::copy(info.fingerprint, info.fingerprint + 4, mapKeyMetadata[pubkey.GetID()].key_origin.fingerprint);
mapKeyMetadata[pubkey.GetID()].key_origin.path = info.path; mapKeyMetadata[pubkey.GetID()].key_origin.path = info.path;
mapKeyMetadata[pubkey.GetID()].has_key_origin = true; mapKeyMetadata[pubkey.GetID()].has_key_origin = true;
@ -1397,8 +1398,7 @@ std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const
// Temporary CWallet accessors and aliases. // Temporary CWallet accessors and aliases.
LegacyScriptPubKeyMan::LegacyScriptPubKeyMan(CWallet& wallet) LegacyScriptPubKeyMan::LegacyScriptPubKeyMan(CWallet& wallet)
: ScriptPubKeyMan(wallet), : ScriptPubKeyMan(wallet),
m_wallet(wallet), m_wallet(wallet) {}
cs_wallet(wallet.cs_wallet) {}
void LegacyScriptPubKeyMan::NotifyWatchonlyChanged(bool fHaveWatchOnly) const { return m_wallet.NotifyWatchonlyChanged(fHaveWatchOnly); } void LegacyScriptPubKeyMan::NotifyWatchonlyChanged(bool fHaveWatchOnly) const { return m_wallet.NotifyWatchonlyChanged(fHaveWatchOnly); }
void LegacyScriptPubKeyMan::NotifyCanGetAddressesChanged() const { return m_wallet.NotifyCanGetAddressesChanged(); } void LegacyScriptPubKeyMan::NotifyCanGetAddressesChanged() const { return m_wallet.NotifyCanGetAddressesChanged(); }

View file

@ -209,7 +209,7 @@ private:
using WatchOnlySet = std::set<CScript>; using WatchOnlySet = std::set<CScript>;
using WatchKeyMap = std::map<CKeyID, CPubKey>; 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>>>; using CryptedKeyMap = std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>;
@ -217,7 +217,7 @@ private:
WatchOnlySet setWatchOnly GUARDED_BY(cs_KeyStore); WatchOnlySet setWatchOnly GUARDED_BY(cs_KeyStore);
WatchKeyMap mapWatchKeys 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 AddKeyPubKeyInner(const CKey& key, const CPubKey &pubkey);
bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
@ -231,14 +231,14 @@ private:
* of the other AddWatchOnly which accepts a timestamp and sets * of the other AddWatchOnly which accepts a timestamp and sets
* nTimeFirstKey more intelligently for more efficient rescans. * nTimeFirstKey more intelligently for more efficient rescans.
*/ */
bool AddWatchOnly(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_wallet); bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
bool AddWatchOnlyInMem(const CScript &dest); bool AddWatchOnlyInMem(const CScript &dest);
//! Adds a watch-only address to the store, and saves it to disk. //! 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. //! 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); void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
@ -252,12 +252,12 @@ private:
CHDChain hdChain; CHDChain hdChain;
/* HD derive new child key (on internal or external chain) */ /* 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> setInternalKeyPool GUARDED_BY(cs_KeyStore);
std::set<int64_t> setExternalKeyPool GUARDED_BY(cs_wallet); std::set<int64_t> setExternalKeyPool GUARDED_BY(cs_KeyStore);
std::set<int64_t> set_pre_split_keypool GUARDED_BY(cs_wallet); std::set<int64_t> set_pre_split_keypool GUARDED_BY(cs_KeyStore);
int64_t m_max_keypool_index GUARDED_BY(cs_wallet) = 0; int64_t m_max_keypool_index GUARDED_BY(cs_KeyStore) = 0;
std::map<CKeyID, int64_t> m_pool_key_to_index; 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 // 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; std::map<int64_t, CKeyID> m_index_to_reserved_key;
@ -297,7 +297,7 @@ public:
void MarkUnusedAddresses(const CScript& script) override; void MarkUnusedAddresses(const CScript& script) override;
//! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo //! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); void UpgradeKeyMetadata();
bool IsHDEnabled() const override; bool IsHDEnabled() const override;
@ -310,7 +310,7 @@ public:
void RewriteDB() override; void RewriteDB() override;
int64_t GetOldestKeyPoolTime() override; int64_t GetOldestKeyPoolTime() override;
size_t KeypoolCountExternalKeys() override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); size_t KeypoolCountExternalKeys() override;
unsigned int GetKeyPoolSize() const override; unsigned int GetKeyPoolSize() const override;
int64_t GetTimeFirstKey() const override; int64_t GetTimeFirstKey() const override;
@ -320,27 +320,27 @@ public:
bool CanGetAddresses(bool internal = false) override; bool CanGetAddresses(bool internal = false) override;
// Map from Key ID to key metadata. // 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). // 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. //! 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) //! Adds a key to the store, without saving it to disk (used by LoadWallet)
bool LoadKey(const CKey& key, const CPubKey &pubkey); bool LoadKey(const CKey& key, const CPubKey &pubkey);
//! Adds an encrypted key to the store, and saves it to disk. //! Adds an encrypted key to the store, and saves it to disk.
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); 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) //! 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); 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 //! Adds a CScript to the store
bool LoadCScript(const CScript& redeemScript); bool LoadCScript(const CScript& redeemScript);
//! Load metadata (used by LoadWallet) //! Load metadata (used by LoadWallet)
void LoadKeyMetadata(const CKeyID& keyID, 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) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); void LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata &metadata);
//! Generate a new key //! 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) */ /* Set the HD chain model (chain child index counters) */
void SetHDChain(const CHDChain& chain, bool memonly); void SetHDChain(const CHDChain& chain, bool memonly);
@ -353,8 +353,8 @@ public:
//! Returns whether there are any watch-only things in the wallet //! Returns whether there are any watch-only things in the wallet
bool HaveWatchOnly() const; bool HaveWatchOnly() const;
//! Remove a watch only script from the keystore //! Remove a watch only script from the keystore
bool RemoveWatchOnly(const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); bool RemoveWatchOnly(const CScript &dest);
bool AddWatchOnly(const CScript& dest, int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); bool AddWatchOnly(const CScript& dest, int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
//! Fetches a pubkey from mapWatchKeys if it exists there //! Fetches a pubkey from mapWatchKeys if it exists there
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const; bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const;
@ -367,14 +367,14 @@ public:
bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override; bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override;
//! Load a keypool entry //! 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(); 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 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_wallet); 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_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_KeyStore);
bool ImportScriptPubKeys(const std::set<CScript>& script_pub_keys, const bool have_solving_data, 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_KeyStore);
/* Returns true if the wallet can generate new keys */ /* Returns true if the wallet can generate new keys */
bool CanGenerateKeys(); bool CanGenerateKeys();
@ -408,7 +408,7 @@ public:
/** /**
* Marks all keys in the keypool up to and including reserve_key as used. * 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; } const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; }
std::set<CKeyID> GetKeys() const override; std::set<CKeyID> GetKeys() const override;
@ -420,7 +420,6 @@ public:
void NotifyCanGetAddressesChanged() const; void NotifyCanGetAddressesChanged() const;
template<typename... Params> void WalletLogPrintf(const std::string& fmt, const Params&... parameters) const; template<typename... Params> void WalletLogPrintf(const std::string& fmt, const Params&... parameters) const;
CWallet& m_wallet; CWallet& m_wallet;
RecursiveMutex& cs_wallet;
}; };
#endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H #endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H

View file

@ -36,7 +36,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// P2PK compressed // P2PK compressed
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
scriptPubKey = GetScriptForRawPubKey(pubkeys[0]); scriptPubKey = GetScriptForRawPubKey(pubkeys[0]);
// Keystore does not have key // Keystore does not have key
@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// P2PK uncompressed // P2PK uncompressed
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
scriptPubKey = GetScriptForRawPubKey(uncompressedPubkey); scriptPubKey = GetScriptForRawPubKey(uncompressedPubkey);
// Keystore does not have key // Keystore does not have key
@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// P2PKH compressed // P2PKH compressed
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
scriptPubKey = GetScriptForDestination(PKHash(pubkeys[0])); scriptPubKey = GetScriptForDestination(PKHash(pubkeys[0]));
// Keystore does not have key // Keystore does not have key
@ -84,7 +84,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// P2PKH uncompressed // P2PKH uncompressed
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
scriptPubKey = GetScriptForDestination(PKHash(uncompressedPubkey)); scriptPubKey = GetScriptForDestination(PKHash(uncompressedPubkey));
// Keystore does not have key // Keystore does not have key
@ -100,7 +100,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// P2SH // P2SH
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
CScript redeemScript = GetScriptForDestination(PKHash(pubkeys[0])); CScript redeemScript = GetScriptForDestination(PKHash(pubkeys[0]));
scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript)); scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
@ -123,7 +123,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// (P2PKH inside) P2SH inside P2SH (invalid) // (P2PKH inside) P2SH inside P2SH (invalid)
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
CScript redeemscript_inner = GetScriptForDestination(PKHash(pubkeys[0])); CScript redeemscript_inner = GetScriptForDestination(PKHash(pubkeys[0]));
CScript redeemscript = GetScriptForDestination(ScriptHash(redeemscript_inner)); CScript redeemscript = GetScriptForDestination(ScriptHash(redeemscript_inner));
@ -140,7 +140,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// (P2PKH inside) P2SH inside P2WSH (invalid) // (P2PKH inside) P2SH inside P2WSH (invalid)
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
CScript redeemscript = GetScriptForDestination(PKHash(pubkeys[0])); CScript redeemscript = GetScriptForDestination(PKHash(pubkeys[0]));
CScript witnessscript = GetScriptForDestination(ScriptHash(redeemscript)); CScript witnessscript = GetScriptForDestination(ScriptHash(redeemscript));
@ -157,7 +157,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// P2WPKH inside P2WSH (invalid) // P2WPKH inside P2WSH (invalid)
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
CScript witnessscript = GetScriptForDestination(WitnessV0KeyHash(PKHash(pubkeys[0]))); CScript witnessscript = GetScriptForDestination(WitnessV0KeyHash(PKHash(pubkeys[0])));
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript)); scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript));
@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// (P2PKH inside) P2WSH inside P2WSH (invalid) // (P2PKH inside) P2WSH inside P2WSH (invalid)
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
CScript witnessscript_inner = GetScriptForDestination(PKHash(pubkeys[0])); CScript witnessscript_inner = GetScriptForDestination(PKHash(pubkeys[0]));
CScript witnessscript = GetScriptForDestination(WitnessV0ScriptHash(witnessscript_inner)); CScript witnessscript = GetScriptForDestination(WitnessV0ScriptHash(witnessscript_inner));
@ -189,7 +189,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// P2WPKH compressed // P2WPKH compressed
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0]));
scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(PKHash(pubkeys[0]))); scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(PKHash(pubkeys[0])));
@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// P2WPKH uncompressed // P2WPKH uncompressed
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(uncompressedKey)); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(uncompressedKey));
scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(PKHash(uncompressedPubkey))); scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(PKHash(uncompressedPubkey)));
@ -221,7 +221,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// scriptPubKey multisig // scriptPubKey multisig
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
scriptPubKey = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]}); scriptPubKey = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]});
@ -251,7 +251,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// P2SH multisig // P2SH multisig
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(uncompressedKey)); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(uncompressedKey));
BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[1])); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[1]));
@ -271,7 +271,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// P2WSH multisig with compressed keys // P2WSH multisig with compressed keys
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0]));
BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[1])); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[1]));
@ -296,7 +296,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// P2WSH multisig with uncompressed key // P2WSH multisig with uncompressed key
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(uncompressedKey)); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(uncompressedKey));
BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[1])); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[1]));
@ -321,7 +321,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// P2WSH multisig wrapped in P2SH // P2WSH multisig wrapped in P2SH
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]}); CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]});
CScript redeemScript = GetScriptForDestination(WitnessV0ScriptHash(witnessScript)); CScript redeemScript = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
@ -347,7 +347,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// OP_RETURN // OP_RETURN
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0]));
scriptPubKey.clear(); scriptPubKey.clear();
@ -360,7 +360,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// witness unspendable // witness unspendable
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0]));
scriptPubKey.clear(); scriptPubKey.clear();
@ -373,7 +373,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// witness unknown // witness unknown
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0]));
scriptPubKey.clear(); scriptPubKey.clear();
@ -386,7 +386,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
// Nonstandard // Nonstandard
{ {
CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
LOCK(keystore.cs_wallet); LOCK(keystore.GetLegacyScriptPubKeyMan()->cs_KeyStore);
BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0]));
scriptPubKey.clear(); scriptPubKey.clear();

View file

@ -17,7 +17,7 @@ BOOST_FIXTURE_TEST_SUITE(psbt_wallet_tests, WalletTestingSetup)
BOOST_AUTO_TEST_CASE(psbt_updater_test) BOOST_AUTO_TEST_CASE(psbt_updater_test)
{ {
auto spk_man = m_wallet.GetLegacyScriptPubKeyMan(); auto spk_man = m_wallet.GetLegacyScriptPubKeyMan();
LOCK(m_wallet.cs_wallet); LOCK2(m_wallet.cs_wallet, spk_man->cs_KeyStore);
// Create prevtxs and add to wallet // Create prevtxs and add to wallet
CDataStream s_prev_tx1(ParseHex("0200000000010158e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7501000000171600145f275f436b09a8cc9a2eb2a2f528485c68a56323feffffff02d8231f1b0100000017a914aed962d6654f9a2b36608eb9d64d2b260db4f1118700c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e88702483045022100a22edcc6e5bc511af4cc4ae0de0fcd75c7e04d8c1c3a8aa9d820ed4b967384ec02200642963597b9b1bc22c75e9f3e117284a962188bf5e8a74c895089046a20ad770121035509a48eb623e10aace8bfd0212fdb8a8e5af3c94b0b133b95e114cab89e4f7965000000"), SER_NETWORK, PROTOCOL_VERSION); CDataStream s_prev_tx1(ParseHex("0200000000010158e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7501000000171600145f275f436b09a8cc9a2eb2a2f528485c68a56323feffffff02d8231f1b0100000017a914aed962d6654f9a2b36608eb9d64d2b260db4f1118700c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e88702483045022100a22edcc6e5bc511af4cc4ae0de0fcd75c7e04d8c1c3a8aa9d820ed4b967384ec02200642963597b9b1bc22c75e9f3e117284a962188bf5e8a74c895089046a20ad770121035509a48eb623e10aace8bfd0212fdb8a8e5af3c94b0b133b95e114cab89e4f7965000000"), SER_NETWORK, PROTOCOL_VERSION);

View file

@ -29,8 +29,7 @@ BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup)
static void AddKey(CWallet& wallet, const CKey& key) static void AddKey(CWallet& wallet, const CKey& key)
{ {
auto spk_man = wallet.GetLegacyScriptPubKeyMan(); auto spk_man = wallet.GetLegacyScriptPubKeyMan();
LOCK(wallet.cs_wallet); LOCK2(wallet.cs_wallet, spk_man->cs_KeyStore);
AssertLockHeld(spk_man->cs_wallet);
spk_man->AddKeyPubKey(key, key.GetPubKey()); spk_man->AddKeyPubKey(key, key.GetPubKey());
} }
@ -217,8 +216,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
{ {
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
auto spk_man = wallet->GetLegacyScriptPubKeyMan(); auto spk_man = wallet->GetLegacyScriptPubKeyMan();
LOCK(wallet->cs_wallet); LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore);
AssertLockHeld(spk_man->cs_wallet);
spk_man->mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME; spk_man->mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME;
spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
@ -272,8 +270,7 @@ BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
auto locked_chain = chain->lock(); auto locked_chain = chain->lock();
LockAssertion lock(::cs_main); LockAssertion lock(::cs_main);
LOCK(wallet.cs_wallet); LOCK2(wallet.cs_wallet, spk_man->cs_KeyStore);
AssertLockHeld(spk_man->cs_wallet);
wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, ::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash(), 0); CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, ::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash(), 0);
@ -377,7 +374,7 @@ static void TestWatchOnlyPubKey(LegacyScriptPubKeyMan* spk_man, const CPubKey& a
CScript p2pk = GetScriptForRawPubKey(add_pubkey); CScript p2pk = GetScriptForRawPubKey(add_pubkey);
CKeyID add_address = add_pubkey.GetID(); CKeyID add_address = add_pubkey.GetID();
CPubKey found_pubkey; CPubKey found_pubkey;
LOCK(spk_man->cs_wallet); LOCK(spk_man->cs_KeyStore);
// all Scripts (i.e. also all PubKeys) are added to the general watch-only set // all Scripts (i.e. also all PubKeys) are added to the general watch-only set
BOOST_CHECK(!spk_man->HaveWatchOnly(p2pk)); BOOST_CHECK(!spk_man->HaveWatchOnly(p2pk));
@ -394,7 +391,6 @@ static void TestWatchOnlyPubKey(LegacyScriptPubKeyMan* spk_man, const CPubKey& a
BOOST_CHECK(found_pubkey == CPubKey()); // passed key is unchanged BOOST_CHECK(found_pubkey == CPubKey()); // passed key is unchanged
} }
AssertLockHeld(spk_man->cs_wallet);
spk_man->RemoveWatchOnly(p2pk); spk_man->RemoveWatchOnly(p2pk);
BOOST_CHECK(!spk_man->HaveWatchOnly(p2pk)); BOOST_CHECK(!spk_man->HaveWatchOnly(p2pk));

View file

@ -219,6 +219,7 @@ WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString&
// Set a seed for the wallet // Set a seed for the wallet
{ {
LOCK(wallet->cs_wallet);
if (auto spk_man = wallet->m_spk_man.get()) { if (auto spk_man = wallet->m_spk_man.get()) {
if (!spk_man->SetupGeneration()) { if (!spk_man->SetupGeneration()) {
error = "Unable to generate initial keys"; error = "Unable to generate initial keys";
@ -265,7 +266,6 @@ void CWallet::UpgradeKeyMetadata()
} }
if (m_spk_man) { if (m_spk_man) {
AssertLockHeld(m_spk_man->cs_wallet);
m_spk_man->UpgradeKeyMetadata(); m_spk_man->UpgradeKeyMetadata();
} }
SetWalletFlag(WALLET_FLAG_KEY_ORIGIN_METADATA); SetWalletFlag(WALLET_FLAG_KEY_ORIGIN_METADATA);
@ -1322,6 +1322,7 @@ bool CWallet::IsHDEnabled() const
bool CWallet::CanGetAddresses(bool internal) bool CWallet::CanGetAddresses(bool internal)
{ {
LOCK(cs_wallet);
{ {
auto spk_man = m_spk_man.get(); auto spk_man = m_spk_man.get();
if (spk_man && spk_man->CanGetAddresses(internal)) { if (spk_man && spk_man->CanGetAddresses(internal)) {
@ -1427,7 +1428,7 @@ bool CWallet::ImportScripts(const std::set<CScript> scripts, int64_t timestamp)
if (!spk_man) { if (!spk_man) {
return false; return false;
} }
AssertLockHeld(spk_man->cs_wallet); LOCK(spk_man->cs_KeyStore);
return spk_man->ImportScripts(scripts, timestamp); return spk_man->ImportScripts(scripts, timestamp);
} }
@ -1437,7 +1438,7 @@ bool CWallet::ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const in
if (!spk_man) { if (!spk_man) {
return false; return false;
} }
AssertLockHeld(spk_man->cs_wallet); LOCK(spk_man->cs_KeyStore);
return spk_man->ImportPrivKeys(privkey_map, timestamp); return spk_man->ImportPrivKeys(privkey_map, timestamp);
} }
@ -1447,7 +1448,7 @@ bool CWallet::ImportPubKeys(const std::vector<CKeyID>& ordered_pubkeys, const st
if (!spk_man) { if (!spk_man) {
return false; return false;
} }
AssertLockHeld(spk_man->cs_wallet); LOCK(spk_man->cs_KeyStore);
return spk_man->ImportPubKeys(ordered_pubkeys, pubkey_map, key_origins, add_keypool, internal, timestamp); return spk_man->ImportPubKeys(ordered_pubkeys, pubkey_map, key_origins, add_keypool, internal, timestamp);
} }
@ -1457,7 +1458,7 @@ bool CWallet::ImportScriptPubKeys(const std::string& label, const std::set<CScri
if (!spk_man) { if (!spk_man) {
return false; return false;
} }
AssertLockHeld(spk_man->cs_wallet); LOCK(spk_man->cs_KeyStore);
if (!spk_man->ImportScriptPubKeys(script_pub_keys, have_solving_data, timestamp)) { if (!spk_man->ImportScriptPubKeys(script_pub_keys, have_solving_data, timestamp)) {
return false; return false;
} }
@ -3103,7 +3104,6 @@ size_t CWallet::KeypoolCountExternalKeys()
unsigned int count = 0; unsigned int count = 0;
if (auto spk_man = m_spk_man.get()) { if (auto spk_man = m_spk_man.get()) {
AssertLockHeld(spk_man->cs_wallet);
count += spk_man->KeypoolCountExternalKeys(); count += spk_man->KeypoolCountExternalKeys();
} }
@ -3123,6 +3123,7 @@ unsigned int CWallet::GetKeyPoolSize() const
bool CWallet::TopUpKeyPool(unsigned int kpSize) bool CWallet::TopUpKeyPool(unsigned int kpSize)
{ {
LOCK(cs_wallet);
bool res = true; bool res = true;
if (auto spk_man = m_spk_man.get()) { if (auto spk_man = m_spk_man.get()) {
res &= spk_man->TopUp(kpSize); res &= spk_man->TopUp(kpSize);
@ -3149,6 +3150,7 @@ bool CWallet::GetNewDestination(const OutputType type, const std::string label,
bool CWallet::GetNewChangeDestination(const OutputType type, CTxDestination& dest, std::string& error) bool CWallet::GetNewChangeDestination(const OutputType type, CTxDestination& dest, std::string& error)
{ {
LOCK(cs_wallet);
error.clear(); error.clear();
ReserveDestination reservedest(this, type); ReserveDestination reservedest(this, type);
@ -3163,6 +3165,7 @@ bool CWallet::GetNewChangeDestination(const OutputType type, CTxDestination& des
int64_t CWallet::GetOldestKeyPoolTime() int64_t CWallet::GetOldestKeyPoolTime()
{ {
LOCK(cs_wallet);
int64_t oldestKey = std::numeric_limits<int64_t>::max(); int64_t oldestKey = std::numeric_limits<int64_t>::max();
if (auto spk_man = m_spk_man.get()) { if (auto spk_man = m_spk_man.get()) {
oldestKey = spk_man->GetOldestKeyPoolTime(); oldestKey = spk_man->GetOldestKeyPoolTime();
@ -3416,7 +3419,7 @@ void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::map<C
LegacyScriptPubKeyMan* spk_man = GetLegacyScriptPubKeyMan(); LegacyScriptPubKeyMan* spk_man = GetLegacyScriptPubKeyMan();
assert(spk_man != nullptr); assert(spk_man != nullptr);
AssertLockHeld(spk_man->cs_wallet); LOCK(spk_man->cs_KeyStore);
// get birth times for keys with metadata // get birth times for keys with metadata
for (const auto& entry : spk_man->mapKeyMetadata) { for (const auto& entry : spk_man->mapKeyMetadata) {
@ -3725,6 +3728,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
walletInstance->SetWalletFlags(wallet_creation_flags, false); walletInstance->SetWalletFlags(wallet_creation_flags, false);
if (!(wallet_creation_flags & (WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET))) { if (!(wallet_creation_flags & (WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET))) {
LOCK(walletInstance->cs_wallet);
if (auto spk_man = walletInstance->m_spk_man.get()) { if (auto spk_man = walletInstance->m_spk_man.get()) {
if (!spk_man->SetupGeneration()) { if (!spk_man->SetupGeneration()) {
error = _("Unable to generate initial keys").translated; error = _("Unable to generate initial keys").translated;
@ -4064,7 +4068,7 @@ bool CWallet::IsLocked() const
if (!IsCrypted()) { if (!IsCrypted()) {
return false; return false;
} }
LOCK(cs_KeyStore); LOCK(cs_wallet);
return vMasterKey.empty(); return vMasterKey.empty();
} }
@ -4074,7 +4078,7 @@ bool CWallet::Lock()
return false; return false;
{ {
LOCK(cs_KeyStore); LOCK(cs_wallet);
vMasterKey.clear(); vMasterKey.clear();
} }
@ -4085,7 +4089,7 @@ bool CWallet::Lock()
bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys) bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys)
{ {
{ {
LOCK(cs_KeyStore); LOCK(cs_wallet);
if (m_spk_man) { if (m_spk_man) {
if (!m_spk_man->CheckDecryptionKey(vMasterKeyIn, accept_no_keys)) { if (!m_spk_man->CheckDecryptionKey(vMasterKeyIn, accept_no_keys)) {
return false; return false;

View file

@ -606,7 +606,7 @@ class WalletRescanReserver; //forward declarations for ScanForWalletTransactions
class CWallet final : public WalletStorage, private interfaces::Chain::Notifications class CWallet final : public WalletStorage, private interfaces::Chain::Notifications
{ {
private: private:
CKeyingMaterial vMasterKey GUARDED_BY(cs_KeyStore); CKeyingMaterial vMasterKey GUARDED_BY(cs_wallet);
bool Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys = false); bool Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys = false);

View file

@ -196,7 +196,7 @@ public:
static bool static bool
ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
CWalletScanState &wss, std::string& strType, std::string& strErr) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet, pwallet->GetLegacyScriptPubKeyMan()->cs_wallet) CWalletScanState &wss, std::string& strType, std::string& strErr) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
{ {
try { try {
// Unserialize // Unserialize
@ -434,7 +434,6 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
DBErrors result = DBErrors::LOAD_OK; DBErrors result = DBErrors::LOAD_OK;
LOCK(pwallet->cs_wallet); LOCK(pwallet->cs_wallet);
AssertLockHeld(pwallet->GetLegacyScriptPubKeyMan()->cs_wallet);
try { try {
int nMinVersion = 0; int nMinVersion = 0;
if (m_batch.Read(DBKeys::MINVERSION, nMinVersion)) { if (m_batch.Read(DBKeys::MINVERSION, nMinVersion)) {
@ -518,6 +517,7 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
if ((wss.nKeys + wss.nCKeys + wss.nWatchKeys) != wss.nKeyMeta) { if ((wss.nKeys + wss.nCKeys + wss.nWatchKeys) != wss.nKeyMeta) {
auto spk_man = pwallet->GetLegacyScriptPubKeyMan(); auto spk_man = pwallet->GetLegacyScriptPubKeyMan();
if (spk_man) { if (spk_man) {
LOCK(spk_man->cs_KeyStore);
spk_man->UpdateTimeFirstKey(1); spk_man->UpdateTimeFirstKey(1);
} }
} }
@ -713,7 +713,6 @@ bool WalletBatch::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, C
{ {
// Required in LoadKeyMetadata(): // Required in LoadKeyMetadata():
LOCK(dummyWallet->cs_wallet); LOCK(dummyWallet->cs_wallet);
AssertLockHeld(dummyWallet->GetLegacyScriptPubKeyMan()->cs_wallet);
fReadOK = ReadKeyValue(dummyWallet, ssKey, ssValue, fReadOK = ReadKeyValue(dummyWallet, ssKey, ssValue,
dummyWss, strType, strErr); dummyWss, strType, strErr);
} }

View file

@ -27,6 +27,7 @@ static std::shared_ptr<CWallet> CreateWallet(const std::string& name, const fs::
} }
// dummy chain interface // dummy chain interface
std::shared_ptr<CWallet> wallet_instance(new CWallet(nullptr /* chain */, WalletLocation(name), WalletDatabase::Create(path)), WalletToolReleaseWallet); std::shared_ptr<CWallet> wallet_instance(new CWallet(nullptr /* chain */, WalletLocation(name), WalletDatabase::Create(path)), WalletToolReleaseWallet);
LOCK(wallet_instance->cs_wallet);
bool first_run = true; bool first_run = true;
DBErrors load_wallet_ret = wallet_instance->LoadWallet(first_run); DBErrors load_wallet_ret = wallet_instance->LoadWallet(first_run);
if (load_wallet_ret != DBErrors::LOAD_OK) { if (load_wallet_ret != DBErrors::LOAD_OK) {