wallet: Set migrated wallet name only on success #32984

pull achow101 wants to merge 2 commits into bitcoin:master from achow101:migratewallet-dont-set-name-on-failed changing 2 files +30 −5
  1. achow101 commented at 11:51 pm on July 15, 2025: member

    After a wallet is migrated and we are trying to load it, if it could not be loaded, don’t try to set the wallet name. Otherwise we have a segfault.

    This can be tested by migrated a legacy wallet from another network (e.g. trying to migrate a testnet wallet on mainnet). The fixed behavior is return an error and restore the backup.

  2. wallet: Set migrated wallet name only on success
    After a wallet is migrated and we are trying to load it, if it could not be
    loaded, don't try to set the wallet name.
    8a4cfddf23
  3. DrahtBot added the label Wallet on Jul 15, 2025
  4. DrahtBot commented at 11:51 pm on July 15, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32984.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK furszy, davidgumberg, rkrux, w0xlt, pablomartin4btc

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

  5. rkrux approved
  6. rkrux commented at 5:50 am on July 16, 2025: contributor

    lgtm ACK 8a4cfddf23a4575a1042dfa97d3478727775e8dd

    Makes sense to add this.

    I recall thinking once about adding something like this when I was working on #32758, but I forgot later.

  7. maflcko commented at 7:05 am on July 16, 2025: member

    I was unable to write a working functional test for this behavior.

    It should be pretty trivial, see https://github.com/bitcoin/bitcoin/pull/32988

  8. achow101 commented at 6:06 pm on July 16, 2025: member

    I was unable to write a working functional test for this behavior.

    It should be pretty trivial, see #32988

    Ah, thanks. Pulled in that commit with some changes.

  9. DrahtBot requested review from rkrux on Jul 16, 2025
  10. DrahtBot added the label CI failed on Jul 16, 2025
  11. DrahtBot removed the label CI failed on Jul 16, 2025
  12. in test/functional/wallet_migration.py:1391 in 3a0be655c4 outdated
    1386+
    1387+        # Check the wallet we tried to migrate is still BDB
    1388+        with open(self.master_node.wallets_path / wallet_name / "wallet.dat", "rb") as f:
    1389+            data = f.read(16)
    1390+            _, _, magic = struct.unpack("QII", data)
    1391+            assert_equal(magic, BTREE_MAGIC)
    


    furszy commented at 9:20 pm on July 16, 2025:
    Might worth pulling this into a separate function. We use the exact same code in the existing test_failed_migration_cleanup() and also #32273 includes it on test_failed_migration_cleanup_relative_path().

    achow101 commented at 10:18 pm on July 16, 2025:
    Done
  13. furszy commented at 9:22 pm on July 16, 2025: member
    ACK 3a0be655c4fd5c74731f1fcb57c45e6a8c3c362f with a small nuance.
  14. test: Failed load after migrate should restore backup 060695c22a
  15. achow101 force-pushed on Jul 16, 2025
  16. furszy commented at 10:21 pm on July 16, 2025: member
    ACK 060695c22ae7b2b0f2a1dd1417ed1b9d5a5ab542
  17. DrahtBot requested review from w0xlt on Jul 16, 2025
  18. davidgumberg commented at 11:47 pm on July 16, 2025: contributor

    ACK 060695c22ae7b2b0f2a1d

    I think this change is good since we can’t ever be certain that loading will always succeed after migration, but I think cases where we know migration will succeed but loading will fail should be addressed. i.e. shouldn’t we also change migration so that the case used in the functional test never successfully migrated in the first place?

    Nit: Update PR description now that functional test is included.

  19. in test/functional/wallet_migration.py:1388 in 060695c22a
    1383+        # Disable network sync and prevent disk space warning on small (tmp)fs
    1384+        self.start_node(self.old_node.index, extra_args=self.old_node.extra_args + ["-maxconnections=0", "-prune=550"])
    1385+
    1386+        wallet_name = "failed_load_after_migrate"
    1387+        self.create_legacy_wallet(wallet_name)
    1388+        assert_raises_rpc_error(-4, "Wallet loading failed. Wallet files should not be reused across chains.", lambda: self.migrate_and_get_rpc(wallet_name))
    


    rkrux commented at 11:52 am on July 17, 2025:

    In 060695c22ae7b2b0f2a1dd1417ed1b9d5a5ab542 “test: Failed load after migrate should restore backup”

    Adding a review note because it took me some time to understand why this error pops up only after migration is complete and not during the process as this particular error comes from inside CWallet::AttachChain that is a part of CWallet::Create. The reason I found is that all the CWallet::Create calls inside the migration process pass an empty context that doesn’t contain the chain due to which the chain doesn’t need to be attached. Only while loading the wallet after migration, the proper wallet context is passed that triggers this error.

    https://github.com/bitcoin/bitcoin/blob/9f713b83dcf7480e6c4447f0f263bef096d55cc7/src/wallet/wallet.cpp#L4206-L4210

    I verified that the migration-before-loading was triggered/completed by using the below patch in the migrate_and_get_rpc function. The below patch can be added separately as well (not necessary in this PR) because all the tests pass.

     0diff --git a/test/functional/wallet_migration.py b/test/functional/wallet_migration.py
     1index a1b319b90b..890478da26 100755
     2--- a/test/functional/wallet_migration.py
     3+++ b/test/functional/wallet_migration.py
     4@@ -125,7 +125,7 @@ class WalletMigrationTest(BitcoinTestFramework):
     5             if w["name"] == wallet_name:
     6                 assert_equal(w["warnings"], ["This wallet is a legacy wallet and will need to be migrated with migratewallet before it can be loaded"])
     7         # Migrate, checking that rescan does not occur
     8-        with self.master_node.assert_debug_log(expected_msgs=[], unexpected_msgs=["Rescanning"]):
     9+        with self.master_node.assert_debug_log(expected_msgs=["Migrating wallet storage database from BerkeleyDB to SQLite."], unexpected_msgs=["Rescanning"]):
    10             migrate_info = self.master_node.migratewallet(wallet_name=wallet_name, **kwargs)
    11         # Update wallet name in case the initial wallet was completely migrated to a watch-only wallet
    12         # (in which case the wallet name would be suffixed by the 'watchonly' term)
    
  20. rkrux commented at 11:52 am on July 17, 2025: contributor
    ACK 060695c22ae7b2b0f2a1dd1417ed1b9d5a5ab542
  21. pablomartin4btc commented at 2:32 am on July 24, 2025: member

    ACK 060695c22ae7b2b0f2a1dd1417ed1b9d5a5ab542

    On a side note: should we not check the wallet chain before executing the migration on it instead of letting it go that far?

  22. fanquake merged this on Jul 24, 2025
  23. fanquake closed this on Jul 24, 2025


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-07-25 18:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me