Skip to content

Commit 1aedc3b

Browse files
committed
Merge bitcoin/bitcoin#26618: rpc: Prevent unloading a wallet when rescanning
109cbb8 doc: Add release notes for #26618 (Aurèle Oulès) b13902d rpc: Prevent unloading a wallet when rescanning (Aurèle Oulès) Pull request description: Fixes #26463. This PR prevents a user from unloading a wallet if it is currently rescanning. To test: ```bash ./src/bitcoin-cli -testnet -named createwallet wallet_name=wo disable_private_keys=true ./src/bitcoin-cli -testnet -rpcwallet=wo importdescriptors '[{ "desc": "addr(mmcuW74MyJUZuLnWXGQLoNXPrS9RbFz6gD)#tpnrahgc", "timestamp": 0, "active": false, "internal": false, "next": 0 }]' ./src/bitcoin-cli -testnet unloadwallet wo error code: -4 error message: Wallet is currently rescanning. Abort existing rescan or wait. ACKs for top commit: achow101: ACK 109cbb8 w0xlt: ACK bitcoin/bitcoin@109cbb8 kouloumos: ACK 109cbb8 promag: ACK 109cbb8 Tree-SHA512: 15fdddf4cf9f3fa08f52069fe4a25a76e04a55bb2586b031bfb0393dce7f175dcdb52823e132a7dff6a894539beeb980a1aad2a792790be036be6977628149b2
2 parents 39363a4 + 109cbb8 commit 1aedc3b

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

doc/release-notes-26618.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
RPC Wallet
2+
----------
3+
4+
- RPC `unloadwallet` now fails if a rescan is in progress. (#26618)

src/wallet/rpc/wallet.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -445,13 +445,20 @@ static RPCHelpMan unloadwallet()
445445
throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
446446
}
447447

448-
// Release the "main" shared pointer and prevent further notifications.
449-
// Note that any attempt to load the same wallet would fail until the wallet
450-
// is destroyed (see CheckUniqueFileid).
451448
std::vector<bilingual_str> warnings;
452-
std::optional<bool> load_on_start = request.params[1].isNull() ? std::nullopt : std::optional<bool>(request.params[1].get_bool());
453-
if (!RemoveWallet(context, wallet, load_on_start, warnings)) {
454-
throw JSONRPCError(RPC_MISC_ERROR, "Requested wallet already unloaded");
449+
{
450+
WalletRescanReserver reserver(*wallet);
451+
if (!reserver.reserve()) {
452+
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
453+
}
454+
455+
// Release the "main" shared pointer and prevent further notifications.
456+
// Note that any attempt to load the same wallet would fail until the wallet
457+
// is destroyed (see CheckUniqueFileid).
458+
std::optional<bool> load_on_start = request.params[1].isNull() ? std::nullopt : std::optional<bool>(request.params[1].get_bool());
459+
if (!RemoveWallet(context, wallet, load_on_start, warnings)) {
460+
throw JSONRPCError(RPC_MISC_ERROR, "Requested wallet already unloaded");
461+
}
455462
}
456463

457464
UnloadWallet(std::move(wallet));

0 commit comments

Comments
 (0)