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 locked_chain = wallet->chain().lock();
LOCK(wallet->cs_wallet);
AssertLockHeld(spk_man->cs_wallet);
LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore);
wallet->SetAddressBook(GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type), "", "receive");
spk_man->AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey());
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)
{
auto spk_man = wallet.GetLegacyScriptPubKeyMan();
LOCK(wallet.cs_wallet);
AssertLockHeld(spk_man->cs_wallet);
LOCK2(wallet.cs_wallet, spk_man->cs_KeyStore);
const auto dest = DecodeDestination(address);
assert(IsValidDestination(dest));
const auto script = GetScriptForDestination(dest);

View file

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

View file

@ -983,7 +983,7 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request)
LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*pwallet);
auto locked_chain = pwallet->chain().lock();
LOCK(pwallet->cs_wallet);
LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore);
std::string label;
if (!request.params[2].isNull())
@ -4014,7 +4014,7 @@ UniValue sethdseed(const JSONRPCRequest& request)
}
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
if (!pwallet->CanSupportFeature(FEATURE_HD)) {

View file

@ -13,6 +13,7 @@
bool LegacyScriptPubKeyMan::GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error)
{
LOCK(cs_KeyStore);
error.clear();
// 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)
{
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore);
encrypted_batch = batch;
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)
{
LOCK(cs_KeyStore);
if (!CanGetAddresses(internal)) {
return false;
}
@ -282,7 +283,7 @@ bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool i
void LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script)
{
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore);
// extract addresses and check if they match with an unused keypool key
for (const auto& keyid : GetAffectedKeys(script, *this)) {
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()
{
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore);
if (m_storage.IsLocked() || m_storage.IsWalletFlagSet(WALLET_FLAG_KEY_ORIGIN_METADATA)) {
return;
}
@ -352,7 +353,7 @@ bool LegacyScriptPubKeyMan::IsHDEnabled() const
bool LegacyScriptPubKeyMan::CanGetAddresses(bool internal)
{
LOCK(cs_wallet);
LOCK(cs_KeyStore);
// Check if the keypool has keys
bool keypool_has_keys;
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)
{
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore);
error = "";
bool hd_upgrade = false;
bool split_upgrade = false;
@ -410,7 +411,7 @@ bool LegacyScriptPubKeyMan::HavePrivateKeys() const
void LegacyScriptPubKeyMan::RewriteDB()
{
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore);
setInternalKeyPool.clear();
setExternalKeyPool.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()
{
LOCK(cs_wallet);
LOCK(cs_KeyStore);
WalletBatch batch(m_storage.GetDatabase());
@ -453,25 +454,25 @@ int64_t LegacyScriptPubKeyMan::GetOldestKeyPoolTime()
size_t LegacyScriptPubKeyMan::KeypoolCountExternalKeys()
{
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore);
return setExternalKeyPool.size() + set_pre_split_keypool.size();
}
unsigned int LegacyScriptPubKeyMan::GetKeyPoolSize() const
{
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore);
return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size();
}
int64_t LegacyScriptPubKeyMan::GetTimeFirstKey() const
{
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore);
return nTimeFirstKey;
}
const CKeyMetadata* LegacyScriptPubKeyMan::GetMetadata(const CTxDestination& dest) const
{
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore);
CKeyID key_id = GetKeyForDestination(*this, dest);
if (!key_id.IsNull()) {
@ -496,7 +497,7 @@ const CKeyMetadata* LegacyScriptPubKeyMan::GetMetadata(const CTxDestination& des
*/
void LegacyScriptPubKeyMan::UpdateTimeFirstKey(int64_t nCreateTime)
{
AssertLockHeld(cs_wallet);
AssertLockHeld(cs_KeyStore);
if (nCreateTime <= 1) {
// Cannot determine birthday information, so set the wallet birthday to
// 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)
{
LOCK(cs_KeyStore);
WalletBatch batch(m_storage.GetDatabase());
return LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(batch, secret, 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
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)
{
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore);
UpdateTimeFirstKey(meta.nCreateTime);
mapKeyMetadata[keyID] = meta;
}
void LegacyScriptPubKeyMan::LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata& meta)
{
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore);
UpdateTimeFirstKey(meta.nCreateTime);
m_script_metadata[script_id] = meta;
}
@ -630,7 +632,7 @@ bool LegacyScriptPubKeyMan::AddCryptedKey(const CPubKey &vchPubKey,
if (!AddCryptedKeyInner(vchPubKey, vchCryptedSecret))
return false;
{
LOCK(cs_wallet);
LOCK(cs_KeyStore);
if (encrypted_batch)
return encrypted_batch->WriteCryptedKey(vchPubKey,
vchCryptedSecret,
@ -663,7 +665,6 @@ static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)
bool LegacyScriptPubKeyMan::RemoveWatchOnly(const CScript &dest)
{
AssertLockHeld(cs_wallet);
{
LOCK(cs_KeyStore);
setWatchOnly.erase(dest);
@ -734,7 +735,7 @@ bool LegacyScriptPubKeyMan::AddWatchOnly(const CScript& dest, int64_t nCreateTim
void LegacyScriptPubKeyMan::SetHDChain(const CHDChain& chain, bool memonly)
{
LOCK(cs_wallet);
LOCK(cs_KeyStore);
if (!memonly && !WalletBatch(m_storage.GetDatabase()).WriteHDChain(chain))
throw std::runtime_error(std::string(__func__) + ": writing chain failed");
@ -771,7 +772,7 @@ bool LegacyScriptPubKeyMan::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& inf
{
CKeyMetadata meta;
{
LOCK(cs_wallet);
LOCK(cs_KeyStore);
auto it = mapKeyMetadata.find(keyID);
if (it != mapKeyMetadata.end()) {
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_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
CKey secret;
@ -913,7 +914,7 @@ void LegacyScriptPubKeyMan::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata&
void LegacyScriptPubKeyMan::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
{
AssertLockHeld(cs_wallet);
LOCK(cs_KeyStore);
if (keypool.m_pre_split) {
set_pre_split_keypool.insert(nIndex);
} else if (keypool.fInternal) {
@ -935,7 +936,7 @@ void LegacyScriptPubKeyMan::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
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)
LOCK(cs_wallet);
LOCK(cs_KeyStore);
return IsHDEnabled() || !m_storage.CanSupportFeature(FEATURE_HD);
}
@ -962,7 +963,7 @@ CPubKey LegacyScriptPubKeyMan::DeriveNewSeed(const CKey& key)
metadata.hd_seed_id = seed.GetID();
{
LOCK(cs_wallet);
LOCK(cs_KeyStore);
// mem store the metadata
mapKeyMetadata[seed.GetID()] = metadata;
@ -977,7 +978,7 @@ CPubKey LegacyScriptPubKeyMan::DeriveNewSeed(const CKey& key)
void LegacyScriptPubKeyMan::SetHDSeed(const CPubKey& seed)
{
LOCK(cs_wallet);
LOCK(cs_KeyStore);
// store the keyid (hash160) together with
// the child index counter in the database
// as a hdchain object
@ -1000,7 +1001,7 @@ bool LegacyScriptPubKeyMan::NewKeyPool()
return false;
}
{
LOCK(cs_wallet);
LOCK(cs_KeyStore);
WalletBatch batch(m_storage.GetDatabase());
for (const int64_t nIndex : setInternalKeyPool) {
@ -1034,7 +1035,7 @@ bool LegacyScriptPubKeyMan::TopUp(unsigned int kpSize)
return false;
}
{
LOCK(cs_wallet);
LOCK(cs_KeyStore);
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)
{
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?
int64_t index = ++m_max_keypool_index;
if (!batch.WritePool(index, CKeyPool(pubkey, internal))) {
@ -1107,7 +1108,7 @@ void LegacyScriptPubKeyMan::ReturnDestination(int64_t nIndex, bool fInternal, co
{
// Return to key pool
{
LOCK(cs_wallet);
LOCK(cs_KeyStore);
if (fInternal) {
setInternalKeyPool.insert(nIndex);
} else if (!set_pre_split_keypool.empty()) {
@ -1131,7 +1132,7 @@ bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, const OutputType typ
CKeyPool keypool;
{
LOCK(cs_wallet);
LOCK(cs_KeyStore);
int64_t nIndex;
if (!ReserveKeyFromKeyPool(nIndex, keypool, internal) && !m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
if (m_storage.IsLocked()) return false;
@ -1150,7 +1151,7 @@ bool LegacyScriptPubKeyMan::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& key
nIndex = -1;
keypool.vchPubKey = CPubKey();
{
LOCK(cs_wallet);
LOCK(cs_KeyStore);
bool fReturningInternal = fRequestedInternal;
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)
{
AssertLockHeld(cs_wallet);
AssertLockHeld(cs_KeyStore);
bool internal = setInternalKeyPool.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);
@ -1281,7 +1282,7 @@ bool LegacyScriptPubKeyMan::AddCScriptWithDB(WalletBatch& batch, const CScript&
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);
mapKeyMetadata[pubkey.GetID()].key_origin.path = info.path;
mapKeyMetadata[pubkey.GetID()].has_key_origin = true;
@ -1397,8 +1398,7 @@ std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const
// Temporary CWallet accessors and aliases.
LegacyScriptPubKeyMan::LegacyScriptPubKeyMan(CWallet& wallet)
: ScriptPubKeyMan(wallet),
m_wallet(wallet),
cs_wallet(wallet.cs_wallet) {}
m_wallet(wallet) {}
void LegacyScriptPubKeyMan::NotifyWatchonlyChanged(bool fHaveWatchOnly) const { return m_wallet.NotifyWatchonlyChanged(fHaveWatchOnly); }
void LegacyScriptPubKeyMan::NotifyCanGetAddressesChanged() const { return m_wallet.NotifyCanGetAddressesChanged(); }

View file

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

View file

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

View file

@ -17,7 +17,7 @@ BOOST_FIXTURE_TEST_SUITE(psbt_wallet_tests, WalletTestingSetup)
BOOST_AUTO_TEST_CASE(psbt_updater_test)
{
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
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)
{
auto spk_man = wallet.GetLegacyScriptPubKeyMan();
LOCK(wallet.cs_wallet);
AssertLockHeld(spk_man->cs_wallet);
LOCK2(wallet.cs_wallet, spk_man->cs_KeyStore);
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());
auto spk_man = wallet->GetLegacyScriptPubKeyMan();
LOCK(wallet->cs_wallet);
AssertLockHeld(spk_man->cs_wallet);
LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore);
spk_man->mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME;
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();
LockAssertion lock(::cs_main);
LOCK(wallet.cs_wallet);
AssertLockHeld(spk_man->cs_wallet);
LOCK2(wallet.cs_wallet, spk_man->cs_KeyStore);
wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
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);
CKeyID add_address = add_pubkey.GetID();
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
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
}
AssertLockHeld(spk_man->cs_wallet);
spk_man->RemoveWatchOnly(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
{
LOCK(wallet->cs_wallet);
if (auto spk_man = wallet->m_spk_man.get()) {
if (!spk_man->SetupGeneration()) {
error = "Unable to generate initial keys";
@ -265,7 +266,6 @@ void CWallet::UpgradeKeyMetadata()
}
if (m_spk_man) {
AssertLockHeld(m_spk_man->cs_wallet);
m_spk_man->UpgradeKeyMetadata();
}
SetWalletFlag(WALLET_FLAG_KEY_ORIGIN_METADATA);
@ -1322,6 +1322,7 @@ bool CWallet::IsHDEnabled() const
bool CWallet::CanGetAddresses(bool internal)
{
LOCK(cs_wallet);
{
auto spk_man = m_spk_man.get();
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) {
return false;
}
AssertLockHeld(spk_man->cs_wallet);
LOCK(spk_man->cs_KeyStore);
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) {
return false;
}
AssertLockHeld(spk_man->cs_wallet);
LOCK(spk_man->cs_KeyStore);
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) {
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);
}
@ -1457,7 +1458,7 @@ bool CWallet::ImportScriptPubKeys(const std::string& label, const std::set<CScri
if (!spk_man) {
return false;
}
AssertLockHeld(spk_man->cs_wallet);
LOCK(spk_man->cs_KeyStore);
if (!spk_man->ImportScriptPubKeys(script_pub_keys, have_solving_data, timestamp)) {
return false;
}
@ -3103,7 +3104,6 @@ size_t CWallet::KeypoolCountExternalKeys()
unsigned int count = 0;
if (auto spk_man = m_spk_man.get()) {
AssertLockHeld(spk_man->cs_wallet);
count += spk_man->KeypoolCountExternalKeys();
}
@ -3123,6 +3123,7 @@ unsigned int CWallet::GetKeyPoolSize() const
bool CWallet::TopUpKeyPool(unsigned int kpSize)
{
LOCK(cs_wallet);
bool res = true;
if (auto spk_man = m_spk_man.get()) {
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)
{
LOCK(cs_wallet);
error.clear();
ReserveDestination reservedest(this, type);
@ -3163,6 +3165,7 @@ bool CWallet::GetNewChangeDestination(const OutputType type, CTxDestination& des
int64_t CWallet::GetOldestKeyPoolTime()
{
LOCK(cs_wallet);
int64_t oldestKey = std::numeric_limits<int64_t>::max();
if (auto spk_man = m_spk_man.get()) {
oldestKey = spk_man->GetOldestKeyPoolTime();
@ -3416,7 +3419,7 @@ void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::map<C
LegacyScriptPubKeyMan* spk_man = GetLegacyScriptPubKeyMan();
assert(spk_man != nullptr);
AssertLockHeld(spk_man->cs_wallet);
LOCK(spk_man->cs_KeyStore);
// get birth times for keys with metadata
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);
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 (!spk_man->SetupGeneration()) {
error = _("Unable to generate initial keys").translated;
@ -4064,7 +4068,7 @@ bool CWallet::IsLocked() const
if (!IsCrypted()) {
return false;
}
LOCK(cs_KeyStore);
LOCK(cs_wallet);
return vMasterKey.empty();
}
@ -4074,7 +4078,7 @@ bool CWallet::Lock()
return false;
{
LOCK(cs_KeyStore);
LOCK(cs_wallet);
vMasterKey.clear();
}
@ -4085,7 +4089,7 @@ bool CWallet::Lock()
bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys)
{
{
LOCK(cs_KeyStore);
LOCK(cs_wallet);
if (m_spk_man) {
if (!m_spk_man->CheckDecryptionKey(vMasterKeyIn, accept_no_keys)) {
return false;

View file

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

View file

@ -196,7 +196,7 @@ public:
static bool
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 {
// Unserialize
@ -434,7 +434,6 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
DBErrors result = DBErrors::LOAD_OK;
LOCK(pwallet->cs_wallet);
AssertLockHeld(pwallet->GetLegacyScriptPubKeyMan()->cs_wallet);
try {
int nMinVersion = 0;
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) {
auto spk_man = pwallet->GetLegacyScriptPubKeyMan();
if (spk_man) {
LOCK(spk_man->cs_KeyStore);
spk_man->UpdateTimeFirstKey(1);
}
}
@ -713,7 +713,6 @@ bool WalletBatch::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, C
{
// Required in LoadKeyMetadata():
LOCK(dummyWallet->cs_wallet);
AssertLockHeld(dummyWallet->GetLegacyScriptPubKeyMan()->cs_wallet);
fReadOK = ReadKeyValue(dummyWallet, ssKey, ssValue,
dummyWss, strType, strErr);
}

View file

@ -27,6 +27,7 @@ static std::shared_ptr<CWallet> CreateWallet(const std::string& name, const fs::
}
// dummy chain interface
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;
DBErrors load_wallet_ret = wallet_instance->LoadWallet(first_run);
if (load_wallet_ret != DBErrors::LOAD_OK) {