aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r--src/wallet/wallet.cpp60
1 files changed, 30 insertions, 30 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 8e31950beb..8df39b9f75 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -162,10 +162,14 @@ bool RemoveWallet(WalletContext& context, const std::shared_ptr<CWallet>& wallet
// Unregister with the validation interface which also drops shared pointers.
wallet->m_chain_notifications_handler.reset();
- LOCK(context.wallets_mutex);
- std::vector<std::shared_ptr<CWallet>>::iterator i = std::find(context.wallets.begin(), context.wallets.end(), wallet);
- if (i == context.wallets.end()) return false;
- context.wallets.erase(i);
+ {
+ LOCK(context.wallets_mutex);
+ std::vector<std::shared_ptr<CWallet>>::iterator i = std::find(context.wallets.begin(), context.wallets.end(), wallet);
+ if (i == context.wallets.end()) return false;
+ context.wallets.erase(i);
+ }
+ // Notify unload so that upper layers release the shared pointer.
+ wallet->NotifyUnload();
// Write the wallet setting
UpdateWalletSetting(chain, name, load_on_start, warnings);
@@ -223,38 +227,35 @@ static std::set<std::string> g_loading_wallet_set GUARDED_BY(g_loading_wallet_mu
static std::set<std::string> g_unloading_wallet_set GUARDED_BY(g_wallet_release_mutex);
// Custom deleter for shared_ptr<CWallet>.
-static void ReleaseWallet(CWallet* wallet)
+static void FlushAndDeleteWallet(CWallet* wallet)
{
const std::string name = wallet->GetName();
- wallet->WalletLogPrintf("Releasing wallet\n");
+ wallet->WalletLogPrintf("Releasing wallet %s..\n", name);
wallet->Flush();
delete wallet;
- // Wallet is now released, notify UnloadWallet, if any.
+ // Wallet is now released, notify WaitForDeleteWallet, if any.
{
LOCK(g_wallet_release_mutex);
if (g_unloading_wallet_set.erase(name) == 0) {
- // UnloadWallet was not called for this wallet, all done.
+ // WaitForDeleteWallet was not called for this wallet, all done.
return;
}
}
g_wallet_release_cv.notify_all();
}
-void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
+void WaitForDeleteWallet(std::shared_ptr<CWallet>&& wallet)
{
// Mark wallet for unloading.
const std::string name = wallet->GetName();
{
LOCK(g_wallet_release_mutex);
- auto it = g_unloading_wallet_set.insert(name);
- assert(it.second);
+ g_unloading_wallet_set.insert(name);
+ // Do not expect to be the only one removing this wallet.
+ // Multiple threads could simultaneously be waiting for deletion.
}
- // The wallet can be in use so it's not possible to explicitly unload here.
- // Notify the unload intent so that all remaining shared pointers are
- // released.
- wallet->NotifyUnload();
- // Time to ditch our shared_ptr and wait for ReleaseWallet call.
+ // Time to ditch our shared_ptr and wait for FlushAndDeleteWallet call.
wallet.reset();
{
WAIT_LOCK(g_wallet_release_mutex, lock);
@@ -1037,9 +1038,8 @@ bool CWallet::IsSpentKey(const CScript& scriptPubKey) const
if (IsAddressPreviouslySpent(dest)) {
return true;
}
- if (IsLegacy()) {
- LegacyScriptPubKeyMan* spk_man = GetLegacyScriptPubKeyMan();
- assert(spk_man != nullptr);
+
+ if (LegacyScriptPubKeyMan* spk_man = GetLegacyScriptPubKeyMan()) {
for (const auto& keyid : GetAffectedKeys(scriptPubKey, *spk_man)) {
WitnessV0KeyHash wpkh_dest(keyid);
if (IsAddressPreviouslySpent(wpkh_dest)) {
@@ -1625,7 +1625,9 @@ isminetype CWallet::IsMine(const CScript& script) const
}
// Legacy wallet
- if (IsLegacy()) return GetLegacyScriptPubKeyMan()->IsMine(script);
+ if (LegacyScriptPubKeyMan* spkm = GetLegacyScriptPubKeyMan()) {
+ return spkm->IsMine(script);
+ }
return ISMINE_NO;
}
@@ -2971,7 +2973,7 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
const auto start{SteadyClock::now()};
// TODO: Can't use std::make_shared because we need a custom deleter but
// should be possible to use std::allocate_shared.
- std::shared_ptr<CWallet> walletInstance(new CWallet(chain, name, std::move(database)), ReleaseWallet);
+ std::shared_ptr<CWallet> walletInstance(new CWallet(chain, name, std::move(database)), FlushAndDeleteWallet);
walletInstance->m_keypool_size = std::max(args.GetIntArg("-keypool", DEFAULT_KEYPOOL_SIZE), int64_t{1});
walletInstance->m_notify_tx_changed_script = args.GetArg("-walletnotify", "");
@@ -3558,7 +3560,8 @@ std::set<ScriptPubKeyMan*> CWallet::GetScriptPubKeyMans(const CScript& script) c
Assume(std::all_of(spk_mans.begin(), spk_mans.end(), [&script, &sigdata](ScriptPubKeyMan* spkm) { return spkm->CanProvide(script, sigdata); }));
// Legacy wallet
- if (IsLegacy() && GetLegacyScriptPubKeyMan()->CanProvide(script, sigdata)) spk_mans.insert(GetLegacyScriptPubKeyMan());
+ LegacyScriptPubKeyMan* spkm = GetLegacyScriptPubKeyMan();
+ if (spkm && spkm->CanProvide(script, sigdata)) spk_mans.insert(spkm);
return spk_mans;
}
@@ -3588,7 +3591,8 @@ std::unique_ptr<SigningProvider> CWallet::GetSolvingProvider(const CScript& scri
}
// Legacy wallet
- if (IsLegacy() && GetLegacyScriptPubKeyMan()->CanProvide(script, sigdata)) return GetLegacyScriptPubKeyMan()->GetSolvingProvider(script);
+ LegacyScriptPubKeyMan* spkm = GetLegacyScriptPubKeyMan();
+ if (spkm && spkm->CanProvide(script, sigdata)) return spkm->GetSolvingProvider(script);
return nullptr;
}
@@ -3845,11 +3849,7 @@ void CWallet::DeactivateScriptPubKeyMan(uint256 id, OutputType type, bool intern
bool CWallet::IsLegacy() const
{
- if (m_internal_spk_managers.count(OutputType::LEGACY) == 0) {
- return false;
- }
- auto spk_man = dynamic_cast<LegacyScriptPubKeyMan*>(m_internal_spk_managers.at(OutputType::LEGACY));
- return spk_man != nullptr;
+ return !IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS);
}
DescriptorScriptPubKeyMan* CWallet::GetDescriptorScriptPubKeyMan(const WalletDescriptor& desc) const
@@ -4387,7 +4387,7 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
if (!RemoveWallet(context, wallet, /*load_on_start=*/std::nullopt, warnings)) {
return util::Error{_("Unable to unload the wallet before migrating")};
}
- UnloadWallet(std::move(wallet));
+ WaitForDeleteWallet(std::move(wallet));
was_loaded = true;
} else {
// Check if the wallet is BDB
@@ -4531,7 +4531,7 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
error += _("\nUnable to cleanup failed migration");
return util::Error{error};
}
- UnloadWallet(std::move(w));
+ WaitForDeleteWallet(std::move(w));
} else {
// Unloading for wallets in local context
assert(w.use_count() == 1);