wallet: fix unnamed wallet migration failure

When migrating any legacy unnamed wallet, a failed migration would
cause the cleanup logic to remove its parent directory. Since this
type of legacy wallet lives directly in the main '/wallets/' folder,
this resulted in unintentionally erasing all wallets, including the
backup file.

To be fully safe, we will no longer call `fs::remove_all`. Instead,
we only erase the individual db files we have created, leaving
everything else intact. The created wallets parent directories are
erased only if they are empty.
As part of this last change, `RestoreWallet` was modified to allow
an existing directory as the destination, since we no longer remove
the original wallet directory (we only remove the files we created
inside it). This also fixes the restore of top-level default wallets
during failures, which were failing due to the directory existence
check that always returns true for the /wallets/ directory.

This bug started after:
f6ee59b6e2
Previously, the `fs::copy_file` call was failing for top-level wallets,
which prevented the `fs::remove_all` call from being reached.

Github-Pull: bitcoin/bitcoin#34156
Rebased-From: f4c7e28e80
This commit is contained in:
furszy
2025-12-26 20:22:55 -05:00
committed by Ava Chow
parent d91f56e1e3
commit a074d36254
2 changed files with 54 additions and 20 deletions

View File

@@ -136,7 +136,7 @@ class WalletBackupTest(BitcoinTestFramework):
backup_file = self.nodes[0].datadir_path / 'wallet.bak'
wallet_name = "res0"
wallet_file = node.wallets_path / wallet_name
error_message = "Failed to create database path '{}'. Database already exists.".format(wallet_file)
error_message = "Failed to restore wallet. Database file exists in '{}'.".format(wallet_file / "wallet.dat")
assert_raises_rpc_error(-36, error_message, node.restorewallet, wallet_name, backup_file)
assert wallet_file.exists()